From 96d573bc9d8521df3bd0f6a0e5054cb598d3039e Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 11 Jun 2013 10:09:20 -0400 Subject: [PATCH 001/460] Change for an initial SeriaLink, and QGCToolBar having a selection menu next to the connect button --- src/QGCCore.cc | 6 +++++ src/ui/QGCToolBar.cc | 55 +++++++++++++++++++++++++++++++++++++++++++- src/ui/QGCToolBar.h | 4 +++- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/QGCCore.cc b/src/QGCCore.cc index d6d7e512a7..3354fe646e 100644 --- a/src/QGCCore.cc +++ b/src/QGCCore.cc @@ -52,6 +52,7 @@ This file is part of the QGROUNDCONTROL project #endif #include "UDPLink.h" #include "MAVLinkSimulationLink.h" +#include "SerialLink.h" /** @@ -157,6 +158,11 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv) MAVLinkSimulationLink* simulationLink = new MAVLinkSimulationLink(":/demo-log.txt"); simulationLink->disconnect(); + + //We want to have a default serial link available for "quick" connecting. + SerialLink *slink = new SerialLink(); + MainWindow::instance()->addLink(slink); + mainWindow = MainWindow::instance(splashScreen); // Remove splash screen diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index e887658f53..78ccac7aa0 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -24,6 +24,7 @@ This file is part of the QGROUNDCONTROL project #include #include #include +#include "SerialLink.h" #include "QGCToolBar.h" #include "UASManager.h" #include "MainWindow.h" @@ -160,6 +161,11 @@ void QGCToolBar::createUI() spacer->setStyleSheet("* { margin: 0px; background-color: transparent; min-height: 24px}"); addWidget(spacer); + portComboBox = new QComboBox(this); + portComboBox->setToolTip(tr("Choose the COM port to use")); + portComboBox->setEnabled(true); + portComboBox->setMinimumWidth(200); + addWidget(portComboBox); connectButton = new QPushButton(tr("Connect"), this); connectButton->setToolTip(tr("Connect wireless link to MAV")); connectButton->setCheckable(true); @@ -523,12 +529,15 @@ void QGCToolBar::addLink(LinkInterface* link) connect(currentLink, SIGNAL(connected(bool)), this, SLOT(updateLinkState(bool))); updateLinkState(link->isConnected()); } + updateComboBox(); } void QGCToolBar::removeLink(LinkInterface* link) { if (link == currentLink) { currentLink = NULL; + //portComboBox->setEnabled(false); + //portComboBox->clear(); // XXX magic number if (LinkManager::instance()->getLinks().count() > 2) { currentLink = LinkManager::instance()->getLinks().last(); @@ -537,6 +546,32 @@ void QGCToolBar::removeLink(LinkInterface* link) connectButton->setText(tr("New Link")); } } + updateComboBox(); +} +void QGCToolBar::updateComboBox() +{ + portComboBox->clear(); + for (int i=0;igetLinks().count();i++) + { + SerialLink *slink = qobject_cast(LinkManager::instance()->getLinks()[i]); + if (slink) + { + //It's a serial link + QVector *portlist = slink->getCurrentPorts(); + //if (!slink->isConnected()) + //{ + for (int j=0;jsize();j++) + { + portComboBox->addItem("Serial port:" + QString::number(i) + ":" + portlist->at(j)); + } + //} + //We only really want to display from unconnected sources. + } + else + { + portComboBox->addItem(LinkManager::instance()->getLinks()[i]->getName()); + } + } } void QGCToolBar::updateLinkState(bool connected) @@ -566,7 +601,25 @@ void QGCToolBar::connectLink(bool connect) { MainWindow::instance()->addLink(); } else if (connect) { - LinkManager::instance()->getLinks().last()->connect(); + if (portComboBox->currentText().split(":").count()>2) + { + int linknum = portComboBox->currentText().split(":")[1].toInt(); + SerialLink *link = qobject_cast(LinkManager::instance()->getLinks().at(linknum)); + if (link) + { + QString portname = portComboBox->currentText().split(":")[2]; + if (portname.indexOf('-') != -1) + { + portname = portname.split("-")[0]; + } + link->setPortName(portname.trimmed()); + } + link->connect(); + } + else + { + LinkManager::instance()->getLinks().last()->connect(); + } } else if (!connect && LinkManager::instance()->getLinks().count() > 2) { LinkManager::instance()->getLinks().last()->disconnect(); } diff --git a/src/ui/QGCToolBar.h b/src/ui/QGCToolBar.h index f83e446191..887c73e836 100644 --- a/src/ui/QGCToolBar.h +++ b/src/ui/QGCToolBar.h @@ -30,6 +30,7 @@ This file is part of the QGROUNDCONTROL project #include #include #include +#include #include "UASInterface.h" #include "QGCMAVLinkLogPlayer.h" @@ -88,7 +89,7 @@ protected: void storeSettings(); void loadSettings(); void createUI(); - + void updateComboBox(); UASInterface* mav; QToolButton* symbolButton; QLabel* toolBarNameLabel; @@ -103,6 +104,7 @@ protected: QProgressBar* toolBarBatteryBar; QLabel* toolBarBatteryVoltageLabel; QGCMAVLinkLogPlayer* player; + QComboBox *portComboBox; bool changed; float batteryPercent; float batteryVoltage; -- GitLab From 2c9317b5db1b70cbc65f52b68d09db2160e108a0 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 12 Jun 2013 07:33:27 -0400 Subject: [PATCH 002/460] Changed radio calibration min/max to 800/2200 for APM connected RC units --- src/ui/QGCVehicleConfig.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ui/QGCVehicleConfig.cc b/src/ui/QGCVehicleConfig.cc index f5982b9a4c..97fba83817 100644 --- a/src/ui/QGCVehicleConfig.cc +++ b/src/ui/QGCVehicleConfig.cc @@ -1460,14 +1460,14 @@ void QGCVehicleConfig::updateView() ui->throttleWidget->setValue(rcValue[2]); ui->yawWidget->setValue(rcValue[3]); - ui->rollWidget->setMin(rcMin[0]); - ui->rollWidget->setMax(rcMax[0]); - ui->pitchWidget->setMin(rcMin[1]); - ui->pitchWidget->setMax(rcMax[1]); - ui->throttleWidget->setMin(rcMin[2]); - ui->throttleWidget->setMax(rcMax[2]); - ui->yawWidget->setMin(rcMin[3]); - ui->yawWidget->setMax(rcMax[3]); + ui->rollWidget->setMin(800); + ui->rollWidget->setMax(2200); + ui->pitchWidget->setMin(800); + ui->pitchWidget->setMax(2200); + ui->throttleWidget->setMin(800); + ui->throttleWidget->setMax(2200); + ui->yawWidget->setMin(800); + ui->yawWidget->setMax(2200); } ui->chanLabel->setText(QString("%1/%2").arg(rcValue[rcMapping[0]]).arg(rcRoll, 5, 'f', 2, QChar(' '))); -- GitLab From ba6c9ba93b9e73be03e5f05fbc6ec364c3ab9041 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 12 Jun 2013 12:36:44 -0400 Subject: [PATCH 003/460] Change for InfoView's QuickView text sizing, and reenabling of RawStatusView --- src/ui/UASRawStatusView.cpp | 2 +- src/ui/uas/UASQuickView.cc | 1 + src/ui/uas/UASQuickViewTextItem.cc | 39 +++++++++++++++++++++++++++--- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/ui/UASRawStatusView.cpp b/src/ui/UASRawStatusView.cpp index 51c48191bf..7f12bfa494 100644 --- a/src/ui/UASRawStatusView.cpp +++ b/src/ui/UASRawStatusView.cpp @@ -16,7 +16,7 @@ UASRawStatusView::UASRawStatusView(QWidget *parent) : QWidget(parent) // FIXME reinstate once fixed. - //timer->start(2000); + timer->start(2000); } void UASRawStatusView::addSource(MAVLinkDecoder *decoder) { diff --git a/src/ui/uas/UASQuickView.cc b/src/ui/uas/UASQuickView.cc index afc633b03e..b6d06645b0 100644 --- a/src/ui/uas/UASQuickView.cc +++ b/src/ui/uas/UASQuickView.cc @@ -77,6 +77,7 @@ UASQuickView::UASQuickView(QWidget *parent) : QWidget(parent) uasPropertyToLabelMap["distToWaypoint"] = item; }*/ + //this->setSizePolicy(); loadSettings(); //If we don't have any predefined settings, set some defaults. if (uasPropertyValueMap.size() == 0) diff --git a/src/ui/uas/UASQuickViewTextItem.cc b/src/ui/uas/UASQuickViewTextItem.cc index d03d1f9dc9..11920e4966 100644 --- a/src/ui/uas/UASQuickViewTextItem.cc +++ b/src/ui/uas/UASQuickViewTextItem.cc @@ -1,5 +1,6 @@ #include "UASQuickViewTextItem.h" #include +#include UASQuickViewTextItem::UASQuickViewTextItem(QWidget *parent) : UASQuickViewItem(parent) { QVBoxLayout *layout = new QVBoxLayout(); @@ -7,13 +8,15 @@ UASQuickViewTextItem::UASQuickViewTextItem(QWidget *parent) : UASQuickViewItem(p layout->setSpacing(0); layout->setMargin(0); titleLabel = new QLabel(this); + titleLabel->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); titleLabel->setAlignment(Qt::AlignHCenter); this->layout()->addWidget(titleLabel); valueLabel = new QLabel(this); + valueLabel->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); valueLabel->setAlignment(Qt::AlignHCenter); valueLabel->setText("0.00"); this->layout()->addWidget(valueLabel); - layout->addSpacerItem(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding)); + layout->addSpacerItem(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Ignored)); QFont valuefont = valueLabel->font(); QFont titlefont = titleLabel->font(); valuefont.setPixelSize(this->height() / 2.0); @@ -34,8 +37,38 @@ void UASQuickViewTextItem::resizeEvent(QResizeEvent *event) { QFont valuefont = valueLabel->font(); QFont titlefont = titleLabel->font(); - valuefont.setPixelSize(this->height() / 2.0); - titlefont.setPixelSize(this->height() / 4.0); + valuefont.setPixelSize(this->height()); + titlefont.setPixelSize(valuefont.pixelSize() / 2.0); + + QFontMetrics metrics(valuefont); + //valuefont.setPixelSize(this->height() / 2.0); + bool fit = false; + while (!fit) + { + + QFontMetrics valfm( valuefont ); + QRect valbound = valfm.boundingRect(0,0, valueLabel->width(), valueLabel->height(), Qt::TextWordWrap | Qt::AlignLeft, valueLabel->text()); + //QFontMetrics titlefm( titlefont ); + //QRect titlebound = titlefm.boundingRect(0,0, titleLabel->width(), titleLabel->height(), Qt::TextWordWrap | Qt::AlignLeft, titleLabel->text()); + + if ((valbound.width() <= valueLabel->width() && valbound.height() <= valueLabel->height()))// && (titlebound.width() <= titleLabel->width() && titlebound.height() <= titleLabel->height())) + fit = true; + else + { + if (valuefont.pixelSize()-5 <= 0) + { + fit = true; + valuefont.setPixelSize(5); + } + else + { + valuefont.setPixelSize(valuefont.pixelSize() - 5); + } + //titlefont.setPixelSize(valuefont.pixelSize() / 2.0); + //qDebug() << "Point size:" << valuefont.pixelSize() << valueLabel->width() << valueLabel->height(); + } + } +titlefont.setPixelSize(valuefont.pixelSize() / 2.0); valueLabel->setFont(valuefont); titleLabel->setFont(titlefont); update(); -- GitLab From 5b969d254cbb9ee9a851ee121cb17dfcd3e7d6da Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Thu, 13 Jun 2013 15:53:52 -0400 Subject: [PATCH 004/460] Fix for a crash involving RawStatusView --- src/ui/UASRawStatusView.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui/UASRawStatusView.cpp b/src/ui/UASRawStatusView.cpp index 7f12bfa494..ca0ac37003 100644 --- a/src/ui/UASRawStatusView.cpp +++ b/src/ui/UASRawStatusView.cpp @@ -122,6 +122,7 @@ void UASRawStatusView::updateTableTimerTick() //We're over what we can do. Add a column and continue. columncount+=2; broke = true; + i = valueMap.constEnd(); // Ensure loop breakout. break; } } -- GitLab From f418c2e555b7fac565670422e76e1cc25a5eb891 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 12 Jun 2013 12:37:46 -0400 Subject: [PATCH 005/460] Addition of requestReset to LinkInterface, to allow MavLinkProtocol to detect when connected, but at the wrong baud rate, request a reset. --- src/comm/LinkInterface.h | 2 ++ src/comm/MAVLinkProtocol.cc | 21 +++++++++++++++++++++ src/comm/MAVLinkSimulationLink.h | 2 +- src/comm/SerialLink.cc | 16 +++++++++++++++- src/comm/SerialLink.h | 5 ++++- src/comm/SerialLinkInterface.h | 2 +- src/comm/UDPLink.h | 2 ++ src/comm/XbeeLink.h | 3 ++- 8 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/comm/LinkInterface.h b/src/comm/LinkInterface.h index 0cd15b3124..a36787af5d 100644 --- a/src/comm/LinkInterface.h +++ b/src/comm/LinkInterface.h @@ -61,6 +61,8 @@ public: */ virtual QString getName() = 0; + virtual void requestReset() = 0; + /** * @brief Determine the connection status * diff --git a/src/comm/MAVLinkProtocol.cc b/src/comm/MAVLinkProtocol.cc index 0b8e314104..180670b813 100644 --- a/src/comm/MAVLinkProtocol.cc +++ b/src/comm/MAVLinkProtocol.cc @@ -215,8 +215,11 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b) mavlink_status_t status; static int mavlink09Count = 0; + static int nonmavlinkCount = 0; static bool decodedFirstPacket = false; static bool warnedUser = false; + static bool checkedUserNonMavlink = false; + static bool warnedUserNonMavlink = false; for (int position = 0; position < b.size(); position++) { unsigned int decodeState = mavlink_parse_char(link->getId(), (uint8_t)(b[position]), &message, &status); @@ -230,6 +233,24 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b) emit protocolStatusMessage("MAVLink Version or Baud Rate Mismatch", "Your MAVLink device seems to use the deprecated version 0.9, while QGroundControl only supports version 1.0+. Please upgrade the MAVLink version of your autopilot. If your autopilot is using version 1.0, check if the baud rates of QGroundControl and your autopilot are the same."); } + if (decodeState == 0 && !decodedFirstPacket) + { + nonmavlinkCount++; + if (nonmavlinkCount > 500 && !warnedUserNonMavlink) + { + //500 bytes with no mavlink message. Are we connected to a mavlink capable device? + if (!checkedUserNonMavlink) + { + link->requestReset(); + checkedUserNonMavlink = true; + } + else + { + warnedUserNonMavlink = true; + emit protocolStatusMessage("MAVLink Baud Rate Mismatch", "Please check if the baud rates of QGroundControl and your autopilot are the same."); + } + } + } if (decodeState == 1) { decodedFirstPacket = true; diff --git a/src/comm/MAVLinkSimulationLink.h b/src/comm/MAVLinkSimulationLink.h index 64520a50a2..6c181112ef 100644 --- a/src/comm/MAVLinkSimulationLink.h +++ b/src/comm/MAVLinkSimulationLink.h @@ -54,7 +54,7 @@ public: qint64 bytesAvailable(); void run(); - + void requestReset() { } bool connect(); bool disconnect(); diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index ae2cde0a79..b9bb95326e 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -213,7 +213,8 @@ SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, port(NULL), ports(new QVector()), m_stopp(false), - bytesRead(0) + bytesRead(0), + m_reqReset(false) { // Setup settings this->porthandle = portname.trimmed(); @@ -265,6 +266,11 @@ SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, } loadSettings(); } +void SerialLink::requestReset() +{ + QMutexLocker locker(&this->m_stoppMutex); + m_reqReset = true; +} SerialLink::~SerialLink() { @@ -417,6 +423,14 @@ void SerialLink::run() this->m_stopp = false; break; } + if (m_reqReset) + { + this->m_reqReset = false; + communicationUpdate(getName(),"Reset requested via DTR signal"); + port->setDtr(true); + this->msleep(250); + port->setDtr(false); + } } // Check if new bytes have arrived, if yes, emit the notification signal checkForBytes(); diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index 5ba8dee1a6..d1f0aa2392 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -71,6 +71,8 @@ public: /** @brief Get a list of the currently available ports */ QVector* getCurrentPorts(); + void requestReset(); + bool isConnected(); qint64 bytesAvailable(); @@ -170,7 +172,8 @@ protected: QVector* ports; private: - volatile bool m_stopp; + volatile bool m_stopp; + volatile bool m_reqReset; QMutex m_stoppMutex; void setName(QString name); diff --git a/src/comm/SerialLinkInterface.h b/src/comm/SerialLinkInterface.h index cc190b3831..59ff90132e 100644 --- a/src/comm/SerialLinkInterface.h +++ b/src/comm/SerialLinkInterface.h @@ -47,7 +47,7 @@ public: virtual int getBaudRate() = 0; virtual int getDataBits() = 0; virtual int getStopBits() = 0; - + virtual void requestReset() = 0; virtual int getBaudRateType() = 0; virtual int getFlowType() = 0; virtual int getParityType() = 0; diff --git a/src/comm/UDPLink.h b/src/comm/UDPLink.h index 41f1158f24..82619c0b46 100644 --- a/src/comm/UDPLink.h +++ b/src/comm/UDPLink.h @@ -49,6 +49,8 @@ public: //UDPLink(QHostAddress host = "239.255.76.67", quint16 port = 7667); ~UDPLink(); + void requestReset() { } + bool isConnected(); qint64 bytesAvailable(); int getPort() const { diff --git a/src/comm/XbeeLink.h b/src/comm/XbeeLink.h index e07e95f8c5..cc691a4a62 100644 --- a/src/comm/XbeeLink.h +++ b/src/comm/XbeeLink.h @@ -21,6 +21,7 @@ public: public: // virtual functions from XbeeLinkInterface QString getPortName(); + void requestReset() { } int getBaudRate(); public slots: // virtual functions from XbeeLinkInterface @@ -71,4 +72,4 @@ private: }; -#endif // _XBEELINK_H_ \ No newline at end of file +#endif // _XBEELINK_H_ -- GitLab From bdeb97354254b073640ac698bae287b1c5372504 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Thu, 13 Jun 2013 15:14:31 -0400 Subject: [PATCH 006/460] Change of name for diydrones fork of QGroundControl to APM Planner 2.0, per Chris Anderson and Craig Elder --- qgroundcontrol.pro | 2 +- qgroundcontrol.qrc | 2 ++ src/QGCCore.cc | 8 ++++---- src/configuration.h | 10 +++++----- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 9990466ebc..bf6c51e0fa 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -30,7 +30,7 @@ QT += network \ sql TEMPLATE = app -TARGET = qgroundcontrol +TARGET = apmplanner2 BASEDIR = $${IN_PWD} linux-g++|linux-g++-64{ debug { diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 4b47ee099e..c36f4140c9 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -102,6 +102,8 @@ files/images/patterns/lenna.jpg files/images/rc_stick.svg files/images/actions/qgroundcontrol-connect.svg + files/images/apm_planner_logo.png + files/images/apm_planner_logo_splash.png files/styles/Vera.ttf diff --git a/src/QGCCore.cc b/src/QGCCore.cc index 3354fe646e..43d170b72a 100644 --- a/src/QGCCore.cc +++ b/src/QGCCore.cc @@ -71,8 +71,8 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv) // Set application name this->setApplicationName(QGC_APPLICATION_NAME); this->setApplicationVersion(QGC_APPLICATION_VERSION); - this->setOrganizationName(QLatin1String("QGroundControl")); - this->setOrganizationDomain("org.qgroundcontrol"); + this->setOrganizationName(QLatin1String("3DRobotics")); + this->setOrganizationDomain("org.3drobotics"); // Set settings format QSettings::setDefaultFormat(QSettings::IniFormat); @@ -108,7 +108,7 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv) settings.sync(); // Show splash screen - QPixmap splashImage(":/files/images/splash.png"); + QPixmap splashImage(":/files/images/apm_planner_logo_splash.png"); QSplashScreen* splashScreen = new QSplashScreen(splashImage); // Delete splash screen after mainWindow was displayed splashScreen->setAttribute(Qt::WA_DeleteOnClose); @@ -168,7 +168,7 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv) // Remove splash screen splashScreen->finish(mainWindow); - if (upgraded) mainWindow->showInfoMessage(tr("Default Settings Loaded"), tr("QGroundControl has been upgraded from version %1 to version %2. Some of your user preferences have been reset to defaults for safety reasons. Please adjust them where needed.").arg(lastApplicationVersion).arg(QGC_APPLICATION_VERSION)); + if (upgraded) mainWindow->showInfoMessage(tr("Default Settings Loaded"), tr("APM Planner has been upgraded from version %1 to version %2. Some of your user preferences have been reset to defaults for safety reasons. Please adjust them where needed.").arg(lastApplicationVersion).arg(QGC_APPLICATION_VERSION)); // Check if link could be connected if (!udpLink->connect()) diff --git a/src/configuration.h b/src/configuration.h index 88e19d8258..f6a9a7bb31 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -10,15 +10,15 @@ #define MAVLINK_HEARTBEAT_DEFAULT_RATE 1 #define WITH_TEXT_TO_SPEECH 1 -#define QGC_APPLICATION_NAME "QGroundControl" -#define QGC_APPLICATION_VERSION "v. 1.0.9 (beta RC1)" +#define QGC_APPLICATION_NAME "APM Planner" +#define QGC_APPLICATION_VERSION "v2.0.0 (beta)" namespace QGC { -const QString APPNAME = "QGROUNDCONTROL"; -const QString COMPANYNAME = "QGROUNDCONTROL"; -const int APPLICATIONVERSION = 109; // 1.0.9 +const QString APPNAME = "APMPLANNER"; +const QString COMPANYNAME = "3DROBOTICS"; +const int APPLICATIONVERSION = 200; // 1.0.9 } #endif // QGC_CONFIGURATION_H -- GitLab From da79b6cef62403b25dbd61c91ffe85d8b4eed170 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 14 Jun 2013 11:40:43 -0400 Subject: [PATCH 007/460] Change for new APM2.0 logo --- files/images/apm_planner_2_0-07.png | Bin 0 -> 47925 bytes files/images/apm_planner_2_0-08.png | Bin 0 -> 120768 bytes files/images/apm_planner_logo.png | Bin 0 -> 97578 bytes files/images/apm_planner_logo_splash.png | Bin 0 -> 55172 bytes qgroundcontrol.qrc | 2 ++ src/QGCCore.cc | 6 +++--- 6 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 files/images/apm_planner_2_0-07.png create mode 100644 files/images/apm_planner_2_0-08.png create mode 100644 files/images/apm_planner_logo.png create mode 100644 files/images/apm_planner_logo_splash.png diff --git a/files/images/apm_planner_2_0-07.png b/files/images/apm_planner_2_0-07.png new file mode 100644 index 0000000000000000000000000000000000000000..d0bfe8fd42042c8f50c900e0e48d7d8d10aeaeb5 GIT binary patch literal 47925 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYU<~A7V_;zDnRrr_fq{XsILO_JVcj{ImkbOH zEa{HEjtmSN`?>!lvNA9*a29w(7BevL9RXp+soH$f3=9mCC9V-A!TD(=<%vb942~)J zNvR5+xryniL8*x;m4zo$Z5SAKE%kJ945^5FJD0WQ&M~3(<7diFB&KCqXc`+E8yC+u z+Fx|pBsJ}sS%9B(T3Q;L@#We7Pi;Ei_s}ou?#r6Z@5}YK>aI=Of7R34TExvI_0L2# zmX-zq0VXF04h}{|1rVoTj>C?};S;!Fe1zmF&JHG}?MqJLX@fHroKnJIkMX588{35{Qbbyz|g|YCkP6rRFxPl8u2a}MJ zux@!0UOhzh8>AwE^Mgc0!l0{jGPlYrwvFHd@K?Rdpp;K_2|twIo)>D zB*Lf|Aj}x(uxF3{E>p`XcCiJfy0 zHQoi^JpaCYRQEnGrD98g5Nc#PEs$eMOboE@QRC|9-|n3kXtmemt3nr7_u}N;e9INr zp8vj)-7*F(C5bTxI^>-DerwCiFINw}*3>fUn{}jg5%;fsew`P6bH8aV=SE4wjcuL> zf*B`D2yhqQ+4+&NB%}TH$~8JYpSmu+I6G7Q@)F+nQ7=6G1W_Hf(A6PkL(ZA+;oW)5 zWGzo?TG`Cw^8T!0rqp=u-Cv`nY9$*luAZZXnh>PK7z+lRqF$IUOaQ7z!{ut@rK`0&adOBxRU zKK$ZIUVm`Ao3lxr?=G~UJLv8pB5<~Nn_;qE?d~68UR{1mH+3x7y#YuUi$Bq-?C_jr<$ zmX`J+WvhE$dxQE*ADp_h6iu%=Nbjuq^QZAGUwgA#)68b#DWxgSV$se@D^1q)blnJD z9a)oZwez^Ji1f@S6Id>-Mbj@2(m!YN_vdrGRa1}VFm$dAa5!Y4*K+F6$|*Obf+l%8 z--_{Rj+*;;fykw;XnOgZ!Tdq!G3Ud-# zBz4jAuH51$H>UA?{~;dAK=5o^DcnI$cEmu1}<+(haUd z3l-KhD44N`3HI?n{I92TZuy4}4Xb6JZLcV8Y?oJ=?2Rb3z=hs_ApzDS{(FwEshHAy zX?nrZFD{4wc8N|bc-nXLsnelDJM%m&s?!eYcCT1qG1+Pf&r)TpyU)~LJ~0AohG)S8 z_AD-pANkWur}jUOKld)oRZGKm&fN_GD+Hzq99CjtWs!?|GcQ!k(RC^7n%Pq>9(=q0 z8B^QgKN?G8yimPm0ZLiVZ@jx)T$rg?dtm0qB+C~zlcx3=mF+hY5ztWjvpL9NM}?ww z+SHHdWt0{*T?w{KeLr#T`v=8Ie>B#joAyFofvcl#S?RYOw$+w@x4e<_>dQRH#o^wt zVbQ{-i;0X68A?-m9r*(s7Bp^fU9x7%|Un+OD@6+ZZMV4?6g6qHq{S6ul zzapycUjCD7e`(Fy_@J1OVblLf+2mI-iJFk!`%y#*(O#3mM$oj$eL zg)hZ^&tqMg3-@lketohLE#P!P1@8r)KRbU_-kPnx4E{2tcuf6 zSTn~#F)@|JE}He|&MTX5Uc9pYX(r>OI6ZCD+`L9mfc1!!xo&#x<`-&ZYfmlL;PcXV zHe187LTZkz_tIxi_e7lNTB@TE;P7D5(k7QFMNJh#M_ObqJ&ekdxgOSSbEy+8tBqXdeZsojBV1Ipt!}|pXtp58X zE)9v8?eYaPah3v=qD<5fd>{)d%O5|v5xBc3?DC7J{DnU5!e(VITBXjB&Nu#Y zl{)d1vT(I8oG?Z6H%DJ0w`PsA6l&$%e1KBhU$uk ze^jlHty)l`p(uKdZ^^Sz#+S$b^RTj+`MVkzsuihuL`R2afxx|iW4p2t7bP!)$HyNR7_%7v3d8jUy@-$ zhqIa*O3&T&R?QK7dHIoxUV_DqO*Tb~(1NiE6pR5|Z#?Jse!nP*&#RxOd)>6A>l_Zp zQ#4zhm%cc9ewouDF@coNt(%&z>|N6%Ql$Dd#qXx|mbb1V!ZQ;Bl`MU+I&oW-cIxY+ z)4A6zjNtR)Pv&k<=ZX{MUlg;6hr44_*%WQr#5J`G(mYy|7S*MhuMG;?>b%R$w#B~v z)+Ap)F(#B$XvNXNw5WN}F}rWi@)j6s%Pl=JBkk1NQ$7c~JA*PS1et^4lvSGQ-2$w- zB&1xqdqwuODIIE`cAZaCQ~OEC{z8)-Uw_7&*wE>gxl|i1x}_QYSy{ZpG8xq_sO)3r z&92sbDxSXRnS!}8zgX1F#Qy?i1%W~z`X&=M?@GNC1brVoADm~o3 zrR4d1M!AJCXoa5yOU(L)oLgHu_x=9I9c0CqO>=5%x~BkWh%Du zhG%)=>C>l|Ph8)#Xr^&`(E7N&E6Uf;dv$-FZFN9W(jsovZF)j68@alRcc^)kRC2{d zIP^#wFxgXlrM=z{%PkN=0Ai;7tjz`A^Om6Ar@in@T~4m&f&?$7+S&BBv) zySFfEH2hN#*kY(4eN)OP>4?Xzz193jj~odoEEH5#R}Wt9C%ZEI{JblR-T7Z#TDsX@ z!m6y-s88vC-N&~gqBA`@z8e@Pgf4sX)#u>pk4hXt>8gu+MEQ>NwJeOXVqZLaqoTo7 ziO5Yo5`tg){lBNV2Xr5K*VpT8g_aJ~8W)5*oMHU)^ZNZSSHtgb5EAkY3=9kj3OaPk z!%$RIbmiQ?SFVIOE55uL`}g*Wz{Lw@{r$2>_sj29%Qfwm8Ah907>7;ei3qT`af&gu z*|dv8&#q&KpfjVPj$C4n=E3`dbNG%rv#!&2J)%+4VJ|jaEJ%ob@Auq7BiA-}c2Rl3 zFywTuu!DnTFB8+90`cmFAqxYr@oxS@__o!>((vqicN59%lxjrRuiGbvW1tAh#9TS_xyE<1% zFEUC!D0L_=QX}nzSNp;Sh3sj8;j&$vty4FA3UiT_;$OT?^Y5K5rza>aAC4j>UMEJw z=LwIG^?vzuB5=yosji%yoWGBlIVc`HzGaew=E3v5(&o=Bg!)ti*G1o*di6+d?yqJ3 z8QEgtUi{A&HLXcdxOdp&;Om728s@r-9TcZhpNu_3C(`?Ie}$i2{`N z*{*Pl{%2gx{*O)daEODJu3Euiqo!N7Ojl=yYHBMjP5pVrXrp*(N_U3|YW7~x?a&` z`SR26_-_pS_>^m+;Pu3m7p7ALr#|Hpl-H6L>rr*Hx@YunHdjixn6UH9j)1F|dyA)X zEv{=j*2Ezc(cKm5`c3X^p9z<;7h2vi<21=&Wy!g=Hr{`++upF%(bLTT_*~aLGGWRT z_8pJ+oSSPoZAmqMs-mM*LPYeOyhv8-7w1j&gKAXRmmcQz4t3P;f4@SRRsYWFD}_(R zghl@@+>|C6dPRGU!c)h00S+Nzx?#7tyo*+5*0{gA^(A3>yZT?0R-H)!6K@=&;q&}E zJMO=joxgwajvYIy?rz#M^Yg2XDy^-pSGHsZFP(D0iK%r-?(J>&N}hf;e0@3X!k@SH zfiW)1$_Hd3*H1A@yuz?jpH*K+E%DT;M3&{V#RM-iHT|0)cRC=9huh0Dlap_mU+?$j z#|qE&oK6=gLg{QfToB}tWMwf9K9m=_IIeo`v-9S6HU*sVPj@b;PL+C)^z_@+Wxm;| ziZAcoEx79x)758|{`&hC(_%sPp2hZkpEUFhRv4vRozZmt#H3JFR{i;rg3e7P`wDJq zl|K&B;)wP=qttfl(jhND&gE}>dpuLKPdMf{c3v?QdFhOjX$>XSOm4dVW49o8 zQrhW9hi~|LhX$_yF*`BS@UdS4Z)dN^qI14{OICD5tWTZBjM6f3n(pACtuW);qeV$o zPp^h&9&B=*GHKC$-PQY|y(2w$L@eUU)8{Yh@9bQ-E_PRdzTT7@&9U1jRIc7OEp$Wo zzv$mm>BqbbySSZr1NVi527geJ)z?v+%J}?h(1&U4o274V;#u8pCHAVTOITAsuVa#u z)@QLx49b2gKA}PWzAwDiPO83Y9`kcIa(l#~LzttI^~jw6rf;UTDz&k)vTFGq&dm16 z{T}OkRLI-QYh~o-WmlG)UsrwT)VbGU+7i#n$3$au&c`|xoBww(oOm)oJj?SSH|rv! z2X}l9W@|`J4dYX`kd@qU>UFCI>yg7-y)_luvc+aay0@$dIoeW^W8}jn(e}gHwN0M| zUVt_3;^<%s>OFUU{~s^=e?KO7@qTQNo@Ty1{cBREYtB~3mwj@!RRR8f%r*u46Q@kI zXup(Usx2>*5qGGS#XB-k!_+83k#+sVho@H5#l>^Qo#%=0+V?3+d1|53hK2>{SF3;C zpPJ@$G&ROpb(`+ihd%@|QBsD}0xQNqhpZjyU0q!qt~}FqB3CsXD@{LrsZiQU(~w*B z(ftjVG`zAz+*iJRyu!7;;%nwDt3D;=NJUM(;Hzg(ck!-vP34L^ys6QlWU(7Z%yu7c zjww8U%$Y7fyx7Xj>w1hMW_^f*&ry~z;gW;m!3))LC;j$hbe5g0TZ`25TEHkMz`CUG zWX#4S*1i9ZMNgSNT|8jBPX0Ud!=>HV|EaFY`LMiYYTt(rgRDzJT%Jr@-%RjWYo!+K zRMa!^EteN(v{#6OWwh6-We-fJ_Ia_gtcyA|?~s(Yt5&>*@sHe{sji`c;ayy-&TZCN z>MA0Ccgp6}ulzH-XPduyB7stb{|9v%xUbp&{loqDjQo+d9Y=Lfb8n0cOi*oJE4Xw` z&Xg(IY9BoVuk48x+M1Ti!sVIu+NGPXKWMR&QHe@`pgZPav;cfW4R0j>3W z`sPO-Y~W={XI(T+p?~20B6-yg5o;FSu z-x1?z_;HQ$BBO+l|3kdupDqfGi`;w2iRoxdf6zwt7?w?IJXn`+_q^BtyK|L)2wGNP z1~v8jg?H!NEUJ2ZcDshX{r#_bk@tAk9`agrXPej5-(fyAB3rZWcibw;^2xO}efU4m zXXD3?EX;1dSu0!bJqlp9R7UL_tCAu$v?i` z>rg+A6zdKgCI(E48Y1Rgkl)duXq2X^rnWI!Oq|i>f-`f*)G(oK6AFICYp6;@drfA^ zxfCVP+BwLLHv$_l^ecv{Ze$xx^Kj?efs}<9sG_po|>+1E`g_) z+!K)%yw0%VqyRjlfrg^?fPA@qNtT6P|5^q8{Wg=r)wyI zo+PcLqdI%`T;q6tDd^_TGgeAzypx2Myy?yIIV-%os@T%f4cYw)9-JLaiz*)#6&1Y@ zJvVJ@(bX)yq!}+xDYeaN-{W6iaP`z#-34N6XI*$HF6%XS*VZRdTCQ`RO@HjEB_go+ z!NR~R6Q&CNn{PCIgYOd08g{RayhmGRT-uN1gBAw{&;YN%msW1^i?`qJ@m{e?jw>(n zs^OtijMvxfnZxwz+HTpog&z~I=xi1IA9LcP%9@T9huYrMg&sTAzG~IEwR;vMN*-@> zaa9Y@I^NdO?rLG;j5@yMpa8PK;OqMRKc^k*{oT7cbz^i`$cwA{8xPI41T!{vPwQfHykM2&ykO#ooogpmcMCoGV5@Z(sf}}BK4^r8 z`R$rFIZ~EIB5NZzw{=UHoym#(n%JTg6cMmwjgtFZlPP_cl`~dZ289HinHTPMDlWn` zq|td>i$e9ZQ*(~$Me9zkzIJ`@pIFpD2f6ro=Pdhr#=T#^S)XFn6uG;pL8^;mjpD_N z6H8w0Y`@sp{&n%4Jxp2;dm^WDaopK-N_*{Ut=EAzlt5P$vyXSJpy5BsNq(lpzv-15lCn}!oRzqDqKGN%yx5O%+NRhBJnN_n39v+(ZwN$%a9J#+&V8|Hgz+_`t z{QTVF^82;(S2rEj)izs_)n2hkUrTG*oi{d8MG5j&uNOVG$guBYzRDev6{j4kueE%7 zpjQlcsJ_cAl!R3P8pl)p{OzZB{6+ctf1aLmbhSn9ZZhE23fQ}$Lwkkz<-p_e4(f9& zXA~WDDs=7(4)5Yvt$0Ocovo|;vE3=pTzF6_hImkdY<= zJN9MnE-n``pUb$m%i3;Q}gAeD1B)bamGN07>oGL>E{=IzxUrE zk|inG`MNImN5!2xe_mM;C^WbFWT#1nL;fkf6U&9xX){H8TyD`*e7)(}q1$0D$Q`e6 zP}<`PPT>3XW%K!$>-YbArtmdIFG)gDLNTV`>ZD0Rryl;8@J%-QvTOJ}x4E~rFMYEo zW~%S%%o=xb4-F-h61c+KK|~THs-vLe zu{AbjXRTh{V1BuVyKni74wtS)Qy9+n#GrI<4~R1@YWU%Fn)P_ymygR${>}e5WzM8E zOC2*_#QL)}X2*sWKl|qrR$p6;f81L5df7Ac4@HVd@pMB)fvdx}q0yrD z{5)GwhjdHn>#%jxCrV6mRWX;*-5~vDZAte{Iy(qQ_G@eUL(dqmpS+ zgGod51LZKMWBvd8CrzFlB6v6;x8StaGl#El-snh~WGKXzzcm$+*JtH+{#rMo5K*AK z16geS{Al{hvUj(Ry7IVR{FZy$`JV3SH7n*FUs=^}`z&MElS$pR&otFh;?Kg_K|~;Z z2iuzKn!(Gow(GF0IDYI%OU?u49Uj)QdHzHz3ub59&a(X7znK z-aCq)`&DHg@wj#LUF5=fy4(VSE9T9e>#G~J@` zr|H!i&&leS-Q{bY0s{kcSOvE0T;V%;=FAei+Fu)#ikep$=%bAD!A8`>W1h|}zrS2F zc-acpa*g!Uhf*X&uXby6>ngd+)LFzHUKe=@$)yS`b3jAhpL=3UTXS!3yQsZ5Zs}a> z^3BmB6%srazu(kjPZ~>*n+v z&Q6ZX?K;7NC(oV@owo3_{_ZJ!HXj)DJx?VfB?JMceW00I@hIL8H_GqT_N)2NlltV! zb9SZcu{Cer$YkBx(y5hlV{i3#HjCFrDoE*<1vH7#nEZa0cK+R6Q{&_;yS}}s6_#glOJKgT@m*TRM zU7@DNE`plDt~{F~1T7Q(|9!b^_PTVnhrDU~QWcOK&A|dHe;w~Wy-eTc^lV(yyiUerRh0yIJL-lFwS;QIX^)y~eb z?4C4fvZj%e(vwOC2CY@fc1vo1e_OSv>hv_-)^3y5oF#$l_qn}% zDY>d6aRvLz*$)I(%sbh2;(;Uc%U`e8E#0xhV*Sih$TJljrc8?(T5k1ZOT3?7|IanP z_HVCNf<|5>TfmWa5izmC9uGa)>NkcZCy$C}D(J={d33=;P@;Nxc4fR<3+wmn_4_?H zr=49iMdaKx)x1biP?p_Sbl&RwoZ=TP!hN4l*PL)gO3ng0EG~?k(`FW}oFi?Pw`6*J zUF+)h^kAo^9jP-fw>W&gbH_$>PyN@c;hU}zeoDb)w=(G`F}lH zy>ZYtruOyWl)c*vj;%SeLdAle!u@;x0G4@-2+28tV|7NA>NR^^P0%r%4P{cppf3J?Z9-X86ns=6Y{GCm!{LMrr-nkRg z)zh=&wBFtpKC2f8*y`<1Fd!HETpf3q>l7Kb>l|r+^6cqKhf>X?h)!9_%@3ws-I6K1 ztB+fXkQWQm57+;=BK_EqV{u3z16|R8@R%G`0%0LJYPZNLUA9cw`v|&w8f06(xmiW{g;{4~<%%jmObZq7ytFfQ> zPs+Uak#Lfwg0+*##H=olxH!A1)23Zu6`$jOT&{SF_B*K~YaBd_HYu8^sj415>1}bX z+|A9+K{tHHtRFutzQ$&8e63i}aoE-H%tlFLt7Ep)kC;~7$tiWQRjiNf@%Hl4G@N)h z)iSUR661bMiyB@m(X9RHli>cXsH?Ys;hHTmzkb}EpKGY+I?&k zoxN2+Ln$?NsfeuX+DGdq2??((oUC@m#&l}b_B_|Ox3(@mH`h8aBqSsub?x(4;;}WF z`b~>9bnZlovUHv6y&muGE?c@pyYkEo%gJ$7FH`TWdH8@PTfd-+Q_uCDdkn#jkiTy5Ve z)_8e;%wKuyrG8>JlU;{p)|C~4U*Ftp{`LK}yK@^)*w*Shm$q#<^!vi${=lN5Nsq1n zuQ+d<^CDo^t5w=}jQ((0eyH8?^4aZ*bwM)E8@eCu^GJ35`ti72p)9wc2M0&v1N8?h z8%|6s{%}71La&03&YW55WeXQQayoV5%(A#z>&u(h-*Il2we8ttR2=fOV0moq9X?*} z{%-w!Cqz#jKX3ovX{LMU$VQl>f6NppP!zdIUZ|$tl~nmdW=ls+lD4a zZr(Ln0d^l`qqk%j)_(b@UUK)V`6cCkJ3nDHzY^Bpmc`FEv9_<3w_#f@{qFVEH8#68 z+J5=4*e1TS?qS2n$2YArE;yJk5}4W2Adry&DohfDrF0H=c6BVCaw9AxD(pz(^`ld! z&-YKCTQ6h#_0ilbyL`RFTsB?p%hfR3%6(I3s-MNb9S!{U>gu!Wetc99J$_W4m;2n8 zFFf@zUbjuna&9bG?c3~QsQ!k2xy3(c#)zgv3V?swC=UB9A!{pr@9`cx$# z_uQMEb(_^38Ez~bIfrk79l1lSRtQzp+`e; zndVVf)y+adPHz;QEG=U;7#Q}wtNviM>)|%0KTKmWx%NuL?_spKN{nND)nP=kMu}6ATiq4!k;yL+c zm-hN)@$UWGF0XxBY@T=PiFo&HO@*?5cbByI%(d!GJ3G&J?Qlk9{hCe@5s^T> z-STtFA8LL%q|G1DJ?*U2o@g;0JCFLxcb4x~{Qr1SeZJP~c6;e0u?el}Gj1L0{dafm zcX4T*xt_2i5gavS&S8MKex3 zI9N9`d1nW>?I0qslby+rA#s`SW9yAVNl}(O_lsXB-^>woSUbU8erNN#-K=?$OL;Hp za$l3x+4Fwy^LGvB*;y(cwocd3JGVmf;rX`Lsp-G-x8Hqt!{@tpeeovk?c1NvUKhFH zgzedP6`!B!fA|)1`uN$|=J8AKe@$=xee+f5>c5pIrPeQfWM?6FZhoQsvCZ3jB4@Jm z$p{p%DS;NtEp&7cnQ&o7`t^PzEv2^ROVO(;1Qt(aKk&(3^{DEUdDA`rvVBY1zUKIg z3(DV?pXqtSHdR-9zPPNrTqVoa%*$#IinkU#REj#Z`)=b3;Y1AuOUCpEYZ=;pPpua} zeecw=&lYFAgV(8ky5y~#@pf0K)$Vnd#Jen&*iPMN{JUXK?(KbtHx^c2{y1f2@L##_ ziKkkB^glZre05nfqe{``0c@z@eJ zTjQp?o1&JOactL#D1E?Gbam?V>Z2!LHs7oGth;Xigg51{*^jlh=K1-3&`>CTevX@y z^~jvrYHM0-{%$F5HT0eLZ=1%$s>;fpYyPkt`_(qf{{5cM^X@;kJCn|NXMNM!Z+(}~ zJHCwP;9yJ#4Tb2$zr5?tbh1!av#I%#_9I7|bNtH-rp_|A)^8U-(fQ@Z;_{1M&EuEp zs8m)SoT+>IMAcNs@;h~_`n`_xIY#m7$H#h2DnE(rU-oZJ=7oa&Cw=_+E&6}4%rH*(yRiKJ+Wa2Vzp|R` z>6@RX|Nizi%y0eYIa9U6f13VXx7?s(cf{svmfttsVzbM-l6`8^>-RhOgXNMBEB4HH zyu0=M@)8YDBVh%oRx8Ti(a)eQ(Hp^O_{i}=O=zUR+OG1jNQvF4qCs_ujIm`WE5AHC zar~yyq$NyOn-?CO6?}y2MDF%`kGKlm_x$lX5VPKfQR3=_yYo4<19pFH+!vXk>+vW` z@qW$kxnY6V*2bTowti7Vu;_%jB$^?ULoe%b(xv$_Etoi=IQ;}x@pO1BLo_u7{ z)X?$fv#VfE^=Du6Up4cD)&G1r+^_YGse6Ni`IQEawkQSd@O3;l)|D=J&XE_iIqmE< zEjFXBqbwU1D8KuAcJ}rx+2Gi@4}bqZx4W_Xw?V4&pW_b{gZ|#h7uFXCH8}+ZSY7g1 zt_yWMZTK={h0D@}ko?fn9;2?lu4OBY(+b{B_|x!q!7rvw6LjV8?k-<`u$lS)Bll+u z=hy$7`snfFTFIv5<67ct7+9IBtu-{{SKN|Y#TzzZ#texj=~?T{ri)H+*r}MvBO&}~ z9n=-~ZpJ?cDSFcSKa(p6F{%RYT=E#uY$l8r9{x18et>JTUQvul-&Tt>I@ zJl7i)8PjI1N|jqG4DP*d2aQKfn<67_z|{Mw=axi8WYw`|iN1&<`X4=RZ7P;t8!s*+ zx^nZTO(CaZcSy1B`fL0z{?^9ibcgbJtBnnk94;~UE<5-7e4)i(J+UVq*0I;wt-s#b zdu-#e^27Uejf|SEt&Lv)bdkq??$_=MM6G&Gp0rYL`1*eTf5EJ`2bx4)v^{G6`};fh z7Kx%-MFke82@Vg!9TYiY+um3=PPq}b=ftB0U$hwI0vv9Lsu;EX`&G+ybmLd$3*0k) zxwWw-?=E}$;=^J7)$aq2|L=2stv#RJ49lzeAfsQmTaySuw(i@!EI zHC9Qp%WSacl{H%O?ED4AEBX8Xt}tfjPga~gckWs)i(kgvG9pLkT9^Ma+PYP4HJ25e z!N0>IJhLVJq8!TJ-*c9){nMGP)932iYElvK;I6~gJ1*d5W{$24jCM^w%6CLBD&V3} zBD2?m1s3f^-Iu03RhT2%ziCs!wz`($2U$FKYySS-BhX!z6SyMz!H>FwTVM2Ek6-F? zPD$hi+jZ?F_gtew%}sYKTcGthx!>-Q+D5IEnP$0GwI3e3Pnj^`K}Su1O5VPgY*HpC z%=iD1G)}wpeU1-<>)QumkGB}D%et|_^!;Q0``gbxd={M-eE+V)^$=00Yd~I9FNulFO zX$w5I=iZ*Cl#_B}*N;ct83O61pTf=5cYj{O^eZ;0wfU2@sOZYQawqox_kFOVzja;5 zZ-eLDrr`lBq2R%21p!cZouzc=GF_&V8+CvDG3x5!TE2Go9r+r*R8HGR*us1_Ev+Q`g)L++IB z_B$>ep@p}&79F0NVfM)0V)2YU= z?&rY$)+;U!A_6=0nnkkLBj)EACb;f23`Y7VCI$g>mp1G128wnVBnB zB`0oQ8}V*kQ{RbWThq=;?LNH9;{Qc=`Q=llh#Y?>somscsH>~H*l(^?q-89`JvY=8 zxH@uME;%Z2xU{$jshBR~{O?!X``gV|#;cN1LR#8eJg&lVtNr0>xoHCbw+X&!UstVu ztuwYveL=^{&PCO#Te+YCSY=LjAO#LH#^^W z9ZBU_z2sSGYlatx@@XHnyQSAY8^IhvFKXvq~cqe!yXSwCd3z1X3!>bAO26U7zq-K2dmeWn*&d zCqWI-6#evXlGg9c%fh=amx(+4Y+>BHtfrWoZ*}b!*DjnBRB?4tK(cQe z)463&m*nxij{9Afo9lZqr!2EL_)oj#{s1HM+*>)7Io9QG7x~-$^@)_ed*efnlonTq z^m4ZpAtps<2ayRAX1;1O4cPJAVyATObTP5#KVs_dZv9=7TJ!SH>aINoNi5b8Udw2Lrf}7Y!TOFuKhJCGC0X`G zK_7RWVcL{%&}l7??R#D01=0sk?Yi~sY_v@D9qF%LT`Qd1`KBFh{d#!qNr5*<8u$FT z#IbbF&cKaEBFB}^ZFv?w(fjmd9d+>Tn=Hi#^F=2-5NDF&oD!txJJaUw)`QP)+>|}h z`sCNQw}-il_fBJsH%wCeax*=1U#4)HLy(D7jrwEDZoz6XV#JEcQQ5SxdYHZ?eK>FTok>+iC8KojspnP_$7So+6d4+d2(VbcF4a7I$g+8=%yyIF z?e|vx;Md_Q-4(w!dVAdKIpOo!BkbQ?(~jIxAb9;#q5oh0^M;T9-QII^yTpXIx3^yw zkFRk(IV)DSw2u9Qt*++9^>1EH3H&9*T$CH6?#h@D+sDIT6aVZG$*!kenoLpml*5Lh3}c+kn-__FQQ z3v=(RJzm>| z8Fy}f+tKyAAbjJ&SDOwOUG)r}m7c%zL?LLvt#KAd2b0ow*8l+xopVbMUCOz&qf|Qg z=AOCY?C*A$Zq&ZBHCsGxhHSvgs-xB`8?#natlRvoePu#ywXVpTQ(})Dc7?xjcz<`d zdBBTrJKtSex*}ZgWrt0K$hO?uvnEtUg#XTe#Bw}FWMPY%np)88Yio78yT9zdcrmaq zDpQ9$ylxSfOZ?kd$3xHO)d$X9s{GD*yXnQr%<}@9*}Z?NTneWP9{&q|{ev@PL^<%QQxsSyr$CbpIT{lz=yX?OW+Q!S3)I$Z4GsaenEW*U`h zi55>{m|Of_lYfo8yIkQ8SwT+8qa{(#Y+5gFZD=>znD+Ko)$yO~$7^-s_c?jrVc(bh zU{N;D)mD9nWm^>&HC(Y?Sp@2I_JQ_n6doyJv}W=0>ekS%S9fi35A=-WJUhee{KnSq zP|J-G4ii4PipL)KC{S3+Hcz_x&bd`et1GXU9Xm5KO3Xz~xVWeMPF~8lPdSBa1YX4% zByQwC-5`Byj^&C_!M7b6T7UJ*ma@O(=KA-iTYu+0?>)(%oG#iueKI-c>;A&WYP#2& zUOCNpmt*zLJwNE9(!0l-&+kw1Ui^2;wg5YUaMO|(2~!h&%A22R^_g?O5$nIAJN=6~ zON&DWXvov#xvhp<>?z45MxQJv`$x1CU7ul8IBk`ABadfZR)og(jEhZu*54xHI;wYP zl;!cP@2Lu1{aQ3a`NN+Z$^8$1G4^H$ID9$Y@IdLt!Q)Bh7joa(XzV?=BR+AV%+YD9 z%HH0}lzevkO<8zQ&-)JJ{xahqHfHCl98a^#)bRbBvq59wv{M(|Wmjgcx)JJ>z<6^* zV)ES2pH3|94_02cGO=7|S=0X~!u=adGv+Cuk`$R^S6h|6^ZXJ>D?66y+@7Uxyi}ia zGpbFPw|!=FNN=lGNrXx7|Lm@7v9+=j&hF^={cd-(d-=BCKVGd~A1bCNyYIy^gMeQK z?9=0l3VS~tJ^K25Q>vDNq+Y?{qO9$5$yau2$b7&3-lX=J&(lROTn_J@H+izNcwE80 zweOy9a^;lf+BN$nTjj5p%QLlmBBP?*Bx5cwU-s>b@%dHnBU^k^&wFIg^$d@zZ2dJ) z@xxtCR-sdm6?&(c-Tkcomy=OZAPUs{S^JZ3*2QH{r8EuB=9oxt%X#+TbM88ByYpwy zF1_q$JymL{Nt*b^Bo7&bV=J`&-hN*nFsJwK%U6eHb6qnHj}LvlLx4G{eEZI2=M2BU zWL(GEB&{JF=V8b-3RCe)9jrVgD~@&F^PzucGzsgW#%u5 zXKY+_XHVs-S*w@%&b}4q)RXRSu{LgVzQV5?8}}Es?KF*I`kT1+<=x%pvV}hqO)@{F zZ0mT*e=fXL`6iQ5#NoYS8`$T>L~w94vbj2lOkgve%bRTQvNGDjtBL!^RQA8e+>T$k zzu$k!jU5rk#hSuS9Q>-KXxDho^0$uG*IQpt?flXIJielHlF4<21AMl3n%nqfgZi10 zS`+R*m)PpSB;8@>zcc=2yiW3ysohSmKgwH|zgyBSUpeL2-*2Y(G5MyNY{-Xld=t9+|*ppBCQt`eYq#_wCKi)mOiI?QBa) zElks2{HQXQH?yKN{h-lvyJkuDO=oAljoGHQRU_wGh-lZBr3a7Zotm=p%a6(a7w>+* zvs~-gYdy1#* zwCGZeXi1;gx&Pfk2cH{HO`jaRd-uK*8FI6yPxn7AQ*5#|=i;ig*X&x&)1wP^oS74~ zp!jXszwrH^8d+aXm-#($#)|!qettY&c=Yp=Csu-r9k+A>GFnq}pC4diQq>R0JwMM@ z#{cm5#lG_YcRlg<@K}<+?{D9PovXH;7mu%VeZS|kobBH;#U-D0w_n_P{jP(2?H|s! zw{~_l6Jwy*gr1V<@6+Z^ zp2&A~K1c(K^B4JMYEy(`ageK)(a``!Nh9n)?!Zhd`Cb9IYw=9ccR zn}1i`;zy0bR{JVL*WOao6ZT>|}T_-T-z00n2gZGz~ zcE@gfS_2*y2?H&aI;uJMr`LiFD(yzxWdSWkyAQq1*rB~p@yDO}_tgu-)W5ULKYTay z|KIk&?|FA`em%80VurhFLEMf|w`z;U6*K1Cf3%DLq?DNJyw7a)AHTi5U3fI*{pw=t zjRD6W=_@N2IKI#hUl$VA7LXIM*xo#EK<>bc+B58@kL6E7TCb?{F_ z$!iW5_o&DB>wY_X&*_!4F1ug*JtQ&enAgc=y|cIOC<~phBPwltqiPYe?qq#P46G6a z4Rdui2x{o*K8ccl6DD-5d(Wo|PG^a2k{@>MZTW9r`YGq_?%!eTJ#)Qv6!P}HbbGgG zSyS`FSMO78#C~*IKP^f0}j)&I1h=1p~&$nH5lf6AA||GBew;?07+rxv}=-w`Go*QN0JQ`p3a?KT2t zbBrr2*Ve3w+1jP8_WFLH+tJUDEk5iCTr85mAw)*_=rygoTpVJ_99MWd=xtV;4)bff-q`TTLIR$LJYahRIqOyCYzEyhKrcY)c?o5u? zc`snTq>Z6O{m!X7XE;uZetUPfiB%_sKhJWM@OBy*79`hzP8H^2ElQCE;fSD@%82O1qJ< zYo*wy?%qeIp4a;v>Ojey{r7vbZ<@o~{3OD?9(f zrPR|hCvQAiZ+N9#_OdF+)U)|}pQ^cMyS%x#clO%$!*u#5eSYPwt`|jp zph15JYsT}YlOr6qJf6yztpsZCc6AkNubT6|x@TgO`7G`E{&Ov&b>IBmyJLMOyP>sp zdmI1$?*B(v*+U;#)-R|z@am!ZbnW1EhA|wxH#_G9*cI?zS#m(>;wksBZqjrosPysT@R#2LPu$uGJ);l=g1+M|I_nT^iO>Se0_mE5xDy zZm5}SZM^u7u>ZB#BZW6NJ?*=bzoOU3<<9z=xn`E2Et&S91sVPeoPQe4{AsPRUZYw3 zP2e%6eMvp%j{-Scd>gUz$ zYb*9!7VckYb}AvzfywY|k*}fx%O2249^w<82)t$~+Ht6|>|ma#dZL-=??je>5H00D z%4OfK=iKnH-u8A;LD^BRl*5ab7A`(ka>`R(`?|JCgl)*#Neo+_$5#Y;D{f)v$a_6$ z#jIWl*7~iMdm`L6+Ng`Q{F7qd7rmjxVdAMXXO`52#cdR*eRcA9<`HlG3yJNruk-`2 zl+Mw5(eXZG`?}cIGTy~y^Fy{)+FVNeo%|u;{`&iMB_|HDU$3-0B5fHuM{wmK!RxBv z!H@@TOpUQmcTVg$v830bE>JA>Nv>x6mg@m;7SG}i_Av>1@0V2n_5j;_>BwxOm;cz` zg>ebh^(Cxke^t%0$ak)p@6QhFr&XdIhLzR6sf-_!O}|*a(R(t*dgk`zZ{IA66M3~6 zlBOo8o<4OdOfS3Rt;L%Q&My|W%PshRueyER-e+3t^6uZey>6@Q_MD$ZPj5YMaS9Ld z{i?jG>(fmOx#*stQBT^M!=f0v%Jx$gJZug43XN`czrjNU9v zn-^_TSv5z*ho#HQVrr(IxKv19cz~S`>ylTx?AaV*KX1I$)6iL9x!EF`?|382rl-%I zUDRAY$K&iQv-H>Qou}%a9$`9l+i>6ad+bxDOc4o?+%q-wd*Kd!BO~LI^62b(X|vo* zv+nKq)w;pLbW=~|_r|2a6YESon0sSOH6#moT?*{hNLPPfw(|F)?CE+XLgIXTe!sJR zvDx2lnfSc=X?pv9D1H6yV0QTLshRJK6CD+o&yWpy|G}#C)f01b9gWrvHxx5l&2zQI z(@V7et_!jMp2h~=Q^VxyuqlDHtA=@>Ud*&@>AJzE*pt+Hm}=*|?AjdHIyHUos(Fms zdTP_u3Z8zJ-~ZD$bw5{#ak+lHtZC5IKOfeF3vtYhll#fFd&8O{72kA)V~<~(8p;Rk zn^*g+e&4)TpFehs=`NbMe$T3P&s~gGk}^`yHS2w*F`rbxCh_W#+nB{eE9;{`UWWjOXq9_bfV9v}n^z z$LG)I*UO0)*{r+geRhuN?0c2pZN09@Tu;?<%-{1-N>x?uns&Pk_;i^M;*96d#soV2 zakX_>7ksSLXj__Y+EM0@LT-WvZ$3EwJdkG=&TvzmRsVv@arKMM-}ig$wA^`1T>IXl z_BENAFTXqq?hjhdH+PTi*^Q5<>Bl?z+kajYRnV4o*hzT4d0hR~LKaZ>;p_~<%Yv!r zb==sGnyIQD{kU<*L#7S4Vv65>?Ypyo1DE2lN5`bstuJ4ZeSPiX<@2iAf-hMuj+n)i zu;=aVt&7>^_w0|GS#SWfwc_(mrYaxaqnvwREtuB4;Dyse>940wm+hKZ3|zd(T|(UcOQIY641r}>X_DFPDaHAGaHUH zWUxt{x_j`g*U}rIx7sVSE05Jll%5YP*(?sn zSi{yEz50(?dxif!Tqm)B-)YK}DOPc(8CTYQe{=J-M7|E!?{BCAGT_IF=@t-E*hsN`I)?=cY_zvRCjKUSf;Mg}}7UeM5>p}^N$0}K^UaU?~!EhrEX5tTalobM{vihR2b4F{OMY`dMe?tQ@iKee~F z<(mAv|DP#r?@j&YFAtTL&f!onH^1I)Tw`ByZqCkC-+F?%4AxjI+@=w8!qC)@Wr6d= zjH|1r`d`yZVQ5xbz58Kc+Y*N5^Xs%qU%l9S`&rDs`v=^<|4mz#z-O8o{(X;Ey^{ln z1!(E-b4l|b+HX$9dAq8*O)cIW5g+QlS}N#6kqw8G)_nhe`O{YYUidrpjqVSobIY2K zCa#}nyVv&U#mAuaZF+HHvm)28YCdY)*nfGe!x`3v!ouCIiehJ(*}jx7st*6Qv+{G= z@ik!u`#)Vhy24xhFt2yHc3NcA)-2EGb85Hw$1c9tBYa9yXXjk&@-LoZmJy&mEdm^% zvFfHO=3US3-RX^aYO^=0ai7*s-ij@u!5?PXKfHgVL*m!>^_h&TYx-If3kwDBmc7

qc)WNICdYMcBG_Hg}G? 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

@!`;jl_&&~d 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 DqD)2V literal 0 HcmV?d00001 diff --git a/files/images/apm_planner_2_0-08.png b/files/images/apm_planner_2_0-08.png new file mode 100644 index 0000000000000000000000000000000000000000..25bea62d80e721cca343dca8675323dd978edede GIT binary patch literal 120768 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Ž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 uzXTr(G|i=tH_LFRJva&+qLs+-6KW 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%0A@n`C6 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 literal 0 HcmV?d00001 diff --git a/files/images/apm_planner_logo_splash.png b/files/images/apm_planner_logo_splash.png new file mode 100644 index 0000000000000000000000000000000000000000..757181f024443f15a0db996166d005f2422bd2aa GIT binary patch literal 55172 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 literal 0 HcmV?d00001 diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index c36f4140c9..0b614ff672 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -104,6 +104,8 @@ files/images/actions/qgroundcontrol-connect.svg files/images/apm_planner_logo.png files/images/apm_planner_logo_splash.png + files/images/apm_planner_2_0-07.png + files/images/apm_planner_2_0-08.png files/styles/Vera.ttf diff --git a/src/QGCCore.cc b/src/QGCCore.cc index 43d170b72a..c4a38bf0e3 100644 --- a/src/QGCCore.cc +++ b/src/QGCCore.cc @@ -71,8 +71,8 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv) // Set application name this->setApplicationName(QGC_APPLICATION_NAME); this->setApplicationVersion(QGC_APPLICATION_VERSION); - this->setOrganizationName(QLatin1String("3DRobotics")); - this->setOrganizationDomain("org.3drobotics"); + this->setOrganizationName(QLatin1String("diydrones")); + this->setOrganizationDomain("org.diydrones"); // Set settings format QSettings::setDefaultFormat(QSettings::IniFormat); @@ -108,7 +108,7 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv) settings.sync(); // Show splash screen - QPixmap splashImage(":/files/images/apm_planner_logo_splash.png"); + QPixmap splashImage(":/files/images/apm_planner_2_0-07.png"); QSplashScreen* splashScreen = new QSplashScreen(splashImage); // Delete splash screen after mainWindow was displayed splashScreen->setAttribute(Qt::WA_DeleteOnClose); -- GitLab From 3a3085ad1d3f8a7062c8b8c8351bee2e312bfffb Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Mon, 17 Jun 2013 08:30:36 -0400 Subject: [PATCH 008/460] Change of Text sizing in QuickView, to allow for smoother resizing --- src/ui/uas/UASQuickViewItemSelect.cc | 2 ++ src/ui/uas/UASQuickViewTextItem.cc | 8 +++++--- src/ui/uas/UASQuickViewTextItem.h | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ui/uas/UASQuickViewItemSelect.cc b/src/ui/uas/UASQuickViewItemSelect.cc index 537d1aafb2..ebe47a7144 100644 --- a/src/ui/uas/UASQuickViewItemSelect.cc +++ b/src/ui/uas/UASQuickViewItemSelect.cc @@ -6,6 +6,8 @@ UASQuickViewItemSelect::UASQuickViewItemSelect(QWidget *parent) : QWidget(parent ui.setupUi(this); currcol = 0; currrow = 0; + ui.gridLayout->setSpacing(0); + ui.gridLayout->setMargin(0); } void UASQuickViewItemSelect::addItem(QString item,bool enabled) { diff --git a/src/ui/uas/UASQuickViewTextItem.cc b/src/ui/uas/UASQuickViewTextItem.cc index 11920e4966..c8fb12e861 100644 --- a/src/ui/uas/UASQuickViewTextItem.cc +++ b/src/ui/uas/UASQuickViewTextItem.cc @@ -9,14 +9,15 @@ UASQuickViewTextItem::UASQuickViewTextItem(QWidget *parent) : UASQuickViewItem(p layout->setMargin(0); titleLabel = new QLabel(this); titleLabel->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); - titleLabel->setAlignment(Qt::AlignHCenter); + titleLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); this->layout()->addWidget(titleLabel); valueLabel = new QLabel(this); valueLabel->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); - valueLabel->setAlignment(Qt::AlignHCenter); + valueLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop); valueLabel->setText("0.00"); this->layout()->addWidget(valueLabel); - layout->addSpacerItem(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Ignored)); + //spacerItem = new QSpacerItem(20,40,QSizePolicy::Minimum,QSizePolicy::Ignored); + //layout->addSpacerItem(spacerItem); QFont valuefont = valueLabel->font(); QFont titlefont = titleLabel->font(); valuefont.setPixelSize(this->height() / 2.0); @@ -39,6 +40,7 @@ void UASQuickViewTextItem::resizeEvent(QResizeEvent *event) QFont titlefont = titleLabel->font(); valuefont.setPixelSize(this->height()); titlefont.setPixelSize(valuefont.pixelSize() / 2.0); + //spacerItem->setGeometry(QRect(0,0,20,this->height()/10.0)); QFontMetrics metrics(valuefont); //valuefont.setPixelSize(this->height() / 2.0); diff --git a/src/ui/uas/UASQuickViewTextItem.h b/src/ui/uas/UASQuickViewTextItem.h index ba3eb8193c..dea8cc3b16 100644 --- a/src/ui/uas/UASQuickViewTextItem.h +++ b/src/ui/uas/UASQuickViewTextItem.h @@ -3,6 +3,7 @@ #include "UASQuickViewItem.h" #include +#include class UASQuickViewTextItem : public UASQuickViewItem { public: @@ -14,6 +15,7 @@ protected: private: QLabel *titleLabel; QLabel *valueLabel; + QSpacerItem *spacerItem; }; #endif // UASQUICKVIEWTEXTITEM_H -- GitLab From 07c10d107049f6eb9d23afcabfc35538995ae140 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 18 Jun 2013 10:13:17 -0400 Subject: [PATCH 009/460] QuickView selection dialog now sorts items by category and lists them in an easier to read format --- src/ui/uas/UASQuickViewItemSelect.cc | 61 +++++++++++++++++++++++++--- src/ui/uas/UASQuickViewItemSelect.h | 5 +++ src/ui/uas/UASQuickViewItemSelect.ui | 23 ++++++++--- 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/src/ui/uas/UASQuickViewItemSelect.cc b/src/ui/uas/UASQuickViewItemSelect.cc index ebe47a7144..bf3832333c 100644 --- a/src/ui/uas/UASQuickViewItemSelect.cc +++ b/src/ui/uas/UASQuickViewItemSelect.cc @@ -6,26 +6,75 @@ UASQuickViewItemSelect::UASQuickViewItemSelect(QWidget *parent) : QWidget(parent ui.setupUi(this); currcol = 0; currrow = 0; - ui.gridLayout->setSpacing(0); + ui.gridLayout->setSpacing(5); ui.gridLayout->setMargin(0); } void UASQuickViewItemSelect::addItem(QString item,bool enabled) { + QString category = "."; + QString name = item; + if (item.indexOf(":") != -1 && item.indexOf(".") != -1) + { + //Item has a subcateogry + category = item.mid(item.indexOf(":")+1,item.indexOf(".") - item.indexOf(":")-1); + name = item.mid(item.indexOf(".")+1); + } + int col = -1; + if (m_categoryToIndexMap.contains(category)) + { + col = m_categoryToIndexMap[category]; + } + else + { + m_categoryToIndexMap[category] = currcol++; + col = m_categoryToIndexMap[category]; + //New column. + QLabel *titlelabel = new QLabel(this); + titlelabel->setText(category); + titlelabel->show(); + ui.gridLayout->addWidget(titlelabel,0,col); + } QCheckBox *label = new QCheckBox(this); + m_checkBoxList.append(label); if (enabled) { label->setChecked(true); } connect(label,SIGNAL(clicked(bool)),this,SLOT(checkBoxClicked(bool))); - label->setText(item); + label->setText(name); label->show(); - ui.gridLayout->addWidget(label,currrow,currcol++); - if (currcol > 10) + //ui.gridLayout->addWidget(label,currrow,currcol++); + bool breakout = false; + int row = -1; + while (!breakout) { - currcol = 0; - currrow++; + if (!ui.gridLayout->itemAtPosition(++row,col) || row > 100) + { + breakout = true; + } } + //Row is the next invalid object, and col is the proper column. + ui.gridLayout->addWidget(label,row,col); } +void UASQuickViewItemSelect::resizeEvent(QResizeEvent *event) +{ + /*for (int i=0;iremoveWidget(m_checkBoxList[i]); + } + int row = 0; + int col = 0; + for (int i=0;iaddWidget(m_checkBoxList[i],row,col); + col++; + ui.gridLayout->widget()->width() > this->width(); + //need to reduce column number. + + }*/ + +} + void UASQuickViewItemSelect::checkBoxClicked(bool checked) { QCheckBox *check = qobject_cast(sender()); diff --git a/src/ui/uas/UASQuickViewItemSelect.h b/src/ui/uas/UASQuickViewItemSelect.h index 4be402c5e1..04174b4b7e 100644 --- a/src/ui/uas/UASQuickViewItemSelect.h +++ b/src/ui/uas/UASQuickViewItemSelect.h @@ -2,6 +2,7 @@ #define UASQUICKVIEWITEMSELECT_H #include +#include #include "ui_UASQuickViewItemSelect.h" class UASQuickViewItemSelect : public QWidget @@ -14,7 +15,11 @@ public: void addItem(QString item,bool enabled = false); int currrow; int currcol; +protected: + void resizeEvent(QResizeEvent *event); private: + QMap m_categoryToIndexMap; + QList m_checkBoxList; Ui::UASQuickViewItemSelect ui; private slots: void checkBoxClicked(bool checked); diff --git a/src/ui/uas/UASQuickViewItemSelect.ui b/src/ui/uas/UASQuickViewItemSelect.ui index 9a35660c0e..60cc4102c8 100644 --- a/src/ui/uas/UASQuickViewItemSelect.ui +++ b/src/ui/uas/UASQuickViewItemSelect.ui @@ -6,8 +6,8 @@ 0 0 - 571 - 474 + 851 + 192 @@ -24,14 +24,27 @@ 0 0 - 551 - 454 + 831 + 172 - + + + + + Qt::Vertical + + + + 20 + 40 + + + + -- GitLab From 0f89c83865e11c136098e87c3e79ff50db83d3e9 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 18 Jun 2013 10:53:33 -0400 Subject: [PATCH 010/460] Some comment cleanup, and fix so when closing the main window, it also closes the item select window --- src/ui/uas/UASQuickView.cc | 71 ++++------------------------ src/ui/uas/UASQuickView.h | 1 + src/ui/uas/UASQuickViewItemSelect.ui | 10 ++-- 3 files changed, 15 insertions(+), 67 deletions(-) diff --git a/src/ui/uas/UASQuickView.cc b/src/ui/uas/UASQuickView.cc index b6d06645b0..9bb52255d4 100644 --- a/src/ui/uas/UASQuickView.cc +++ b/src/ui/uas/UASQuickView.cc @@ -16,69 +16,8 @@ UASQuickView::UASQuickView(QWidget *parent) : QWidget(parent) } this->setContextMenuPolicy(Qt::ActionsContextMenu); - - /*{ - QAction *action = new QAction("latitude",this); - action->setCheckable(true); - action->setChecked(true); - connect(action,SIGNAL(toggled(bool)),this,SLOT(actionTriggered(bool))); - this->addAction(action); - UASQuickViewItem *item = new UASQuickViewItem(this); - item->setTitle("latitude"); - ui.verticalLayout->addWidget(item); - uasPropertyToLabelMap["latitude"] = item; - } - - { - QAction *action = new QAction("longitude",this); - action->setCheckable(true); - action->setChecked(true); - connect(action,SIGNAL(toggled(bool)),this,SLOT(actionTriggered(bool))); - this->addAction(action); - UASQuickViewItem *item = new UASQuickViewItem(this); - item->setTitle("longitude"); - ui.verticalLayout->addWidget(item); - uasPropertyToLabelMap["longitude"] = item; - } - - { - QAction *action = new QAction("altitude",this); - action->setCheckable(true); - action->setChecked(true); - connect(action,SIGNAL(toggled(bool)),this,SLOT(actionTriggered(bool))); - this->addAction(action); - UASQuickViewItem *item = new UASQuickViewItem(this); - item->setTitle("altitude"); - ui.verticalLayout->addWidget(item); - uasPropertyToLabelMap["altitude"] = item; - } - - { - QAction *action = new QAction("satelliteCount",this); - action->setCheckable(true); - action->setChecked(true); - connect(action,SIGNAL(toggled(bool)),this,SLOT(actionTriggered(bool))); - this->addAction(action); - UASQuickViewItem *item = new UASQuickViewItem(this); - item->setTitle("satelliteCount"); - ui.verticalLayout->addWidget(item); - uasPropertyToLabelMap["satelliteCount"] = item; - } - - { - QAction *action = new QAction("distToWaypoint",this); - action->setCheckable(true); - action->setChecked(true); - connect(action,SIGNAL(toggled(bool)),this,SLOT(actionTriggered(bool))); - this->addAction(action); - UASQuickViewItem *item = new UASQuickViewItem(this); - item->setTitle("distToWaypoint"); - ui.verticalLayout->addWidget(item); - uasPropertyToLabelMap["distToWaypoint"] = item; - }*/ - - //this->setSizePolicy(); loadSettings(); + //If we don't have any predefined settings, set some defaults. if (uasPropertyValueMap.size() == 0) { @@ -98,6 +37,14 @@ UASQuickView::UASQuickView(QWidget *parent) : QWidget(parent) connect(updateTimer,SIGNAL(timeout()),this,SLOT(updateTimerTick())); updateTimer->start(1000); } +UASQuickView::~UASQuickView() +{ + if (quickViewSelectDialog) + { + delete quickViewSelectDialog; + } +} + void UASQuickView::actionTriggered() { if (quickViewSelectDialog) diff --git a/src/ui/uas/UASQuickView.h b/src/ui/uas/UASQuickView.h index 7a709f20d0..4a0dc9b7b2 100644 --- a/src/ui/uas/UASQuickView.h +++ b/src/ui/uas/UASQuickView.h @@ -15,6 +15,7 @@ class UASQuickView : public QWidget Q_OBJECT public: UASQuickView(QWidget *parent = 0); + ~UASQuickView(); void addSource(MAVLinkDecoder *decoder); private: UASInterface *uas; diff --git a/src/ui/uas/UASQuickViewItemSelect.ui b/src/ui/uas/UASQuickViewItemSelect.ui index 60cc4102c8..5371e2248d 100644 --- a/src/ui/uas/UASQuickViewItemSelect.ui +++ b/src/ui/uas/UASQuickViewItemSelect.ui @@ -6,12 +6,12 @@ 0 0 - 851 - 192 + 947 + 248 - Form + Select Item @@ -24,8 +24,8 @@ 0 0 - 831 - 172 + 927 + 228 -- GitLab From 8f585b40a52fa197e81956f3bfb5898a7712b468 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 18 Jun 2013 11:34:48 -0400 Subject: [PATCH 011/460] Fix for category values not being updated in QuickView properly --- src/ui/uas/UASQuickViewItemSelect.cc | 11 +++++++++-- src/ui/uas/UASQuickViewItemSelect.h | 1 + src/ui/uas/UASQuickViewTextItem.cc | 9 ++++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/ui/uas/UASQuickViewItemSelect.cc b/src/ui/uas/UASQuickViewItemSelect.cc index bf3832333c..6536529cae 100644 --- a/src/ui/uas/UASQuickViewItemSelect.cc +++ b/src/ui/uas/UASQuickViewItemSelect.cc @@ -35,6 +35,7 @@ void UASQuickViewItemSelect::addItem(QString item,bool enabled) ui.gridLayout->addWidget(titlelabel,0,col); } QCheckBox *label = new QCheckBox(this); + m_checkboxToValueMap[label] = item; m_checkBoxList.append(label); if (enabled) { @@ -82,13 +83,19 @@ void UASQuickViewItemSelect::checkBoxClicked(bool checked) { return; } + QString checkval = check->text(); + if (m_checkboxToValueMap.contains(check)) + { + checkval = m_checkboxToValueMap[check]; + } if (checked) { - emit valueEnabled(check->text()); + + emit valueEnabled(checkval); } else { - emit valueDisabled(check->text()); + emit valueDisabled(checkval); } } diff --git a/src/ui/uas/UASQuickViewItemSelect.h b/src/ui/uas/UASQuickViewItemSelect.h index 04174b4b7e..efd769cb3a 100644 --- a/src/ui/uas/UASQuickViewItemSelect.h +++ b/src/ui/uas/UASQuickViewItemSelect.h @@ -19,6 +19,7 @@ protected: void resizeEvent(QResizeEvent *event); private: QMap m_categoryToIndexMap; + QMap m_checkboxToValueMap; QList m_checkBoxList; Ui::UASQuickViewItemSelect ui; private slots: diff --git a/src/ui/uas/UASQuickViewTextItem.cc b/src/ui/uas/UASQuickViewTextItem.cc index c8fb12e861..3fbdd932d2 100644 --- a/src/ui/uas/UASQuickViewTextItem.cc +++ b/src/ui/uas/UASQuickViewTextItem.cc @@ -32,7 +32,14 @@ void UASQuickViewTextItem::setValue(double value) void UASQuickViewTextItem::setTitle(QString title) { - titleLabel->setText(title); + if (title.indexOf(".") != -1 && title.indexOf(":") != -1) + { + titleLabel->setText(title.mid(title.indexOf(".")+1)); + } + else + { + titleLabel->setText(title); + } } void UASQuickViewTextItem::resizeEvent(QResizeEvent *event) { -- GitLab From 632ddad3ade6ba332be5e7f28b2e3ab4d416f3e4 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 19 Jun 2013 13:18:31 -0400 Subject: [PATCH 012/460] New configuration menu setup. Placeholders for now, waiting for functionality --- qgroundcontrol.pro | 54 ++- src/ui/MainWindow.cc | 63 +++- src/ui/MainWindow.h | 11 +- src/ui/MainWindow.ui | 14 +- .../configuration/AccelCalibrationConfig.cc | 11 + src/ui/configuration/AccelCalibrationConfig.h | 19 + .../configuration/AccelCalibrationConfig.ui | 35 ++ src/ui/configuration/AirspeedConfig.cc | 11 + src/ui/configuration/AirspeedConfig.h | 19 + src/ui/configuration/AirspeedConfig.ui | 35 ++ src/ui/configuration/AntennaTrackerConfig.cc | 11 + src/ui/configuration/AntennaTrackerConfig.h | 19 + src/ui/configuration/AntennaTrackerConfig.ui | 35 ++ src/ui/configuration/ApmHardwareConfig.cc | 145 ++++++++ src/ui/configuration/ApmHardwareConfig.h | 54 +++ src/ui/configuration/ApmHardwareConfig.ui | 327 ++++++++++++++++++ src/ui/configuration/ApmSoftwareConfig.cc | 11 + src/ui/configuration/ApmSoftwareConfig.h | 19 + src/ui/configuration/ApmSoftwareConfig.ui | 99 ++++++ src/ui/configuration/BatteryMonitorConfig.cc | 11 + src/ui/configuration/BatteryMonitorConfig.h | 19 + src/ui/configuration/BatteryMonitorConfig.ui | 35 ++ src/ui/configuration/CameraGimbalConfig.cc | 11 + src/ui/configuration/CameraGimbalConfig.h | 19 + src/ui/configuration/CameraGimbalConfig.ui | 35 ++ src/ui/configuration/CompassConfig.cc | 11 + src/ui/configuration/CompassConfig.h | 19 + src/ui/configuration/CompassConfig.ui | 35 ++ src/ui/configuration/FlightModeConfig.cc | 11 + src/ui/configuration/FlightModeConfig.h | 19 + src/ui/configuration/FlightModeConfig.ui | 35 ++ src/ui/configuration/FrameTypeConfig.cc | 11 + src/ui/configuration/FrameTypeConfig.h | 19 + src/ui/configuration/FrameTypeConfig.ui | 35 ++ src/ui/configuration/OpticalFlowConfig.cc | 11 + src/ui/configuration/OpticalFlowConfig.h | 19 + src/ui/configuration/OpticalFlowConfig.ui | 35 ++ src/ui/configuration/OsdConfig.cc | 11 + src/ui/configuration/OsdConfig.h | 19 + src/ui/configuration/OsdConfig.ui | 35 ++ src/ui/configuration/Radio3DRConfig.cc | 11 + src/ui/configuration/Radio3DRConfig.h | 19 + src/ui/configuration/Radio3DRConfig.ui | 35 ++ .../configuration/RadioCalibrationConfig.cc | 11 + src/ui/configuration/RadioCalibrationConfig.h | 19 + .../configuration/RadioCalibrationConfig.ui | 35 ++ src/ui/configuration/SonarConfig.cc | 11 + src/ui/configuration/SonarConfig.h | 19 + src/ui/configuration/SonarConfig.ui | 35 ++ 49 files changed, 1616 insertions(+), 26 deletions(-) create mode 100644 src/ui/configuration/AccelCalibrationConfig.cc create mode 100644 src/ui/configuration/AccelCalibrationConfig.h create mode 100644 src/ui/configuration/AccelCalibrationConfig.ui create mode 100644 src/ui/configuration/AirspeedConfig.cc create mode 100644 src/ui/configuration/AirspeedConfig.h create mode 100644 src/ui/configuration/AirspeedConfig.ui create mode 100644 src/ui/configuration/AntennaTrackerConfig.cc create mode 100644 src/ui/configuration/AntennaTrackerConfig.h create mode 100644 src/ui/configuration/AntennaTrackerConfig.ui create mode 100644 src/ui/configuration/ApmHardwareConfig.cc create mode 100644 src/ui/configuration/ApmHardwareConfig.h create mode 100644 src/ui/configuration/ApmHardwareConfig.ui create mode 100644 src/ui/configuration/ApmSoftwareConfig.cc create mode 100644 src/ui/configuration/ApmSoftwareConfig.h create mode 100644 src/ui/configuration/ApmSoftwareConfig.ui create mode 100644 src/ui/configuration/BatteryMonitorConfig.cc create mode 100644 src/ui/configuration/BatteryMonitorConfig.h create mode 100644 src/ui/configuration/BatteryMonitorConfig.ui create mode 100644 src/ui/configuration/CameraGimbalConfig.cc create mode 100644 src/ui/configuration/CameraGimbalConfig.h create mode 100644 src/ui/configuration/CameraGimbalConfig.ui create mode 100644 src/ui/configuration/CompassConfig.cc create mode 100644 src/ui/configuration/CompassConfig.h create mode 100644 src/ui/configuration/CompassConfig.ui create mode 100644 src/ui/configuration/FlightModeConfig.cc create mode 100644 src/ui/configuration/FlightModeConfig.h create mode 100644 src/ui/configuration/FlightModeConfig.ui create mode 100644 src/ui/configuration/FrameTypeConfig.cc create mode 100644 src/ui/configuration/FrameTypeConfig.h create mode 100644 src/ui/configuration/FrameTypeConfig.ui create mode 100644 src/ui/configuration/OpticalFlowConfig.cc create mode 100644 src/ui/configuration/OpticalFlowConfig.h create mode 100644 src/ui/configuration/OpticalFlowConfig.ui create mode 100644 src/ui/configuration/OsdConfig.cc create mode 100644 src/ui/configuration/OsdConfig.h create mode 100644 src/ui/configuration/OsdConfig.ui create mode 100644 src/ui/configuration/Radio3DRConfig.cc create mode 100644 src/ui/configuration/Radio3DRConfig.h create mode 100644 src/ui/configuration/Radio3DRConfig.ui create mode 100644 src/ui/configuration/RadioCalibrationConfig.cc create mode 100644 src/ui/configuration/RadioCalibrationConfig.h create mode 100644 src/ui/configuration/RadioCalibrationConfig.ui create mode 100644 src/ui/configuration/SonarConfig.cc create mode 100644 src/ui/configuration/SonarConfig.h create mode 100644 src/ui/configuration/SonarConfig.ui diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index bf6c51e0fa..edf55c06c5 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -235,7 +235,22 @@ FORMS += src/ui/MainWindow.ui \ src/ui/uas/UASActionsWidget.ui \ src/ui/QGCTabbedInfoView.ui \ src/ui/UASRawStatusView.ui \ - src/ui/uas/QGCMessageView.ui + src/ui/uas/QGCMessageView.ui \ + src/ui/configuration/ApmHardwareConfig.ui \ + src/ui/configuration/ApmSoftwareConfig.ui \ + src/ui/configuration/FrameTypeConfig.ui \ + src/ui/configuration/CompassConfig.ui \ + src/ui/configuration/AccelCalibrationConfig.ui \ + src/ui/configuration/RadioCalibrationConfig.ui \ + src/ui/configuration/FlightModeConfig.ui \ + src/ui/configuration/Radio3DRConfig.ui \ + src/ui/configuration/BatteryMonitorConfig.ui \ + src/ui/configuration/SonarConfig.ui \ + src/ui/configuration/AirspeedConfig.ui \ + src/ui/configuration/OpticalFlowConfig.ui \ + src/ui/configuration/OsdConfig.ui \ + src/ui/configuration/AntennaTrackerConfig.ui \ + src/ui/configuration/CameraGimbalConfig.ui INCLUDEPATH += src \ src/ui \ src/ui/linechart \ @@ -251,7 +266,8 @@ INCLUDEPATH += src \ src/ui/watchdog \ src/ui/map3D \ src/ui/mission \ - src/ui/designer + src/ui/designer \ + src/ui/configuration HEADERS += src/MG.h \ src/QGCCore.h \ src/uas/UASInterface.h \ @@ -393,7 +409,22 @@ HEADERS += src/MG.h \ src/ui/QGCTabbedInfoView.h \ src/ui/UASRawStatusView.h \ src/ui/PrimaryFlightDisplay.h \ - src/ui/uas/QGCMessageView.h + src/ui/uas/QGCMessageView.h \ + src/ui/configuration/ApmHardwareConfig.h \ + src/ui/configuration/ApmSoftwareConfig.h \ + src/ui/configuration/FrameTypeConfig.h \ + src/ui/configuration/CompassConfig.h \ + src/ui/configuration/AccelCalibrationConfig.h \ + src/ui/configuration/RadioCalibrationConfig.h \ + src/ui/configuration/FlightModeConfig.h \ + src/ui/configuration/Radio3DRConfig.h \ + src/ui/configuration/BatteryMonitorConfig.h \ + src/ui/configuration/SonarConfig.h \ + src/ui/configuration/AirspeedConfig.h \ + src/ui/configuration/OpticalFlowConfig.h \ + src/ui/configuration/OsdConfig.h \ + src/ui/configuration/AntennaTrackerConfig.h \ + src/ui/configuration/CameraGimbalConfig.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -570,7 +601,22 @@ SOURCES += src/main.cc \ src/ui/QGCTabbedInfoView.cpp \ src/ui/UASRawStatusView.cpp \ src/ui/PrimaryFlightDisplay.cpp \ - src/ui/uas/QGCMessageView.cc + src/ui/uas/QGCMessageView.cc \ + src/ui/configuration/ApmHardwareConfig.cc \ + src/ui/configuration/ApmSoftwareConfig.cc \ + src/ui/configuration/FrameTypeConfig.cc \ + src/ui/configuration/CompassConfig.cc \ + src/ui/configuration/AccelCalibrationConfig.cc \ + src/ui/configuration/RadioCalibrationConfig.cc \ + src/ui/configuration/FlightModeConfig.cc \ + src/ui/configuration/Radio3DRConfig.cc \ + src/ui/configuration/BatteryMonitorConfig.cc \ + src/ui/configuration/SonarConfig.cc \ + src/ui/configuration/AirspeedConfig.cc \ + src/ui/configuration/OpticalFlowConfig.cc \ + src/ui/configuration/OsdConfig.cc \ + src/ui/configuration/AntennaTrackerConfig.cc \ + src/ui/configuration/CameraGimbalConfig.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 54e8d226f8..aaa076ba8f 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -174,7 +174,9 @@ MainWindow::MainWindow(QWidget *parent): QList actions; actions << ui.actionFlightView; actions << ui.actionMissionView; - actions << ui.actionConfiguration_2; + //actions << ui.actionConfiguration_2; + actions << ui.actionHardwareConfig; + actions << ui.actionSoftwareConfig; toolBar->setPerspectiveChangeActions(actions); // Add actions for advanced users (displayed in dropdown under "advanced") @@ -472,12 +474,20 @@ void MainWindow::buildCommonWidgets() if (!configView) { configView = new SubMainWindow(this); - configView->setObjectName("VIEW_CONFIGURATION"); - configView->setCentralWidget(new QGCVehicleConfig(this)); - addCentralWidget(configView,"Config"); - centralWidgetToDockWidgetsMap[VIEW_CONFIGURATION] = QMap(); + configView->setObjectName("VIEW_HARDWARE_CONFIG"); + configView->setCentralWidget(new ApmHardwareConfig(this)); + addCentralWidget(configView,"Hardware"); + centralWidgetToDockWidgetsMap[VIEW_HARDWARE_CONFIG] = QMap(); } + if (!softwareConfigView) + { + softwareConfigView = new SubMainWindow(this); + softwareConfigView->setObjectName("VIEW_SOFTWARE_CONFIG"); + softwareConfigView->setCentralWidget(new ApmSoftwareConfig(this)); + addCentralWidget(softwareConfigView,"Software"); + centralWidgetToDockWidgetsMap[VIEW_SOFTWARE_CONFIG] = QMap(); + } if (!engineeringView) { engineeringView = new SubMainWindow(this); @@ -1413,7 +1423,9 @@ void MainWindow::connectCommonActions() perspectives->addAction(ui.actionFlightView); perspectives->addAction(ui.actionSimulation_View); perspectives->addAction(ui.actionMissionView); - perspectives->addAction(ui.actionConfiguration_2); + //perspectives->addAction(ui.actionConfiguration_2); + perspectives->addAction(ui.actionHardwareConfig); + perspectives->addAction(ui.actionSoftwareConfig); perspectives->addAction(ui.actionFirmwareUpdateView); perspectives->addAction(ui.actionUnconnectedView); perspectives->setExclusive(true); @@ -1444,10 +1456,15 @@ void MainWindow::connectCommonActions() ui.actionMissionView->setChecked(true); ui.actionMissionView->activate(QAction::Trigger); } - if (currentView == VIEW_CONFIGURATION) + if (currentView == VIEW_HARDWARE_CONFIG) + { + ui.actionHardwareConfig->setChecked(true); + ui.actionHardwareConfig->activate(QAction::Trigger); + } + if (currentView == VIEW_SOFTWARE_CONFIG) { - ui.actionConfiguration_2->setChecked(true); - ui.actionConfiguration_2->activate(QAction::Trigger); + ui.actionSoftwareConfig->setChecked(true); + ui.actionSoftwareConfig->activate(QAction::Trigger); } if (currentView == VIEW_FIRMWAREUPDATE) { @@ -1489,7 +1506,9 @@ void MainWindow::connectCommonActions() connect(ui.actionEngineersView, SIGNAL(triggered()), this, SLOT(loadEngineerView())); connect(ui.actionMissionView, SIGNAL(triggered()), this, SLOT(loadOperatorView())); connect(ui.actionUnconnectedView, SIGNAL(triggered()), this, SLOT(loadUnconnectedView())); - connect(ui.actionConfiguration_2,SIGNAL(triggered()),this,SLOT(loadConfigurationView())); + //connect(ui.actionConfiguration_2,SIGNAL(triggered()),this,SLOT(loadConfigurationView())); + connect(ui.actionHardwareConfig,SIGNAL(triggered()),this,SLOT(loadHardwareConfigView())); + connect(ui.actionSoftwareConfig,SIGNAL(triggered()),this,SLOT(loadSoftwareConfigView())); connect(ui.actionFirmwareUpdateView, SIGNAL(triggered()), this, SLOT(loadFirmwareUpdateView())); connect(ui.actionMavlinkView, SIGNAL(triggered()), this, SLOT(loadMAVLinkView())); @@ -1955,9 +1974,12 @@ void MainWindow::loadViewState() // Load defaults switch (currentView) { - case VIEW_CONFIGURATION: + case VIEW_HARDWARE_CONFIG: centerStack->setCurrentWidget(configView); break; + case VIEW_SOFTWARE_CONFIG: + centerStack->setCurrentWidget(softwareConfigView); + break; case VIEW_ENGINEER: centerStack->setCurrentWidget(engineeringView); break; @@ -2067,13 +2089,24 @@ void MainWindow::loadOperatorView() loadViewState(); } } -void MainWindow::loadConfigurationView() +void MainWindow::loadHardwareConfigView() +{ + if (currentView != VIEW_HARDWARE_CONFIG) + { + storeViewState(); + currentView = VIEW_HARDWARE_CONFIG; + ui.actionHardwareConfig->setChecked(true); + loadViewState(); + } +} + +void MainWindow::loadSoftwareConfigView() { - if (currentView != VIEW_CONFIGURATION) + if (currentView != VIEW_SOFTWARE_CONFIG) { storeViewState(); - currentView = VIEW_CONFIGURATION; - ui.actionConfiguration_2->setChecked(true); + currentView = VIEW_SOFTWARE_CONFIG; + ui.actionSoftwareConfig->setChecked(true); loadViewState(); } } diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index f9b322961e..4435268f1c 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -82,6 +82,8 @@ This file is part of the QGROUNDCONTROL project #include "QGCMAVLinkLogPlayer.h" #include "QGCVehicleConfig.h" #include "MAVLinkDecoder.h" +#include "ApmHardwareConfig.h" +#include "ApmSoftwareConfig.h" class QGCMapTool; class QGCMAVLinkMessageSender; @@ -164,8 +166,9 @@ public slots: /** @brief Sets advanced mode, allowing for editing of tool widget locations */ void setAdvancedMode(); - /** @brief Load configuration view */ - void loadConfigurationView(); + /** @brief Load configuration views */ + void loadHardwareConfigView(); + void loadSoftwareConfigView(); /** @brief Load default view when no MAV is connected */ void loadUnconnectedView(); /** @brief Load view for pilot */ @@ -282,7 +285,8 @@ protected: VIEW_SIMULATION, VIEW_MAVLINK, VIEW_FIRMWAREUPDATE, - VIEW_CONFIGURATION, + VIEW_HARDWARE_CONFIG, + VIEW_SOFTWARE_CONFIG, VIEW_UNCONNECTED, ///< View in unconnected mode, when no UAS is available VIEW_FULL ///< All widgets shown at once } VIEW_SECTIONS; @@ -349,6 +353,7 @@ protected: QPointer plannerView; QPointer pilotView; QPointer configView; + QPointer softwareConfigView; QPointer mavlinkView; QPointer engineeringView; QPointer simView; diff --git a/src/ui/MainWindow.ui b/src/ui/MainWindow.ui index 24eef80933..f51da403fb 100644 --- a/src/ui/MainWindow.ui +++ b/src/ui/MainWindow.ui @@ -51,7 +51,7 @@ 0 0 800 - 22 + 21 @@ -105,7 +105,8 @@ - + + @@ -466,7 +467,7 @@ Open the simulation view - + true @@ -475,7 +476,7 @@ :/files/images/categories/preferences-system.svg:/files/images/categories/preferences-system.svg - Config + Hardware Configuration options of the vehicle. @@ -494,6 +495,11 @@ Simulation + + + Software + + diff --git a/src/ui/configuration/AccelCalibrationConfig.cc b/src/ui/configuration/AccelCalibrationConfig.cc new file mode 100644 index 0000000000..b861e6e78c --- /dev/null +++ b/src/ui/configuration/AccelCalibrationConfig.cc @@ -0,0 +1,11 @@ +#include "AccelCalibrationConfig.h" + + +AccelCalibrationConfig::AccelCalibrationConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +AccelCalibrationConfig::~AccelCalibrationConfig() +{ +} diff --git a/src/ui/configuration/AccelCalibrationConfig.h b/src/ui/configuration/AccelCalibrationConfig.h new file mode 100644 index 0000000000..51ae8d76f6 --- /dev/null +++ b/src/ui/configuration/AccelCalibrationConfig.h @@ -0,0 +1,19 @@ +#ifndef ACCELCALIBRATIONCONFIG_H +#define ACCELCALIBRATIONCONFIG_H + +#include +#include "ui_AccelCalibrationConfig.h" + +class AccelCalibrationConfig : public QWidget +{ + Q_OBJECT + +public: + explicit AccelCalibrationConfig(QWidget *parent = 0); + ~AccelCalibrationConfig(); + +private: + Ui::AccelCalibrationConfig ui; +}; + +#endif // ACCELCALIBRATIONCONFIG_H diff --git a/src/ui/configuration/AccelCalibrationConfig.ui b/src/ui/configuration/AccelCalibrationConfig.ui new file mode 100644 index 0000000000..75fdd0c659 --- /dev/null +++ b/src/ui/configuration/AccelCalibrationConfig.ui @@ -0,0 +1,35 @@ + + + AccelCalibrationConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 20 + 231 + 31 + + + + <h2>Accelerometer Calibration</h2> + + + false + + + + + + diff --git a/src/ui/configuration/AirspeedConfig.cc b/src/ui/configuration/AirspeedConfig.cc new file mode 100644 index 0000000000..bff387fb6a --- /dev/null +++ b/src/ui/configuration/AirspeedConfig.cc @@ -0,0 +1,11 @@ +#include "AirspeedConfig.h" + + +AirspeedConfig::AirspeedConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +AirspeedConfig::~AirspeedConfig() +{ +} diff --git a/src/ui/configuration/AirspeedConfig.h b/src/ui/configuration/AirspeedConfig.h new file mode 100644 index 0000000000..cd67ba49ec --- /dev/null +++ b/src/ui/configuration/AirspeedConfig.h @@ -0,0 +1,19 @@ +#ifndef AIRSPEEDCONFIG_H +#define AIRSPEEDCONFIG_H + +#include +#include "ui_AirspeedConfig.h" + +class AirspeedConfig : public QWidget +{ + Q_OBJECT + +public: + explicit AirspeedConfig(QWidget *parent = 0); + ~AirspeedConfig(); + +private: + Ui::AirspeedConfig ui; +}; + +#endif // AIRSPEEDCONFIG_H diff --git a/src/ui/configuration/AirspeedConfig.ui b/src/ui/configuration/AirspeedConfig.ui new file mode 100644 index 0000000000..07c97247a9 --- /dev/null +++ b/src/ui/configuration/AirspeedConfig.ui @@ -0,0 +1,35 @@ + + + AirspeedConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 20 + 131 + 31 + + + + <h2>Airspeed</h2> + + + false + + + + + + diff --git a/src/ui/configuration/AntennaTrackerConfig.cc b/src/ui/configuration/AntennaTrackerConfig.cc new file mode 100644 index 0000000000..6b406da474 --- /dev/null +++ b/src/ui/configuration/AntennaTrackerConfig.cc @@ -0,0 +1,11 @@ +#include "AntennaTrackerConfig.h" + + +AntennaTrackerConfig::AntennaTrackerConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +AntennaTrackerConfig::~AntennaTrackerConfig() +{ +} diff --git a/src/ui/configuration/AntennaTrackerConfig.h b/src/ui/configuration/AntennaTrackerConfig.h new file mode 100644 index 0000000000..35271cb288 --- /dev/null +++ b/src/ui/configuration/AntennaTrackerConfig.h @@ -0,0 +1,19 @@ +#ifndef ANTENNATRACKERCONFIG_H +#define ANTENNATRACKERCONFIG_H + +#include +#include "ui_AntennaTrackerConfig.h" + +class AntennaTrackerConfig : public QWidget +{ + Q_OBJECT + +public: + explicit AntennaTrackerConfig(QWidget *parent = 0); + ~AntennaTrackerConfig(); + +private: + Ui::AntennaTrackerConfig ui; +}; + +#endif // ANTENNATRACKERCONFIG_H diff --git a/src/ui/configuration/AntennaTrackerConfig.ui b/src/ui/configuration/AntennaTrackerConfig.ui new file mode 100644 index 0000000000..e259e1fcef --- /dev/null +++ b/src/ui/configuration/AntennaTrackerConfig.ui @@ -0,0 +1,35 @@ + + + AntennaTrackerConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 30 + 30 + 151 + 31 + + + + <h2>Antenna Tracker</h2> + + + false + + + + + + diff --git a/src/ui/configuration/ApmHardwareConfig.cc b/src/ui/configuration/ApmHardwareConfig.cc new file mode 100644 index 0000000000..829b43292a --- /dev/null +++ b/src/ui/configuration/ApmHardwareConfig.cc @@ -0,0 +1,145 @@ +#include "ApmHardwareConfig.h" + + +ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); + //ui.firmwareButton->setVisible(valse); + ui.manditoryHardware->setVisible(false); + ui.frameTypeButton->setVisible(false); + ui.compassButton->setVisible(false); + ui.accelCalibrateButton->setVisible(false); + ui.radioCalibrateButton->setVisible(false); + ui.flightModesButton->setVisible(false); + ui.optionalHardwareButton->setVisible(false); + //ui.radio3DRButton->setVisible(false); + ui.batteryMonitorButton->setVisible(false); + ui.sonarButton->setVisible(false); + ui.airspeedButton->setVisible(false); + ui.opticalFlowButton->setVisible(false); + ui.osdButton->setVisible(false); + ui.cameraGimbalButton->setVisible(false); + //ui.antennaTrackerButton->setVisible(false); + + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.frameTypeButton,SLOT(setShown(bool))); + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.compassButton,SLOT(setShown(bool))); + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.accelCalibrateButton,SLOT(setShown(bool))); + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.radioCalibrateButton,SLOT(setShown(bool))); + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.flightModesButton,SLOT(setShown(bool))); + + connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.radio3DRButton,SLOT(setShown(bool))); + connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.batteryMonitorButton,SLOT(setShown(bool))); + connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.sonarButton,SLOT(setShown(bool))); + connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.airspeedButton,SLOT(setShown(bool))); + connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.opticalFlowButton,SLOT(setShown(bool))); + connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.osdButton,SLOT(setShown(bool))); + connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.cameraGimbalButton,SLOT(setShown(bool))); + connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.antennaTrackerButton,SLOT(setShown(bool))); + + connect(ui.frameTypeButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + + QWidget *widget = new QWidget(this); + ui.stackedWidget->addWidget(widget); //Firmware placeholder. + buttonToConfigWidgetMap[ui.firmwareButton] = widget; + connect(ui.firmwareButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + frameConfig = new FrameTypeConfig(this); + ui.stackedWidget->addWidget(frameConfig); + buttonToConfigWidgetMap[ui.frameTypeButton] = frameConfig; + connect(ui.frameTypeButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + compassConfig = new CompassConfig(this); + ui.stackedWidget->addWidget(compassConfig); + buttonToConfigWidgetMap[ui.compassButton] = compassConfig; + connect(ui.compassButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + accelConfig = new AccelCalibrationConfig(this); + ui.stackedWidget->addWidget(accelConfig); + buttonToConfigWidgetMap[ui.accelCalibrateButton] = accelConfig; + connect(ui.accelCalibrateButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + radioConfig = new RadioCalibrationConfig(this); + ui.stackedWidget->addWidget(radioConfig); + buttonToConfigWidgetMap[ui.radioCalibrateButton] = radioConfig; + connect(ui.radioCalibrateButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + flightConfig = new FlightModeConfig(this); + ui.stackedWidget->addWidget(flightConfig); + buttonToConfigWidgetMap[ui.flightModesButton] = flightConfig; + connect(ui.flightModesButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + radio3drConfig = new Radio3DRConfig(this); + ui.stackedWidget->addWidget(radio3drConfig); + buttonToConfigWidgetMap[ui.radio3DRButton] = radio3drConfig; + connect(ui.radio3DRButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + batteryConfig = new BatteryMonitorConfig(this); + ui.stackedWidget->addWidget(batteryConfig); + buttonToConfigWidgetMap[ui.batteryMonitorButton] = batteryConfig; + connect(ui.batteryMonitorButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + sonarConfig = new SonarConfig(this); + ui.stackedWidget->addWidget(sonarConfig); + buttonToConfigWidgetMap[ui.sonarButton] = sonarConfig; + connect(ui.sonarButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + airspeedConfig = new AirspeedConfig(this); + ui.stackedWidget->addWidget(airspeedConfig); + buttonToConfigWidgetMap[ui.airspeedButton] = airspeedConfig; + connect(ui.airspeedButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + opticalFlowConfig = new OpticalFlowConfig(this); + ui.stackedWidget->addWidget(opticalFlowConfig); + buttonToConfigWidgetMap[ui.opticalFlowButton] = opticalFlowConfig; + connect(ui.opticalFlowButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + osdConfig = new OsdConfig(this); + ui.stackedWidget->addWidget(osdConfig); + buttonToConfigWidgetMap[ui.osdButton] = osdConfig; + connect(ui.osdButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + cameraGimbalConfig = new CameraGimbalConfig(this); + ui.stackedWidget->addWidget(cameraGimbalConfig); + buttonToConfigWidgetMap[ui.cameraGimbalButton] = cameraGimbalConfig; + connect(ui.cameraGimbalButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + antennaTrackerConfig = new AntennaTrackerConfig(this); + ui.stackedWidget->addWidget(antennaTrackerConfig); + buttonToConfigWidgetMap[ui.antennaTrackerButton] = antennaTrackerConfig; + connect(ui.antennaTrackerButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + + + connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); + if (UASManager::instance()->getActiveUAS()) + { + activeUASSet(UASManager::instance()->getActiveUAS()); + } +} +void ApmHardwareConfig::activateStackedWidget() +{ + if (buttonToConfigWidgetMap.contains(sender())) + { + ui.stackedWidget->setCurrentWidget(buttonToConfigWidgetMap[sender()]); + } +} + +ApmHardwareConfig::~ApmHardwareConfig() +{ +} + +void ApmHardwareConfig::activeUASSet(UASInterface *uas) +{ + if (!uas) + { + return; + } + ui.firmwareButton->setVisible(true); + ui.manditoryHardware->setVisible(true); + ui.manditoryHardware->setChecked(false); + ui.optionalHardwareButton->setVisible(true); + ui.optionalHardwareButton->setChecked(false); + ui.radio3DRButton->setVisible(false); + ui.antennaTrackerButton->setVisible(false); +} diff --git a/src/ui/configuration/ApmHardwareConfig.h b/src/ui/configuration/ApmHardwareConfig.h new file mode 100644 index 0000000000..d021d26720 --- /dev/null +++ b/src/ui/configuration/ApmHardwareConfig.h @@ -0,0 +1,54 @@ +#ifndef APMHARDWARECONFIG_H +#define APMHARDWARECONFIG_H + +#include +#include "ui_ApmHardwareConfig.h" +#include +#include +#include "FrameTypeConfig.h" +#include "CompassConfig.h" +#include "AccelCalibrationConfig.h" +#include "RadioCalibrationConfig.h" +#include "FlightModeConfig.h" +#include "Radio3DRConfig.h" +#include "BatteryMonitorConfig.h" +#include "SonarConfig.h" +#include "AirspeedConfig.h" +#include "OpticalFlowConfig.h" +#include "OsdConfig.h" +#include "CameraGimbalConfig.h" +#include "AntennaTrackerConfig.h" + +class ApmHardwareConfig : public QWidget +{ + Q_OBJECT + +public: + explicit ApmHardwareConfig(QWidget *parent = 0); + ~ApmHardwareConfig(); +private: + FrameTypeConfig *frameConfig; + CompassConfig *compassConfig; + AccelCalibrationConfig *accelConfig; + RadioCalibrationConfig *radioConfig; + FlightModeConfig *flightConfig; + + Radio3DRConfig *radio3drConfig; + BatteryMonitorConfig *batteryConfig; + SonarConfig *sonarConfig; + AirspeedConfig *airspeedConfig; + OpticalFlowConfig *opticalFlowConfig; + OsdConfig *osdConfig; + CameraGimbalConfig *cameraGimbalConfig; + AntennaTrackerConfig *antennaTrackerConfig; +private slots: + void activeUASSet(UASInterface *uas); + void activateStackedWidget(); +private: + Ui::ApmHardwareConfig ui; + + //This is a map between the buttons, and the widgets they should be displying + QMap buttonToConfigWidgetMap; +}; + +#endif // APMHARDWARECONFIG_H diff --git a/src/ui/configuration/ApmHardwareConfig.ui b/src/ui/configuration/ApmHardwareConfig.ui new file mode 100644 index 0000000000..87e2230ed7 --- /dev/null +++ b/src/ui/configuration/ApmHardwareConfig.ui @@ -0,0 +1,327 @@ + + + ApmHardwareConfig + + + + 0 + 0 + 984 + 553 + + + + Form + + + + + 0 + 20 + 175 + 531 + + + + + 175 + 0 + + + + + 175 + 16777215 + + + + true + + + + + 0 + 0 + 156 + 676 + + + + + + + QLayout::SetMinAndMaxSize + + + + + + 100 + 35 + + + + Install Firmware + + + + + + + + 0 + 35 + + + + >>> Manditory Hardware + + + true + + + + + + + + 0 + 35 + + + + Qt::LeftToRight + + + Frame Type + + + + + + + + 0 + 35 + + + + Compass + + + + + + + + 0 + 35 + + + + Qt::LeftToRight + + + false + + + Accel Calibration + + + + + + + + 100 + 35 + + + + + 16777215 + 16777215 + + + + Radio Calibration + + + false + + + false + + + + + + + + 0 + 35 + + + + Flight Modes + + + false + + + + + + + + 0 + 35 + + + + >>> Optional Hardware + + + true + + + + + + + + 0 + 35 + + + + 3DR Radio + + + + + + + + 0 + 35 + + + + Battery Monitor + + + + + + + + 0 + 35 + + + + Sonar + + + + + + + + 0 + 35 + + + + Airspeed + + + + + + + + 0 + 35 + + + + Optical Flow + + + + + + + + 0 + 35 + + + + OSD + + + + + + + + 0 + 35 + + + + Camera Gimbal + + + + + + + + 0 + 35 + + + + Antenna Tracker + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + 200 + 30 + 721 + 491 + + + + -1 + + + + + + diff --git a/src/ui/configuration/ApmSoftwareConfig.cc b/src/ui/configuration/ApmSoftwareConfig.cc new file mode 100644 index 0000000000..f8ae035ab8 --- /dev/null +++ b/src/ui/configuration/ApmSoftwareConfig.cc @@ -0,0 +1,11 @@ +#include "ApmSoftwareConfig.h" + + +ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +ApmSoftwareConfig::~ApmSoftwareConfig() +{ +} diff --git a/src/ui/configuration/ApmSoftwareConfig.h b/src/ui/configuration/ApmSoftwareConfig.h new file mode 100644 index 0000000000..35eabfd5d6 --- /dev/null +++ b/src/ui/configuration/ApmSoftwareConfig.h @@ -0,0 +1,19 @@ +#ifndef APMSOFTWARECONFIG_H +#define APMSOFTWARECONFIG_H + +#include +#include "ui_ApmSoftwareConfig.h" + +class ApmSoftwareConfig : public QWidget +{ + Q_OBJECT + +public: + explicit ApmSoftwareConfig(QWidget *parent = 0); + ~ApmSoftwareConfig(); + +private: + Ui::ApmSoftwareConfig ui; +}; + +#endif // APMSOFTWARECONFIG_H diff --git a/src/ui/configuration/ApmSoftwareConfig.ui b/src/ui/configuration/ApmSoftwareConfig.ui new file mode 100644 index 0000000000..0132c2f5c2 --- /dev/null +++ b/src/ui/configuration/ApmSoftwareConfig.ui @@ -0,0 +1,99 @@ + + + ApmSoftwareConfig + + + + 0 + 0 + 718 + 531 + + + + Form + + + + + 20 + 10 + 175 + 531 + + + + + 175 + 0 + + + + + 175 + 16777215 + + + + true + + + + + 0 + 0 + 173 + 529 + + + + + + + QLayout::SetMinAndMaxSize + + + + + + 100 + 35 + + + + APM Planner 2.0 Config + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + 220 + 20 + 471 + 491 + + + + + + + diff --git a/src/ui/configuration/BatteryMonitorConfig.cc b/src/ui/configuration/BatteryMonitorConfig.cc new file mode 100644 index 0000000000..23ef9a731e --- /dev/null +++ b/src/ui/configuration/BatteryMonitorConfig.cc @@ -0,0 +1,11 @@ +#include "BatteryMonitorConfig.h" + + +BatteryMonitorConfig::BatteryMonitorConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +BatteryMonitorConfig::~BatteryMonitorConfig() +{ +} diff --git a/src/ui/configuration/BatteryMonitorConfig.h b/src/ui/configuration/BatteryMonitorConfig.h new file mode 100644 index 0000000000..bdddcd8237 --- /dev/null +++ b/src/ui/configuration/BatteryMonitorConfig.h @@ -0,0 +1,19 @@ +#ifndef BATTERYMONITORCONFIG_H +#define BATTERYMONITORCONFIG_H + +#include +#include "ui_BatteryMonitorConfig.h" + +class BatteryMonitorConfig : public QWidget +{ + Q_OBJECT + +public: + explicit BatteryMonitorConfig(QWidget *parent = 0); + ~BatteryMonitorConfig(); + +private: + Ui::BatteryMonitorConfig ui; +}; + +#endif // BATTERYMONITORCONFIG_H diff --git a/src/ui/configuration/BatteryMonitorConfig.ui b/src/ui/configuration/BatteryMonitorConfig.ui new file mode 100644 index 0000000000..564ec5503f --- /dev/null +++ b/src/ui/configuration/BatteryMonitorConfig.ui @@ -0,0 +1,35 @@ + + + BatteryMonitorConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 20 + 141 + 31 + + + + <h2>Battery Monitor</h2> + + + false + + + + + + diff --git a/src/ui/configuration/CameraGimbalConfig.cc b/src/ui/configuration/CameraGimbalConfig.cc new file mode 100644 index 0000000000..377cbdd8f5 --- /dev/null +++ b/src/ui/configuration/CameraGimbalConfig.cc @@ -0,0 +1,11 @@ +#include "CameraGimbalConfig.h" + + +CameraGimbalConfig::CameraGimbalConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +CameraGimbalConfig::~CameraGimbalConfig() +{ +} diff --git a/src/ui/configuration/CameraGimbalConfig.h b/src/ui/configuration/CameraGimbalConfig.h new file mode 100644 index 0000000000..4373fbf5f1 --- /dev/null +++ b/src/ui/configuration/CameraGimbalConfig.h @@ -0,0 +1,19 @@ +#ifndef CAMERAGIMBALCONFIG_H +#define CAMERAGIMBALCONFIG_H + +#include +#include "ui_CameraGimbalConfig.h" + +class CameraGimbalConfig : public QWidget +{ + Q_OBJECT + +public: + explicit CameraGimbalConfig(QWidget *parent = 0); + ~CameraGimbalConfig(); + +private: + Ui::CameraGimbalConfig ui; +}; + +#endif // CAMERAGIMBALCONFIG_H diff --git a/src/ui/configuration/CameraGimbalConfig.ui b/src/ui/configuration/CameraGimbalConfig.ui new file mode 100644 index 0000000000..b2b7f607b3 --- /dev/null +++ b/src/ui/configuration/CameraGimbalConfig.ui @@ -0,0 +1,35 @@ + + + CameraGimbalConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 30 + 20 + 131 + 31 + + + + <h2>Camera Gimbal</h2> + + + false + + + + + + diff --git a/src/ui/configuration/CompassConfig.cc b/src/ui/configuration/CompassConfig.cc new file mode 100644 index 0000000000..015c45c8ee --- /dev/null +++ b/src/ui/configuration/CompassConfig.cc @@ -0,0 +1,11 @@ +#include "CompassConfig.h" + + +CompassConfig::CompassConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +CompassConfig::~CompassConfig() +{ +} diff --git a/src/ui/configuration/CompassConfig.h b/src/ui/configuration/CompassConfig.h new file mode 100644 index 0000000000..e70f34052b --- /dev/null +++ b/src/ui/configuration/CompassConfig.h @@ -0,0 +1,19 @@ +#ifndef COMPASSCONFIG_H +#define COMPASSCONFIG_H + +#include +#include "ui_CompassConfig.h" + +class CompassConfig : public QWidget +{ + Q_OBJECT + +public: + explicit CompassConfig(QWidget *parent = 0); + ~CompassConfig(); + +private: + Ui::CompassConfig ui; +}; + +#endif // COMPASSCONFIG_H diff --git a/src/ui/configuration/CompassConfig.ui b/src/ui/configuration/CompassConfig.ui new file mode 100644 index 0000000000..b97069d7ce --- /dev/null +++ b/src/ui/configuration/CompassConfig.ui @@ -0,0 +1,35 @@ + + + CompassConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 30 + 20 + 131 + 31 + + + + <h2>Compass</h2> + + + false + + + + + + diff --git a/src/ui/configuration/FlightModeConfig.cc b/src/ui/configuration/FlightModeConfig.cc new file mode 100644 index 0000000000..07a1ed3941 --- /dev/null +++ b/src/ui/configuration/FlightModeConfig.cc @@ -0,0 +1,11 @@ +#include "FlightModeConfig.h" + + +FlightModeConfig::FlightModeConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +FlightModeConfig::~FlightModeConfig() +{ +} diff --git a/src/ui/configuration/FlightModeConfig.h b/src/ui/configuration/FlightModeConfig.h new file mode 100644 index 0000000000..fdf1129bbd --- /dev/null +++ b/src/ui/configuration/FlightModeConfig.h @@ -0,0 +1,19 @@ +#ifndef FLIGHTMODECONFIG_H +#define FLIGHTMODECONFIG_H + +#include +#include "ui_FlightModeConfig.h" + +class FlightModeConfig : public QWidget +{ + Q_OBJECT + +public: + explicit FlightModeConfig(QWidget *parent = 0); + ~FlightModeConfig(); + +private: + Ui::FlightModeConfig ui; +}; + +#endif // FLIGHTMODECONFIG_H diff --git a/src/ui/configuration/FlightModeConfig.ui b/src/ui/configuration/FlightModeConfig.ui new file mode 100644 index 0000000000..737d405231 --- /dev/null +++ b/src/ui/configuration/FlightModeConfig.ui @@ -0,0 +1,35 @@ + + + FlightModeConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 10 + 20 + 131 + 31 + + + + <h2>Flight Modes</h2> + + + false + + + + + + diff --git a/src/ui/configuration/FrameTypeConfig.cc b/src/ui/configuration/FrameTypeConfig.cc new file mode 100644 index 0000000000..ac514cae3e --- /dev/null +++ b/src/ui/configuration/FrameTypeConfig.cc @@ -0,0 +1,11 @@ +#include "FrameTypeConfig.h" + + +FrameTypeConfig::FrameTypeConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +FrameTypeConfig::~FrameTypeConfig() +{ +} diff --git a/src/ui/configuration/FrameTypeConfig.h b/src/ui/configuration/FrameTypeConfig.h new file mode 100644 index 0000000000..592bf564d9 --- /dev/null +++ b/src/ui/configuration/FrameTypeConfig.h @@ -0,0 +1,19 @@ +#ifndef FRAMETYPECONFIG_H +#define FRAMETYPECONFIG_H + +#include +#include "ui_FrameTypeConfig.h" + +class FrameTypeConfig : public QWidget +{ + Q_OBJECT + +public: + explicit FrameTypeConfig(QWidget *parent = 0); + ~FrameTypeConfig(); + +private: + Ui::FrameTypeConfig ui; +}; + +#endif // FRAMETYPECONFIG_H diff --git a/src/ui/configuration/FrameTypeConfig.ui b/src/ui/configuration/FrameTypeConfig.ui new file mode 100644 index 0000000000..4359e41a0f --- /dev/null +++ b/src/ui/configuration/FrameTypeConfig.ui @@ -0,0 +1,35 @@ + + + FrameTypeConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 20 + 131 + 31 + + + + <h2>Frame Setup</h2> + + + false + + + + + + diff --git a/src/ui/configuration/OpticalFlowConfig.cc b/src/ui/configuration/OpticalFlowConfig.cc new file mode 100644 index 0000000000..bc977317b1 --- /dev/null +++ b/src/ui/configuration/OpticalFlowConfig.cc @@ -0,0 +1,11 @@ +#include "OpticalFlowConfig.h" + + +OpticalFlowConfig::OpticalFlowConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +OpticalFlowConfig::~OpticalFlowConfig() +{ +} diff --git a/src/ui/configuration/OpticalFlowConfig.h b/src/ui/configuration/OpticalFlowConfig.h new file mode 100644 index 0000000000..72ea2b0a3e --- /dev/null +++ b/src/ui/configuration/OpticalFlowConfig.h @@ -0,0 +1,19 @@ +#ifndef OPTICALFLOWCONFIG_H +#define OPTICALFLOWCONFIG_H + +#include +#include "ui_OpticalFlowConfig.h" + +class OpticalFlowConfig : public QWidget +{ + Q_OBJECT + +public: + explicit OpticalFlowConfig(QWidget *parent = 0); + ~OpticalFlowConfig(); + +private: + Ui::OpticalFlowConfig ui; +}; + +#endif // OPTICALFLOWCONFIG_H diff --git a/src/ui/configuration/OpticalFlowConfig.ui b/src/ui/configuration/OpticalFlowConfig.ui new file mode 100644 index 0000000000..19ffbd7e40 --- /dev/null +++ b/src/ui/configuration/OpticalFlowConfig.ui @@ -0,0 +1,35 @@ + + + OpticalFlowConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 20 + 131 + 31 + + + + <h2>Optical Flow</h2> + + + false + + + + + + diff --git a/src/ui/configuration/OsdConfig.cc b/src/ui/configuration/OsdConfig.cc new file mode 100644 index 0000000000..badf1b8e0f --- /dev/null +++ b/src/ui/configuration/OsdConfig.cc @@ -0,0 +1,11 @@ +#include "OsdConfig.h" + + +OsdConfig::OsdConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +OsdConfig::~OsdConfig() +{ +} diff --git a/src/ui/configuration/OsdConfig.h b/src/ui/configuration/OsdConfig.h new file mode 100644 index 0000000000..ecfb3ceaa3 --- /dev/null +++ b/src/ui/configuration/OsdConfig.h @@ -0,0 +1,19 @@ +#ifndef OSDCONFIG_H +#define OSDCONFIG_H + +#include +#include "ui_OsdConfig.h" + +class OsdConfig : public QWidget +{ + Q_OBJECT + +public: + explicit OsdConfig(QWidget *parent = 0); + ~OsdConfig(); + +private: + Ui::OsdConfig ui; +}; + +#endif // OSDCONFIG_H diff --git a/src/ui/configuration/OsdConfig.ui b/src/ui/configuration/OsdConfig.ui new file mode 100644 index 0000000000..c45bc6a259 --- /dev/null +++ b/src/ui/configuration/OsdConfig.ui @@ -0,0 +1,35 @@ + + + OsdConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 20 + 131 + 31 + + + + <h2>OSD</h2> + + + false + + + + + + diff --git a/src/ui/configuration/Radio3DRConfig.cc b/src/ui/configuration/Radio3DRConfig.cc new file mode 100644 index 0000000000..435ae290f9 --- /dev/null +++ b/src/ui/configuration/Radio3DRConfig.cc @@ -0,0 +1,11 @@ +#include "Radio3DRConfig.h" + + +Radio3DRConfig::Radio3DRConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +Radio3DRConfig::~Radio3DRConfig() +{ +} diff --git a/src/ui/configuration/Radio3DRConfig.h b/src/ui/configuration/Radio3DRConfig.h new file mode 100644 index 0000000000..5233921d15 --- /dev/null +++ b/src/ui/configuration/Radio3DRConfig.h @@ -0,0 +1,19 @@ +#ifndef RADIO3DRCONFIG_H +#define RADIO3DRCONFIG_H + +#include +#include "ui_Radio3DRConfig.h" + +class Radio3DRConfig : public QWidget +{ + Q_OBJECT + +public: + explicit Radio3DRConfig(QWidget *parent = 0); + ~Radio3DRConfig(); + +private: + Ui::Radio3DRConfig ui; +}; + +#endif // RADIO3DRCONFIG_H diff --git a/src/ui/configuration/Radio3DRConfig.ui b/src/ui/configuration/Radio3DRConfig.ui new file mode 100644 index 0000000000..7a98b9dba7 --- /dev/null +++ b/src/ui/configuration/Radio3DRConfig.ui @@ -0,0 +1,35 @@ + + + Radio3DRConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 20 + 131 + 31 + + + + <h2>3DR Radio</h2> + + + false + + + + + + diff --git a/src/ui/configuration/RadioCalibrationConfig.cc b/src/ui/configuration/RadioCalibrationConfig.cc new file mode 100644 index 0000000000..81b898eda6 --- /dev/null +++ b/src/ui/configuration/RadioCalibrationConfig.cc @@ -0,0 +1,11 @@ +#include "RadioCalibrationConfig.h" + + +RadioCalibrationConfig::RadioCalibrationConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +RadioCalibrationConfig::~RadioCalibrationConfig() +{ +} diff --git a/src/ui/configuration/RadioCalibrationConfig.h b/src/ui/configuration/RadioCalibrationConfig.h new file mode 100644 index 0000000000..df0cb44d6d --- /dev/null +++ b/src/ui/configuration/RadioCalibrationConfig.h @@ -0,0 +1,19 @@ +#ifndef RADIOCALIBRATIONCONFIG_H +#define RADIOCALIBRATIONCONFIG_H + +#include +#include "ui_RadioCalibrationConfig.h" + +class RadioCalibrationConfig : public QWidget +{ + Q_OBJECT + +public: + explicit RadioCalibrationConfig(QWidget *parent = 0); + ~RadioCalibrationConfig(); + +private: + Ui::RadioCalibrationConfig ui; +}; + +#endif // RADIOCALIBRATIONCONFIG_H diff --git a/src/ui/configuration/RadioCalibrationConfig.ui b/src/ui/configuration/RadioCalibrationConfig.ui new file mode 100644 index 0000000000..3fdd683782 --- /dev/null +++ b/src/ui/configuration/RadioCalibrationConfig.ui @@ -0,0 +1,35 @@ + + + RadioCalibrationConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 20 + 171 + 31 + + + + <h2>Radio Calibration</h2> + + + false + + + + + + diff --git a/src/ui/configuration/SonarConfig.cc b/src/ui/configuration/SonarConfig.cc new file mode 100644 index 0000000000..fa9ce05d70 --- /dev/null +++ b/src/ui/configuration/SonarConfig.cc @@ -0,0 +1,11 @@ +#include "SonarConfig.h" + + +SonarConfig::SonarConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +SonarConfig::~SonarConfig() +{ +} diff --git a/src/ui/configuration/SonarConfig.h b/src/ui/configuration/SonarConfig.h new file mode 100644 index 0000000000..07dc9cfbcd --- /dev/null +++ b/src/ui/configuration/SonarConfig.h @@ -0,0 +1,19 @@ +#ifndef SONARCONFIG_H +#define SONARCONFIG_H + +#include +#include "ui_SonarConfig.h" + +class SonarConfig : public QWidget +{ + Q_OBJECT + +public: + explicit SonarConfig(QWidget *parent = 0); + ~SonarConfig(); + +private: + Ui::SonarConfig ui; +}; + +#endif // SONARCONFIG_H diff --git a/src/ui/configuration/SonarConfig.ui b/src/ui/configuration/SonarConfig.ui new file mode 100644 index 0000000000..e286253853 --- /dev/null +++ b/src/ui/configuration/SonarConfig.ui @@ -0,0 +1,35 @@ + + + SonarConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 20 + 131 + 31 + + + + <h2>Sonar</h2> + + + false + + + + + + -- GitLab From 274b20d8b4268c92d29f86983e1e1900a3657db1 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Thu, 20 Jun 2013 14:36:36 -0400 Subject: [PATCH 013/460] Change for layout of configuration widgets, and start of implmentation of RadioCalibration Widget --- files/images/devices/BR-HMC5883-01-2.jpg | Bin 0 -> 14551 bytes qgroundcontrol.qrc | 4 + .../configuration/AccelCalibrationConfig.ui | 35 ++- src/ui/configuration/ApmHardwareConfig.cc | 30 +++ src/ui/configuration/ApmHardwareConfig.h | 31 +++ src/ui/configuration/CompassConfig.ui | 173 +++++++++++- src/ui/configuration/FrameTypeConfig.cc | 49 ++++ src/ui/configuration/FrameTypeConfig.h | 40 ++- src/ui/configuration/FrameTypeConfig.ui | 110 ++++++-- .../configuration/RadioCalibrationConfig.cc | 100 +++++++ src/ui/configuration/RadioCalibrationConfig.h | 52 +++- .../configuration/RadioCalibrationConfig.ui | 253 +++++++++++++++++- 12 files changed, 840 insertions(+), 37 deletions(-) create mode 100644 files/images/devices/BR-HMC5883-01-2.jpg diff --git a/files/images/devices/BR-HMC5883-01-2.jpg b/files/images/devices/BR-HMC5883-01-2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f695795f6f93082d0e4a9b588aef3e9f515ff133 GIT binary patch literal 14551 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 literal 0 HcmV?d00001 diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 0b614ff672..fab4b89ebf 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -106,6 +106,10 @@ files/images/apm_planner_logo_splash.png files/images/apm_planner_2_0-07.png files/images/apm_planner_2_0-08.png + files/images/mavs/frames_plus.png + files/images/mavs/frames_x.png + files/images/mavs/frames-05.png + files/images/devices/BR-HMC5883-01-2.jpg files/styles/Vera.ttf diff --git a/src/ui/configuration/AccelCalibrationConfig.ui b/src/ui/configuration/AccelCalibrationConfig.ui index 75fdd0c659..43ca6a1536 100644 --- a/src/ui/configuration/AccelCalibrationConfig.ui +++ b/src/ui/configuration/AccelCalibrationConfig.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 300 + 576 + 354 @@ -16,8 +16,8 @@ - 20 - 20 + 10 + 0 231 31 @@ -29,6 +29,33 @@ false + + + + 60 + 60 + 81 + 31 + + + + Calibrate +Accelerometer + + + + + + 40 + 120 + 161 + 51 + + + + + + diff --git a/src/ui/configuration/ApmHardwareConfig.cc b/src/ui/configuration/ApmHardwareConfig.cc index 829b43292a..909db3ad5b 100644 --- a/src/ui/configuration/ApmHardwareConfig.cc +++ b/src/ui/configuration/ApmHardwareConfig.cc @@ -1,3 +1,33 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2013 Michael Carpenter (malcom2073@gmail.com) + +This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + +======================================================================*/ + +/** + * @file + * @brief APM Hardware Configuration widget source. + * + * @author Michael Carpenter + * + */ #include "ApmHardwareConfig.h" diff --git a/src/ui/configuration/ApmHardwareConfig.h b/src/ui/configuration/ApmHardwareConfig.h index d021d26720..8a2beacff3 100644 --- a/src/ui/configuration/ApmHardwareConfig.h +++ b/src/ui/configuration/ApmHardwareConfig.h @@ -1,3 +1,34 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2013 Michael Carpenter (malcom2073@gmail.com) + +This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + +======================================================================*/ + +/** + * @file + * @brief APM Hardware Configuration widget header. + * + * @author Michael Carpenter + * + */ + #ifndef APMHARDWARECONFIG_H #define APMHARDWARECONFIG_H diff --git a/src/ui/configuration/CompassConfig.ui b/src/ui/configuration/CompassConfig.ui index b97069d7ce..8f7edd5945 100644 --- a/src/ui/configuration/CompassConfig.ui +++ b/src/ui/configuration/CompassConfig.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 300 + 565 + 241 @@ -16,9 +16,9 @@ - 30 - 20 - 131 + 10 + 0 + 521 31 @@ -29,7 +29,168 @@ false + + + + 230 + 100 + 101 + 16 + + + + <a href="http://magnetic-declination.com/">Declination Website</a> + + + + + + 280 + 120 + 201 + 22 + + + + + + + 300 + 180 + 91 + 23 + + + + Live Calibration + + + + + + 390 + 180 + 91 + 23 + + + + Log Calibration + + + + + + 340 + 160 + 91 + 16 + + + + Advanced Config + + + + + + 220 + 70 + 321 + 31 + + + + + + + + + + in Degrees eg 2* 3' W is -2.3 + + + + + + + + + 10 + 70 + 201 + 111 + + + + + + + + 100 + 100 + + + + + + + :/files/images/devices/BR-HMC5883-01-2.jpg + + + true + + + + + + + + + Enable + + + + + + + Auto Declination + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + 220 + 120 + 54 + 20 + + + + Orientation + + - + + + diff --git a/src/ui/configuration/FrameTypeConfig.cc b/src/ui/configuration/FrameTypeConfig.cc index ac514cae3e..abb894245b 100644 --- a/src/ui/configuration/FrameTypeConfig.cc +++ b/src/ui/configuration/FrameTypeConfig.cc @@ -1,11 +1,60 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2013 Michael Carpenter (malcom2073@gmail.com) + +This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Airframe type configuration widget source. + * + * @author Michael Carpenter + * + */ + #include "FrameTypeConfig.h" FrameTypeConfig::FrameTypeConfig(QWidget *parent) : QWidget(parent) { ui.setupUi(this); + connect(ui.plusRadioButton,SIGNAL(clicked()),this,SLOT(plusFrameSelected())); + connect(ui.xRadioButton,SIGNAL(clicked()),this,SLOT(xFrameSelected())); + connect(ui.vRadioButton,SIGNAL(clicked()),this,SLOT(vFrameSelected())); + //connect(UASManager::instance()->getActiveUAS()->getParamManager(),SIGNAL(parameterListUpToDate(int)) } FrameTypeConfig::~FrameTypeConfig() { } +void FrameTypeConfig::xFrameSelected() +{ + +} + +void FrameTypeConfig::plusFrameSelected() +{ + +} + +void FrameTypeConfig::vFrameSelected() +{ + +} diff --git a/src/ui/configuration/FrameTypeConfig.h b/src/ui/configuration/FrameTypeConfig.h index 592bf564d9..f24e00f9fd 100644 --- a/src/ui/configuration/FrameTypeConfig.h +++ b/src/ui/configuration/FrameTypeConfig.h @@ -1,9 +1,42 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2013 Michael Carpenter (malcom2073@gmail.com) + +This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Airframe type configuration widget header. + * + * @author Michael Carpenter + * + */ + #ifndef FRAMETYPECONFIG_H #define FRAMETYPECONFIG_H #include #include "ui_FrameTypeConfig.h" - +#include "UASInterface.h" +#include "UASManager.h" +#include "QGCUASParamManager.h" class FrameTypeConfig : public QWidget { Q_OBJECT @@ -11,7 +44,10 @@ class FrameTypeConfig : public QWidget public: explicit FrameTypeConfig(QWidget *parent = 0); ~FrameTypeConfig(); - +private slots: + void xFrameSelected(); + void plusFrameSelected(); + void vFrameSelected(); private: Ui::FrameTypeConfig ui; }; diff --git a/src/ui/configuration/FrameTypeConfig.ui b/src/ui/configuration/FrameTypeConfig.ui index 4359e41a0f..6787fa5dbc 100644 --- a/src/ui/configuration/FrameTypeConfig.ui +++ b/src/ui/configuration/FrameTypeConfig.ui @@ -6,30 +6,102 @@ 0 0 - 400 - 300 + 553 + 497 Form - - - - 20 - 20 - 131 - 31 - - - - <h2>Frame Setup</h2> - - - false - - + + + + + <h2>Frame Setup</h2> + + + false + + + + + + + + + 'Plus' Style + + + + :/files/images/mavs/frames_plus.png:/files/images/mavs/frames_plus.png + + + + 300 + 150 + + + + + + + + 'X' Style + + + + :/files/images/mavs/frames_x.png:/files/images/mavs/frames_x.png + + + + 300 + 150 + + + + + + + + Qt::LeftToRight + + + false + + + 'V' Style + + + + :/files/images/mavs/frames-05.png:/files/images/mavs/frames-05.png + + + + 300 + 120 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + - + + + diff --git a/src/ui/configuration/RadioCalibrationConfig.cc b/src/ui/configuration/RadioCalibrationConfig.cc index 81b898eda6..37aaac0886 100644 --- a/src/ui/configuration/RadioCalibrationConfig.cc +++ b/src/ui/configuration/RadioCalibrationConfig.cc @@ -1,11 +1,111 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2013 Michael Carpenter (malcom2073@gmail.com) + +This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Radio Calibration Configuration source. + * + * @author Michael Carpenter + * + */ + #include "RadioCalibrationConfig.h" RadioCalibrationConfig::RadioCalibrationConfig(QWidget *parent) : QWidget(parent) { ui.setupUi(this); + m_uas = 0; + m_calibrationEnabled = false; + connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); + setActiveUAS(UASManager::instance()->getActiveUAS()); + ui.rollWidget->setMin(800); + ui.rollWidget->setMax(2200); + ui.pitchWidget->setMin(800); + ui.pitchWidget->setMax(2200); + ui.throttleWidget->setMin(800); + ui.throttleWidget->setMax(2200); + ui.yawWidget->setMin(800); + ui.yawWidget->setMax(2200); + guiUpdateTimer = new QTimer(this); + connect(guiUpdateTimer,SIGNAL(timeout()),this,SLOT(guiUpdateTimerTick())); } RadioCalibrationConfig::~RadioCalibrationConfig() { } +void RadioCalibrationConfig::setActiveUAS(UASInterface *uas) +{ + if (uas==NULL) return; + if (m_uas) + { + // Disconnect old system + disconnect(m_uas, SIGNAL(remoteControlChannelRawChanged(int,float)), this,SLOT(remoteControlChannelRawChanged(int,float))); + disconnect(m_uas, SIGNAL(parameterChanged(int,int,QString,QVariant)), this,SLOT(parameterChanged(int,int,QString,QVariant))); + } + +} +void RadioCalibrationConfig::remoteControlChannelRawChanged(int chan,float val) +{ + + //Channel is 0-7 typically? + //Val will be 0-3000, PWM value. + if (m_calibrationEnabled) { + if (val < rcMin[chan]) + { + rcMin[chan] = val; + } + + if (val > rcMax[chan]) + { + rcMax[chan] = val; + } + } + + // Raw value + rcValue[chan] = val; +} + +void RadioCalibrationConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + +} +void RadioCalibrationConfig::guiUpdateTimerTick() +{ + ui.rollWidget->setValue(rcValue[0]); + ui.pitchWidget->setValue(rcValue[1]); + ui.throttleWidget->setValue(rcValue[2]); + ui.yawWidget->setValue(rcValue[3]); + ui.radio5Widget->setValue(rcValue[4]); + ui.radio6Widget->setValue(rcValue[5]); + ui.radio7Widget->setValue(rcValue[6]); + ui.radio8Widget->setValue(rcValue[7]); +} +void RadioCalibrationConfig::showEvent(QShowEvent *event) +{ + guiUpdateTimer->stop(); +} +void RadioCalibrationConfig::hideEvent(QHideEvent *event) +{ + guiUpdateTimer->start(100); +} diff --git a/src/ui/configuration/RadioCalibrationConfig.h b/src/ui/configuration/RadioCalibrationConfig.h index df0cb44d6d..a873483191 100644 --- a/src/ui/configuration/RadioCalibrationConfig.h +++ b/src/ui/configuration/RadioCalibrationConfig.h @@ -1,9 +1,44 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2013 Michael Carpenter (malcom2073@gmail.com) + +This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Radio Calibration Configuration widget header. + * + * @author Michael Carpenter + * + */ + #ifndef RADIOCALIBRATIONCONFIG_H #define RADIOCALIBRATIONCONFIG_H #include +#include +#include +#include #include "ui_RadioCalibrationConfig.h" - +#include "UASManager.h" +#include "UASInterface.h" class RadioCalibrationConfig : public QWidget { Q_OBJECT @@ -11,8 +46,21 @@ class RadioCalibrationConfig : public QWidget public: explicit RadioCalibrationConfig(QWidget *parent = 0); ~RadioCalibrationConfig(); - +protected: + void showEvent(QShowEvent *event); + void hideEvent(QHideEvent *event); +private slots: + void setActiveUAS(UASInterface *uas); + void remoteControlChannelRawChanged(int chan,float val); + void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void guiUpdateTimerTick(); private: + double rcMin[8]; + double rcMax[8]; + double rcValue[8]; + QTimer *guiUpdateTimer; + bool m_calibrationEnabled; + UASInterface *m_uas; Ui::RadioCalibrationConfig ui; }; diff --git a/src/ui/configuration/RadioCalibrationConfig.ui b/src/ui/configuration/RadioCalibrationConfig.ui index 3fdd683782..321d20087d 100644 --- a/src/ui/configuration/RadioCalibrationConfig.ui +++ b/src/ui/configuration/RadioCalibrationConfig.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 300 + 771 + 389 @@ -16,8 +16,8 @@ - 20 - 20 + 10 + 10 171 31 @@ -29,7 +29,252 @@ false + + + + 10 + 50 + 716 + 300 + + + + + QLayout::SetMinAndMaxSize + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 50 + 200 + + + + + 50 + 200 + + + + + + + + Qt::Horizontal + + + + 250 + 20 + + + + + + + + + 50 + 200 + + + + + 50 + 200 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 20 + 360 + 75 + 23 + + + + Calibrate + + + + + QGCRadioChannelDisplay + QWidget +

ui/designer/QGCRadioChannelDisplay.h
+ 1 + + -- GitLab From 36060bd15e271564c06cbaf5dff856b66696974f Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 21 Jun 2013 09:57:23 -0400 Subject: [PATCH 014/460] Implementation of FrameTypeConfig completed, now reads and sets Frame Type --- src/ui/configuration/FrameTypeConfig.cc | 57 +++++++++++++++++++++++-- src/ui/configuration/FrameTypeConfig.h | 3 ++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/ui/configuration/FrameTypeConfig.cc b/src/ui/configuration/FrameTypeConfig.cc index abb894245b..571c10073b 100644 --- a/src/ui/configuration/FrameTypeConfig.cc +++ b/src/ui/configuration/FrameTypeConfig.cc @@ -34,27 +34,76 @@ This file is part of the QGROUNDCONTROL project FrameTypeConfig::FrameTypeConfig(QWidget *parent) : QWidget(parent) { + m_uas=0; ui.setupUi(this); + + //Disable until we get a FRAME parameter. + ui.xRadioButton->setEnabled(false); + ui.vRadioButton->setEnabled(false); + ui.plusRadioButton->setEnabled(false); + connect(ui.plusRadioButton,SIGNAL(clicked()),this,SLOT(plusFrameSelected())); connect(ui.xRadioButton,SIGNAL(clicked()),this,SLOT(xFrameSelected())); connect(ui.vRadioButton,SIGNAL(clicked()),this,SLOT(vFrameSelected())); - //connect(UASManager::instance()->getActiveUAS()->getParamManager(),SIGNAL(parameterListUpToDate(int)) + connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); + activeUASSet(UASManager::instance()->getActiveUAS()); } FrameTypeConfig::~FrameTypeConfig() { } -void FrameTypeConfig::xFrameSelected() +void FrameTypeConfig::activeUASSet(UASInterface *uas) +{ + if (!uas) return; + if (!m_uas) + { + disconnect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); + } + m_uas = uas; + connect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); +} +void FrameTypeConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { + if (parameterName == "FRAME") + { + ui.xRadioButton->setEnabled(true); + ui.vRadioButton->setEnabled(true); + ui.plusRadioButton->setEnabled(true); + if (value.toInt() == 0) + { + ui.plusRadioButton->setChecked(true); + } + else if (value.toInt() == 1) + { + ui.xRadioButton->setChecked(true); + } + else if (value.toInt() == 2) + { + ui.vRadioButton->setChecked(true); + } + } +} +void FrameTypeConfig::xFrameSelected() +{ + if (m_uas) + { + m_uas->setParameter(0,"FRAME",QVariant(1)); + } } void FrameTypeConfig::plusFrameSelected() { - + if (m_uas) + { + m_uas->setParameter(0,"FRAME",QVariant(0)); + } } void FrameTypeConfig::vFrameSelected() { - + if (m_uas) + { + m_uas->setParameter(0,"FRAME",QVariant(2)); + } } diff --git a/src/ui/configuration/FrameTypeConfig.h b/src/ui/configuration/FrameTypeConfig.h index f24e00f9fd..d28c914391 100644 --- a/src/ui/configuration/FrameTypeConfig.h +++ b/src/ui/configuration/FrameTypeConfig.h @@ -45,11 +45,14 @@ public: explicit FrameTypeConfig(QWidget *parent = 0); ~FrameTypeConfig(); private slots: + void activeUASSet(UASInterface *uas); + void parameterChanged(int uas, int component, QString parameterName, QVariant value); void xFrameSelected(); void plusFrameSelected(); void vFrameSelected(); private: Ui::FrameTypeConfig ui; + UASInterface *m_uas; }; #endif // FRAMETYPECONFIG_H -- GitLab From 223a748441f8302c961c1294b8229aa13741511d Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 21 Jun 2013 18:32:54 -0400 Subject: [PATCH 015/460] CompassConfig implementation --- src/ui/configuration/CompassConfig.cc | 99 ++++++++++++++++++++++++++- src/ui/configuration/CompassConfig.h | 11 ++- src/ui/configuration/CompassConfig.ui | 4 +- 3 files changed, 109 insertions(+), 5 deletions(-) diff --git a/src/ui/configuration/CompassConfig.cc b/src/ui/configuration/CompassConfig.cc index 015c45c8ee..fda95b6620 100644 --- a/src/ui/configuration/CompassConfig.cc +++ b/src/ui/configuration/CompassConfig.cc @@ -3,9 +3,106 @@ CompassConfig::CompassConfig(QWidget *parent) : QWidget(parent) { + m_uas=0; ui.setupUi(this); -} + ui.autoDecCheckBox->setEnabled(false); + ui.enableCheckBox->setEnabled(false); + ui.orientationComboBox->setEnabled(false); + ui.declinationLineEdit->setEnabled(false); + connect(ui.enableCheckBox,SIGNAL(clicked(bool)),this,SLOT(enableClicked(bool))); + connect(ui.autoDecCheckBox,SIGNAL(clicked(bool)),this,SLOT(autoDecClicked(bool))); + connect(ui.orientationComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(orientationComboChanged(int))); + + connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); + activeUASSet(UASManager::instance()->getActiveUAS()); +} CompassConfig::~CompassConfig() { } +void CompassConfig::activeUASSet(UASInterface *uas) +{ + if (!uas) return; + if (!m_uas) + { + disconnect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); + } + m_uas = uas; + connect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); +} +void CompassConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + if (parameterName == "MAG_ENABLE") + { + if (value.toInt() == 0) + { + ui.enableCheckBox->setChecked(false); + ui.autoDecCheckBox->setEnabled(false); + ui.declinationLineEdit->setEnabled(false); + } + else + { + ui.enableCheckBox->setChecked(true); + ui.autoDecCheckBox->setEnabled(true); + ui.declinationLineEdit->setEnabled(true); + } + ui.enableCheckBox->setEnabled(true); + } + else if (parameterName == "COMPASS_AUTODEC") + { + if (value.toInt() == 0) + { + ui.autoDecCheckBox->setChecked(false); + } + else + { + ui.autoDecCheckBox->setChecked(true); + } + } + else if (parameterName == "COMPASS_DEC") + { + ui.declinationLineEdit->setText(QString::number(value.toDouble())); + } +} + +void CompassConfig::enableClicked(bool enabled) +{ + if (m_uas) + { + if (enabled) + { + m_uas->setParameter(0,"MAG_ENABLE",QVariant(1)); + ui.autoDecCheckBox->setEnabled(true); + if (!ui.autoDecCheckBox->isChecked()) + { + ui.declinationLineEdit->setEnabled(true); + } + } + else + { + m_uas->setParameter(0,"MAG_ENABLE",QVariant(0)); + ui.autoDecCheckBox->setEnabled(false); + ui.declinationLineEdit->setEnabled(false); + } + } +} + +void CompassConfig::autoDecClicked(bool enabled) +{ + if (m_uas) + { + if (enabled) + { + m_uas->setParameter(0,"COMPASS_AUTODEC",QVariant(1)); + } + else + { + m_uas->setParameter(0,"COMPASS_AUTODEC",QVariant(0)); + } + } +} + +void CompassConfig::orientationComboChanged(int index) +{ + +} diff --git a/src/ui/configuration/CompassConfig.h b/src/ui/configuration/CompassConfig.h index e70f34052b..31a7fe3e1f 100644 --- a/src/ui/configuration/CompassConfig.h +++ b/src/ui/configuration/CompassConfig.h @@ -3,7 +3,8 @@ #include #include "ui_CompassConfig.h" - +#include "UASManager.h" +#include "UASInterface.h" class CompassConfig : public QWidget { Q_OBJECT @@ -11,9 +12,15 @@ class CompassConfig : public QWidget public: explicit CompassConfig(QWidget *parent = 0); ~CompassConfig(); - +private slots: + void activeUASSet(UASInterface *uas); + void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void enableClicked(bool enabled); + void autoDecClicked(bool enabled); + void orientationComboChanged(int index); private: Ui::CompassConfig ui; + UASInterface *m_uas; }; #endif // COMPASSCONFIG_H diff --git a/src/ui/configuration/CompassConfig.ui b/src/ui/configuration/CompassConfig.ui index 8f7edd5945..7ac1ede4fa 100644 --- a/src/ui/configuration/CompassConfig.ui +++ b/src/ui/configuration/CompassConfig.ui @@ -42,7 +42,7 @@ <a href="http://magnetic-declination.com/">Declination Website</a> - + 280 @@ -102,7 +102,7 @@ - + -- GitLab From f909055d74b859820c6226058d48007ca2d47468 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Mon, 24 Jun 2013 15:33:03 -0400 Subject: [PATCH 016/460] Working accelerometer calibation for APM3.0 and greater --- .../configuration/AccelCalibrationConfig.cc | 82 +++++++++++++++++++ src/ui/configuration/AccelCalibrationConfig.h | 10 ++- .../configuration/AccelCalibrationConfig.ui | 14 ++-- 3 files changed, 97 insertions(+), 9 deletions(-) diff --git a/src/ui/configuration/AccelCalibrationConfig.cc b/src/ui/configuration/AccelCalibrationConfig.cc index b861e6e78c..eedd35e963 100644 --- a/src/ui/configuration/AccelCalibrationConfig.cc +++ b/src/ui/configuration/AccelCalibrationConfig.cc @@ -3,9 +3,91 @@ AccelCalibrationConfig::AccelCalibrationConfig(QWidget *parent) : QWidget(parent) { + m_uas=0; ui.setupUi(this); + connect(ui.calibrateAccelButton,SIGNAL(clicked()),this,SLOT(calibrateButtonClicked())); + + connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); + activeUASSet(UASManager::instance()->getActiveUAS()); + accelAckCount=0; } AccelCalibrationConfig::~AccelCalibrationConfig() { } +void AccelCalibrationConfig::activeUASSet(UASInterface *uas) +{ + if (!uas) + { + return; + } + if (m_uas) + { + } + m_uas = uas; + connect(m_uas,SIGNAL(textMessageReceived(int,int,int,QString)),this,SLOT(uasTextMessageReceived(int,int,int,QString))); +} + +void AccelCalibrationConfig::calibrateButtonClicked() +{ + if (accelAckCount == 0) + { + MAV_CMD command = MAV_CMD_PREFLIGHT_CALIBRATION; + int confirm = 0; + float param1 = 0; + float param2 = 0; + float param3 = 0; + float param4 = 0; + float param5 = 1; + float param6 = 0; + float param7 = 0; + int component = 1; + m_uas->executeCommand(command, confirm, param1, param2, param3, param4, param5, param6, param7, component); + } + else if (accelAckCount <= 5) + { + m_uas->executeCommandAck(accelAckCount++,true); + } + else + { + m_uas->executeCommandAck(accelAckCount++,true); + ui.calibrateAccelButton->setText("Calibrate\nAccelerometer"); + //accelAckCount = 0; + } + +} +void AccelCalibrationConfig::uasTextMessageReceived(int uasid, int componentid, int severity, QString text) +{ + //command received: " Severity 1 + //Place APM Level and press any key" severity 5 + if (severity == 5) + { + //This is a calibration instruction + if (accelAckCount == 0) + { + //Calibration Sucessful\r" + ui.calibrateAccelButton->setText("Any\nKey"); + accelAckCount++; + } + if (accelAckCount == 7) + { + //All finished + //ui.outputLabel->setText(ui.outputLabel->text() + "\n" + text); + ui.outputLabel->setText(text); + accelAckCount++; + } + if (accelAckCount == 8) + { + if (text.contains("Calibration") && text.contains("successful")) + { + accelAckCount = 0; + } + ui.outputLabel->setText(ui.outputLabel->text() + "\n" + text); + } + else + { + ui.outputLabel->setText(text); + } + } + +} diff --git a/src/ui/configuration/AccelCalibrationConfig.h b/src/ui/configuration/AccelCalibrationConfig.h index 51ae8d76f6..a9e5f20534 100644 --- a/src/ui/configuration/AccelCalibrationConfig.h +++ b/src/ui/configuration/AccelCalibrationConfig.h @@ -3,7 +3,8 @@ #include #include "ui_AccelCalibrationConfig.h" - +#include "UASManager.h" +#include "UASInterface.h" class AccelCalibrationConfig : public QWidget { Q_OBJECT @@ -11,9 +12,14 @@ class AccelCalibrationConfig : public QWidget public: explicit AccelCalibrationConfig(QWidget *parent = 0); ~AccelCalibrationConfig(); - +private slots: + void activeUASSet(UASInterface *uas); + void calibrateButtonClicked(); + void uasTextMessageReceived(int uasid, int componentid, int severity, QString text); private: + int accelAckCount; Ui::AccelCalibrationConfig ui; + UASInterface *m_uas; }; #endif // ACCELCALIBRATIONCONFIG_H diff --git a/src/ui/configuration/AccelCalibrationConfig.ui b/src/ui/configuration/AccelCalibrationConfig.ui index 43ca6a1536..a1b99045e6 100644 --- a/src/ui/configuration/AccelCalibrationConfig.ui +++ b/src/ui/configuration/AccelCalibrationConfig.ui @@ -32,8 +32,8 @@ - 60 - 60 + 70 + 160 81 31 @@ -43,13 +43,13 @@ Accelerometer - + - 40 - 120 - 161 - 51 + 20 + 50 + 211 + 91 -- GitLab From 8a48aa0035b9ee94e64d487ac95dd53f1ceba535 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Mon, 24 Jun 2013 17:03:10 -0400 Subject: [PATCH 017/460] Changes so radio configuration widgets are now the proper orientation --- src/ui/configuration/RadioCalibrationConfig.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/ui/configuration/RadioCalibrationConfig.cc b/src/ui/configuration/RadioCalibrationConfig.cc index 37aaac0886..c357f0e050 100644 --- a/src/ui/configuration/RadioCalibrationConfig.cc +++ b/src/ui/configuration/RadioCalibrationConfig.cc @@ -47,6 +47,21 @@ RadioCalibrationConfig::RadioCalibrationConfig(QWidget *parent) : QWidget(parent ui.throttleWidget->setMax(2200); ui.yawWidget->setMin(800); ui.yawWidget->setMax(2200); + ui.rollWidget->setOrientation(Qt::Horizontal); + ui.rollWidget->setName("Roll"); + ui.yawWidget->setOrientation(Qt::Horizontal); + ui.yawWidget->setName("Yaw"); + ui.pitchWidget->setName("Pitch"); + ui.throttleWidget->setName("Throttle"); + ui.radio5Widget->setOrientation(Qt::Horizontal); + ui.radio5Widget->setName("Radio 5"); + ui.radio6Widget->setOrientation(Qt::Horizontal); + ui.radio6Widget->setName("Radio 6"); + ui.radio7Widget->setOrientation(Qt::Horizontal); + ui.radio7Widget->setName("Radio 7"); + ui.radio8Widget->setOrientation(Qt::Horizontal); + ui.radio8Widget->setName("Radio 8"); + guiUpdateTimer = new QTimer(this); connect(guiUpdateTimer,SIGNAL(timeout()),this,SLOT(guiUpdateTimerTick())); } -- GitLab From 8190209dc8015677fbe9d8e35fc823d2fbbeb6e2 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 25 Jun 2013 11:46:36 -0400 Subject: [PATCH 018/460] Fix for apm_planner issue #3, Serial port handling of '-' characters, since OSX can have a '-' in the port name --- src/ui/QGCToolBar.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 78ccac7aa0..f18d4a221b 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -608,9 +608,11 @@ void QGCToolBar::connectLink(bool connect) if (link) { QString portname = portComboBox->currentText().split(":")[2]; - if (portname.indexOf('-') != -1) + if (portname.indexOf('-') >= 0) { - portname = portname.split("-")[0]; + //Take everything before the last -, this ensures if the com port has a - in it, it will be included, + //since the last - is inserted by me. + portname = portname.mid(0,portname.lastIndexOf("-")-1); } link->setPortName(portname.trimmed()); } -- GitLab From bf53df056c2cb102c55527f0feebcfcb14955f1e Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 26 Jun 2013 11:48:47 -0400 Subject: [PATCH 019/460] Another change for issue #3, SerialLink::getCurrentPortS() should now return consistant results on Windows to match linux and OSX --- src/comm/SerialLink.cc | 2 +- src/ui/QGCToolBar.cc | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index b9bb95326e..4865ecf6ea 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -348,7 +348,7 @@ QVector* SerialLink::getCurrentPorts() for (int i = ports.size() - 1; i >= 0; i--) { QextPortInfo portInfo = ports.at(i); - QString portString = QString(portInfo.portName.toLocal8Bit().constData()) + " - " + QString(ports.at(i).friendName.toLocal8Bit().constData()).split("(").first(); + QString portString = QString(portInfo.portName.toLocal8Bit().constData());// + " - " + QString(ports.at(i).friendName.toLocal8Bit().constData()).split("(").first(); // Prepend newly found port to the list this->ports->append(portString); } diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index f18d4a221b..777a70aa12 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -608,12 +608,6 @@ void QGCToolBar::connectLink(bool connect) if (link) { QString portname = portComboBox->currentText().split(":")[2]; - if (portname.indexOf('-') >= 0) - { - //Take everything before the last -, this ensures if the com port has a - in it, it will be included, - //since the last - is inserted by me. - portname = portname.mid(0,portname.lastIndexOf("-")-1); - } link->setPortName(portname.trimmed()); } link->connect(); -- GitLab From 9b62308e6e54a9074a2693cbf309d851e1fcc93b Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 25 Jun 2013 11:41:06 -0400 Subject: [PATCH 020/460] Initial implementation of Flight Mode Config screen --- src/ui/configuration/FlightModeConfig.cc | 230 +++++++++++++++++++++++ src/ui/configuration/FlightModeConfig.h | 11 +- src/ui/configuration/FlightModeConfig.ui | 210 ++++++++++++++++++++- 3 files changed, 448 insertions(+), 3 deletions(-) diff --git a/src/ui/configuration/FlightModeConfig.cc b/src/ui/configuration/FlightModeConfig.cc index 07a1ed3941..cff7772dae 100644 --- a/src/ui/configuration/FlightModeConfig.cc +++ b/src/ui/configuration/FlightModeConfig.cc @@ -4,8 +4,238 @@ FlightModeConfig::FlightModeConfig(QWidget *parent) : QWidget(parent) { ui.setupUi(this); + connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(setActiveUAS(UASInterface*))); + + } FlightModeConfig::~FlightModeConfig() { } +void FlightModeConfig::setActiveUAS(UASInterface *uas) +{ + if (!uas) return; + if (m_uas) + { + } + m_uas = uas; + connect(m_uas,SIGNAL(modeChanged(int,QString,QString)),this,SLOT(modeChanged(int,QString,QString))); + connect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); + connect(m_uas,SIGNAL(remoteControlChannelRawChanged(int,float)),this,SLOT(remoteControlChannelRawChanged(int,float))); + QStringList itemlist; + if (m_uas->getSystemType() == MAV_TYPE_FIXED_WING) + { + itemlist << "Manual"; + itemlist << "Circle"; + itemlist << "Stabilize"; + itemlist << "Training"; + itemlist << "FBW A"; + itemlist << "FBW B"; + itemlist << "Auto"; + itemlist << "RTL"; + itemlist << "Loiter"; + itemlist << "Guided"; + + planeModeIndexToUiIndex[0] = 0; + planeModeIndexToUiIndex[1] = 1; + planeModeIndexToUiIndex[2] = 2; + planeModeIndexToUiIndex[3] = 3; + planeModeIndexToUiIndex[5] = 4; + planeModeIndexToUiIndex[6] = 5; + planeModeIndexToUiIndex[10] = 6; + planeModeIndexToUiIndex[11] = 7; + planeModeIndexToUiIndex[12] = 8; + planeModeIndexToUiIndex[15] = 9; + ui.mode6ComboBox->setEnabled(true); + } + else if (m_uas->getSystemType() == MAV_TYPE_GROUND_ROVER) + { + itemlist << "Manual"; + itemlist << "Learning"; + itemlist << "Steering"; + itemlist << "Hold"; + itemlist << "Auto"; + itemlist << "RTL"; + itemlist << "Guided"; + itemlist << "Initialising"; + ui.mode6ComboBox->setEnabled(false); + roverModeIndexToUiIndex[0] = 0; + roverModeIndexToUiIndex[2] = 1; + roverModeIndexToUiIndex[3] = 2; + roverModeIndexToUiIndex[4] = 3; + roverModeIndexToUiIndex[10] = 5; + roverModeIndexToUiIndex[11] = 6; + roverModeIndexToUiIndex[15] = 7; + roverModeIndexToUiIndex[16] = 8; + + } + else if (m_uas->getSystemType() == MAV_TYPE_QUADROTOR) + { + itemlist << "Stabilize"; + itemlist << "Acro"; + itemlist << "Alt Hold"; + itemlist << "Auto"; + itemlist << "Guided"; + itemlist << "Loiter"; + itemlist << "RTL"; + itemlist << "Circle"; + itemlist << "Pos Hold"; + itemlist << "Land"; + itemlist << "OF_LOITER"; + itemlist << "Toy"; + ui.mode6ComboBox->setEnabled(true); + } + ui.mode1ComboBox->addItems(itemlist); + ui.mode2ComboBox->addItems(itemlist); + ui.mode3ComboBox->addItems(itemlist); + ui.mode4ComboBox->addItems(itemlist); + ui.mode5ComboBox->addItems(itemlist); + ui.mode6ComboBox->addItems(itemlist); +} +void FlightModeConfig::modeChanged(int sysId, QString status, QString description) +{ + //Unused? +} +void FlightModeConfig::remoteControlChannelRawChanged(int chan,float val) +{ + if (chan == 5) + { + //Channel 5 is the mode switch. + ///TODO: Make this configurable + if (val <= 1230) + { + ui.mode1ComboBox->setBackgroundRole(QPalette::Highlight); + ui.mode2ComboBox->setBackgroundRole(QPalette::Background); + ui.mode3ComboBox->setBackgroundRole(QPalette::Background); + ui.mode4ComboBox->setBackgroundRole(QPalette::Background); + ui.mode5ComboBox->setBackgroundRole(QPalette::Background); + ui.mode6ComboBox->setBackgroundRole(QPalette::Background); + } + else if (val <= 1360) + { + ui.mode1ComboBox->setBackgroundRole(QPalette::Background); + ui.mode2ComboBox->setBackgroundRole(QPalette::Highlight); + ui.mode3ComboBox->setBackgroundRole(QPalette::Background); + ui.mode4ComboBox->setBackgroundRole(QPalette::Background); + ui.mode5ComboBox->setBackgroundRole(QPalette::Background); + ui.mode6ComboBox->setBackgroundRole(QPalette::Background); + } + else if (val <= 1490) + { + ui.mode1ComboBox->setBackgroundRole(QPalette::Background); + ui.mode2ComboBox->setBackgroundRole(QPalette::Background); + ui.mode3ComboBox->setBackgroundRole(QPalette::Highlight); + ui.mode4ComboBox->setBackgroundRole(QPalette::Background); + ui.mode5ComboBox->setBackgroundRole(QPalette::Background); + ui.mode6ComboBox->setBackgroundRole(QPalette::Background); + } + else if (val <=1620) + { + ui.mode1ComboBox->setBackgroundRole(QPalette::Background); + ui.mode2ComboBox->setBackgroundRole(QPalette::Background); + ui.mode3ComboBox->setBackgroundRole(QPalette::Background); + ui.mode4ComboBox->setBackgroundRole(QPalette::Highlight); + ui.mode5ComboBox->setBackgroundRole(QPalette::Background); + ui.mode6ComboBox->setBackgroundRole(QPalette::Background); + } + else if (val <=1749) + { + ui.mode1ComboBox->setBackgroundRole(QPalette::Background); + ui.mode2ComboBox->setBackgroundRole(QPalette::Background); + ui.mode3ComboBox->setBackgroundRole(QPalette::Background); + ui.mode4ComboBox->setBackgroundRole(QPalette::Background); + ui.mode5ComboBox->setBackgroundRole(QPalette::Highlight); + ui.mode6ComboBox->setBackgroundRole(QPalette::Background); + } + else + { + ui.mode1ComboBox->setBackgroundRole(QPalette::Background); + ui.mode2ComboBox->setBackgroundRole(QPalette::Background); + ui.mode3ComboBox->setBackgroundRole(QPalette::Background); + ui.mode4ComboBox->setBackgroundRole(QPalette::Background); + ui.mode5ComboBox->setBackgroundRole(QPalette::Background); + ui.mode6ComboBox->setBackgroundRole(QPalette::Highlight); + } + } +} + +void FlightModeConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + if (m_uas->getSystemType() == MAV_TYPE_FIXED_WING) + { + if (parameterName == "FLTMODE1") + { + ui.mode1ComboBox->setCurrentIndex(planeModeIndexToUiIndex[value.toInt()]); + } + else if (parameterName == "FLTMODE2") + { + ui.mode2ComboBox->setCurrentIndex(planeModeIndexToUiIndex[value.toInt()]); + } + else if (parameterName == "FLTMODE3") + { + ui.mode3ComboBox->setCurrentIndex(planeModeIndexToUiIndex[value.toInt()]); + } + else if (parameterName == "FLTMODE4") + { + ui.mode4ComboBox->setCurrentIndex(planeModeIndexToUiIndex[value.toInt()]); + } + else if (parameterName == "FLTMODE5") + { + ui.mode5ComboBox->setCurrentIndex(planeModeIndexToUiIndex[value.toInt()]); + } + else if (parameterName == "FLTMODE6") + { + ui.mode6ComboBox->setCurrentIndex(planeModeIndexToUiIndex[value.toInt()]); + } + } + else if (m_uas->getSystemType() == MAV_TYPE_GROUND_ROVER) + { + if (parameterName == "MODE1") + { + ui.mode1ComboBox->setCurrentIndex(roverModeIndexToUiIndex[value.toInt()]); + } + else if (parameterName == "MODE2") + { + ui.mode2ComboBox->setCurrentIndex(roverModeIndexToUiIndex[value.toInt()]); + } + else if (parameterName == "MODE3") + { + ui.mode3ComboBox->setCurrentIndex(roverModeIndexToUiIndex[value.toInt()]); + } + else if (parameterName == "MODE4") + { + ui.mode4ComboBox->setCurrentIndex(roverModeIndexToUiIndex[value.toInt()]); + } + else if (parameterName == "MODE5") + { + ui.mode5ComboBox->setCurrentIndex(roverModeIndexToUiIndex[value.toInt()]); + } + } + else if (m_uas->getSystemType() == MAV_TYPE_QUADROTOR) + { + if (parameterName == "FLTMODE1") + { + ui.mode1ComboBox->setCurrentIndex(value.toInt()-1); + } + else if (parameterName == "FLTMODE2") + { + ui.mode2ComboBox->setCurrentIndex(value.toInt()-1); + } + else if (parameterName == "FLTMODE3") + { + ui.mode3ComboBox->setCurrentIndex(value.toInt()-1); + } + else if (parameterName == "FLTMODE4") + { + ui.mode4ComboBox->setCurrentIndex(value.toInt()-1); + } + else if (parameterName == "FLTMODE5") + { + ui.mode5ComboBox->setCurrentIndex(value.toInt()-1); + } + else if (parameterName == "FLTMODE6") + { + ui.mode6ComboBox->setCurrentIndex(value.toInt()-1); + } + } +} diff --git a/src/ui/configuration/FlightModeConfig.h b/src/ui/configuration/FlightModeConfig.h index fdf1129bbd..b9130bdcb9 100644 --- a/src/ui/configuration/FlightModeConfig.h +++ b/src/ui/configuration/FlightModeConfig.h @@ -3,6 +3,8 @@ #include #include "ui_FlightModeConfig.h" +#include "UASInterface.h" +#include "UASManager.h" class FlightModeConfig : public QWidget { @@ -11,9 +13,16 @@ class FlightModeConfig : public QWidget public: explicit FlightModeConfig(QWidget *parent = 0); ~FlightModeConfig(); - +private slots: + void setActiveUAS(UASInterface *uas); + void modeChanged(int sysId, QString status, QString description); + void remoteControlChannelRawChanged(int chan,float val); + void parameterChanged(int uas, int component, QString parameterName, QVariant value); private: + QMap roverModeIndexToUiIndex; + QMap planeModeIndexToUiIndex; Ui::FlightModeConfig ui; + UASInterface *m_uas; }; #endif // FLIGHTMODECONFIG_H diff --git a/src/ui/configuration/FlightModeConfig.ui b/src/ui/configuration/FlightModeConfig.ui index 737d405231..bf5c1b7773 100644 --- a/src/ui/configuration/FlightModeConfig.ui +++ b/src/ui/configuration/FlightModeConfig.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 300 + 608 + 359 @@ -29,6 +29,212 @@ false + + + + 20 + 70 + 481 + 191 + + + + + + + 8 + + + 0 + + + + + Flight Mode 1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Flight Mode 2 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Flight Mode 3 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Flight Mode 4 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Flight Mode 5 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Flight Mode 6 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + 8 + + + 0 + + + + + Simple Mode + + + + + + + Simple Mode + + + + + + + Simple Mode + + + + + + + Simple Mode + + + + + + + Simple Mode + + + + + + + Simple Mode + + + + + + + + + + + PWM 0 - 1230 + + + + + + + PWM 1231 - 1360 + + + + + + + PWM 1361 - 1490 + + + + + + + PWM 1491 - 1620 + + + + + + + PWM 1621 - 1749 + + + + + + + PWM 1750 + + + + + + + + -- GitLab From ea3e16143a35b924acafdb4e51ff87d8848a2b65 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 26 Jun 2013 15:57:00 -0400 Subject: [PATCH 021/460] Fixes for Radio Calibration to work with proper min/max values --- .../configuration/RadioCalibrationConfig.cc | 121 +++++++++++++++++- src/ui/configuration/RadioCalibrationConfig.h | 2 + .../configuration/RadioCalibrationConfig.ui | 2 +- 3 files changed, 121 insertions(+), 4 deletions(-) diff --git a/src/ui/configuration/RadioCalibrationConfig.cc b/src/ui/configuration/RadioCalibrationConfig.cc index c357f0e050..047ffadc5d 100644 --- a/src/ui/configuration/RadioCalibrationConfig.cc +++ b/src/ui/configuration/RadioCalibrationConfig.cc @@ -30,11 +30,13 @@ This file is part of the QGROUNDCONTROL project */ #include "RadioCalibrationConfig.h" - +#include RadioCalibrationConfig::RadioCalibrationConfig(QWidget *parent) : QWidget(parent) { ui.setupUi(this); + + connect(ui.calibrateButton,SIGNAL(clicked()),this,SLOT(calibrateButtonClicked())); m_uas = 0; m_calibrationEnabled = false; connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); @@ -47,6 +49,14 @@ RadioCalibrationConfig::RadioCalibrationConfig(QWidget *parent) : QWidget(parent ui.throttleWidget->setMax(2200); ui.yawWidget->setMin(800); ui.yawWidget->setMax(2200); + ui.radio5Widget->setMin(800); + ui.radio5Widget->setMax(2200); + ui.radio6Widget->setMin(800); + ui.radio6Widget->setMax(2200); + ui.radio7Widget->setMin(800); + ui.radio7Widget->setMax(2200); + ui.radio8Widget->setMin(800); + ui.radio8Widget->setMax(2200); ui.rollWidget->setOrientation(Qt::Horizontal); ui.rollWidget->setName("Roll"); ui.yawWidget->setOrientation(Qt::Horizontal); @@ -72,12 +82,16 @@ RadioCalibrationConfig::~RadioCalibrationConfig() void RadioCalibrationConfig::setActiveUAS(UASInterface *uas) { if (uas==NULL) return; + if (m_uas) { // Disconnect old system disconnect(m_uas, SIGNAL(remoteControlChannelRawChanged(int,float)), this,SLOT(remoteControlChannelRawChanged(int,float))); disconnect(m_uas, SIGNAL(parameterChanged(int,int,QString,QVariant)), this,SLOT(parameterChanged(int,int,QString,QVariant))); } + m_uas = uas; + connect(m_uas,SIGNAL(remoteControlChannelRawChanged(int,float)),this,SLOT(remoteControlChannelRawChanged(int,float))); + connect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); } void RadioCalibrationConfig::remoteControlChannelRawChanged(int chan,float val) @@ -115,12 +129,113 @@ void RadioCalibrationConfig::guiUpdateTimerTick() ui.radio6Widget->setValue(rcValue[5]); ui.radio7Widget->setValue(rcValue[6]); ui.radio8Widget->setValue(rcValue[7]); + if (m_calibrationEnabled) + { + ui.rollWidget->setMin(rcMin[0]); + ui.rollWidget->setMax(rcMax[0]); + ui.pitchWidget->setMin(rcMin[1]); + ui.pitchWidget->setMax(rcMax[1]); + ui.throttleWidget->setMin(rcMin[2]); + ui.throttleWidget->setMax(rcMax[2]); + ui.yawWidget->setMin(rcMin[3]); + ui.yawWidget->setMax(rcMax[3]); + ui.radio5Widget->setMin(rcMin[4]); + ui.radio5Widget->setMax(rcMax[4]); + ui.radio6Widget->setMin(rcMin[5]); + ui.radio6Widget->setMax(rcMax[5]); + ui.radio7Widget->setMin(rcMin[6]); + ui.radio7Widget->setMax(rcMax[6]); + ui.radio8Widget->setMin(rcMin[7]); + ui.radio8Widget->setMax(rcMax[7]); + } } void RadioCalibrationConfig::showEvent(QShowEvent *event) { - guiUpdateTimer->stop(); + guiUpdateTimer->start(100); } void RadioCalibrationConfig::hideEvent(QHideEvent *event) { - guiUpdateTimer->start(100); + guiUpdateTimer->stop(); +} +void RadioCalibrationConfig::calibrateButtonClicked() +{ + if (!m_calibrationEnabled) + { + ui.calibrateButton->setText("End Calibration"); + QMessageBox::information(0,"Warning!","You are about to start radio calibration.\nPlease ensure all motor power is disconnected AND all props are removed from the vehicle.\nAlso ensure transmitter and reciever are powered and connected\n\nClick OK to confirm"); + m_calibrationEnabled = true; + for (int i=0;i<8;i++) + { + rcMin[i] = 1500; + rcMax[i] = 1500; + } + ui.rollWidget->showMinMax(); + ui.pitchWidget->showMinMax(); + ui.yawWidget->showMinMax(); + ui.radio5Widget->showMinMax(); + ui.radio6Widget->showMinMax(); + ui.radio7Widget->showMinMax(); + ui.radio8Widget->showMinMax(); + QMessageBox::information(0,"Information","Click OK, then move all sticks to their extreme positions, watching the min/max values to ensure you get the most range from your controller. This includes all switches"); + } + else + { + ui.calibrateButton->setText("Calibrate"); + QMessageBox::information(0,"Trims","Ensure all sticks are centered and throttle is in the downmost position, click OK to continue"); + ///TODO: Set trims! + m_calibrationEnabled = false; + ui.rollWidget->hideMinMax(); + ui.pitchWidget->hideMinMax(); + ui.yawWidget->hideMinMax(); + ui.radio5Widget->hideMinMax(); + ui.radio6Widget->hideMinMax(); + ui.radio7Widget->hideMinMax(); + ui.radio8Widget->hideMinMax(); + QString statusstr; + statusstr = "Below you will find the detected radio calibration information that will be sent to the autopilot\n"; + statusstr += "Normal values are around 1100 to 1900, with disconnected channels reading very close to 1500\n\n"; + statusstr += "Channel\tMin\tCenter\tMax\n"; + statusstr += "--------------------\n"; + for (int i=0;i<8;i++) + { + statusstr += QString::number(i) + "\t" + QString::number(rcMin[i]) + "\t" + QString::number(rcValue[i]) + "\t" + QString::number(rcMax[i]) + "\n"; + } + QMessageBox::information(0,"Status",statusstr); + //Send calibrations. + QString minTpl("RC%1_MIN"); + QString maxTpl("RC%1_MAX"); + //QString trimTpl("RC%1_TRIM"); + + // Do not write the RC type, as these values depend on this + // active onboard parameter + + for (unsigned int i = 0; i < 8; ++i) + { + qDebug() << "SENDING MIN" << minTpl.arg(i+1) << rcMin[i]; + qDebug() << "SENDING MAX" << maxTpl.arg(i+1) << rcMax[i]; + m_uas->setParameter(0, minTpl.arg(i+1), (float)rcMin[i]); + QGC::SLEEP::usleep(50000); + //m_uas->setParameter(0, trimTpl.arg(i+1), rcTrim[i]); + //QGC::SLEEP::usleep(50000); + m_uas->setParameter(0, maxTpl.arg(i+1), (float)rcMax[i]); + QGC::SLEEP::usleep(50000); + } + ui.rollWidget->setMin(800); + ui.rollWidget->setMax(2200); + ui.pitchWidget->setMin(800); + ui.pitchWidget->setMax(2200); + ui.throttleWidget->setMin(800); + ui.throttleWidget->setMax(2200); + ui.yawWidget->setMin(800); + ui.yawWidget->setMax(2200); + ui.radio5Widget->setMin(800); + ui.radio5Widget->setMax(2200); + ui.radio6Widget->setMin(800); + ui.radio6Widget->setMax(2200); + ui.radio7Widget->setMin(800); + ui.radio7Widget->setMax(2200); + ui.radio8Widget->setMin(800); + ui.radio8Widget->setMax(2200); + + } } diff --git a/src/ui/configuration/RadioCalibrationConfig.h b/src/ui/configuration/RadioCalibrationConfig.h index a873483191..e51501dd65 100644 --- a/src/ui/configuration/RadioCalibrationConfig.h +++ b/src/ui/configuration/RadioCalibrationConfig.h @@ -54,9 +54,11 @@ private slots: void remoteControlChannelRawChanged(int chan,float val); void parameterChanged(int uas, int component, QString parameterName, QVariant value); void guiUpdateTimerTick(); + void calibrateButtonClicked(); private: double rcMin[8]; double rcMax[8]; + double rcTrim[8]; double rcValue[8]; QTimer *guiUpdateTimer; bool m_calibrationEnabled; diff --git a/src/ui/configuration/RadioCalibrationConfig.ui b/src/ui/configuration/RadioCalibrationConfig.ui index 321d20087d..ccf8062119 100644 --- a/src/ui/configuration/RadioCalibrationConfig.ui +++ b/src/ui/configuration/RadioCalibrationConfig.ui @@ -258,7 +258,7 @@ 20 360 - 75 + 91 23 -- GitLab From a6f871ba92b352ecbb3f24321e32bee7783b9e66 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 26 Jun 2013 16:40:07 -0400 Subject: [PATCH 022/460] Additional functionality for Flight Mode config, including highlighting of current PWM value on channel 5 --- src/ui/configuration/FlightModeConfig.cc | 145 ++++++++++++++++------- src/ui/configuration/FlightModeConfig.h | 3 + src/ui/configuration/FlightModeConfig.ui | 39 ++++-- 3 files changed, 139 insertions(+), 48 deletions(-) diff --git a/src/ui/configuration/FlightModeConfig.cc b/src/ui/configuration/FlightModeConfig.cc index cff7772dae..9e10175efd 100644 --- a/src/ui/configuration/FlightModeConfig.cc +++ b/src/ui/configuration/FlightModeConfig.cc @@ -4,9 +4,8 @@ FlightModeConfig::FlightModeConfig(QWidget *parent) : QWidget(parent) { ui.setupUi(this); + connect(ui.savePushButton,SIGNAL(clicked()),this,SLOT(saveButtonClicked())); connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(setActiveUAS(UASInterface*))); - - } FlightModeConfig::~FlightModeConfig() @@ -37,15 +36,35 @@ void FlightModeConfig::setActiveUAS(UASInterface *uas) itemlist << "Guided"; planeModeIndexToUiIndex[0] = 0; + planeModeUiIndexToIndex[0] = 0; + planeModeIndexToUiIndex[1] = 1; + planeModeUiIndexToIndex[1] = 1; + planeModeIndexToUiIndex[2] = 2; + planeModeUiIndexToIndex[2] = 2; + planeModeIndexToUiIndex[3] = 3; + planeModeUiIndexToIndex[3] = 3; + planeModeIndexToUiIndex[5] = 4; + planeModeUiIndexToIndex[4] = 5; + planeModeIndexToUiIndex[6] = 5; + planeModeUiIndexToIndex[5] = 6; + planeModeIndexToUiIndex[10] = 6; + planeModeUiIndexToIndex[6] = 10; + planeModeIndexToUiIndex[11] = 7; + planeModeUiIndexToIndex[7] = 11; + planeModeIndexToUiIndex[12] = 8; + planeModeUiIndexToIndex[8] = 12; + planeModeIndexToUiIndex[15] = 9; + planeModeUiIndexToIndex[9] = 15; + ui.mode6ComboBox->setEnabled(true); } else if (m_uas->getSystemType() == MAV_TYPE_GROUND_ROVER) @@ -60,13 +79,29 @@ void FlightModeConfig::setActiveUAS(UASInterface *uas) itemlist << "Initialising"; ui.mode6ComboBox->setEnabled(false); roverModeIndexToUiIndex[0] = 0; + roverModeUiIndexToIndex[0] = 0; + roverModeIndexToUiIndex[2] = 1; + roverModeUiIndexToIndex[1] = 2; + roverModeIndexToUiIndex[3] = 2; + roverModeUiIndexToIndex[2] = 3; + roverModeIndexToUiIndex[4] = 3; + roverModeUiIndexToIndex[3] = 4; + roverModeIndexToUiIndex[10] = 5; + roverModeUiIndexToIndex[5] = 10; + roverModeIndexToUiIndex[11] = 6; + roverModeUiIndexToIndex[6] = 11; + roverModeIndexToUiIndex[15] = 7; + roverModeUiIndexToIndex[7] = 15; + roverModeIndexToUiIndex[16] = 8; + roverModeUiIndexToIndex[8] = 16; + } else if (m_uas->getSystemType() == MAV_TYPE_QUADROTOR) @@ -96,65 +131,95 @@ void FlightModeConfig::modeChanged(int sysId, QString status, QString descriptio { //Unused? } +void FlightModeConfig::saveButtonClicked() +{ + if (m_uas->getSystemType() == MAV_TYPE_FIXED_WING) + { + m_uas->setParameter(0,"FLTMODE1",(char)planeModeUiIndexToIndex[ui.mode1ComboBox->currentIndex()]); + m_uas->setParameter(0,"FLTMODE2",(char)planeModeUiIndexToIndex[ui.mode2ComboBox->currentIndex()]); + m_uas->setParameter(0,"FLTMODE3",(char)planeModeUiIndexToIndex[ui.mode3ComboBox->currentIndex()]); + m_uas->setParameter(0,"FLTMODE4",(char)planeModeUiIndexToIndex[ui.mode4ComboBox->currentIndex()]); + m_uas->setParameter(0,"FLTMODE5",(char)planeModeUiIndexToIndex[ui.mode5ComboBox->currentIndex()]); + m_uas->setParameter(0,"FLTMODE6",(char)planeModeUiIndexToIndex[ui.mode6ComboBox->currentIndex()]); + } + else if (m_uas->getSystemType() == MAV_TYPE_GROUND_ROVER) + { + m_uas->setParameter(0,"MODE1",(char)roverModeUiIndexToIndex[ui.mode1ComboBox->currentIndex()]); + m_uas->setParameter(0,"MODE2",(char)roverModeUiIndexToIndex[ui.mode2ComboBox->currentIndex()]); + m_uas->setParameter(0,"MODE3",(char)roverModeUiIndexToIndex[ui.mode3ComboBox->currentIndex()]); + m_uas->setParameter(0,"MODE4",(char)roverModeUiIndexToIndex[ui.mode4ComboBox->currentIndex()]); + m_uas->setParameter(0,"MODE5",(char)roverModeUiIndexToIndex[ui.mode5ComboBox->currentIndex()]); + } + else if (m_uas->getSystemType() == MAV_TYPE_QUADROTOR) + { + m_uas->setParameter(0,"FLTMODE1",(char)ui.mode1ComboBox->currentIndex()+1); + m_uas->setParameter(0,"FLTMODE2",(char)ui.mode2ComboBox->currentIndex()+1); + m_uas->setParameter(0,"FLTMODE3",(char)ui.mode3ComboBox->currentIndex()+1); + m_uas->setParameter(0,"FLTMODE4",(char)ui.mode4ComboBox->currentIndex()+1); + m_uas->setParameter(0,"FLTMODE5",(char)ui.mode5ComboBox->currentIndex()+1); + m_uas->setParameter(0,"FLTMODE6",(char)ui.mode6ComboBox->currentIndex()+1); + } +} + void FlightModeConfig::remoteControlChannelRawChanged(int chan,float val) { - if (chan == 5) + if (chan == 4) { - //Channel 5 is the mode switch. + //Channel 5 (0 array) is the mode switch. ///TODO: Make this configurable if (val <= 1230) { - ui.mode1ComboBox->setBackgroundRole(QPalette::Highlight); - ui.mode2ComboBox->setBackgroundRole(QPalette::Background); - ui.mode3ComboBox->setBackgroundRole(QPalette::Background); - ui.mode4ComboBox->setBackgroundRole(QPalette::Background); - ui.mode5ComboBox->setBackgroundRole(QPalette::Background); - ui.mode6ComboBox->setBackgroundRole(QPalette::Background); + ui.mode1Label->setStyleSheet("background-color: rgb(0, 255, 0);color: rgb(0, 0, 0);"); + ui.mode2Label->setStyleSheet(""); + ui.mode3Label->setStyleSheet(""); + ui.mode4Label->setStyleSheet(""); + ui.mode5Label->setStyleSheet(""); + ui.mode6Label->setStyleSheet(""); } else if (val <= 1360) { - ui.mode1ComboBox->setBackgroundRole(QPalette::Background); - ui.mode2ComboBox->setBackgroundRole(QPalette::Highlight); - ui.mode3ComboBox->setBackgroundRole(QPalette::Background); - ui.mode4ComboBox->setBackgroundRole(QPalette::Background); - ui.mode5ComboBox->setBackgroundRole(QPalette::Background); - ui.mode6ComboBox->setBackgroundRole(QPalette::Background); + ui.mode1Label->setStyleSheet(""); + ui.mode2Label->setStyleSheet("background-color: rgb(0, 255, 0);color: rgb(0, 0, 0);"); + ui.mode3Label->setStyleSheet(""); + ui.mode4Label->setStyleSheet(""); + ui.mode5Label->setStyleSheet(""); + ui.mode6Label->setStyleSheet(""); } else if (val <= 1490) { - ui.mode1ComboBox->setBackgroundRole(QPalette::Background); - ui.mode2ComboBox->setBackgroundRole(QPalette::Background); - ui.mode3ComboBox->setBackgroundRole(QPalette::Highlight); - ui.mode4ComboBox->setBackgroundRole(QPalette::Background); - ui.mode5ComboBox->setBackgroundRole(QPalette::Background); - ui.mode6ComboBox->setBackgroundRole(QPalette::Background); + ui.mode1Label->setStyleSheet(""); + ui.mode2Label->setStyleSheet(""); + ui.mode3Label->setStyleSheet("background-color: rgb(0, 255, 0);color: rgb(0, 0, 0);"); + ui.mode4Label->setStyleSheet(""); + ui.mode5Label->setStyleSheet(""); + ui.mode6Label->setStyleSheet(""); } else if (val <=1620) { - ui.mode1ComboBox->setBackgroundRole(QPalette::Background); - ui.mode2ComboBox->setBackgroundRole(QPalette::Background); - ui.mode3ComboBox->setBackgroundRole(QPalette::Background); - ui.mode4ComboBox->setBackgroundRole(QPalette::Highlight); - ui.mode5ComboBox->setBackgroundRole(QPalette::Background); - ui.mode6ComboBox->setBackgroundRole(QPalette::Background); + ui.mode1Label->setStyleSheet(""); + ui.mode2Label->setStyleSheet(""); + ui.mode3Label->setStyleSheet(""); + ui.mode4Label->setStyleSheet("background-color: rgb(0, 255, 0);color: rgb(0, 0, 0);"); + ui.mode5Label->setStyleSheet(""); + ui.mode6Label->setStyleSheet(""); } else if (val <=1749) { - ui.mode1ComboBox->setBackgroundRole(QPalette::Background); - ui.mode2ComboBox->setBackgroundRole(QPalette::Background); - ui.mode3ComboBox->setBackgroundRole(QPalette::Background); - ui.mode4ComboBox->setBackgroundRole(QPalette::Background); - ui.mode5ComboBox->setBackgroundRole(QPalette::Highlight); - ui.mode6ComboBox->setBackgroundRole(QPalette::Background); + ui.mode1Label->setStyleSheet(""); + ui.mode2Label->setStyleSheet(""); + ui.mode3Label->setStyleSheet(""); + ui.mode4Label->setStyleSheet(""); + ui.mode5Label->setStyleSheet("background-color: rgb(0, 255, 0);color: rgb(0, 0, 0);"); + ui.mode6Label->setStyleSheet(""); } else { - ui.mode1ComboBox->setBackgroundRole(QPalette::Background); - ui.mode2ComboBox->setBackgroundRole(QPalette::Background); - ui.mode3ComboBox->setBackgroundRole(QPalette::Background); - ui.mode4ComboBox->setBackgroundRole(QPalette::Background); - ui.mode5ComboBox->setBackgroundRole(QPalette::Background); - ui.mode6ComboBox->setBackgroundRole(QPalette::Highlight); + ui.mode1Label->setStyleSheet(""); + ui.mode2Label->setStyleSheet(""); + ui.mode3Label->setStyleSheet(""); + ui.mode4Label->setStyleSheet(""); + ui.mode5Label->setStyleSheet(""); + ui.mode6Label->setStyleSheet("background-color: rgb(0, 255, 0);color: rgb(0, 0, 0);"); } } } diff --git a/src/ui/configuration/FlightModeConfig.h b/src/ui/configuration/FlightModeConfig.h index b9130bdcb9..fa3ded3338 100644 --- a/src/ui/configuration/FlightModeConfig.h +++ b/src/ui/configuration/FlightModeConfig.h @@ -15,12 +15,15 @@ public: ~FlightModeConfig(); private slots: void setActiveUAS(UASInterface *uas); + void saveButtonClicked(); void modeChanged(int sysId, QString status, QString description); void remoteControlChannelRawChanged(int chan,float val); void parameterChanged(int uas, int component, QString parameterName, QVariant value); private: QMap roverModeIndexToUiIndex; QMap planeModeIndexToUiIndex; + QMap roverModeUiIndexToIndex; + QMap planeModeUiIndexToIndex; Ui::FlightModeConfig ui; UASInterface *m_uas; }; diff --git a/src/ui/configuration/FlightModeConfig.ui b/src/ui/configuration/FlightModeConfig.ui index bf5c1b7773..2cb8585bd3 100644 --- a/src/ui/configuration/FlightModeConfig.ui +++ b/src/ui/configuration/FlightModeConfig.ui @@ -6,7 +6,7 @@ 0 0 - 608 + 818 359 @@ -119,7 +119,11 @@ - + + + + + @@ -190,42 +194,48 @@ - + + + + PWM 0 - 1230 - + PWM 1231 - 1360 - + PWM 1361 - 1490 - + PWM 1491 - 1620 - + PWM 1621 - 1749 - + + + + PWM 1750 + @@ -235,6 +245,19 @@ + + + + 50 + 290 + 75 + 23 + + + + Save + + -- GitLab From 0b4fb183906f2d013a9e8fd969fadc0a10e40325 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Thu, 27 Jun 2013 11:09:17 -0400 Subject: [PATCH 023/460] Implementation of Battery Monitor configuration, and addition of AP2ConfigWidget, which automatically handles UAS connections to allow for simpler configuration window code. --- files/images/devices/BR-APMPWRDEAN-2.jpg | Bin 0 -> 18425 bytes qgroundcontrol.pro | 6 +- qgroundcontrol.qrc | 1 + src/ui/configuration/AP2ConfigWidget.cc | 23 ++ src/ui/configuration/AP2ConfigWidget.h | 21 ++ src/ui/configuration/BatteryMonitorConfig.cc | 231 ++++++++++++++++++- src/ui/configuration/BatteryMonitorConfig.h | 12 +- src/ui/configuration/BatteryMonitorConfig.ui | 202 +++++++++++++++- 8 files changed, 487 insertions(+), 9 deletions(-) create mode 100644 files/images/devices/BR-APMPWRDEAN-2.jpg create mode 100644 src/ui/configuration/AP2ConfigWidget.cc create mode 100644 src/ui/configuration/AP2ConfigWidget.h diff --git a/files/images/devices/BR-APMPWRDEAN-2.jpg b/files/images/devices/BR-APMPWRDEAN-2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..62a6a83b8380283f52d1b9981cd960711a2e8630 GIT binary patch literal 18425 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 SJqo7R^6@3?!&}V%Zvp_0D~)~t literal 0 HcmV?d00001 diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index edf55c06c5..2e0d9c43d0 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -424,7 +424,8 @@ HEADERS += src/MG.h \ src/ui/configuration/OpticalFlowConfig.h \ src/ui/configuration/OsdConfig.h \ src/ui/configuration/AntennaTrackerConfig.h \ - src/ui/configuration/CameraGimbalConfig.h + src/ui/configuration/CameraGimbalConfig.h \ + src/ui/configuration/AP2ConfigWidget.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -616,7 +617,8 @@ SOURCES += src/main.cc \ src/ui/configuration/OpticalFlowConfig.cc \ src/ui/configuration/OsdConfig.cc \ src/ui/configuration/AntennaTrackerConfig.cc \ - src/ui/configuration/CameraGimbalConfig.cc + src/ui/configuration/CameraGimbalConfig.cc \ + src/ui/configuration/AP2ConfigWidget.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index fab4b89ebf..b40e399506 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -110,6 +110,7 @@ files/images/mavs/frames_x.png files/images/mavs/frames-05.png files/images/devices/BR-HMC5883-01-2.jpg + files/images/devices/BR-APMPWRDEAN-2.jpg
files/styles/Vera.ttf diff --git a/src/ui/configuration/AP2ConfigWidget.cc b/src/ui/configuration/AP2ConfigWidget.cc new file mode 100644 index 0000000000..21c5895069 --- /dev/null +++ b/src/ui/configuration/AP2ConfigWidget.cc @@ -0,0 +1,23 @@ +#include "AP2ConfigWidget.h" + +AP2ConfigWidget::AP2ConfigWidget(QWidget *parent) : QWidget(parent) +{ + m_uas = 0; + connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); + activeUASSet(UASManager::instance()->getActiveUAS()); +} +void AP2ConfigWidget::activeUASSet(UASInterface *uas) +{ + if (!uas) return; + if (m_uas) + { + disconnect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); + } + m_uas = uas; + connect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); +} + +void AP2ConfigWidget::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + +} diff --git a/src/ui/configuration/AP2ConfigWidget.h b/src/ui/configuration/AP2ConfigWidget.h new file mode 100644 index 0000000000..2f27e35abf --- /dev/null +++ b/src/ui/configuration/AP2ConfigWidget.h @@ -0,0 +1,21 @@ +#ifndef AP2CONFIGWIDGET_H +#define AP2CONFIGWIDGET_H + +#include +#include "UASManager.h" +#include "UASInterface.h" +class AP2ConfigWidget : public QWidget +{ + Q_OBJECT +public: + explicit AP2ConfigWidget(QWidget *parent = 0); +protected: + UASInterface *m_uas; +signals: + +public slots: + virtual void activeUASSet(UASInterface *uas); + virtual void parameterChanged(int uas, int component, QString parameterName, QVariant value); +}; + +#endif // AP2CONFIGWIDGET_H diff --git a/src/ui/configuration/BatteryMonitorConfig.cc b/src/ui/configuration/BatteryMonitorConfig.cc index 23ef9a731e..96990bb954 100644 --- a/src/ui/configuration/BatteryMonitorConfig.cc +++ b/src/ui/configuration/BatteryMonitorConfig.cc @@ -1,11 +1,238 @@ #include "BatteryMonitorConfig.h" +#include - -BatteryMonitorConfig::BatteryMonitorConfig(QWidget *parent) : QWidget(parent) +BatteryMonitorConfig::BatteryMonitorConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); + ui.monitorComboBox->addItem("0: Disabled"); + ui.monitorComboBox->addItem("3: Battery Volts"); + ui.monitorComboBox->addItem("4: Voltage and Current"); + + ui.sensorComboBox->addItem("0: Other"); + ui.sensorComboBox->addItem("1: AttoPilot 45A"); + ui.sensorComboBox->addItem("2: AttoPilot 90A"); + ui.sensorComboBox->addItem("3: AttoPilot 180A"); + ui.sensorComboBox->addItem("4: 3DR Power Module"); + + ui.apmVerComboBox->addItem("0: APM1"); + ui.apmVerComboBox->addItem("1: APM2 - 2.5 non 3DR"); + ui.apmVerComboBox->addItem("2: APM2.5 - 3DR Power Module"); + ui.apmVerComboBox->addItem("3: PX4"); + + connect(ui.monitorComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(monitorCurrentIndexChanged(int))); + connect(ui.sensorComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(sensorCurrentIndexChanged(int))); + connect(ui.apmVerComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(apmVerCurrentIndexChanged(int))); + + connect(ui.calcDividerLineEdit,SIGNAL(editingFinished()),this,SLOT(calcDividerSet())); + connect(ui.ampsPerVoltsLineEdit,SIGNAL(editingFinished()),this,SLOT(ampsPerVoltSet())); + connect(ui.battCapacityLineEdit,SIGNAL(editingFinished()),this,SLOT(batteryCapacitySet())); + + ui.alertOnLowCheckBox->setVisible(false); + +} +void BatteryMonitorConfig::calcDividerSet() +{ + bool ok = false; + float newval = ui.calcDividerLineEdit->text().toFloat(&ok); + if (!ok) + { + //Error parsing; + QMessageBox::information(0,"Error","Invalid number entered for voltage divider. Please try again"); + return; + } + m_uas->setParameter(0,"VOLT_DIVIDER",newval); +} +void BatteryMonitorConfig::ampsPerVoltSet() +{ + bool ok = false; + float newval = ui.ampsPerVoltsLineEdit->text().toFloat(&ok); + if (!ok) + { + //Error parsing; + QMessageBox::information(0,"Error","Invalid number entered for amps per volts. Please try again"); + return; + } + m_uas->setParameter(0,"AMPS_PER_VOLT",newval); +} +void BatteryMonitorConfig::batteryCapacitySet() +{ + bool ok = false; + float newval = ui.battCapacityLineEdit->text().toFloat(&ok); + if (!ok) + { + //Error parsing; + QMessageBox::information(0,"Error","Invalid number entered for amps per volts. Please try again"); + return; + } + m_uas->setParameter(0,"BATT_CAPACITY",newval); +} + +void BatteryMonitorConfig::monitorCurrentIndexChanged(int index) +{ + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } + if (index == 0) + { + m_uas->setParameter(0,"BATT_VOLT_PIN",-1); + m_uas->setParameter(0,"BATT_CURR_PIN",-1); + m_uas->setParameter(0,"BATT_MONITOR",0); + ui.sensorComboBox->setEnabled(false); + ui.apmVerComboBox->setEnabled(false); + ui.measuredVoltsLineEdit->setEnabled(false); + ui.measuredVoltsLineEdit->setEnabled(false); + ui.calcDividerLineEdit->setEnabled(false); + ui.calcVoltsLineEdit->setEnabled(false); + ui.ampsPerVoltsLineEdit->setEnabled(false); + } + else if (index == 1) + { + m_uas->setParameter(0,"BATT_MONITOR",3); + ui.sensorComboBox->setEnabled(false); + ui.apmVerComboBox->setEnabled(true); + ui.measuredVoltsLineEdit->setEnabled(true); + ui.calcDividerLineEdit->setEnabled(true); + ui.calcVoltsLineEdit->setEnabled(false); + ui.ampsPerVoltsLineEdit->setEnabled(false); + } + else if (index == 2) + { + m_uas->setParameter(0,"BATT_MONITOR",4); + ui.sensorComboBox->setEnabled(true); + ui.apmVerComboBox->setEnabled(true); + ui.measuredVoltsLineEdit->setEnabled(true); + ui.calcDividerLineEdit->setEnabled(true); + ui.calcVoltsLineEdit->setEnabled(false); + ui.ampsPerVoltsLineEdit->setEnabled(true); + } + + +} +void BatteryMonitorConfig::sensorCurrentIndexChanged(int index) +{ + float maxvolt = 0; + float maxamps = 0; + float mvpervolt = 0; + float mvperamp = 0; + float topvolt = 0; + float topamps = 0; + + if (index == 1) + { + //atto 45 + maxvolt = 13.6; + maxamps = 44.7; + mvpervolt = 242.3; + mvperamp = 73.20; + } + else if (index == 2) + { + //atto 90 + maxvolt = 50; + maxamps = 89.4; + mvpervolt = 63.69; + mvperamp = 36.60; + } + else if (index == 3) + { + //atto 180 + maxvolt = 50; + maxamps = 178.8; + mvpervolt = 63.69; + mvperamp = 18.30; + } + else if (index == 4) + { + //3dr + maxvolt = 50; + maxamps = 90; + mvpervolt = 100; + mvperamp = 55.55; + } + if (index == 0) + { + //Other + ui.ampsPerVoltsLineEdit->setEnabled(true); + ui.calcDividerLineEdit->setEnabled(true); + ui.measuredVoltsLineEdit->setEnabled(true); + } + else + { + topvolt = (maxvolt * mvpervolt) / 1000.0; + topamps = (maxamps * mvperamp) / 1000.0; + + ui.calcDividerLineEdit->setText(QString::number(maxvolt/topvolt)); + ui.ampsPerVoltsLineEdit->setText(QString::number(maxamps / topamps)); + ui.ampsPerVoltsLineEdit->setEnabled(false); + ui.calcDividerLineEdit->setEnabled(false); + ui.measuredVoltsLineEdit->setEnabled(false); + } +} + +void BatteryMonitorConfig::apmVerCurrentIndexChanged(int index) +{ + } BatteryMonitorConfig::~BatteryMonitorConfig() { } + +void BatteryMonitorConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + if (parameterName == "VOLT_DIVIDER") + { + ui.calcDividerLineEdit->setText(QString::number(value.toFloat(),'f',4)); + } + else if (parameterName == "AMP_PER_VOLT") + { + ui.ampsPerVoltsLineEdit->setText(QString::number(value.toFloat(),'g',2)); + + } + else if (parameterName == "BATT_MONITOR") + { + if (value.toInt() == 0) //0: Disable + { + ui.monitorComboBox->setCurrentIndex(0); + } + else if (value.toInt() == 3) //3: Battery volts + { + ui.monitorComboBox->setCurrentIndex(1); + } + else if (value.toInt() == 4) //4: Voltage and Current + { + ui.monitorComboBox->setCurrentIndex(2); + } + + } + else if (parameterName == "BATT_CAPACITY") + { + ui.battCapacityLineEdit->setText(QString::number(value.toFloat())); + } + else if (parameterName == "BATT_VOLT_PIN") + { + int ivalue = value.toInt(); + if (ivalue == 0) //APM1 + { + ui.apmVerComboBox->setCurrentIndex(0); + } + else if (ivalue == 1) //APM2 + { + ui.apmVerComboBox->setCurrentIndex(1); + } + else if (ivalue == 13) //APM2.5 + { + ui.apmVerComboBox->setCurrentIndex(2); + } + else if (ivalue == 100) //PX4 + { + ui.apmVerComboBox->setCurrentIndex(3); + } + } + else if (parameterName == "BATT_CURR_PIN") + { + //Unused at the moment, everything is off BATT_VOLT_PIN + } +} diff --git a/src/ui/configuration/BatteryMonitorConfig.h b/src/ui/configuration/BatteryMonitorConfig.h index bdddcd8237..183d782d23 100644 --- a/src/ui/configuration/BatteryMonitorConfig.h +++ b/src/ui/configuration/BatteryMonitorConfig.h @@ -2,16 +2,24 @@ #define BATTERYMONITORCONFIG_H #include +#include "AP2ConfigWidget.h" #include "ui_BatteryMonitorConfig.h" -class BatteryMonitorConfig : public QWidget +class BatteryMonitorConfig : public AP2ConfigWidget { Q_OBJECT public: explicit BatteryMonitorConfig(QWidget *parent = 0); ~BatteryMonitorConfig(); - +private slots: + void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void monitorCurrentIndexChanged(int index); + void sensorCurrentIndexChanged(int index); + void apmVerCurrentIndexChanged(int index); + void calcDividerSet(); + void ampsPerVoltSet(); + void batteryCapacitySet(); private: Ui::BatteryMonitorConfig ui; }; diff --git a/src/ui/configuration/BatteryMonitorConfig.ui b/src/ui/configuration/BatteryMonitorConfig.ui index 564ec5503f..0c008dc1a8 100644 --- a/src/ui/configuration/BatteryMonitorConfig.ui +++ b/src/ui/configuration/BatteryMonitorConfig.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 300 + 745 + 494 @@ -29,7 +29,203 @@ false + + + + 10 + 70 + 141 + 51 + + + + + + + :/files/images/devices/BR-APMPWRDEAN-2.jpg + + + true + + + + + + 480 + 120 + 70 + 17 + + + + CheckBox + + + + + + 160 + 170 + 241 + 141 + + + + Calibration + + + + + + + + + + 1. Measured battery voltage: + + + + + + + 2. Battery voltage (Calc'ed): + + + + + + + 3. Voltage divider (Calc'ed): + + + + + + + 4. Amperes per volt: + + + + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + + + + + + 160 + 70 + 281 + 80 + + + + + + + + + Monitor + + + + + + + Sensor + + + + + + + APM Version + + + + + + + + + + + + + + + + + + + + + + + + 470 + 70 + 195 + 41 + + + + + + + Battery Capacity: + + + + + + + + + + mAh + + + + + - + + + -- GitLab From be00fa35409b335a29985cfcd00df3d4b34949e5 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Thu, 27 Jun 2013 14:25:57 -0400 Subject: [PATCH 024/460] Added in checks for being connected to a MAV before attempting edits of configuration in Battery Monitor Config --- src/ui/configuration/BatteryMonitorConfig.cc | 43 +++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/ui/configuration/BatteryMonitorConfig.cc b/src/ui/configuration/BatteryMonitorConfig.cc index 96990bb954..39556ca202 100644 --- a/src/ui/configuration/BatteryMonitorConfig.cc +++ b/src/ui/configuration/BatteryMonitorConfig.cc @@ -32,6 +32,11 @@ BatteryMonitorConfig::BatteryMonitorConfig(QWidget *parent) : AP2ConfigWidget(pa } void BatteryMonitorConfig::calcDividerSet() { + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } bool ok = false; float newval = ui.calcDividerLineEdit->text().toFloat(&ok); if (!ok) @@ -44,6 +49,11 @@ void BatteryMonitorConfig::calcDividerSet() } void BatteryMonitorConfig::ampsPerVoltSet() { + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } bool ok = false; float newval = ui.ampsPerVoltsLineEdit->text().toFloat(&ok); if (!ok) @@ -56,6 +66,11 @@ void BatteryMonitorConfig::ampsPerVoltSet() } void BatteryMonitorConfig::batteryCapacitySet() { + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } bool ok = false; float newval = ui.battCapacityLineEdit->text().toFloat(&ok); if (!ok) @@ -173,7 +188,33 @@ void BatteryMonitorConfig::sensorCurrentIndexChanged(int index) void BatteryMonitorConfig::apmVerCurrentIndexChanged(int index) { - + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } + if (index == 0) //APM1 + { + m_uas->setParameter(0,"BATT_VOLT_PIN",0); + m_uas->setParameter(0,"BATT_CURR_PIN",1); + } + else if (index == 1) //APM2 + { + m_uas->setParameter(0,"BATT_VOLT_PIN",1); + m_uas->setParameter(0,"BATT_CURR_PIN",2); + } + else if (index == 2) //APM2.5 + { + m_uas->setParameter(0,"BATT_VOLT_PIN",13); + m_uas->setParameter(0,"BATT_CURR_PIN",12); + } + else if (index == 3) //PX4 + { + m_uas->setParameter(0,"BATT_VOLT_PIN",100); + m_uas->setParameter(0,"BATT_CURR_PIN",101); + m_uas->setParameter(0,"VOLT_DIVIDER",1); + ui.calcDividerLineEdit->setText("1"); + } } BatteryMonitorConfig::~BatteryMonitorConfig() -- GitLab From 1142b6f34273851718e81ba0cf4e67f46c6beec8 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Thu, 27 Jun 2013 14:28:24 -0400 Subject: [PATCH 025/460] Implemented Sonar Config --- files/images/devices/AC-0004-11-2.jpg | Bin 0 -> 10600 bytes qgroundcontrol.qrc | 1 + src/ui/configuration/SonarConfig.cc | 61 +++++++++++++++++++++++++- src/ui/configuration/SonarConfig.h | 8 +++- src/ui/configuration/SonarConfig.ui | 50 +++++++++++++++++++-- 5 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 files/images/devices/AC-0004-11-2.jpg diff --git a/files/images/devices/AC-0004-11-2.jpg b/files/images/devices/AC-0004-11-2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..334486b6756e6b2671c1a2dd1099f2c051e4a20c GIT binary patch literal 10600 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 literal 0 HcmV?d00001 diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index b40e399506..2f8034f33d 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -111,6 +111,7 @@ files/images/mavs/frames-05.png files/images/devices/BR-HMC5883-01-2.jpg files/images/devices/BR-APMPWRDEAN-2.jpg + files/images/devices/AC-0004-11-2.jpg files/styles/Vera.ttf diff --git a/src/ui/configuration/SonarConfig.cc b/src/ui/configuration/SonarConfig.cc index fa9ce05d70..fb3481d908 100644 --- a/src/ui/configuration/SonarConfig.cc +++ b/src/ui/configuration/SonarConfig.cc @@ -1,11 +1,68 @@ #include "SonarConfig.h" +#include - -SonarConfig::SonarConfig(QWidget *parent) : QWidget(parent) +SonarConfig::SonarConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); + connect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(checkBoxToggled(bool))); + connect(ui.sonarTypeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(sonarTypeChanged(int))); + + ui.sonarTypeComboBox->addItem("XL-EZ0 / XL-EZ4"); + ui.sonarTypeComboBox->addItem("LV-EZ0"); + ui.sonarTypeComboBox->addItem("XL-EZL0"); + ui.sonarTypeComboBox->addItem("HRLV"); } SonarConfig::~SonarConfig() { } +void SonarConfig::checkBoxToggled(bool enabled) +{ + if (enabled) + { + ui.sonarTypeComboBox->setEnabled(false); + } + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } + m_uas->setParameter(0,"SONAR_ENABLE",ui.enableCheckBox->isChecked() ? 1 : 0); +} +void SonarConfig::sonarTypeChanged(int index) +{ + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } + m_uas->setParameter(0,"SONAR_TYPE",ui.sonarTypeComboBox->currentIndex()); +} + +void SonarConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + if (parameterName == "SONAR_ENABLE") + { + if (value.toInt() == 0) + { + //Disabled + disconnect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(checkBoxToggled(bool))); + ui.enableCheckBox->setChecked(false); + connect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(checkBoxToggled(bool))); + ui.sonarTypeComboBox->setEnabled(false); + } + else + { + disconnect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(checkBoxToggled(bool))); + ui.enableCheckBox->setChecked(true); + connect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(checkBoxToggled(bool))); + ui.sonarTypeComboBox->setEnabled(true); + } + } + else if (parameterName == "SONAR_TYPE") + { + disconnect(ui.sonarTypeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(sonarTypeChanged(int))); + ui.sonarTypeComboBox->setCurrentIndex(value.toInt()); + connect(ui.sonarTypeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(sonarTypeChanged(int))); + } +} diff --git a/src/ui/configuration/SonarConfig.h b/src/ui/configuration/SonarConfig.h index 07dc9cfbcd..825591a652 100644 --- a/src/ui/configuration/SonarConfig.h +++ b/src/ui/configuration/SonarConfig.h @@ -2,16 +2,20 @@ #define SONARCONFIG_H #include +#include "AP2ConfigWidget.h" #include "ui_SonarConfig.h" -class SonarConfig : public QWidget +class SonarConfig : public AP2ConfigWidget { Q_OBJECT public: explicit SonarConfig(QWidget *parent = 0); ~SonarConfig(); - +private slots: + void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void checkBoxToggled(bool enabled); + void sonarTypeChanged(int index); private: Ui::SonarConfig ui; }; diff --git a/src/ui/configuration/SonarConfig.ui b/src/ui/configuration/SonarConfig.ui index e286253853..6bce3475ae 100644 --- a/src/ui/configuration/SonarConfig.ui +++ b/src/ui/configuration/SonarConfig.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 300 + 651 + 432 @@ -29,7 +29,51 @@ false + + + + 30 + 60 + 91 + 81 + + + + + + + :/files/images/devices/AC-0004-11-2.jpg + + + true + + + + + + 140 + 60 + 70 + 17 + + + + CheckBox + + + + + + 150 + 100 + 171 + 22 + + + - + + + -- GitLab From 6b3769f4b9c90455768ca42ea177fc6cfc89fc52 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Thu, 27 Jun 2013 14:56:53 -0400 Subject: [PATCH 026/460] Implemented Airspeed configuration --- files/images/devices/BR-0004-03-2.jpg | Bin 0 -> 17831 bytes qgroundcontrol.qrc | 1 + src/ui/configuration/AirspeedConfig.cc | 75 ++++++++++++++++++++++++- src/ui/configuration/AirspeedConfig.h | 8 ++- src/ui/configuration/AirspeedConfig.ui | 49 +++++++++++++++- 5 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 files/images/devices/BR-0004-03-2.jpg diff --git a/files/images/devices/BR-0004-03-2.jpg b/files/images/devices/BR-0004-03-2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0126646ef48942d00ed34f2b0e720b26a308f155 GIT binary patch literal 17831 zcmex=Xl~0)0b01APV?`-+0Zy;bpa#8ycOYHUSr0o+)uVTGj7 z*B8Ii++0uqfJ3IZBq$Z(UaSTehg24%>IbD3=a&{Grv{~_DTAykuyQU+O)SYT3dzsU zfrVl~Mt(_taYlZDf^)E`LU?9gN`84UShcUOm1kaYNn&1ds;7&sQblfoUS?*Bm9vF~ zsk5_*sgr@Ro1vkrfu*H^fuot3lckY?k+YMN8BDKBesXDUYF-IUZwf-M8BV>Rgpga{ z>ucqbT9jFqn&MWJpQ`}&uvI2*w;1Cz52`l>w_8kb>eaVXu+axaD^fJWgo0e$KumCo z1f@%}cRWDpIny`~QxC51dpPQVuXMFfjhV&CtRiz|GCg!!5wWBOuPt%P%f1 zA|N0lEiVoN@^a!*Qc_ala&pS5>Z;0e`ufJk`uYy2fKia2Ur<<3R7glvL{LOfL`pi!5-O&{|6WZIT*h%eqm-*Vqg+v zWEN!ne}rKH10w??Di!YG z^6zl}tGWlT{s!(p`^5A1e+D->@A|ua{~3h%U0>OKcoD&SDEx1AcSS_Ze+Kg}f0s>r z|7UXF@;_@NPswhY)%{adxpBdr9bbL+ip&3Vds)0_e{a?4$9|FP_ZnAU`t_f|`_w(cKk0?@VeD`!sn`yz$&ubw6K9)Lb~0ulMPuvq$*8 zoSCwUYhKkodMT@GI(4FaaO;Z7W&b!nzgzyEZ|jxlrrkfYeS+b9h1)_MX%~Uy_jo1OY8l!_3nRm+vQe2{jzw%tGeH>eopPvHF#^gv*vQ0QT>9M zpPp37#Rncb)IH7j#cj{fWmoImRY7S?)${Pu$e^c}ukCs<|HI+V!*}_hh-H z)v2I7SHoGoH7lcX4>g1Dk6MKVi zEcIM#zV4Bpwb|DjT#uhlUXwMQ&1L1G)f1SUD&COzsmhR90-EX}p?q6(v;>l~@tgGrpOWL-gi`SM&b9x+yeuk19{J{zv!o#qswhdD^oSmwzhKzf+!n zXX@=qYtzlos>l5lo_Oc0{ZFBzJFRPt4)6KTaBcU~_Cwm?-(;o-eP<7QRa8IguxZS_f zbkCC4qIY(d>l}K$UDC}yWW}5vOKU;n_-Wv

9cly_|37V^|@M8dY?Bf39~~ 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%0AVm8a_ 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 literal 0 HcmV?d00001 diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 2f8034f33d..c9e4ccbf48 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -112,6 +112,7 @@ files/images/devices/BR-HMC5883-01-2.jpg files/images/devices/BR-APMPWRDEAN-2.jpg files/images/devices/AC-0004-11-2.jpg + files/images/devices/BR-0004-03-2.jpg files/styles/Vera.ttf diff --git a/src/ui/configuration/AirspeedConfig.cc b/src/ui/configuration/AirspeedConfig.cc index bff387fb6a..8402622ee6 100644 --- a/src/ui/configuration/AirspeedConfig.cc +++ b/src/ui/configuration/AirspeedConfig.cc @@ -1,11 +1,82 @@ #include "AirspeedConfig.h" +#include - -AirspeedConfig::AirspeedConfig(QWidget *parent) : QWidget(parent) +AirspeedConfig::AirspeedConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); + connect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(enableCheckBoxClicked(bool))); + connect(ui.useAirspeedCheckBox,SIGNAL(toggled(bool)),this,SLOT(useCheckBoxClicked(bool))); } AirspeedConfig::~AirspeedConfig() { } +void AirspeedConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + if (parameterName == "ARSPD_ENABLE") + { + if (value.toInt() == 0) + { + disconnect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(enableCheckBoxClicked(bool))); + ui.enableCheckBox->setChecked(false); + connect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(enableCheckBoxClicked(bool))); + ui.useAirspeedCheckBox->setEnabled(false); + } + else + { + disconnect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(enableCheckBoxClicked(bool))); + ui.enableCheckBox->setChecked(true); + connect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(enableCheckBoxClicked(bool))); + ui.useAirspeedCheckBox->setEnabled(true); + } + } + else if (parameterName == "ARSPD_USE") + { + if (value.toInt() == 0) + { + disconnect(ui.useAirspeedCheckBox,SIGNAL(toggled(bool)),this,SLOT(useCheckBoxClicked(bool))); + ui.useAirspeedCheckBox->setChecked(false); + connect(ui.useAirspeedCheckBox,SIGNAL(toggled(bool)),this,SLOT(useCheckBoxClicked(bool))); + } + else + { + disconnect(ui.useAirspeedCheckBox,SIGNAL(toggled(bool)),this,SLOT(useCheckBoxClicked(bool))); + ui.useAirspeedCheckBox->setChecked(true); + connect(ui.useAirspeedCheckBox,SIGNAL(toggled(bool)),this,SLOT(useCheckBoxClicked(bool))); + } + } +} + +void AirspeedConfig::useCheckBoxClicked(bool checked) +{ + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } + if (checked) + { + m_uas->setParameter(0,"ARSPD_USE",1); + } + else + { + m_uas->setParameter(0,"ARSPD_USE",0); + } +} + +void AirspeedConfig::enableCheckBoxClicked(bool checked) +{ + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } + if (checked) + { + m_uas->setParameter(0,"ARSPD_ENABLE",1); + } + else + { + m_uas->setParameter(0,"ARSPD_ENABLE",0); + } +} diff --git a/src/ui/configuration/AirspeedConfig.h b/src/ui/configuration/AirspeedConfig.h index cd67ba49ec..1646b36759 100644 --- a/src/ui/configuration/AirspeedConfig.h +++ b/src/ui/configuration/AirspeedConfig.h @@ -2,16 +2,20 @@ #define AIRSPEEDCONFIG_H #include +#include "AP2ConfigWidget.h" #include "ui_AirspeedConfig.h" -class AirspeedConfig : public QWidget +class AirspeedConfig : public AP2ConfigWidget { Q_OBJECT public: explicit AirspeedConfig(QWidget *parent = 0); ~AirspeedConfig(); - +private slots: + void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void useCheckBoxClicked(bool checked); + void enableCheckBoxClicked(bool checked); private: Ui::AirspeedConfig ui; }; diff --git a/src/ui/configuration/AirspeedConfig.ui b/src/ui/configuration/AirspeedConfig.ui index 07c97247a9..7d33cae366 100644 --- a/src/ui/configuration/AirspeedConfig.ui +++ b/src/ui/configuration/AirspeedConfig.ui @@ -29,7 +29,54 @@ false + + + + 20 + 60 + 71 + 71 + + + + + + + :/files/images/devices/BR-0004-03-2.jpg + + + true + + + + + + 110 + 70 + 70 + 17 + + + + Enable + + + + + + 110 + 100 + 91 + 17 + + + + Use Airspeed + + - + + + -- GitLab From d440a4d62bf7b9b087bba0aa9b6da1a2249c5a04 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 28 Jun 2013 08:27:27 -0400 Subject: [PATCH 027/460] Implementation of Optical Flow config --- files/images/devices/BR-0016-01-3T.jpg | Bin 0 -> 12395 bytes qgroundcontrol.qrc | 1 + src/ui/configuration/OpticalFlowConfig.cc | 29 +++++++++++++++-- src/ui/configuration/OpticalFlowConfig.h | 7 +++-- src/ui/configuration/OpticalFlowConfig.ui | 36 +++++++++++++++++++++- 5 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 files/images/devices/BR-0016-01-3T.jpg diff --git a/files/images/devices/BR-0016-01-3T.jpg b/files/images/devices/BR-0016-01-3T.jpg new file mode 100644 index 0000000000000000000000000000000000000000..534eba3f0b7cfa4f16f7aeab02f410bc489bc50b GIT binary patch literal 12395 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 DBPI3` literal 0 HcmV?d00001 diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index c9e4ccbf48..bf6092bcf1 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -113,6 +113,7 @@ files/images/devices/BR-APMPWRDEAN-2.jpg files/images/devices/AC-0004-11-2.jpg files/images/devices/BR-0004-03-2.jpg + files/images/devices/BR-0016-01-3T.jpg files/styles/Vera.ttf diff --git a/src/ui/configuration/OpticalFlowConfig.cc b/src/ui/configuration/OpticalFlowConfig.cc index bc977317b1..7c39431174 100644 --- a/src/ui/configuration/OpticalFlowConfig.cc +++ b/src/ui/configuration/OpticalFlowConfig.cc @@ -1,11 +1,36 @@ #include "OpticalFlowConfig.h" +#include - -OpticalFlowConfig::OpticalFlowConfig(QWidget *parent) : QWidget(parent) +OpticalFlowConfig::OpticalFlowConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); + connect(ui.enableCheckBox,SIGNAL(clicked(bool)),this,SLOT(enableCheckBoxClicked(bool))); } OpticalFlowConfig::~OpticalFlowConfig() { } +void OpticalFlowConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + if (parameterName == "FLOW_ENABLE") + { + if (value.toInt() == 0) + { + ui.enableCheckBox->setChecked(false); + } + else + { + ui.enableCheckBox->setChecked(true); + } + } +} + +void OpticalFlowConfig::enableCheckBoxClicked(bool checked) +{ + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } + m_uas->setParameter(0,"FLOW_ENABLE",checked ? 1 : 0); +} diff --git a/src/ui/configuration/OpticalFlowConfig.h b/src/ui/configuration/OpticalFlowConfig.h index 72ea2b0a3e..38b4ae7ebb 100644 --- a/src/ui/configuration/OpticalFlowConfig.h +++ b/src/ui/configuration/OpticalFlowConfig.h @@ -2,16 +2,19 @@ #define OPTICALFLOWCONFIG_H #include +#include "AP2ConfigWidget.h" #include "ui_OpticalFlowConfig.h" -class OpticalFlowConfig : public QWidget +class OpticalFlowConfig : public AP2ConfigWidget { Q_OBJECT public: explicit OpticalFlowConfig(QWidget *parent = 0); ~OpticalFlowConfig(); - +private slots: + void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void enableCheckBoxClicked(bool checked); private: Ui::OpticalFlowConfig ui; }; diff --git a/src/ui/configuration/OpticalFlowConfig.ui b/src/ui/configuration/OpticalFlowConfig.ui index 19ffbd7e40..e5a5bce4c6 100644 --- a/src/ui/configuration/OpticalFlowConfig.ui +++ b/src/ui/configuration/OpticalFlowConfig.ui @@ -29,7 +29,41 @@ false + + + + 100 + 60 + 70 + 17 + + + + Enable + + + + + + 10 + 60 + 81 + 71 + + + + + + + :/files/images/devices/BR-0016-01-3T.jpg + + + true + + - + + + -- GitLab From 4decb8d647f0380106988b73c6763fb77a8ff7ec Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 28 Jun 2013 08:35:41 -0400 Subject: [PATCH 028/460] Implementation of OSD Configuration --- files/images/devices/MinimOSD.jpg | Bin 0 -> 41403 bytes qgroundcontrol.qrc | 1 + src/ui/configuration/OsdConfig.cc | 30 ++++++++++++++-- src/ui/configuration/OsdConfig.h | 6 ++-- src/ui/configuration/OsdConfig.ui | 56 ++++++++++++++++++++++++++++-- 5 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 files/images/devices/MinimOSD.jpg diff --git a/files/images/devices/MinimOSD.jpg b/files/images/devices/MinimOSD.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b24c7e4a9759278435edcefe778e51765177d26e GIT binary patch literal 41403 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 literal 0 HcmV?d00001 diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index bf6092bcf1..49cd25075d 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -114,6 +114,7 @@ files/images/devices/AC-0004-11-2.jpg files/images/devices/BR-0004-03-2.jpg files/images/devices/BR-0016-01-3T.jpg + files/images/devices/MinimOSD.jpg files/styles/Vera.ttf diff --git a/src/ui/configuration/OsdConfig.cc b/src/ui/configuration/OsdConfig.cc index badf1b8e0f..d71430e3ca 100644 --- a/src/ui/configuration/OsdConfig.cc +++ b/src/ui/configuration/OsdConfig.cc @@ -1,11 +1,37 @@ #include "OsdConfig.h" +#include - -OsdConfig::OsdConfig(QWidget *parent) : QWidget(parent) +OsdConfig::OsdConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); + connect(ui.enablePushButton,SIGNAL(clicked()),this,SLOT(enableButtonClicked())); } OsdConfig::~OsdConfig() { } +void OsdConfig::enableButtonClicked() +{ + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } + m_uas->setParameter(0,"SR0_EXT_STAT",2); + m_uas->setParameter(0,"SR0_EXTRA1",10); + m_uas->setParameter(0,"SR0_EXTRA2",10); + m_uas->setParameter(0,"SR0_EXTRA3",2); + m_uas->setParameter(0,"SR0_POSITION",3); + m_uas->setParameter(0,"SR0_RAW_CTRL",2); + m_uas->setParameter(0,"SR0_RAW_SENS",2); + m_uas->setParameter(0,"SR0_RC_CHAN",2); + + m_uas->setParameter(0,"SR3_EXT_STAT",2); + m_uas->setParameter(0,"SR3_EXTRA1",10); + m_uas->setParameter(0,"SR3_EXTRA2",10); + m_uas->setParameter(0,"SR3_EXTRA3",2); + m_uas->setParameter(0,"SR3_POSITION",3); + m_uas->setParameter(0,"SR3_RAW_CTRL",2); + m_uas->setParameter(0,"SR3_RAW_SENS",2); + m_uas->setParameter(0,"SR3_RC_CHAN",2); +} diff --git a/src/ui/configuration/OsdConfig.h b/src/ui/configuration/OsdConfig.h index ecfb3ceaa3..963fa0dd1a 100644 --- a/src/ui/configuration/OsdConfig.h +++ b/src/ui/configuration/OsdConfig.h @@ -2,16 +2,18 @@ #define OSDCONFIG_H #include +#include "AP2ConfigWidget.h" #include "ui_OsdConfig.h" -class OsdConfig : public QWidget +class OsdConfig : public AP2ConfigWidget { Q_OBJECT public: explicit OsdConfig(QWidget *parent = 0); ~OsdConfig(); - +private slots: + void enableButtonClicked(); private: Ui::OsdConfig ui; }; diff --git a/src/ui/configuration/OsdConfig.ui b/src/ui/configuration/OsdConfig.ui index c45bc6a259..6c9e4d7aec 100644 --- a/src/ui/configuration/OsdConfig.ui +++ b/src/ui/configuration/OsdConfig.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 300 + 499 + 243 @@ -29,7 +29,57 @@ false + + + + 10 + 60 + 101 + 41 + + + + + + + :/files/images/devices/MinimOSD.jpg + + + true + + + + + + 230 + 60 + 191 + 41 + + + + You only need to use this if you are +having issue with your OSD not +updating + + + + + + 120 + 60 + 91 + 41 + + + + Enable +Telemetry + + - + + + -- GitLab From 04040e40ef199154525972ccbb2794e3e3ed6f19 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Fri, 28 Jun 2013 10:33:01 -0700 Subject: [PATCH 029/460] First Commit with new changes to support new QtSerialPort (not yet working) --- qgroundcontrol.pri | 96 +++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/qgroundcontrol.pri b/qgroundcontrol.pri index e3b7f8eb1a..d8ec27616b 100644 --- a/qgroundcontrol.pri +++ b/qgroundcontrol.pri @@ -48,82 +48,82 @@ macx|macx-g++42|macx-g++|macx-llvm: { ICON = $$BASEDIR/files/images/icons/macx.icns # Copy contributed files - QMAKE_POST_LINK += && cp -rf $$BASEDIR/files $$TARGETDIR/qgroundcontrol.app/Contents/MacOS + QMAKE_POST_LINK += && cp -rf $$BASEDIR/files $$TARGETDIR/apmplanner2.app/Contents/MacOS # Copy google earth starter file - QMAKE_POST_LINK += && cp -f $$BASEDIR/files/images/earth.html $$TARGETDIR/qgroundcontrol.app/Contents/MacOS + QMAKE_POST_LINK += && cp -f $$BASEDIR/files/images/earth.html $$TARGETDIR/apmplanner2.app/Contents/MacOS # Copy CSS stylesheets - QMAKE_POST_LINK += && cp -f $$BASEDIR/files/styles/style-indoor.css $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/style-indoor.css - QMAKE_POST_LINK += && cp -f $$BASEDIR/files/styles/style-outdoor.css $$TARGETDIR/qgroundcontrol.app/Contents/MacOS + QMAKE_POST_LINK += && cp -f $$BASEDIR/files/styles/style-indoor.css $$TARGETDIR/apmplanner2.app/Contents/MacOS/style-indoor.css + QMAKE_POST_LINK += && cp -f $$BASEDIR/files/styles/style-outdoor.css $$TARGETDIR/apmplanner2.app/Contents/MacOS # Copy support files - QMAKE_POST_LINK += && cp -rf $$BASEDIR/files $$TARGETDIR/qgroundcontrol.app/Contents/MacOS + QMAKE_POST_LINK += && cp -rf $$BASEDIR/files $$TARGETDIR/apmplanner2.app/Contents/MacOS # Copy MAVLink - QMAKE_POST_LINK += && cp -rf $$BASEDIR/libs/mavlink $$TARGETDIR/qgroundcontrol.app/Contents/MacOS + QMAKE_POST_LINK += && cp -rf $$BASEDIR/libs/mavlink $$TARGETDIR/apmplanner2.app/Contents/MacOS # Copy libraries - QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/libs - QMAKE_POST_LINK += && cp -rf $$BASEDIR/libs/lib/mac64/lib/* $$TARGETDIR/qgroundcontrol.app/Contents/libs + QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/apmplanner2.app/Contents/libs + QMAKE_POST_LINK += && cp -rf $$BASEDIR/libs/lib/mac64/lib/* $$TARGETDIR/apmplanner2.app/Contents/libs # Copy frameworks - QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/Frameworks - QMAKE_POST_LINK += && cp -rf $$BASEDIR/libs/lib/Frameworks/* $$TARGETDIR/qgroundcontrol.app/Contents/Frameworks + QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/apmplanner2.app/Contents/Frameworks + QMAKE_POST_LINK += && cp -rf $$BASEDIR/libs/lib/Frameworks/* $$TARGETDIR/apmplanner2.app/Contents/Frameworks # Fix library paths inside executable - QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qgroundcontrol - QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qgroundcontrol - QMAKE_POST_LINK += && install_name_tool -change libosgViewer.dylib "@executable_path/../libs/libosgViewer.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qgroundcontrol - QMAKE_POST_LINK += && install_name_tool -change libosgGA.dylib "@executable_path/../libs/libosgGA.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qgroundcontrol - QMAKE_POST_LINK += && install_name_tool -change libosgDB.dylib "@executable_path/../libs/libosgDB.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qgroundcontrol - QMAKE_POST_LINK += && install_name_tool -change libosgText.dylib "@executable_path/../libs/libosgText.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qgroundcontrol - QMAKE_POST_LINK += && install_name_tool -change libosgWidget.dylib "@executable_path/../libs/libosgWidget.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qgroundcontrol + QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/apmplanner2.app/Contents/MacOS/apmplanner2 + QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/apmplanner2.app/Contents/MacOS/apmplanner2 + QMAKE_POST_LINK += && install_name_tool -change libosgViewer.dylib "@executable_path/../libs/libosgViewer.dylib" $$TARGETDIR/apmplanner2.app/Contents/MacOS/apmplanner2 + QMAKE_POST_LINK += && install_name_tool -change libosgGA.dylib "@executable_path/../libs/libosgGA.dylib" $$TARGETDIR/apmplanner2.app/Contents/MacOS/apmplanner2 + QMAKE_POST_LINK += && install_name_tool -change libosgDB.dylib "@executable_path/../libs/libosgDB.dylib" $$TARGETDIR/apmplanner2.app/Contents/MacOS/apmplanner2 + QMAKE_POST_LINK += && install_name_tool -change libosgText.dylib "@executable_path/../libs/libosgText.dylib" $$TARGETDIR/apmplanner2.app/Contents/MacOS/apmplanner2 + QMAKE_POST_LINK += && install_name_tool -change libosgWidget.dylib "@executable_path/../libs/libosgWidget.dylib" $$TARGETDIR/apmplanner2.app/Contents/MacOS/apmplanner2 # Fix library paths within libraries (inter-library dependencies) # OSG GA LIBRARY - QMAKE_POST_LINK += && install_name_tool -change libosgGA.dylib "@executable_path/../libs/libosgGA.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgGA.dylib - QMAKE_POST_LINK += && install_name_tool -change libosgDB.dylib "@executable_path/../libs/libosgDB.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgGA.dylib - QMAKE_POST_LINK += && install_name_tool -change libosgUtil.dylib "@executable_path/../libs/libosgUtil.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgGA.dylib - QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgGA.dylib - QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgGA.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgGA.dylib "@executable_path/../libs/libosgGA.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgGA.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgDB.dylib "@executable_path/../libs/libosgDB.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgGA.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgUtil.dylib "@executable_path/../libs/libosgUtil.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgGA.dylib + QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgGA.dylib + QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgGA.dylib # OSG DB LIBRARY - QMAKE_POST_LINK += && install_name_tool -change libosgDB.dylib "@executable_path/../libs/libosgDB.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgDB.dylib - QMAKE_POST_LINK += && install_name_tool -change libosgUtil.dylib "@executable_path/../libs/libosgUtil.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgDB.dylib - QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgDB.dylib - QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgDB.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgDB.dylib "@executable_path/../libs/libosgDB.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgDB.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgUtil.dylib "@executable_path/../libs/libosgUtil.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgDB.dylib + QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgDB.dylib + QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgDB.dylib # OSG TEXT LIBRARY - QMAKE_POST_LINK += && install_name_tool -change libosgText.dylib "@executable_path/../libs/libosgText.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgText.dylib - QMAKE_POST_LINK += && install_name_tool -change libosgDB.dylib "@executable_path/../libs/libosgDB.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgText.dylib - QMAKE_POST_LINK += && install_name_tool -change libosgUtil.dylib "@executable_path/../libs/libosgUtil.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgText.dylib - QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgText.dylib - QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgText.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgText.dylib "@executable_path/../libs/libosgText.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgText.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgDB.dylib "@executable_path/../libs/libosgDB.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgText.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgUtil.dylib "@executable_path/../libs/libosgUtil.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgText.dylib + QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgText.dylib + QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgText.dylib # OSG UTIL LIBRARY - QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgUtil.dylib - QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgUtil.dylib + QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgUtil.dylib + QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgUtil.dylib # OSG VIEWER LIBRARY - QMAKE_POST_LINK += && install_name_tool -change libosgGA.dylib "@executable_path/../libs/libosgGA.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgViewer.dylib - QMAKE_POST_LINK += && install_name_tool -change libosgText.dylib "@executable_path/../libs/libosgText.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgViewer.dylib - QMAKE_POST_LINK += && install_name_tool -change libosgDB.dylib "@executable_path/../libs/libosgDB.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgViewer.dylib - QMAKE_POST_LINK += && install_name_tool -change libosgUtil.dylib "@executable_path/../libs/libosgUtil.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgViewer.dylib - QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgViewer.dylib - QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgViewer.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgGA.dylib "@executable_path/../libs/libosgGA.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgViewer.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgText.dylib "@executable_path/../libs/libosgText.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgViewer.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgDB.dylib "@executable_path/../libs/libosgDB.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgViewer.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgUtil.dylib "@executable_path/../libs/libosgUtil.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgViewer.dylib + QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgViewer.dylib + QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgViewer.dylib # OSG WIDGET LIBRARY - QMAKE_POST_LINK += && install_name_tool -change libosgGA.dylib "@executable_path/../libs/libosgGA.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgWidget.dylib - QMAKE_POST_LINK += && install_name_tool -change libosgText.dylib "@executable_path/../libs/libosgText.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgWidget.dylib - QMAKE_POST_LINK += && install_name_tool -change libosgDB.dylib "@executable_path/../libs/libosgDB.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgWidget.dylib - QMAKE_POST_LINK += && install_name_tool -change libosgUtil.dylib "@executable_path/../libs/libosgUtil.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgWidget.dylib - QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgWidget.dylib - QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgWidget.dylib - QMAKE_POST_LINK += && install_name_tool -change libosgViewer.dylib "@executable_path/../libs/libosgViewer.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosgWidget.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgGA.dylib "@executable_path/../libs/libosgGA.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgWidget.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgText.dylib "@executable_path/../libs/libosgText.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgWidget.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgDB.dylib "@executable_path/../libs/libosgDB.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgWidget.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgUtil.dylib "@executable_path/../libs/libosgUtil.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgWidget.dylib + QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgWidget.dylib + QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgWidget.dylib + QMAKE_POST_LINK += && install_name_tool -change libosgViewer.dylib "@executable_path/../libs/libosgViewer.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosgWidget.dylib # CORE OSG LIBRARY - QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/libs/libosg.dylib + QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/apmplanner2.app/Contents/libs/libosg.dylib # SDL Framework - QMAKE_POST_LINK += && install_name_tool -change "@rpath/SDL.framework/Versions/A/SDL" "@executable_path/../Frameworks/SDL.framework/Versions/A/SDL" $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qgroundcontrol + QMAKE_POST_LINK += && install_name_tool -change "@rpath/SDL.framework/Versions/A/SDL" "@executable_path/../Frameworks/SDL.framework/Versions/A/SDL" $$TARGETDIR/apmplanner2.app/Contents/MacOS/apmplanner2 # No check for GLUT.framework since it's a MAC default message("Building support for OpenSceneGraph") -- GitLab From c2abde102926e1527f22cb366ab8f6b4afe80e65 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Fri, 28 Jun 2013 10:36:28 -0700 Subject: [PATCH 030/460] adds missing files --- libs/serialport/apmserial.pri | 59 + .../doc/images/blockingmaster-example.png | Bin 0 -> 4656 bytes .../doc/images/blockingslave-example.png | Bin 0 -> 4784 bytes .../doc/images/cenumerator-example.png | Bin 0 -> 3532 bytes .../doc/images/enumerator-example.png | Bin 0 -> 18510 bytes .../doc/images/terminal-example.png | Bin 0 -> 10918 bytes libs/serialport/doc/qtserialport.qdocconf | 37 + libs/serialport/doc/src/index.qdoc | 65 + .../doc/src/qtserialport-module.qdoc | 46 + libs/serialport/doc/style/style.css | 137 ++ libs/serialport/qserialport.cpp | 1167 ++++++++++++++ libs/serialport/qserialport.h | 257 ++++ libs/serialport/qserialport_p.h | 89 ++ libs/serialport/qserialport_symbian.cpp | 645 ++++++++ libs/serialport/qserialport_symbian_p.h | 118 ++ libs/serialport/qserialport_unix.cpp | 1343 +++++++++++++++++ libs/serialport/qserialport_unix_p.h | 156 ++ libs/serialport/qserialport_win.cpp | 1091 +++++++++++++ libs/serialport/qserialport_win_p.h | 162 ++ libs/serialport/qserialport_wince.cpp | 509 +++++++ libs/serialport/qserialportglobal.h | 67 + libs/serialport/qserialportinfo.cpp | 259 ++++ libs/serialport/qserialportinfo.h | 98 ++ libs/serialport/qserialportinfo_mac.cpp | 272 ++++ libs/serialport/qserialportinfo_p.h | 85 ++ libs/serialport/qserialportinfo_symbian.cpp | 249 +++ libs/serialport/qserialportinfo_unix.cpp | 261 ++++ libs/serialport/qserialportinfo_win.cpp | 233 +++ libs/serialport/qserialportinfo_wince.cpp | 134 ++ libs/serialport/qt4support/install-helper.pri | 43 + libs/serialport/qt4support/qringbuffer_p.h | 451 ++++++ .../qt4support/qwineventnotifier_p.h | 94 ++ libs/serialport/qt4support/serialport.prf | 27 + libs/serialport/qttylocker_unix.cpp | 188 +++ libs/serialport/qttylocker_unix_p.h | 59 + libs/serialport/serialport-lib.pri | 87 ++ libs/serialport/serialport.pro | 17 + qgroundcontrol.pro | 41 +- src/comm/SerialLink.cc | 1102 ++++---------- src/comm/SerialLink.h | 55 +- src/ui/SerialConfigurationWindow.cc | 2 +- 41 files changed, 8874 insertions(+), 831 deletions(-) create mode 100644 libs/serialport/apmserial.pri create mode 100644 libs/serialport/doc/images/blockingmaster-example.png create mode 100644 libs/serialport/doc/images/blockingslave-example.png create mode 100644 libs/serialport/doc/images/cenumerator-example.png create mode 100644 libs/serialport/doc/images/enumerator-example.png create mode 100644 libs/serialport/doc/images/terminal-example.png create mode 100644 libs/serialport/doc/qtserialport.qdocconf create mode 100644 libs/serialport/doc/src/index.qdoc create mode 100644 libs/serialport/doc/src/qtserialport-module.qdoc create mode 100644 libs/serialport/doc/style/style.css create mode 100644 libs/serialport/qserialport.cpp create mode 100644 libs/serialport/qserialport.h create mode 100644 libs/serialport/qserialport_p.h create mode 100644 libs/serialport/qserialport_symbian.cpp create mode 100644 libs/serialport/qserialport_symbian_p.h create mode 100644 libs/serialport/qserialport_unix.cpp create mode 100644 libs/serialport/qserialport_unix_p.h create mode 100644 libs/serialport/qserialport_win.cpp create mode 100644 libs/serialport/qserialport_win_p.h create mode 100644 libs/serialport/qserialport_wince.cpp create mode 100644 libs/serialport/qserialportglobal.h create mode 100644 libs/serialport/qserialportinfo.cpp create mode 100644 libs/serialport/qserialportinfo.h create mode 100644 libs/serialport/qserialportinfo_mac.cpp create mode 100644 libs/serialport/qserialportinfo_p.h create mode 100644 libs/serialport/qserialportinfo_symbian.cpp create mode 100644 libs/serialport/qserialportinfo_unix.cpp create mode 100644 libs/serialport/qserialportinfo_win.cpp create mode 100644 libs/serialport/qserialportinfo_wince.cpp create mode 100644 libs/serialport/qt4support/install-helper.pri create mode 100644 libs/serialport/qt4support/qringbuffer_p.h create mode 100644 libs/serialport/qt4support/qwineventnotifier_p.h create mode 100644 libs/serialport/qt4support/serialport.prf create mode 100644 libs/serialport/qttylocker_unix.cpp create mode 100644 libs/serialport/qttylocker_unix_p.h create mode 100644 libs/serialport/serialport-lib.pri create mode 100644 libs/serialport/serialport.pro diff --git a/libs/serialport/apmserial.pri b/libs/serialport/apmserial.pri new file mode 100644 index 0000000000..738c482946 --- /dev/null +++ b/libs/serialport/apmserial.pri @@ -0,0 +1,59 @@ + +INCLUDEPATH += $$PWD + +unix { + CONFIG += link_pkgconfig + + packagesExist(libudev) { + DEFINES += HAVE_LIBUDEV + PKGCONFIG += libudev + } +} + +PUBLIC_HEADERS += \ + $$PWD/qserialportglobal.h \ + $$PWD/qserialport.h \ + $$PWD/qserialportinfo.h + +PRIVATE_HEADERS += \ + $$PWD/qserialport_p.h \ + $$PWD/qserialportinfo_p.h + +SOURCES += \ + $$PWD/qserialport.cpp \ + $$PWD/qserialportinfo.cpp + +win32 { + PRIVATE_HEADERS += \ + $$PWD/qserialport_win_p.h + + SOURCES += \ + $$PWD/qserialport_win.cpp \ + $$PWD/qserialportinfo_win.cpp + + LIBS += -lsetupapi -ladvapi32 + +} + +unix:!symbian { + PRIVATE_HEADERS += \ + $$PWD/qttylocker_unix_p.h \ + $$PWD/qserialport_unix_p.h + + SOURCES += \ + $$PWD/qttylocker_unix.cpp \ + $$PWD/qserialport_unix.cpp \ + $$PWD/qserialportinfo_unix.cpp + + macx { + SOURCES += $$PWD/qserialportinfo_mac.cpp + + LIBS += -framework IOKit -framework CoreFoundation + } else { + linux*:contains( DEFINES, HAVE_LIBUDEV ) { + LIBS += -ludev + } + } +} + +HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS diff --git a/libs/serialport/doc/images/blockingmaster-example.png b/libs/serialport/doc/images/blockingmaster-example.png new file mode 100644 index 0000000000000000000000000000000000000000..44aa5ecfa894a78074ce7e89a331d0006be6d834 GIT binary patch literal 4656 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 F2>?rU&V~R0 literal 0 HcmV?d00001 diff --git a/libs/serialport/doc/images/blockingslave-example.png b/libs/serialport/doc/images/blockingslave-example.png new file mode 100644 index 0000000000000000000000000000000000000000..44aa39394d3dbfbf8a5d519a428d60230b188805 GIT binary patch literal 4784 zcmeAS@N?(olHy`uVBq!ia0y~yU{qvaU|7w;#K6F?OnI*x0|NtNage(c!@6@aFBupZ zSkfJR9T^xl_H+M9WMyDr;4JWnEM{QfI}E~%$MaXDFfa(Ydb&7Eybn~6%nc9U)3^SADQxLv4Yebi^7{rEQ(S& zIa{I^#9DW1-&^3p=;Y`dWFEP`e*JBAo#$sPjf>OX)z;lVS^U0spL}mw`nfqXtv}A| zf4}*4dOn*tBZF$<@j5<-<3A5F^KV)BGLxr(=S$0)YtyfOF=4Y{t8xl^eLAa3idlx) zR&n*$R8!kt#=gdR6R!T+G;7{5hT{(2JI^mzxG`nxzBS918y+yc;C4l~*{??pqBL<+ zvcF7y)~Rp);`__r-?NQnJHQmNKBt~1a;^XUZ?cb-FPq!;CT>c$-|?j?cX!Fp-qZPe zDqnsz->$!3QSeeud3pGB#tQ;VWf!L{-SpRT*1Tf|H#b^;UzYpi#<_ESdaq?~FMpD~ zHfK)tai1d>dG-|NJ>K`*FZcC{$Lox**OjU)zZU!4?t{^V#nbE8YGiTVyyD~QpFHEu zjRK25?e%}Qv&-NAb!TJ#-($~iw(qZccH+9<{_pR0fB*Kb?Hl+0&o;Gh_9yQ%nk&ma zJ!fz7S;gf%;tLjj+5LFNT=t!>)b4Y7e4OL)k||Sl_?bH$%i6>vj;H8#dwrLw7kN{b zwmo?HC1sAh(z%Df9hkJl<3euEw3!>vu8YaPnX=U`cyrdxe=-ms`#!&+Kkvun_Aa1mHM#5s(hnJ`C?+;zN%57PGmDFL8zPtOp`)Xg^d@lFn zSGe8p-sSe+|9oseS2I!O_szX8W^9@IYo_~}^%0w<9x6_id}XZf$-66bU)kgVp(ZV9IxGv@Y(z8ew}oW ztE#De&HrQTqUxzTqWW5;ibat1g?eq!Tw+v@W7 zar^h}uFg%Lx=()ctm4O8crI_cymOYM(zLZVufLn5%YFEbhH0aeh5MwWZF3yfC#-+= zJ2K10oBL!|Z6qYX-&$8MkN;tonKrxh&9}ADORk-3mtVIlIq29nKIg=+G>N&T^B*nI zOuL+V$e{c5jX7(l%@E<6^KSB-z-4dF2W9;izU2bRc861rue-Zr_y3D~|NfoN`~L2| z{~7u9|CL|;zkmMyo4b39zn_~s+dThG-2J7$Z=99B9{zXhB7XJKDC^08&p5vdPfxy5 zHq*kVY_g-x?Dj`$&-4@@S0sp=TsI28ym99q+mwCP(kI|f-l%Wu`zhph=kooVexBKU z+~>*E@c-+Mzh62@sJrD+x9aI1w@Oq(XPo(vC4M2dWRlp76}}3S7FwP=wzK%8pvYY# z0iiREzUPju48FR0rs3p2l1qY5tHTR{?fLhgO>YWzXnJUS@U%j);Fj)_eT~x|^Q^ve z)FHbeIaZ}wlH*_$uMG17odTYQO$Q7aPB9&4(BOs%^pw20&&aTO@jr=UmfN@)X0TeY zIYd5?U`TCDW|+d-#~2`nM_}!PkMCo0>o0F^l59*~+o1KMIr^}fxrLc|!5Yy3*8g9w zZ8*!@ca~Qsn>FNMcs}3lI}dK$Ij}K|;dqr#wCwIpJGX7CbY=hBuJuFRygfIsASaK@ z!mWyD%E?(hMVW=itx`2ZKm0at+qkzV5ckyR`4To~-TT_H?f)Q9%NNet>)y9kwl?MM1!4P=LOD6B2bb^It(g?%?&AKkpgK<45Xe=XJ1jmgEA_asNhJUz(V z#8mgdWXGdd_EnQa_b*8=)aHzDF#0mt@03t=T7CG^sbSRsdfCd&@%L& zD(9q9_xKAtUZ&49<$gW;_bk^cRiJvPHX#KKh2--#%V`SN_}K=&5IJ-E}kh?tVU{ zFtZ>hugmh-j_9DR*K%EceKEX~?sR0GSKHr`H}&gyW0foUYCrnEY!Bnyck)w>zul>V zf-m__Hs0KaJ$qSBD=j>@acAbejaxqy`L4Fvw<0*_tM`4E71j^!o{4O}{YhwNVw(4% z)Sdayqu4_~^snPxTKk>l|Cz^?_BC~Lf6K&J|BU6GSD#_9 zH(N5~;QzhGJa3hBb9<7n|KgB&Egf?3|5oFi;^ySy%Yw&$@r8bBZ%nRj*4pvc_xvoUtv?)N%_|D*kM8+hX4N(s(&r zU*on56Oz;WD>m<_f1*?0mdqd!(rus1Q1s?R1DK-s+V!;g>3CQCv+ zm#vGFuwc8zboJ3ywThXoim7qe3^)FLa&Qy# zH$CpTG{9goS6`!?^VT1e+bVy4c<|x$m&h{{`MRH~sY)zs$+^K&z_W#Q)zRA!C@ z9@anluQB=dCCMEb9UeWu)DE?rdDf6zoBaCf=ePM)*QTV&6i=&IWUDWGZDYxf`X2_j zr&^{NmF_VpSd$;X`o4b8i`M07J<0FC3R+w3)yglvyy5G!7P&9(``FjmY4ZNYwO!YA>^pDsEOAy{ z8}GLBXlCc}4bQx@YTm7nl?*!6To&WAy{M%wHB@TFO_Rp&7oQ97Za?kmo?hY5vtxp- zoc_a>U)=&Tlk@Grd&WJJRSrKQ)VKRyjUadIlqVPSKOAQQ`(TI8&ME71)?HRFUHxq8 zqL!MnH!Lw%e}$$opM8?a>v`neg1@JRqHRhH-7Di>Tm<^DcP)+xwwoK@b_-Pz@Bw~TpiY5i8?pfy1i3xzib?(SN6_tl?` zKZP#VIEHy1PYw^|++3-CcX`#qkGI2STr+%oUfgp*_avKOCG`?@R^#9UhAZp-|IaDh zZv5Np;`DhTi7Sp~1>W)~E%Q45DYVHjC8baKOqg}g{pGt({>atVIc>P}SH*)HO;ZYb zy!z{JEmTcoU-oIm?EA-?jGcm(#hjg*DL?Uy$%B}6YbJ?rxHS3h*;PCA9&G;Px9|Lo z$DA@A-?sU@zH#Du<7F427mHN-{|VnX$M-)r@xlt`K3xyNwJ6HR;l9 z{iKE6lWczZC-B*3Kb?Q#!Hp)7!Z(lAI5sG#_*EJIx^Y4#S=;8GxN*|6ZWoaCc6$yv zue@b^U?Xc|vf!;W&#tR?k8?SLlF0l6$3XEW-d8$5)pD8rJb7-JXaS3BT+^Q3m~w*i zuIIrs2R4Rn5ILU41gp*7=2wLoC}XWrAysUY^m4s4n=V^l zsf5Kf&Ib|gjmdKvkU0x<`;Nx%l>fW>t3qAvb*$YrI;?&AxS*%w=Qqdu$vZX(%7yvV?)rST>S*0X zyW@|7=LOx=II(oSV4c8X)5iHfT!MdfUWoZ8a=oBx8>f5eitvek_A-n6{(XITOlbW~ z+233SPq=OF+$hk#yLRoac{1M2b?p@g3+Byu8Gcly`YPXLspDVzuhv*U`(n_+f9WG< zAdC8iY&9jln=)_1%^oHmIKJEA(TsWb4}ZaL#)FFvt8EZ_RPF z6Fh?7&Xg(qx%lV#h3>{#p?8<0em4|!b_(lf(f6EWus7N1t(t7|q1v9*4L|Z%yg5EW zUTb&PS(QT@Zk-gknvp#FW#1tWl~d1-nKeq*u6lRD=s1U7-9?>mQ{GtazNWE!M(vUH z8q+FN|DNQ3J@sf}WcAE9GkAr}^3qqvA2K{zM<#Aqv)8BK%w2b(QkA%wOB>EV&Wn38 z>pkb;EcXS8J68GJ?6=D)y}jW5`;rh#LQI?J_J`Wge^h{9KiP&G3{@U9+&c!39Pyi)VGO<6qhTIP7(0 z-==Qi?0#FflkZ;U%@J1ra_?!plu-8T`B(2HeCUk-*`g&StRSDkpDI)Qb={&56IR=M zgeTAZxWTP|)y8e>W#eKti#4PMpEA^~{T;Y$wO&i)Y`21C%V$kkd+Hj~1*tB}XI=HR zo0S;8E-&o4e8z1nr&-2wh74g=*~|G8DlA@ZUDUEhecAcXm)84U;7eDP4rgM}X-10bAmrpDIg#W$r_q85k*;O7z9?z~FSuXv=I#b8yu7b{&!k=?Z%uj#N zQ&uvaxv7)wjq1Tu7xyIpvet~s;L~)Gt;kx-k$LI4(be8B^G-}G(cka&{j%bGrJVWk z8V8F1F_ne=Dx3CAT6AUaZ00L5;%kJ?S}!Z;{i(It_1USwi3u~#UfPjgF6p@KP8|>D zrep%sa_e7OX6&_wvNe z9bXQH3u{@lt|efgrM!m<6;86nLD0Vd;*FkN+8&)@pR_Z29WXz`(%Z M>FVdQ&MBb@0DU4s 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 literal 0 HcmV?d00001 diff --git a/libs/serialport/doc/images/enumerator-example.png b/libs/serialport/doc/images/enumerator-example.png new file mode 100644 index 0000000000000000000000000000000000000000..c4add83896d3b144c99945384060b0f22bd962e8 GIT binary patch literal 18510 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 z zc;e);m6ohG4jmFSN`5u-xW_bJ56}?HzDc~-oilX1(%Tds)+BQ|_pW!V?+NB9UDUQI zeBZ)_?wbNb()I>02nqbqu#$cFNPt&*;sMZ1hVG1=3F3>yUVOjc?Dj*~@WZt25vTvu z$}mcwXnUV=VRFmy1AL+)o6p8PKK=FhJEvDgsajJiIE-HAoxDFc{jp=9X}?&?;pOE@ zH_LKBpMLZ)x%3n7{E+^)IwAL?cyXq>tdZg7xDD0se0ZAvJ<4rTIBue=>8o^sk>!nI zG`pUT|3r>2rYtHqm&~5T@q?3b`^Bv~bvC!I$N7D#Q)QBMJ8(UqOm^P}n?R)t*99h| zd=3_0wBA&wa(@+QrlhkWGgdk-8OVJYH(0stNGS#d93BLI;XgA z*TO7G?Ps;c-BF%$_d(u|3GI-*EcoeG)!aR*v%`agid~JieQVQm;n}{%|KjRt8?}|h zbk`i0*v8j-=BBv7hRHb*&5L9&`!>B~3f}wUMy!a!T zE27-~>G6nP7N3>;exLj86KqS5p39xR;H-PG3Fk6yldq4G%TtUwZ)UgVyc0QDkn!SI z68F!K$?lGVO*y|r_GZmor*ZPy?w=P{mZvk{%s9h#zCj=kOAJV6{4GV zhN{H-w!L??DHdsx`11Lg&;E7(7gtVGy=k>o@muSmT!q;u&uLbLZd~|7VzSJyjuZPP zpPj2DDX($h`z7;=7r!1wOV@T;U)}U2r?ydaZb|=KZ?ll7#aeD%aWy#-dnGJ=oxW9l z$$8fG$wbJ(lxhUti1|HP`h~ZmI|Wi^u;F+;`nhzJ8JZ7XHe9Go=UGH*?l> z>3At!*ey6AWipo#s5c8Pc=rCDtNZ>O7t^GiN#IqH3MZebFIcLy$$PA9y_J1 z$yUC@uxQ`SR&g&r4vq(g_IpHwZiVtj_JM|da}=cGuefErd+5x5JJfgs_r&KLY?a=c zXr4?H->_-UI;R7En-mK~#X9bC$}09Ky>EBb(%@e>!G$GtSMHKIR)tprI-44LBW^X# zb5@zHmQoa+sJ>oX@B!*L)~s?lAkMODQqI0B(etzgUlek9Z1T)q z0%~A+Z2HOhLhifNG|_Fc@WBpn^4PXtEw#~>4^`0iovDs?jx}nU$*uQ2#Z)bWDp-9d zJ0k2x8H>tIm76L|bxsbG&iXst{x@q1>o*Hj!S6e+Z&YN=W`A+gx zdZ5m-C1tjK{k}JDzutzb>t9(eAaK&G=*fu&{e3^2Cav|~%22tv&bi@4+f9LhoHH{F z8Bb5sot*Mn`qw9?S}w+kIggL`^GEEh+Nu&gKa25G+TXSYk8Pd8>TEeTHYENoD}80Z zeuap=H)!rS$5CPVf)25(4jVOtm$BsB+?4v`!^6UWA{(?FVnR?KR5O6xzdf% zmXYt?N*Uchb#VXn&7bq`oZMfz{Xtn?U|HP9yG@to9NKhe(WgC+s(-4AvM!z4n)>}@ z*D3judTpJ0hp>P$`8M}s^95}cY@}>jXIr+KzhipER2*XY=Ffo-FJB1%y!?dym-;)i z*6qT_8*g;|*m&d28kyk7CFu<9JyMn@OfxPlh}@jU`sU{5^fxy)Cd8FLkj^^xbD6qy zfPsRvLy5nc^S;b^yWZD4PEp?1n6pCYN16Kmmd|U|C-JUlo|u27q$B@}(-QSVKcAUz zdbly_X>|AmUf=1zg)VSCsrr7mTwE_kqTs=S#s?1)&Uo`l8nLYWaah1_mWzYZ17)To z%Nm*4`6LV&@_3CWGPd)}^YQZD-BbB_mT9(_Zj?##u^!LKYPCNew$E58W0-VgL*n5! zK3OigOYsXn9sjS*ufin6$jkJAyTdr^ipB(vkXd%MR?{{eH2LuQKl87@Ec`L0S)mLJ O3=E#GelF{r5}E+h<92rd literal 0 HcmV?d00001 diff --git a/libs/serialport/doc/images/terminal-example.png b/libs/serialport/doc/images/terminal-example.png new file mode 100644 index 0000000000000000000000000000000000000000..28aa366709c8e54968f54a75d4c3569e98c0cdc5 GIT binary patch literal 10918 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 Z-s3!Z`t&^?85kHCJYD@<);T3K0RVZhx)A^X literal 0 HcmV?d00001 diff --git a/libs/serialport/doc/qtserialport.qdocconf b/libs/serialport/doc/qtserialport.qdocconf new file mode 100644 index 0000000000..f095c2f18b --- /dev/null +++ b/libs/serialport/doc/qtserialport.qdocconf @@ -0,0 +1,37 @@ +include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) + +project = QtSerialPort +description = Qt Serial Port Reference Documentation +url = http://qt-project.org/doc/qt-$QT_VER/qtserialport +version = $QT_VERSION + +qhp.projects = QtSerialPort + +qhp.QtSerialPort.file = qtserialport.qhp +qhp.QtSerialPort.namespace = org.qt-project.qtserialport.$QT_VERSION_TAG +qhp.QtSerialPort.virtualFolder = qtserialport +qhp.QtSerialPort.indexTitle = Qt Serial Port +qhp.QtSerialPort.indexRoot = + +qhp.QtSerialPort.filterAttributes = qtserialport $QT_VERSION qtrefdoc +qhp.QtSerialPort.customFilters.Qt.name = QtSerialPort $QT_VERSION +qhp.QtSerialPort.customFilters.Qt.filterAttributes = qtserialport $QT_VERSION + +qhp.QtSerialPort.subprojects = classes examples + +qhp.QtSerialPort.subprojects.classes.title = C++ Classes +qhp.QtSerialPort.subprojects.classes.indexTitle = Qt Serial Port C++ Classes +qhp.QtSerialPort.subprojects.classes.selectors = class fake:headerfile +qhp.QtSerialPort.subprojects.classes.sortPages = true + +qhp.QtSerialPort.subprojects.examples.title = Examples +qhp.QtSerialPort.subprojects.examples.indexTitle = Qt Serial Port Examples +qhp.QtSerialPort.subprojects.examples.selectors = fake:example +qhp.QtSerialPort.subprojects.examples.sortPages = true + +headerdirs += .. +sourcedirs += .. +exampledirs += ../../../examples/serialport +imagedirs += images + +depends += qtcore qtdoc diff --git a/libs/serialport/doc/src/index.qdoc b/libs/serialport/doc/src/index.qdoc new file mode 100644 index 0000000000..ae5faebc96 --- /dev/null +++ b/libs/serialport/doc/src/index.qdoc @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2011 - 2012 Denis Shienkov +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtserialport-index.html + \title Qt Serial Port + \brief Provides API to make the serial programming simple and portable. + + Qt Serial Port provides the basic functionality, which includes + configuring, I/O operations, get and set control signals of the + RS-232 pinouts. + + The following are not supported by this module: + \list + \li Terminal features such as echo, control CR/LF, and so on. + \li Text mode. + \li Configuring timeouts and delays while reading. + \li Tracking and notification when the state of RS-232 pinout signals change. + \endlist + + To use these classes in your application, use the following include + statement: + + \code + #include + \endcode + + To link against the module, add this line to your \l qmake \c + .pro file: + + \code + QT += serialport + \endcode + + \section1 Related information + \list + \li \l{Qt Serial Port C++ Classes}{C++ Classes} + \li \l{Qt Serial Port Examples}{Examples} + \endlist + +*/ diff --git a/libs/serialport/doc/src/qtserialport-module.qdoc b/libs/serialport/doc/src/qtserialport-module.qdoc new file mode 100644 index 0000000000..b0fc506e52 --- /dev/null +++ b/libs/serialport/doc/src/qtserialport-module.qdoc @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2011 - 2012 Denis Shienkov +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \module QtSerialPort + \title Qt Serial Port C++ Classes + \brief List of C++ classes that enable access to a serial port. + + To use these classes in your application, use the following include + statement: + + \code + #include + \endcode + + To link against the module, add this line to your \l qmake \c + .pro file: + + \code + QT += serialport + \endcode +*/ diff --git a/libs/serialport/doc/style/style.css b/libs/serialport/doc/style/style.css new file mode 100644 index 0000000000..df84049f12 --- /dev/null +++ b/libs/serialport/doc/style/style.css @@ -0,0 +1,137 @@ +a:link, a:visited { + color: #00732F; + text-decoration: none; + font-weight: bold; +} + +body { + font: normal 400 14px/1.2 Arial; + margin-top: 85px; +} + +h1 { + margin: 0; +} + +h2 { + font: 500 20px/1.2 Arial; +} + +h3.fn, span.fn { + -moz-border-radius: 7px 7px 7px 7px; + -webkit-border-radius: 7px 7px 7px 7px; + border-radius: 7px 7px 7px 7px; + background-color: #F6F6F6; + border-width: 1px; + border-style: solid; + border-color: #E6E6E6; + word-spacing: 3px; + padding: 3px 5px; +} + +table, pre { + -moz-border-radius: 7px 7px 7px 7px; + -webkit-border-radius: 7px 7px 7px 7px; + border-radius: 7px 7px 7px 7px; + background-color: #F6F6F6; + border: 1px solid #E6E6E6; + border-collapse: separate; + font-size: 12px; + line-height: 1.2; + margin-bottom: 25px; + margin-left: 15px; +} + +table td { + padding: 3px 15px 3px 20px; +} + +table tr.even { + background-color: white; + color: #66666E; +} + +table tr.odd { + background-color: #F6F6F6; + color: #66666E; +} + +li { + margin-bottom: 10px; + padding-left: 12px; +} + +.cpp { + display: block; + margin: 10; + overflow: hidden; + overflow-x: hidden; + overflow-y: hidden; + padding: 20px 0 20px 0; +} + +.footer { + margin-top: 50px; +} + +.memItemLeft { + padding-right: 3px; +} + +.memItemRight { + padding: 3px 15px 3px 0; +} + +.qml { + display: block; + margin: 10; + overflow: hidden; + overflow-x: hidden; + overflow-y: hidden; + padding: 20px 0 20px 0; +} + +.qmldefault { + padding-left: 5px; + float: right; + color: red; +} + +.qmlreadonly { + padding-left: 5px; + float: right; + color: #254117; +} + +.rightAlign { + padding: 3px 5px 3px 10px; + text-align: right; +} + +.title { + background-color: white; + color: #44A51C; + font-family: Verdana; + font-size: 35px; + font-weight: normal; + left: 0; + padding-bottom: 5px; + padding-left: 16px; + padding-top: 20px; + position: absolute; + right: 0; + top: 0; +} + +.toc { + float: right; + -moz-border-radius: 7px 7px 7px 7px; + -webkit-border-radius: 7px 7px 7px 7px; + border-radius: 7px 7px 7px 7px; + background-color: #F6F6F6; + border: 1px solid #DDD; + margin: 0 20px 10px 10px; + padding: 20px 15px 20px 20px; + height: auto; + width: 200px; +} diff --git a/libs/serialport/qserialport.cpp b/libs/serialport/qserialport.cpp new file mode 100644 index 0000000000..96f06d4bd9 --- /dev/null +++ b/libs/serialport/qserialport.cpp @@ -0,0 +1,1167 @@ +/**************************************************************************** +** +** Copyright (C) 2011-2012 Denis Shienkov +** Copyright (C) 2011 Sergey Belyashov +** Copyright (C) 2012 Laszlo Papp +** Copyright (C) 2012 Andre Hartmann +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qserialport.h" +#include "qserialportinfo.h" + +#ifdef Q_OS_WIN +#include "qserialport_win_p.h" +#elif defined (Q_OS_SYMBIAN) +#include "qserialport_symbian_p.h" +#elif defined (Q_OS_UNIX) +#include "qserialport_unix_p.h" +#else +#error Unsupported OS +#endif + +#ifndef SERIALPORT_BUFFERSIZE +# define SERIALPORT_BUFFERSIZE 16384 +#endif + +QT_BEGIN_NAMESPACE + +QSerialPortPrivateData::QSerialPortPrivateData(QSerialPort *q) + : readBufferMaxSize(0) + , readBuffer(SERIALPORT_BUFFERSIZE) + , writeBuffer(SERIALPORT_BUFFERSIZE) + , error(QSerialPort::NoError) + , inputBaudRate(0) + , outputBaudRate(0) + , dataBits(QSerialPort::UnknownDataBits) + , parity(QSerialPort::UnknownParity) + , stopBits(QSerialPort::UnknownStopBits) + , flow(QSerialPort::UnknownFlowControl) + , policy(QSerialPort::IgnorePolicy) + , settingsRestoredOnClose(true) + , q_ptr(q) +{ +} + +int QSerialPortPrivateData::timeoutValue(int msecs, int elapsed) +{ + if (msecs == -1) + return msecs; + msecs -= elapsed; + return qMax(msecs, 0); +} + +/*! + \class QSerialPort + + \brief Provides functions to access serial ports. + + \reentrant + \ingroup serialport-main + \inmodule QtSerialPort + \since 5.1 + + You can get information about the available serial ports using the + QSerialPortInfo helper class, which allows an enumeration of all the serial + ports in the system. This is useful to obtain the correct name of the + serial port you want to use. You can pass an object + of the helper class as an argument to the setPort() or setPortName() + methods to assign the desired serial device. + + After setting the port, you can open it in read-only (r/o), write-only + (w/o), or read-write (r/w) mode using the open() method. + + \note The serial port is always opened with exclusive access + (that is, no other process or thread can access an already opened serial port). + + Having successfully opened, QSerialPort tries to determine the current + configuration of the port and initializes itself. You can reconfigure the + port to the desired setting using the setBaudRate(), setDataBits(), + setParity(), setStopBits(), and setFlowControl() methods. + + The status of the control pinout signals is determined with the + isDataTerminalReady(), isRequestToSend, and pinoutSignals() methods. To + change the control line status, use the setDataTerminalReady(), and + setRequestToSend() methods. + + Once you know that the ports are ready to read or write, you can + use the read() or write() methods. Alternatively the + readLine() and readAll() convenience methods can also be invoked. + If not all the data is read at once, the remaining data will + be available for later as new incoming data is appended to the + QSerialPort's internal read buffer. You can limit the size of the read + buffer using setReadBufferSize(). + + Use the close() method to close the port and cancel the I/O operations. + + See the following example: + + \code + int numRead = 0, numReadTotal = 0; + char buffer[50]; + + forever { + numRead = serial.read(buffer, 50); + + // Do whatever with the array + + numReadTotal += numRead; + if (numRead == 0 && !serial.waitForReadyRead()) + break; + } + \endcode + + If \l{QIODevice::}{waitForReadyRead()} returns false, the + connection has been closed or an error has occurred. + + Programming with a blocking serial port is radically different from + programming with a non-blocking serial port. A blocking serial port + does not require an event loop and typically leads to simpler code. + However, in a GUI application, blocking serial port should only be + used in non-GUI threads, to avoid freezing the user interface. + + For more details about these approaches, refer to the + \l {Examples}{example} applications. + + The QSerialPort class can also be used with QTextStream and QDataStream's + stream operators (operator<<() and operator>>()). There is one issue to be + aware of, though: make sure that enough data is available before attempting + to read by using the operator>>() overloaded operator. + + \sa QSerialPortInfo +*/ + +/*! + \enum QSerialPort::Direction + + This enum describes the possible directions of the data transmission. + + \note This enumeration is used for setting the baud rate of the device + separately for each direction on some operating systems (for example, + POSIX-like). + + \value Input Input direction. + \value Output Output direction. + \value AllDirections Simultaneously in two directions. +*/ + +/*! + \enum QSerialPort::BaudRate + + This enum describes the baud rate which the communication device operates + with. Note: only the most common standard baud rates are listed in this + enum. + + \value Baud1200 1200 baud. + \value Baud2400 2400 baud. + \value Baud4800 4800 baud. + \value Baud9600 9600 baud. + \value Baud19200 19200 baud. + \value Baud38400 38400 baud. + \value Baud57600 57600 baud. + \value Baud115200 115200 baud. + \value UnknownBaud Unknown baud. + + \sa QSerialPort::baudRate +*/ + +/*! + \enum QSerialPort::DataBits + + This enum describes the number of data bits used. + + \value Data5 Five bits. + \value Data6 Six bits. + \value Data7 Seven bits + \value Data8 Eight bits. + \value UnknownDataBits Unknown number of bits. + + \sa QSerialPort::dataBits +*/ + +/*! + \enum QSerialPort::Parity + + This enum describes the parity scheme used. + + \value NoParity No parity. + \value EvenParity Even parity. + \value OddParity Odd parity. + \value SpaceParity Space parity. + \value MarkParity Mark parity. + \value UnknownParity Unknown parity. + + \sa QSerialPort::parity +*/ + +/*! + \enum QSerialPort::StopBits + + This enum describes the number of stop bits used. + + \value OneStop 1 stop bit. + \value OneAndHalfStop 1.5 stop bits. + \value TwoStop 2 stop bits. + \value UnknownStopBits Unknown number of stop bit. + + \sa QSerialPort::stopBits +*/ + +/*! + \enum QSerialPort::FlowControl + + This enum describes the flow control used. + + \value NoFlowControl No flow control. + \value HardwareControl Hardware flow control (RTS/CTS). + \value SoftwareControl Software flow control (XON/XOFF). + \value UnknownFlowControl Unknown flow control. + + \sa QSerialPort::flowControl +*/ + +/*! + \enum QSerialPort::PinoutSignal + + This enum describes the possible RS-232 pinout signals. + + \value NoSignal No line active + \value TransmittedDataSignal TxD (Transmitted Data). + \value ReceivedDataSignal RxD (Received Data). + \value DataTerminalReadySignal DTR (Data Terminal Ready). + \value DataCarrierDetectSignal DCD (Data Carrier Detect). + \value DataSetReadySignal DSR (Data Set Ready). + \value RingIndicatorSignal RNG (Ring Indicator). + \value RequestToSendSignal RTS (Request To Send). + \value ClearToSendSignal CTS (Clear To Send). + \value SecondaryTransmittedDataSignal STD (Secondary Transmitted Data). + \value SecondaryReceivedDataSignal SRD (Secondary Received Data). + + \sa pinoutSignals(), QSerialPort::dataTerminalReady, + QSerialPort::requestToSend +*/ + +/*! + \enum QSerialPort::DataErrorPolicy + + This enum describes the policies for the received symbols + while parity errors were detected. + + \value SkipPolicy Skips the bad character. + \value PassZeroPolicy Replaces bad character to zero. + \value IgnorePolicy Ignores the error for a bad character. + \value StopReceivingPolicy Stops data reception on error. + \value UnknownPolicy Unknown policy. + + \sa QSerialPort::dataErrorPolicy +*/ + +/*! + \enum QSerialPort::SerialPortError + + This enum describes the errors that may be contained by the + QSerialPort::error property. + + \value NoError No error occurred. + \value DeviceNotFoundError An error occurred while attempting to + open an non-existing device. + \value PermissionError An error occurred while attempting to + open an already opened device by another process or a user not + having enough permission and credentials to open. + \value OpenError An error occurred while attempting to + open an already opened device in this object. + \value ParityError Parity error detected by the hardware while reading data. + \value FramingError Framing error detected by the hardware while reading data. + \value BreakConditionError Break condition detected by the hardware on + the input line. + \value WriteError An I/O error occurred while writing the data. + \value ReadError An I/O error occurred while reading the data. + \value ResourceError An I/O error occurred when a resource becomes unavailable, + e.g. when the device is unexpectedly removed from the system. + \value UnsupportedOperationError The requested device operation is + not supported or prohibited by the running operating system. + \value UnknownError An unidentified error occurred. + + \sa QSerialPort::error +*/ + + + +/*! + Constructs a new serial port object with the given \a parent. +*/ +QSerialPort::QSerialPort(QObject *parent) + : QIODevice(parent) + , d_ptr(new QSerialPortPrivate(this)) +{} + +/*! + Constructs a new serial port object with the given \a parent + to represent the serial port with the specified \a name. + + The name should have a specific format; see the setPort() method. +*/ +QSerialPort::QSerialPort(const QString &name, QObject *parent) + : QIODevice(parent) + , d_ptr(new QSerialPortPrivate(this)) +{ + setPortName(name); +} + +/*! + Constructs a new serial port object with the given \a parent + to represent the serial port with the specified helper class + \a serialPortInfo. +*/ +QSerialPort::QSerialPort(const QSerialPortInfo &serialPortInfo, QObject *parent) + : QIODevice(parent) + , d_ptr(new QSerialPortPrivate(this)) +{ + setPort(serialPortInfo); +} + +/*! + Closes the serial port, if necessary, and then destroys object. +*/ +QSerialPort::~QSerialPort() +{ + /**/ + close(); + delete d_ptr; +} + +/*! + Sets the \a name of the serial port. + + The name of the serial port can be passed on as either a short name or + the long system location if necessary. + + \sa portName(), QSerialPortInfo +*/ +void QSerialPort::setPortName(const QString &name) +{ + Q_D(QSerialPort); + d->systemLocation = QSerialPortPrivate::portNameToSystemLocation(name); +} + +/*! + Sets the port stored in the serial port info instance \a serialPortInfo. + + \sa portName(), QSerialPortInfo +*/ +void QSerialPort::setPort(const QSerialPortInfo &serialPortInfo) +{ + Q_D(QSerialPort); + d->systemLocation = QSerialPortPrivate::portNameToSystemLocation(serialPortInfo.systemLocation()); +} + +/*! + Returns the name set by setPort() or to the QSerialPort constructors. + This name is short, i.e. it extract and convert out from the internal + variable system location of the device. Conversion algorithm is + platform specific: + \table + \header + \li Platform + \li Brief Description + \row + \li Windows + \li Removes the prefix "\\\\.\\" from the system location + and returns the remainder of the string. + \row + \li Windows CE + \li Removes the postfix ":" from the system location + and returns the remainder of the string. + \row + \li Symbian + \li Returns the system location as it is, + as it is equivalent to the port name. + \row + \li GNU/Linux + \li Removes the prefix "/dev/" from the system location + and returns the remainder of the string. + \row + \li Mac OSX + \li Removes the prefix "/dev/cu." and "/dev/tty." from the + system location and returns the remainder of the string. + \row + \li Other *nix + \li The same as for GNU/Linux. + \endtable + + \sa setPort(), QSerialPortInfo::portName() +*/ +QString QSerialPort::portName() const +{ + Q_D(const QSerialPort); + return QSerialPortPrivate::portNameFromSystemLocation(d->systemLocation); +} + +/*! + \reimp + + Opens the serial port using OpenMode \a mode, and then returns true if + successful; otherwise returns false with and sets an error code which can be + obtained by calling the error() method. + + \warning The \a mode has to be QIODevice::ReadOnly, QIODevice::WriteOnly, + or QIODevice::ReadWrite. Other modes are unsupported. + + \sa QIODevice::OpenMode, setPort() +*/ +bool QSerialPort::open(OpenMode mode) +{ + Q_D(QSerialPort); + + if (isOpen()) { + setError(QSerialPort::OpenError); + return false; + } + + // Define while not supported modes. + static const OpenMode unsupportedModes = Append | Truncate | Text | Unbuffered; + if ((mode & unsupportedModes) || mode == NotOpen) { + setError(QSerialPort::UnsupportedOperationError); + return false; + } + + clearError(); + if (d->open(mode)) { + QIODevice::open(mode); + + d->dataTerminalReady = isDataTerminalReady(); + d->requestToSend = isRequestToSend(); + + return true; + } + return false; +} + +/*! + \reimp + + \sa QIODevice::close() +*/ +void QSerialPort::close() +{ + Q_D(QSerialPort); + if (!isOpen()) { + return; + } + + QIODevice::close(); + d->close(); +} + +/*! + \property QSerialPort::settingsRestoredOnClose + \brief the flag which allows to restore the previous settings while closing + the serial port. + + If this flag is true, the settings will be restored; otherwise not. + The default state of the QSerialPort class is configured to restore the + settings. +*/ +void QSerialPort::setSettingsRestoredOnClose(bool restore) +{ + Q_D(QSerialPort); + + if (d->settingsRestoredOnClose != restore) { + d->settingsRestoredOnClose = restore; + emit settingsRestoredOnCloseChanged(d->settingsRestoredOnClose); + } +} + +bool QSerialPort::settingsRestoredOnClose() const +{ + Q_D(const QSerialPort); + return d->settingsRestoredOnClose; +} + +/*! + \fn void QSerialPort::settingsRestoredOnCloseChanged(bool restore) + + This signal is emitted after the flag which allows to restore the + previous settings while closing the serial port has been changed. The new + flag which allows to restore the previous settings while closing the serial + port is passed as \a restore. + + \sa QSerialPort::settingsRestoredOnClose +*/ + +/*! + \property QSerialPort::baudRate + \brief the data baud rate for the desired direction + + If the setting is successful, returns true; otherwise returns false and sets + an error code which can be obtained by accessing the value of the + QSerialPort::error property. To set the baud rate, use the enumeration + QSerialPort::BaudRate or any positive qint32 value. + + \warning Only the AllDirections flag is support for setting this property on + Windows, Windows CE, and Symbian. + + \warning Returns equal baud rate in any direction on Windows, Windows CE, and + Symbian. +*/ +bool QSerialPort::setBaudRate(qint32 baudRate, Directions dir) +{ + Q_D(QSerialPort); + + if (d->setBaudRate(baudRate, dir)) { + if (dir & QSerialPort::Input) { + if (d->inputBaudRate != baudRate) + d->inputBaudRate = baudRate; + else + dir &= ~QSerialPort::Input; + } + + if (dir & QSerialPort::Output) { + if (d->outputBaudRate != baudRate) + d->outputBaudRate = baudRate; + else + dir &= ~QSerialPort::Output; + } + + if (dir) + emit baudRateChanged(baudRate, dir); + + return true; + } + + return false; +} + +qint32 QSerialPort::baudRate(Directions dir) const +{ + Q_D(const QSerialPort); + if (dir == QSerialPort::AllDirections) + return d->inputBaudRate == d->outputBaudRate ? + d->inputBaudRate : QSerialPort::UnknownBaud; + return dir & QSerialPort::Input ? d->inputBaudRate : d->outputBaudRate; +} + +/*! + \fn void QSerialPort::baudRateChanged(qint32 baudRate, Directions dir) + + This signal is emitted after the baud rate has been changed. The new baud + rate is passed as \a baudRate and directions as \a dir. + + \sa QSerialPort::baudRate +*/ + +/*! + \property QSerialPort::dataBits + \brief the data bits in a frame + + If the setting is successful, returns true; otherwise returns false and sets + an error code which can be obtained by accessing the value of the + QSerialPort::error property. +*/ +bool QSerialPort::setDataBits(DataBits dataBits) +{ + Q_D(QSerialPort); + + if (d->setDataBits(dataBits)) { + if (d->dataBits != dataBits) { + d->dataBits = dataBits; + emit dataBitsChanged(d->dataBits); + } + return true; + } + + return false; +} + +QSerialPort::DataBits QSerialPort::dataBits() const +{ + Q_D(const QSerialPort); + return d->dataBits; +} + +/*! + \fn void QSerialPort::dataBitsChanged(DataBits dataBits) + + This signal is emitted after the data bits in a frame has been changed. The + new data bits in a frame is passed as \a dataBits. + + \sa QSerialPort::dataBits +*/ + + +/*! + \property QSerialPort::parity + \brief the parity checking mode + + If the setting is successful, returns true; otherwise returns false and sets + an error code which can be obtained by accessing the value of the + QSerialPort::error property. +*/ +bool QSerialPort::setParity(Parity parity) +{ + Q_D(QSerialPort); + + if (d->setParity(parity)) { + if (d->parity != parity) { + d->parity = parity; + emit parityChanged(d->parity); + } + return true; + } + + return false; +} + +QSerialPort::Parity QSerialPort::parity() const +{ + Q_D(const QSerialPort); + return d->parity; +} + +/*! + \fn void QSerialPort::parityChanged(Parity parity) + + This signal is emitted after the parity checking mode has been changed. The + new parity checking mode is passed as \a parity. + + \sa QSerialPort::parity +*/ + +/*! + \property QSerialPort::stopBits + \brief the number of stop bits in a frame + + If the setting is successful, returns true; otherwise returns false and + sets an error code which can be obtained by accessing the value of the + QSerialPort::error property. +*/ +bool QSerialPort::setStopBits(StopBits stopBits) +{ + Q_D(QSerialPort); + + if (d->setStopBits(stopBits)) { + if (d->stopBits != stopBits) { + d->stopBits = stopBits; + emit stopBitsChanged(d->stopBits); + } + return true; + } + + return false; +} + +QSerialPort::StopBits QSerialPort::stopBits() const +{ + Q_D(const QSerialPort); + return d->stopBits; +} + +/*! + \fn void QSerialPort::stopBitsChanged(StopBits stopBits) + + This signal is emitted after the number of stop bits in a frame has been + changed. The new number of stop bits in a frame is passed as \a stopBits. + + \sa QSerialPort::stopBits +*/ + +/*! + \property QSerialPort::flowControl + \brief the desired flow control mode + + If the setting is successful, returns true; otherwise returns false and sets + an error code which can be obtained by accessing the value of the + QSerialPort::error property. +*/ +bool QSerialPort::setFlowControl(FlowControl flow) +{ + Q_D(QSerialPort); + + if (d->setFlowControl(flow)) { + if (d->flow != flow) { + d->flow = flow; + emit flowControlChanged(d->flow); + } + return true; + } + + return false; +} + +QSerialPort::FlowControl QSerialPort::flowControl() const +{ + Q_D(const QSerialPort); + return d->flow; +} + +/*! + \fn void QSerialPort::flowControlChanged(FlowControl flow) + + This signal is emitted after the flow control mode has been changed. The + new flow control mode is passed as \a flow. + + \sa QSerialPort::flowControl +*/ + +/*! + \property QSerialPort::dataTerminalReady + \brief the state (high or low) of the line signal DTR + + If the setting is successful, returns true; otherwise returns false. + If the flag is true then the DTR signal is set to high; otherwise low. + + \sa pinoutSignals() +*/ +bool QSerialPort::setDataTerminalReady(bool set) +{ + Q_D(QSerialPort); + + bool retval = d->setDataTerminalReady(set); + if (retval && (d->dataTerminalReady != set)) { + d->dataTerminalReady = set; + emit dataTerminalReadyChanged(set); + } + + return retval; +} + +bool QSerialPort::isDataTerminalReady() +{ + Q_D(const QSerialPort); + return d->pinoutSignals() & QSerialPort::DataTerminalReadySignal; +} + +/*! + \fn void QSerialPort::dataTerminalReadyChanged(bool set) + + This signal is emitted after the state (high or low) of the line signal DTR + has been changed. The new the state (high or low) of the line signal DTR is + passed as \a set. + + \sa QSerialPort::dataTerminalReady +*/ + +/*! + \property QSerialPort::requestToSend + \brief the state (high or low) of the line signal RTS + + If the setting is successful, returns true; otherwise returns false. + If the flag is true then the RTS signal is set to high; otherwise low. + + \sa pinoutSignals() +*/ +bool QSerialPort::setRequestToSend(bool set) +{ + Q_D(QSerialPort); + + bool retval = d->setRequestToSend(set); + if (retval && (d->requestToSend != set)) { + d->requestToSend = set; + emit requestToSendChanged(set); + } + + return retval; +} + +bool QSerialPort::isRequestToSend() +{ + Q_D(const QSerialPort); + return d->pinoutSignals() & QSerialPort::RequestToSendSignal; +} + +/*! + \fn void QSerialPort::requestToSendChanged(bool set) + + This signal is emitted after the state (high or low) of the line signal RTS + has been changed. The new the state (high or low) of the line signal RTS is + passed as \a set. + + \sa QSerialPort::requestToSend +*/ + +/*! + Returns the state of the line signals in a bitmap format. + + From this result, it is possible to allocate the state of the + desired signal by applying a mask "AND", where the mask is + the desired enumeration value from QSerialPort::PinoutSignals. + + Note that, this method performs a system call, thus ensuring that the line + signal states are returned properly. This is necessary when the underlying + operating systems cannot provide proper notifications about the changes. + + \sa isDataTerminalReady(), isRequestToSend, setDataTerminalReady(), + setRequestToSend() +*/ +QSerialPort::PinoutSignals QSerialPort::pinoutSignals() +{ + Q_D(const QSerialPort); + return d->pinoutSignals(); +} + +/*! + This function writes as much as possible from the internal write + buffer to the underlying serial port without blocking. If any data + was written, this function returns true; otherwise returns false. + + Call this function for sending the buffered data immediately to the serial + port. The number of bytes successfully written depends on the operating + system. In most cases, this function does not need to be called, because the + QSerialPort class will start sending data automatically once control is + returned to the event loop. In the absence of an event loop, call + waitForBytesWritten() instead. + + \sa write(), waitForBytesWritten() +*/ +bool QSerialPort::flush() +{ + Q_D(QSerialPort); + return d->flush(); +} + +/*! + Discards all characters from the output or input buffer, depending on + a given direction \a dir. Including clear an internal class buffers and + the UART (driver) buffers. Also terminate pending read or write operations. + If successful, returns true; otherwise returns false. +*/ +bool QSerialPort::clear(Directions dir) +{ + Q_D(QSerialPort); + if (dir & Input) + d->readBuffer.clear(); + if (dir & Output) + d->writeBuffer.clear(); + return d->clear(dir); +} + +/*! + \reimp + + Returns true if no more data is currently available for reading; otherwise + returns false. + + This function is most commonly used when reading data from the + serial port in a loop. For example: + + \code + // This slot is connected to QSerialPort::readyRead() + void QSerialPortClass::readyReadSlot() + { + while (!port.atEnd()) { + QByteArray data = port.read(100); + .... + } + } + \endcode + + \sa bytesAvailable(), readyRead() + */ +bool QSerialPort::atEnd() const +{ + Q_D(const QSerialPort); + return QIODevice::atEnd() && (!isOpen() || (d->bytesAvailable() == 0)); +} + +/*! + \property QSerialPort::dataErrorPolicy + \brief the error policy how the process receives the character in case of + parity error detection. + + If the setting is successful, returns true; otherwise returns false. The + default policy set is IgnorePolicy. +*/ +bool QSerialPort::setDataErrorPolicy(DataErrorPolicy policy) +{ + Q_D(QSerialPort); + + const bool ret = d->policy == policy || d->setDataErrorPolicy(policy); + if (ret && (d->policy != policy)) { + d->policy = policy; + emit dataErrorPolicyChanged(d->policy); + } + + return ret; +} + +QSerialPort::DataErrorPolicy QSerialPort::dataErrorPolicy() const +{ + Q_D(const QSerialPort); + return d->policy; +} + +/*! + \fn void QSerialPort::dataErrorPolicyChanged(DataErrorPolicy policy) + + This signal is emitted after the error policy how the process receives the + character in case of parity error detection has been changed. The new error + policy how the process receives the character in case of parity error + detection is passed as \a policy. + + \sa QSerialPort::dataErrorPolicy +*/ + +/*! + \property QSerialPort::error + \brief the error status of the serial port + + The I/O device status returns an error code. For example, if open() + returns false, or a read/write operation returns -1, this property can + be used to figure out the reason why the operation failed. + + The error code is set to the default QSerialPort::NoError after a call to + clearError() +*/ +QSerialPort::SerialPortError QSerialPort::error() const +{ + Q_D(const QSerialPort); + return d->error; +} + +void QSerialPort::clearError() +{ + setError(QSerialPort::NoError); +} + +/*! + \fn void QSerialPort::error(SerialPortError error) + + This signal is emitted after the error has been changed. The new erroris + passed as \a error. + + \sa QSerialPort::error +*/ + +/*! + Returns the size of the internal read buffer. This limits the + amount of data that the client can receive before calling the read() + or readAll() methods. + + A read buffer size of 0 (the default) means that the buffer has + no size limit, ensuring that no data is lost. + + \sa setReadBufferSize(), read() +*/ +qint64 QSerialPort::readBufferSize() const +{ + Q_D(const QSerialPort); + return d->readBufferMaxSize; +} + +/*! + Sets the size of QSerialPort's internal read buffer to be \a + size bytes. + + If the buffer size is limited to a certain size, QSerialPort + will not buffer more than this size of data. Exceptionally, a buffer + size of 0 means that the read buffer is unlimited and all + incoming data is buffered. This is the default. + + This option is useful if the data is only read at certain points + in time (for instance in a real-time streaming application) or if the serial + port should be protected against receiving too much data, which may + eventually causes that the application runs out of memory. + + \sa readBufferSize(), read() +*/ +void QSerialPort::setReadBufferSize(qint64 size) +{ + Q_D(QSerialPort); + + if (d->readBufferMaxSize == size) + return; + d->readBufferMaxSize = size; +} + +/*! + \reimp + + Always returns true. The serial port is a sequential device. +*/ +bool QSerialPort::isSequential() const +{ + return true; +} + +/*! + \reimp + + Returns the number of incoming bytes that are waiting to be read. + + \sa bytesToWrite(), read() +*/ +qint64 QSerialPort::bytesAvailable() const +{ + Q_D(const QSerialPort); + return d->bytesAvailable() + QIODevice::bytesAvailable(); +} + +/*! + \reimp + + Returns the number of bytes that are waiting to be written. The + bytes are written when control goes back to the event loop or + when flush() is called. + + \sa bytesAvailable(), flush() +*/ +qint64 QSerialPort::bytesToWrite() const +{ + Q_D(const QSerialPort); + return d->writeBuffer.size() + QIODevice::bytesToWrite(); +} + +/*! + \reimp + + Returns true if a line of data can be read from the serial port; + otherwise returns false. + + \sa readLine() +*/ +bool QSerialPort::canReadLine() const +{ + Q_D(const QSerialPort); + const bool hasLine = (d->bytesAvailable() > 0) && d->readBuffer.canReadLine(); + return hasLine || QIODevice::canReadLine(); +} + +/*! + \reimp + + This function blocks until new data is available for reading and the + \l{QIODevice::}{readyRead()} signal has been emitted. The function + will timeout after \a msecs milliseconds. + + The function returns true if the readyRead() signal is emitted and + there is new data available for reading; otherwise it returns false + (if an error occurred or the operation timed out). + + \sa waitForBytesWritten() +*/ +bool QSerialPort::waitForReadyRead(int msecs) +{ + Q_D(QSerialPort); + return d->waitForReadyRead(msecs); +} + +/*! + \reimp +*/ +bool QSerialPort::waitForBytesWritten(int msecs) +{ + Q_D(QSerialPort); + return d->waitForBytesWritten(msecs); +} + +/*! + Sends a continuous stream of zero bits during a specified period + of time \a duration in msec if the terminal is using asynchronous + serial data. If successful, returns true; otherwise returns false. + + If the duration is zero then zero bits are transmitted by at least + 0.25 seconds, but no more than 0.5 seconds. + + If the duration is non zero then zero bits are transmitted within a certain + period of time depending on the implementation. + + \sa setBreakEnabled() +*/ +bool QSerialPort::sendBreak(int duration) +{ + Q_D(QSerialPort); + return d->sendBreak(duration); +} + +/*! + Controls the signal break, depending on the flag \a set. + If successful, returns true; otherwise returns false. + + If \a set is true then enables the break transmission; otherwise disables. + + \sa sendBreak() +*/ +bool QSerialPort::setBreakEnabled(bool set) +{ + Q_D(QSerialPort); + return d->setBreakEnabled(set); +} + +/*! + \reimp +*/ +qint64 QSerialPort::readData(char *data, qint64 maxSize) +{ + Q_D(QSerialPort); + return d->readFromBuffer(data, maxSize); +} + +/*! + \reimp +*/ +qint64 QSerialPort::readLineData(char *data, qint64 maxSize) +{ + return QIODevice::readLineData(data, maxSize); +} + +/*! + \reimp +*/ +qint64 QSerialPort::writeData(const char *data, qint64 maxSize) +{ + Q_D(QSerialPort); + return d->writeToBuffer(data, maxSize); +} + +void QSerialPort::setError(QSerialPort::SerialPortError serialPortError, const QString &errorString) +{ + Q_D(QSerialPort); + + d->error = serialPortError; + + if (errorString.isNull()) + setErrorString(qt_error_string(-1)); + else + setErrorString(errorString); + + emit error(serialPortError); +} + +#include "moc_qserialport.cpp" + +QT_END_NAMESPACE diff --git a/libs/serialport/qserialport.h b/libs/serialport/qserialport.h new file mode 100644 index 0000000000..8a2842fe0d --- /dev/null +++ b/libs/serialport/qserialport.h @@ -0,0 +1,257 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Denis Shienkov +** Copyright (C) 2013 Laszlo Papp +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSERIALPORT_H +#define QSERIALPORT_H + +#include + +#include +//#include +QT_BEGIN_NAMESPACE + +class QSerialPortInfo; +class QSerialPortPrivate; + +class Q_SERIALPORT_EXPORT QSerialPort : public QIODevice +{ + Q_OBJECT + + Q_PROPERTY(qint32 baudRate READ baudRate WRITE setBaudRate NOTIFY baudRateChanged) + Q_PROPERTY(DataBits dataBits READ dataBits WRITE setDataBits NOTIFY dataBitsChanged) + Q_PROPERTY(Parity parity READ parity WRITE setParity NOTIFY parityChanged) + Q_PROPERTY(StopBits stopBits READ stopBits WRITE setStopBits NOTIFY stopBitsChanged) + Q_PROPERTY(FlowControl flowControl READ flowControl WRITE setFlowControl NOTIFY flowControlChanged) + Q_PROPERTY(DataErrorPolicy dataErrorPolicy READ dataErrorPolicy WRITE setDataErrorPolicy NOTIFY dataErrorPolicyChanged) + Q_PROPERTY(bool dataTerminalReady READ isDataTerminalReady WRITE setDataTerminalReady NOTIFY dataTerminalReadyChanged) + Q_PROPERTY(bool requestToSend READ isRequestToSend WRITE setRequestToSend NOTIFY requestToSendChanged) + Q_PROPERTY(SerialPortError error READ error RESET clearError NOTIFY error) + Q_PROPERTY(bool settingsRestoredOnClose READ settingsRestoredOnClose WRITE setSettingsRestoredOnClose NOTIFY settingsRestoredOnCloseChanged) + + Q_ENUMS( Directions Rate DataBits Parity StopBits FlowControl PinoutSignals DataErrorPolicy SerialPortError ) + +public: + + enum Direction { + Input = 1, + Output = 2, + AllDirections = Input | Output + }; + Q_DECLARE_FLAGS(Directions, Direction) + + enum BaudRate { + Baud1200 = 1200, + Baud2400 = 2400, + Baud4800 = 4800, + Baud9600 = 9600, + Baud19200 = 19200, + Baud38400 = 38400, + Baud57600 = 57600, + Baud115200 = 115200, + UnknownBaud = -1 + }; + + enum DataBits { + Data5 = 5, + Data6 = 6, + Data7 = 7, + Data8 = 8, + UnknownDataBits = -1 + }; + + enum Parity { + NoParity = 0, + EvenParity = 2, + OddParity = 3, + SpaceParity = 4, + MarkParity = 5, + UnknownParity = -1 + }; + + enum StopBits { + OneStop = 1, + OneAndHalfStop = 3, + TwoStop = 2, + UnknownStopBits = -1 + }; + + enum FlowControl { + NoFlowControl, + HardwareControl, + SoftwareControl, + UnknownFlowControl = -1 + }; + + enum PinoutSignal { + NoSignal = 0x00, + TransmittedDataSignal = 0x01, + ReceivedDataSignal = 0x02, + DataTerminalReadySignal = 0x04, + DataCarrierDetectSignal = 0x08, + DataSetReadySignal = 0x10, + RingIndicatorSignal = 0x20, + RequestToSendSignal = 0x40, + ClearToSendSignal = 0x80, + SecondaryTransmittedDataSignal = 0x100, + SecondaryReceivedDataSignal = 0x200 + }; + Q_DECLARE_FLAGS(PinoutSignals, PinoutSignal) + + enum DataErrorPolicy { + SkipPolicy, + PassZeroPolicy, + IgnorePolicy, + StopReceivingPolicy, + UnknownPolicy = -1 + }; + + enum SerialPortError { + NoError, + DeviceNotFoundError, + PermissionError, + OpenError, + ParityError, + FramingError, + BreakConditionError, + WriteError, + ReadError, + ResourceError, + UnsupportedOperationError, + UnknownError + }; + + explicit QSerialPort(QObject *parent = 0); + explicit QSerialPort(const QString &name, QObject *parent = 0); + explicit QSerialPort(const QSerialPortInfo &info, QObject *parent = 0); + virtual ~QSerialPort(); + + void setPortName(const QString &name); + QString portName() const; + + void setPort(const QSerialPortInfo &info); + + bool open(OpenMode mode) Q_DECL_OVERRIDE; + void close() Q_DECL_OVERRIDE; + + void setSettingsRestoredOnClose(bool restore); + bool settingsRestoredOnClose() const; + + bool setBaudRate(qint32 baudRate, Directions dir = AllDirections); + qint32 baudRate(Directions dir = AllDirections) const; + + bool setDataBits(DataBits dataBits); + DataBits dataBits() const; + + bool setParity(Parity parity); + Parity parity() const; + + bool setStopBits(StopBits stopBits); + StopBits stopBits() const; + + bool setFlowControl(FlowControl flow); + FlowControl flowControl() const; + + bool setDataTerminalReady(bool set); + bool isDataTerminalReady(); + + bool setRequestToSend(bool set); + bool isRequestToSend(); + + PinoutSignals pinoutSignals(); + + bool flush(); + bool clear(Directions dir = AllDirections); + bool atEnd() const Q_DECL_OVERRIDE; + + bool setDataErrorPolicy(DataErrorPolicy policy = IgnorePolicy); + DataErrorPolicy dataErrorPolicy() const; + + SerialPortError error() const; + void clearError(); + + qint64 readBufferSize() const; + void setReadBufferSize(qint64 size); + + bool isSequential() const Q_DECL_OVERRIDE; + + qint64 bytesAvailable() const Q_DECL_OVERRIDE; + qint64 bytesToWrite() const Q_DECL_OVERRIDE; + bool canReadLine() const Q_DECL_OVERRIDE; + + bool waitForReadyRead(int msecs) Q_DECL_OVERRIDE; + bool waitForBytesWritten(int msecs) Q_DECL_OVERRIDE; + + bool sendBreak(int duration = 0); + bool setBreakEnabled(bool set = true); + +Q_SIGNALS: + void baudRateChanged(qint32 baudRate, QSerialPort::Directions dir); + void dataBitsChanged(QSerialPort::DataBits dataBits); + void parityChanged(QSerialPort::Parity parity); + void stopBitsChanged(QSerialPort::StopBits stopBits); + void flowControlChanged(QSerialPort::FlowControl flow); + void dataErrorPolicyChanged(QSerialPort::DataErrorPolicy policy); + void dataTerminalReadyChanged(bool set); + void requestToSendChanged(bool set); + void error(QSerialPort::SerialPortError serialPortError); + void settingsRestoredOnCloseChanged(bool restore); + +protected: + qint64 readData(char *data, qint64 maxSize) Q_DECL_OVERRIDE; + qint64 readLineData(char *data, qint64 maxSize) Q_DECL_OVERRIDE; + qint64 writeData(const char *data, qint64 maxSize) Q_DECL_OVERRIDE; + +private: + void setError(QSerialPort::SerialPortError error, const QString &errorString = QString()); + + QSerialPortPrivate * const d_ptr; + + Q_DECLARE_PRIVATE(QSerialPort) + Q_DISABLE_COPY(QSerialPort) +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QSerialPort::Directions) +Q_DECLARE_OPERATORS_FOR_FLAGS(QSerialPort::PinoutSignals) + +QT_END_NAMESPACE + +#endif // QSERIALPORT_H diff --git a/libs/serialport/qserialport_p.h b/libs/serialport/qserialport_p.h new file mode 100644 index 0000000000..abd9cb633d --- /dev/null +++ b/libs/serialport/qserialport_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2011-2012 Denis Shienkov +** Copyright (C) 2011 Sergey Belyashov +** Copyright (C) 2012 Laszlo Papp +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSERIALPORT_P_H +#define QSERIALPORT_P_H + +#include "qserialport.h" + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) +#include +#else +#include "qt4support/qringbuffer_p.h" +#endif + +QT_BEGIN_NAMESPACE + +class QSerialPortPrivateData +{ + Q_DECLARE_PUBLIC(QSerialPort) +public: + enum IoConstants { + ReadChunkSize = 512, + WriteChunkSize = 512 + }; + + QSerialPortPrivateData(QSerialPort *q); + int timeoutValue(int msecs, int elapsed); + + qint64 readBufferMaxSize; + QRingBuffer readBuffer; + QRingBuffer writeBuffer; + QSerialPort::SerialPortError error; + QString systemLocation; + qint32 inputBaudRate; + qint32 outputBaudRate; + QSerialPort::DataBits dataBits; + QSerialPort::Parity parity; + QSerialPort::StopBits stopBits; + QSerialPort::FlowControl flow; + QSerialPort::DataErrorPolicy policy; + bool dataTerminalReady; + bool requestToSend; + bool settingsRestoredOnClose; + QSerialPort * const q_ptr; +}; + +QT_END_NAMESPACE + +#endif // QSERIALPORT_P_H diff --git a/libs/serialport/qserialport_symbian.cpp b/libs/serialport/qserialport_symbian.cpp new file mode 100644 index 0000000000..2bba5a4d86 --- /dev/null +++ b/libs/serialport/qserialport_symbian.cpp @@ -0,0 +1,645 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Denis Shienkov +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qserialport_symbian_p.h" + +#include + +#include +//#include +#include + +QT_BEGIN_NAMESPACE + +// Physical device driver. +#ifdef __WINS__ +_LIT(KPddName, "ECDRV"); +#else // defined (__EPOC32__) +_LIT(KPddName, "EUART"); +#endif + +// Logical device driver. +_LIT(KLddName,"ECOMM"); + +// Modules names. +_LIT(KRS232ModuleName, "ECUART"); +_LIT(KBluetoothModuleName, "BTCOMM"); +_LIT(KInfraRedModuleName, "IRCOMM"); +_LIT(KACMModuleName, "ECACM"); + +// Return false on error load. +static bool loadDevices() +{ + TInt r = KErrNone; +#ifdef __WINS__ + RFs fileServer; + r = User::LeaveIfError(fileServer.Connect()); + if (r != KErrNone) + return false; + fileServer.Close (); +#endif + + r = User::LoadPhysicalDevice(KPddName); + if (r != KErrNone && r != KErrAlreadyExists) + return false; //User::Leave(r); + + r = User::LoadLogicalDevice(KLddName); + if (r != KErrNone && r != KErrAlreadyExists) + return false; //User::Leave(r); + +#ifndef __WINS__ + r = StartC32(); + if (r != KErrNone && r != KErrAlreadyExists) + return false; //User::Leave(r); +#endif + + return true; +} + +QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) + : QSerialPortPrivateData(q) + , errnum(KErrNone) +{ +} + +bool QSerialPortPrivate::open(QIODevice::OpenMode mode) +{ + // FIXME: Maybe need added check an ReadWrite open mode? + Q_UNUSED(mode) + + if (!loadDevices()) { + q_ptr->setError(QSerialPort::UnknownError); + return false; + } + + RCommServ server; + errnum = server.Connect(); + if (errnum != KErrNone) { + q_ptr->setError(decodeSystemError()); + return false; + } + + if (systemLocation.contains("BTCOMM")) + errnum = server.LoadCommModule(KBluetoothModuleName); + else if (systemLocation.contains("IRCOMM")) + errnum = server.LoadCommModule(KInfraRedModuleName); + else if (systemLocation.contains("ACM")) + errnum = server.LoadCommModule(KACMModuleName); + else + errnum = server.LoadCommModule(KRS232ModuleName); + + if (errnum != KErrNone) { + q_ptr->setError(decodeSystemError()); + return false; + } + + // In Symbian OS port opening only in R/W mode? + TPtrC portName(static_cast(systemLocation.utf16()), systemLocation.length()); + errnum = descriptor.Open(server, portName, ECommExclusive); + + if (errnum != KErrNone) { + q_ptr->setError(decodeSystemError()); + return false; + } + + // Save current port settings. + errnum = descriptor.Config(restoredSettings); + if (errnum != KErrNone) { + q_ptr->setError(decodeSystemError()); + return false; + } + + detectDefaultSettings(); + return true; +} + +void QSerialPortPrivate::close() +{ + if (settingsRestoredOnClose) + descriptor.SetConfig(restoredSettings); + descriptor.Close(); +} + +QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals() const +{ + QSerialPort::PinoutSignals ret = QSerialPort::NoSignal; + + TUint signalMask = 0; + descriptor.Signals(signalMask); + + if (signalMask & KSignalCTS) + ret |= QSerialPort::ClearToSendSignal; + if (signalMask & KSignalDSR) + ret |= QSerialPort::DataSetReadySignal; + if (signalMask & KSignalDCD) + ret |= QSerialPort::DataCarrierDetectSignal; + if (signalMask & KSignalRNG) + ret |= QSerialPort::RingIndicatorSignal; + if (signalMask & KSignalRTS) + ret |= QSerialPort::RequestToSendSignal; + if (signalMask & KSignalDTR) + ret |= QSerialPort::DataTerminalReadySignal; + + //if (signalMask & KSignalBreak) + // ret |= + return ret; +} + +bool QSerialPortPrivate::setDataTerminalReady(bool set) +{ + TInt r; + if (set) + r = descriptor.SetSignalsToMark(KSignalDTR); + else + r = descriptor.SetSignalsToSpace(KSignalDTR); + + return r == KErrNone; +} + +bool QSerialPortPrivate::setRequestToSend(bool set) +{ + TInt r; + if (set) + r = descriptor.SetSignalsToMark(KSignalRTS); + else + r = descriptor.SetSignalsToSpace(KSignalRTS); + + return r == KErrNone; +} + +bool QSerialPortPrivate::flush() +{ + // TODO: Implement me + return false; +} + +bool QSerialPortPrivate::clear(QSerialPort::Directions dir) +{ + TUint flags = 0; + if (dir & QSerialPort::Input) + flags |= KCommResetRx; + if (dir & QSerialPort::Output) + flags |= KCommResetTx; + TInt r = descriptor.ResetBuffers(flags); + return r == KErrNone; +} + +bool QSerialPortPrivate::sendBreak(int duration) +{ + TRequestStatus status; + descriptor.Break(status, TTimeIntervalMicroSeconds32(duration * 1000)); + return false; +} + +bool QSerialPortPrivate::setBreakEnabled(bool set) +{ + // TODO: Implement me + return false; +} + +qint64 QSerialPortPrivate::systemInputQueueSize () const +{ + return descriptor.QueryReceiveBuffer(); +} + +qint64 QSerialPortPrivate::systemOutputQueueSize () const +{ + // TODO: Implement me + return 0; +} + +qint64 QSerialPortPrivate::bytesAvailable() const +{ + return readBuffer.size(); +} + +qint64 QSerialPortPrivate::readFromBuffer(char *data, qint64 maxSize) +{ + // TODO: Implement me + return -1; +} + +qint64 QSerialPortPrivate::writeToBuffer(const char *data, qint64 maxSize) +{ + // TODO: Implement me + return -1; +} + +bool QSerialPortPrivate::waitForReadyRead(int msec) +{ + // TODO: Implement me + return false; +} + +bool QSerialPortPrivate::waitForBytesWritten(int msec) +{ + // TODO: Implement me + return false; +} + +bool QSerialPortPrivate::setBaudRate(qint32 baudRate, QSerialPort::Directions dir) +{ + if (dir != QSerialPort::AllDirections) { + q_ptr->setError(QSerialPort::UnsupportedOperationError); + return false; + } + + baudRate = settingFromBaudRate(baudRate); + if (baudRate) + currentSettings().iRate = static_cast(baudRate); + else { + q_ptr->setError(QSerialPort::UnsupportedOperationError); + return false; + } + + return updateCommConfig(); +} + +bool QSerialPortPrivate::setDataBits(QSerialPort::DataBits dataBits) +{ + switch (dataBits) { + case QSerialPort::Data5: + currentSettings().iDataBits = EData5; + break; + case QSerialPort::Data6: + currentSettings().iDataBits = EData6; + break; + case QSerialPort::Data7: + currentSettings().iDataBits = EData7; + break; + case QSerialPort::Data8: + currentSettings().iDataBits = EData8; + break; + default: + currentSettings().iDataBits = EData8; + break; + } + + return updateCommConfig(); +} + +bool QSerialPortPrivate::setParity(QSerialPort::Parity parity) +{ + switch (parity) { + case QSerialPort::NoParity: + currentSettings().iParity = EParityNone; + break; + case QSerialPort::EvenParity: + currentSettings().iParity = EParityEven; + break; + case QSerialPort::OddParity: + currentSettings().iParity = EParityOdd; + break; + case QSerialPort::MarkParity: + currentSettings().iParity = EParityMark; + break; + case QSerialPort::SpaceParity: + currentSettings().iParity = EParitySpace; + break; + default: + currentSettings().iParity = EParityNone; + break; + } + + return updateCommConfig(); +} + +bool QSerialPortPrivate::setStopBits(QSerialPort::StopBits stopBits) +{ + switch (stopBits) { + case QSerialPort::OneStop: + currentSettings().iStopBits = EStop1; + break; + case QSerialPort::TwoStop: + currentSettings().iStopBits = EStop2; + break; + default: + currentSettings().iStopBits = EStop1; + break; + } + + return updateCommConfig(); +} + +bool QSerialPortPrivate::setFlowControl(QSerialPort::FlowControl flow) +{ + switch (flow) { + case QSerialPort::NoFlowControl: + currentSettings().iHandshake = KConfigFailDSR; + break; + case QSerialPort::HardwareControl: + currentSettings().iHandshake = KConfigObeyCTS | KConfigFreeRTS; + break; + case QSerialPort::SoftwareControl: + currentSettings().iHandshake = KConfigObeyXoff | KConfigSendXoff; + break; + default: + currentSettings().iHandshake = KConfigFailDSR; + break; + } + + return updateCommConfig(); +} + +bool QSerialPortPrivate::setDataErrorPolicy(QSerialPort::DataErrorPolicy policy) +{ + // TODO: Implement me + return false; +} + +bool QSerialPortPrivate::notifyRead() +{ + // TODO: Implement me + return false; +} + +bool QSerialPortPrivate::notifyWrite() +{ + // TODO: Implement me + return false; +} + +bool QSerialPortPrivate::updateCommConfig() +{ + if (descriptor.SetConfig(currentSettings) != KErrNone) { + q_ptr->setError(QSerialPort::UnsupportedOperationError); + return false; + } + return true; +} + +void QSerialPortPrivate::detectDefaultSettings() +{ + // Detect baud rate. + inputBaudRate = baudRateFromSetting(currentSettings().iRate); + outputBaudRate = inputBaudRate; + + // Detect databits. + switch (currentSettings().iDataBits) { + case EData5: + dataBits = QSerialPort::Data5; + break; + case EData6: + dataBits = QSerialPort::Data6; + break; + case EData7: + dataBits = QSerialPort::Data7; + break; + case EData8: + dataBits = QSerialPort::Data8; + break; + default: + dataBits = QSerialPort::UnknownDataBits; + break; + } + + // Detect parity. + switch (currentSettings().iParity) { + case EParityNone: + parity = QSerialPort::NoParity; + break; + case EParityEven: + parity = QSerialPort::EvenParity; + break; + case EParityOdd: + parity = QSerialPort::OddParity; + break; + case EParityMark: + parity = QSerialPort::MarkParity; + break; + case EParitySpace: + parity = QSerialPort::SpaceParity; + break; + default: + parity = QSerialPort::UnknownParity; + break; + } + + // Detect stopbits. + switch (currentSettings().iStopBits) { + case EStop1: + stopBits = QSerialPort::OneStop; + break; + case EStop2: + stopBits = QSerialPort::TwoStop; + break; + default: + stopBits = QSerialPort::UnknownStopBits; + break; + } + + // Detect flow control. + if ((currentSettings().iHandshake & (KConfigObeyXoff | KConfigSendXoff)) + == (KConfigObeyXoff | KConfigSendXoff)) + flow = QSerialPort::SoftwareControl; + else if ((currentSettings().iHandshake & (KConfigObeyCTS | KConfigFreeRTS)) + == (KConfigObeyCTS | KConfigFreeRTS)) + flow = QSerialPort::HardwareControl; + else if (currentSettings().iHandshake & KConfigFailDSR) + flow = QSerialPort::NoFlowControl; + else + flow = QSerialPort::UnknownFlowControl; +} + +QSerialPort::SerialPortError QSerialPortPrivate::decodeSystemError() const +{ + QSerialPort::SerialPortError error; + switch (errnum) { + case KErrPermissionDenied: + error = QSerialPort::DeviceNotFoundError; + break; + case KErrLocked: + error = QSerialPort::PermissionError; + break; + case KErrAccessDenied: + error = QSerialPort::PermissionError; + break; + default: + error = QSerialPort::UnknownError; + break; + } + return error; +} + +bool QSerialPortPrivate::waitForReadOrWrite(bool *selectForRead, bool *selectForWrite, + bool checkRead, bool checkWrite, + int msecs, bool *timedOut) +{ + + // FIXME: I'm not sure in implementation this method. + // Someone needs to check and correct. + + TRequestStatus timerStatus; + TRequestStatus readStatus; + TRequestStatus writeStatus; + + if (msecs > 0) { + if (!selectTimer.Handle()) { + if (selectTimer.CreateLocal() != KErrNone) + return false; + } + selectTimer.HighRes(timerStatus, msecs * 1000); + } + + if (checkRead) + descriptor.NotifyDataAvailable(readStatus); + + if (checkWrite) + descriptor.NotifyOutputEmpty(writeStatus); + + enum { STATUSES_COUNT = 3 }; + TRequestStatus *statuses[STATUSES_COUNT]; + TInt num = 0; + statuses[num++] = &timerStatus; + statuses[num++] = &readStatus; + statuses[num++] = &writeStatus; + + User::WaitForNRequest(statuses, num); + + bool result = false; + + // By timeout? + if (timerStatus != KRequestPending) { + Q_ASSERT(selectForRead); + *selectForRead = false; + Q_ASSERT(selectForWrite); + *selectForWrite = false; + } else { + selectTimer.Cancel(); + User::WaitForRequest(timerStatus); + + // By read? + if (readStatus != KRequestPending) { + Q_ASSERT(selectForRead); + *selectForRead = true; + } + + // By write? + if (writeStatus != KRequestPending) { + Q_ASSERT(selectForWrite); + *selectForWrite = true; + } + + if (checkRead) + descriptor.NotifyDataAvailableCancel(); + if (checkWrite) + descriptor.NotifyOutputEmptyCancel(); + + result = true; + } + return result; +} + +QString QSerialPortPrivate::portNameToSystemLocation(const QString &port) +{ + // Port name is equval to port systemLocation. + return port; +} + +QString QSerialPortPrivate::portNameFromSystemLocation(const QString &location) +{ + // Port name is equval to port systemLocation. + return location; +} + +typedef QMap BaudRateMap; + +// This table contains correspondences standard pairs values of +// baud rates that are defined in files +// - d32comm.h for Symbian^3 +// - d32public.h for Symbian SR1 + +static const BaudRateMap createStandardBaudRateMap() +{ + BaudRateMap baudRateMap; + + baudRateMap.insert(50, EBps50) + baudRateMap.insert(75, EBps75) + baudRateMap.insert(110, EBps110) + baudRateMap.insert(134, EBps134) + baudRateMap.insert(150, EBps150) + baudRateMap.insert(300, EBps300) + baudRateMap.insert(600, EBps600) + baudRateMap.insert(1200, EBps1200) + baudRateMap.insert(1800, EBps1800) + baudRateMap.insert(2000, EBps2000) + baudRateMap.insert(2400, EBps2400) + baudRateMap.insert(3600, EBps3600) + baudRateMap.insert(4800, EBps4800) + baudRateMap.insert(7200, EBps7200) + baudRateMap.insert(9600, EBps9600) + baudRateMap.insert(19200, EBps19200) + baudRateMap.insert(38400, EBps38400) + baudRateMap.insert(57600, EBps57600) + baudRateMap.insert(115200, EBps115200) + baudRateMap.insert(230400, EBps230400) + baudRateMap.insert(460800, EBps460800) + baudRateMap.insert(576000, EBps576000) + baudRateMap.insert(921600, EBps921600) + baudRateMap.insert(1152000, EBps1152000) + // << baudRateMap.insert(1843200, EBps1843200) only for Symbian SR1 + baudRateMap.insert(4000000, EBps4000000); + + return baudRateMap; +} + +static const BaudRateMap& standardBaudRateMap() +{ + static const BaudRateMap baudRateMap = createStandardBaudRateMap(); + return baudRateMap; +} + +qint32 QSerialPortPrivate::baudRateFromSetting(qint32 setting) +{ + return standardBaudRateMap().key(setting); +} + +qint32 QSerialPortPrivate::settingFromBaudRate(qint32 baudRate) +{ + return standardBaudRateMap().value(baudRate); +} + +QList QSerialPortPrivate::standardBaudRates() +{ + return standardBaudRateMap().keys(); +} + +QT_END_NAMESPACE diff --git a/libs/serialport/qserialport_symbian_p.h b/libs/serialport/qserialport_symbian_p.h new file mode 100644 index 0000000000..7f9eaddd3e --- /dev/null +++ b/libs/serialport/qserialport_symbian_p.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Denis Shienkov +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSERIALPORT_SYMBIAN_P_H +#define QSERIALPORT_SYMBIAN_P_H + +#include "qserialport_p.h" + +#include + +QT_BEGIN_NAMESPACE + +class QSerialPortPrivate : public QSerialPortPrivateData +{ +public: + QSerialPortPrivate(QSerialPort *q); + + bool open(QIODevice::OpenMode mode); + void close(); + + QSerialPort::PinoutSignals pinoutSignals() const; + + bool setDataTerminalReady(bool set); + bool setRequestToSend(bool set); + + bool flush(); + bool clear(QSerialPort::Directions dir); + + bool sendBreak(int duration); + bool setBreakEnabled(bool set); + + qint64 systemInputQueueSize () const; + qint64 systemOutputQueueSize () const; + + qint64 bytesAvailable() const; + + qint64 readFromBuffer(char *data, qint64 maxSize); + qint64 writeToBuffer(const char *data, qint64 maxSize); + + bool waitForReadyRead(int msec); + bool waitForBytesWritten(int msec); + + bool setBaudRate(qint32 baudRate, QSerialPort::Directions dir); + bool setDataBits(QSerialPort::DataBits dataBits); + bool setParity(QSerialPort::Parity parity); + bool setStopBits(QSerialPort::StopBits stopBits); + bool setFlowControl(QSerialPort::FlowControl flowControl); + bool setDataErrorPolicy(QSerialPort::DataErrorPolicy policy); + + bool notifyRead(); + bool notifyWrite(); + + static QString portNameToSystemLocation(const QString &port); + static QString portNameFromSystemLocation(const QString &location); + + static qint32 baudRateFromSetting(qint32 setting); + static qint32 settingFromBaudRate(qint32 baudRate); + + static QList standardBaudRates(); + + TCommConfig currentSettings; + TCommConfig restoredSettings; + RComm descriptor; + mutable RTimer selectTimer; + TInt errnum; + +private: + bool updateCommConfig(); + + void detectDefaultSettings(); + QSerialPort::SerialPortError decodeSystemError() const; + + bool waitForReadOrWrite(bool *selectForRead, bool *selectForWrite, + bool checkRead, bool checkWrite, + int msecs, bool *timedOut); +}; + +QT_END_NAMESPACE + +#endif // QSERIALPORT_SYMBIAN_P_H diff --git a/libs/serialport/qserialport_unix.cpp b/libs/serialport/qserialport_unix.cpp new file mode 100644 index 0000000000..2f6c8ccbaf --- /dev/null +++ b/libs/serialport/qserialport_unix.cpp @@ -0,0 +1,1343 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Denis Shienkov +** Copyright (C) 2012 Laszlo Papp +** Copyright (C) 2012 Andre Hartmann +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qserialport_unix_p.h" +#include "qttylocker_unix_p.h" + +#include +#include +#include +#include +#include + +#ifdef Q_OS_MAC +#if defined (MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) +#include +#endif +#endif + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class ReadNotifier : public QSocketNotifier +{ +public: + ReadNotifier(QSerialPortPrivate *d, QObject *parent) + : QSocketNotifier(d->descriptor, QSocketNotifier::Read, parent) + , dptr(d) + {} + +protected: + bool event(QEvent *e) Q_DECL_OVERRIDE { + bool ret = QSocketNotifier::event(e); + if (ret) + dptr->readNotification(); + return ret; + } + +private: + QSerialPortPrivate *dptr; +}; + +class WriteNotifier : public QSocketNotifier +{ +public: + WriteNotifier(QSerialPortPrivate *d, QObject *parent) + : QSocketNotifier(d->descriptor, QSocketNotifier::Write, parent) + , dptr(d) + {} + +protected: + bool event(QEvent *e) Q_DECL_OVERRIDE { + bool ret = QSocketNotifier::event(e); + if (ret) + dptr->writeNotification(QSerialPortPrivateData::WriteChunkSize); + return ret; + } + +private: + QSerialPortPrivate *dptr; +}; + +class ExceptionNotifier : public QSocketNotifier +{ +public: + ExceptionNotifier(QSerialPortPrivate *d, QObject *parent) + : QSocketNotifier(d->descriptor, QSocketNotifier::Exception, parent) + , dptr(d) + {} + +protected: + bool event(QEvent *e) Q_DECL_OVERRIDE { + bool ret = QSocketNotifier::event(e); + if (ret) + dptr->exceptionNotification(); + return ret; + } + +private: + QSerialPortPrivate *dptr; +}; + +QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) + : QSerialPortPrivateData(q) + , descriptor(-1) + , isCustomBaudRateSupported(false) + , readNotifier(0) + , writeNotifier(0) + , exceptionNotifier(0) + , readPortNotifierCalled(false) + , readPortNotifierState(false) + , readPortNotifierStateSet(false) + , emittedReadyRead(false) + , emittedBytesWritten(false) +{ +} + +bool QSerialPortPrivate::open(QIODevice::OpenMode mode) +{ + QByteArray portName = portNameFromSystemLocation(systemLocation).toLocal8Bit(); + const char *ptr = portName.constData(); + + bool byCurrPid = false; + if (QTtyLocker::isLocked(ptr, &byCurrPid)) { + q_ptr->setError(QSerialPort::PermissionError); + return false; + } + + int flags = O_NOCTTY | O_NONBLOCK; + + switch (mode & QIODevice::ReadWrite) { + case QIODevice::WriteOnly: + flags |= O_WRONLY; + break; + case QIODevice::ReadWrite: + flags |= O_RDWR; + break; + default: + flags |= O_RDONLY; + break; + } + + descriptor = ::open(systemLocation.toLocal8Bit().constData(), flags); + + if (descriptor == -1) { + q_ptr->setError(decodeSystemError()); + return false; + } + + ::fcntl(descriptor, F_SETFL, FNDELAY); + + QTtyLocker::lock(ptr); + if (!QTtyLocker::isLocked(ptr, &byCurrPid)) { + q_ptr->setError(QSerialPort::PermissionError); + return false; + } + +#ifdef TIOCEXCL + ::ioctl(descriptor, TIOCEXCL); +#endif + + if (::tcgetattr(descriptor, &restoredTermios) == -1) { + q_ptr->setError(decodeSystemError()); + return false; + } + + currentTermios = restoredTermios; + ::cfmakeraw(¤tTermios); + currentTermios.c_cflag |= CLOCAL; + currentTermios.c_cc[VTIME] = 0; + currentTermios.c_cc[VMIN] = 0; + + if (mode & QIODevice::ReadOnly) + currentTermios.c_cflag |= CREAD; + + if (!updateTermios()) + return false; + + setExceptionNotificationEnabled(true); + + if ((flags & O_WRONLY) == 0) + setReadNotificationEnabled(true); + + detectDefaultSettings(); + return true; +} + +void QSerialPortPrivate::close() +{ + if (settingsRestoredOnClose) { + ::tcsetattr(descriptor, TCSANOW, &restoredTermios); +#ifdef Q_OS_LINUX + if (isCustomBaudRateSupported) + ::ioctl(descriptor, TIOCSSERIAL, &restoredSerialInfo); +#endif + } + +#ifdef TIOCNXCL + ::ioctl(descriptor, TIOCNXCL); +#endif + + if (readNotifier) { + readNotifier->setEnabled(false); + readNotifier->deleteLater(); + readNotifier = 0; + } + + if (writeNotifier) { + writeNotifier->setEnabled(false); + writeNotifier->deleteLater(); + writeNotifier = 0; + } + + if (exceptionNotifier) { + exceptionNotifier->setEnabled(false); + exceptionNotifier->deleteLater(); + exceptionNotifier = 0; + } + + ::close(descriptor); + + QByteArray portName = portNameFromSystemLocation(systemLocation).toLocal8Bit(); + const char *ptr = portName.constData(); + + bool byCurrPid = false; + if (QTtyLocker::isLocked(ptr, &byCurrPid) && byCurrPid) + QTtyLocker::unlock(ptr); + + descriptor = -1; + isCustomBaudRateSupported = false; +} + +QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals() const +{ + int arg = 0; + QSerialPort::PinoutSignals ret = QSerialPort::NoSignal; + + if (::ioctl(descriptor, TIOCMGET, &arg) == -1) { + q_ptr->setError(decodeSystemError()); + return ret; + } + +#ifdef TIOCM_LE + if (arg & TIOCM_LE) + ret |= QSerialPort::DataSetReadySignal; +#endif +#ifdef TIOCM_DTR + if (arg & TIOCM_DTR) + ret |= QSerialPort::DataTerminalReadySignal; +#endif +#ifdef TIOCM_RTS + if (arg & TIOCM_RTS) + ret |= QSerialPort::RequestToSendSignal; +#endif +#ifdef TIOCM_ST + if (arg & TIOCM_ST) + ret |= QSerialPort::SecondaryTransmittedDataSignal; +#endif +#ifdef TIOCM_SR + if (arg & TIOCM_SR) + ret |= QSerialPort::SecondaryReceivedDataSignal; +#endif +#ifdef TIOCM_CTS + if (arg & TIOCM_CTS) + ret |= QSerialPort::ClearToSendSignal; +#endif +#ifdef TIOCM_CAR + if (arg & TIOCM_CAR) + ret |= QSerialPort::DataCarrierDetectSignal; +#elif defined TIOCM_CD + if (arg & TIOCM_CD) + ret |= QSerialPort::DataCarrierDetectSignal; +#endif +#ifdef TIOCM_RNG + if (arg & TIOCM_RNG) + ret |= QSerialPort::RingIndicatorSignal; +#elif defined TIOCM_RI + if (arg & TIOCM_RI) + ret |= QSerialPort::RingIndicatorSignal; +#endif +#ifdef TIOCM_DSR + if (arg & TIOCM_DSR) + ret |= QSerialPort::DataSetReadySignal; +#endif + + return ret; +} + +bool QSerialPortPrivate::setDataTerminalReady(bool set) +{ + int status = TIOCM_DTR; + return ::ioctl(descriptor, set ? TIOCMBIS : TIOCMBIC, &status) != -1; +} + +bool QSerialPortPrivate::setRequestToSend(bool set) +{ + int status = TIOCM_RTS; + return ::ioctl(descriptor, set ? TIOCMBIS : TIOCMBIC, &status) != -1; +} + +bool QSerialPortPrivate::flush() +{ + return writeNotification() && (::tcdrain(descriptor) != -1); +} + +bool QSerialPortPrivate::clear(QSerialPort::Directions dir) +{ + return ::tcflush(descriptor, (dir == QSerialPort::AllDirections) + ? TCIOFLUSH : (dir & QSerialPort::Input) ? TCIFLUSH : TCOFLUSH) != -1; +} + +bool QSerialPortPrivate::sendBreak(int duration) +{ + return ::tcsendbreak(descriptor, duration) != -1; +} + +bool QSerialPortPrivate::setBreakEnabled(bool set) +{ + return ::ioctl(descriptor, set ? TIOCSBRK : TIOCCBRK) != -1; +} + +qint64 QSerialPortPrivate::systemInputQueueSize () const +{ + int nbytes = 0; +#ifdef TIOCINQ + if (::ioctl(descriptor, TIOCINQ, &nbytes) == -1) + return -1; +#endif + return nbytes; +} + +qint64 QSerialPortPrivate::systemOutputQueueSize () const +{ + int nbytes = 0; +#ifdef TIOCOUTQ + if (::ioctl(descriptor, TIOCOUTQ, &nbytes) == -1) + return -1; +#endif + return nbytes; +} + +qint64 QSerialPortPrivate::bytesAvailable() const +{ + return readBuffer.size(); +} + +qint64 QSerialPortPrivate::readFromBuffer(char *data, qint64 maxSize) +{ + if (readBuffer.isEmpty()) + return 0; + + if (maxSize == 1) { + *data = readBuffer.getChar(); + if (readBuffer.isEmpty()) + setReadNotificationEnabled(true); + return 1; + } + + const qint64 bytesToRead = qMin(qint64(readBuffer.size()), maxSize); + qint64 readSoFar = 0; + while (readSoFar < bytesToRead) { + const char *ptr = readBuffer.readPointer(); + const int bytesToReadFromThisBlock = qMin(int(bytesToRead - readSoFar), + readBuffer.nextDataBlockSize()); + ::memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock); + readSoFar += bytesToReadFromThisBlock; + readBuffer.free(bytesToReadFromThisBlock); + } + + if (!isReadNotificationEnabled()) + setReadNotificationEnabled(true); + + if (readSoFar > 0) { + if (readBuffer.isEmpty()) + setReadNotificationEnabled(true); + return readSoFar; + } + + return readSoFar; +} + +qint64 QSerialPortPrivate::writeToBuffer(const char *data, qint64 maxSize) +{ + char *ptr = writeBuffer.reserve(maxSize); + if (maxSize == 1) + *ptr = *data; + else + ::memcpy(ptr, data, maxSize); + + const qint64 written = maxSize; + + if (!writeBuffer.isEmpty() && !isWriteNotificationEnabled()) + setWriteNotificationEnabled(true); + + return written; +} + +bool QSerialPortPrivate::waitForReadyRead(int msecs) +{ + QElapsedTimer stopWatch; + + stopWatch.start(); + + do { + bool readyToRead = false; + bool readyToWrite = false; + bool timedOut = false; + if (!waitForReadOrWrite(&readyToRead, &readyToWrite, true, !writeBuffer.isEmpty(), + timeoutValue(msecs, stopWatch.elapsed()), &timedOut)) { + q_ptr->setError(decodeSystemError()); + return false; + } + + if (readyToRead) { + if (readNotification()) + return true; + } + + if (readyToWrite) + writeNotification(WriteChunkSize); + + } while (msecs == -1 || timeoutValue(msecs, stopWatch.elapsed()) > 0); + return false; +} + +bool QSerialPortPrivate::waitForBytesWritten(int msecs) +{ + if (writeBuffer.isEmpty()) + return false; + + QElapsedTimer stopWatch; + + stopWatch.start(); + + forever { + bool readyToRead = false; + bool readyToWrite = false; + bool timedOut = false; + if (!waitForReadOrWrite(&readyToRead, &readyToWrite, true, !writeBuffer.isEmpty(), + timeoutValue(msecs, stopWatch.elapsed()), &timedOut)) { + q_ptr->setError(decodeSystemError()); + return false; + } + + if (readyToRead && !readNotification()) + return false; + + if (readyToWrite) + return writeNotification(WriteChunkSize); + } + return false; +} + +bool QSerialPortPrivate::setBaudRate(qint32 baudRate, QSerialPort::Directions dir) +{ + bool ret = baudRate > 0; + + // prepare section + + if (ret) { + const qint32 unixBaudRate = QSerialPortPrivate::settingFromBaudRate(baudRate); + if (unixBaudRate > 0) { + // try prepate to set standard baud rate +#ifdef Q_OS_LINUX + // prepare to forcefully reset the custom mode + if (isCustomBaudRateSupported) { + //currentSerialInfo.flags |= ASYNC_SPD_MASK; + currentSerialInfo.flags &= ~(ASYNC_SPD_CUST /* | ASYNC_LOW_LATENCY*/); + currentSerialInfo.custom_divisor = 0; + } +#endif + // prepare to set standard baud rate + ret = !(((dir & QSerialPort::Input) && ::cfsetispeed(¤tTermios, unixBaudRate) < 0) + || ((dir & QSerialPort::Output) && ::cfsetospeed(¤tTermios, unixBaudRate) < 0)); + } else { + // try prepate to set custom baud rate +#ifdef Q_OS_LINUX + // prepare to forcefully set the custom mode + if (isCustomBaudRateSupported) { + currentSerialInfo.flags &= ~ASYNC_SPD_MASK; + currentSerialInfo.flags |= (ASYNC_SPD_CUST /* | ASYNC_LOW_LATENCY*/); + currentSerialInfo.custom_divisor = currentSerialInfo.baud_base / baudRate; + if (currentSerialInfo.custom_divisor == 0) + currentSerialInfo.custom_divisor = 1; + // for custom mode needed prepare to set B38400 baud rate + ret = (::cfsetspeed(¤tTermios, B38400) != -1); + } else { + ret = false; + } +#elif defined(Q_OS_MAC) + +# if defined (MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) + // Starting with Tiger, the IOSSIOSPEED ioctl can be used to set arbitrary baud rates + // other than those specified by POSIX. The driver for the underlying serial hardware + // ultimately determines which baud rates can be used. This ioctl sets both the input + // and output speed. + ret = ::ioctl(descriptor, IOSSIOSPEED, &baudRate) != -1; +# else + // others MacOSX version, can't prepare to set custom baud rate + ret = false; +# endif + +#else + // others *nix OS, can't prepare to set custom baud rate + ret = false; +#endif + } + } + + // finally section + +#ifdef Q_OS_LINUX + if (ret && isCustomBaudRateSupported) // finally, set or reset the custom mode + ret = ::ioctl(descriptor, TIOCSSERIAL, ¤tSerialInfo) != -1; +#endif + + if (ret) // finally, set baud rate + ret = updateTermios(); + else + q_ptr->setError(decodeSystemError()); + return ret; +} + +bool QSerialPortPrivate::setDataBits(QSerialPort::DataBits dataBits) +{ + currentTermios.c_cflag &= ~CSIZE; + switch (dataBits) { + case QSerialPort::Data5: + currentTermios.c_cflag |= CS5; + break; + case QSerialPort::Data6: + currentTermios.c_cflag |= CS6; + break; + case QSerialPort::Data7: + currentTermios.c_cflag |= CS7; + break; + case QSerialPort::Data8: + currentTermios.c_cflag |= CS8; + break; + default: + currentTermios.c_cflag |= CS8; + break; + } + return updateTermios(); +} + +bool QSerialPortPrivate::setParity(QSerialPort::Parity parity) +{ + currentTermios.c_iflag &= ~(PARMRK | INPCK); + currentTermios.c_iflag |= IGNPAR; + + switch (parity) { + +#ifdef CMSPAR + // Here Installation parity only for GNU/Linux where the macro CMSPAR. + case QSerialPort::SpaceParity: + currentTermios.c_cflag &= ~PARODD; + currentTermios.c_cflag |= PARENB | CMSPAR; + break; + case QSerialPort::MarkParity: + currentTermios.c_cflag |= PARENB | CMSPAR | PARODD; + break; +#endif + case QSerialPort::NoParity: + currentTermios.c_cflag &= ~PARENB; + break; + case QSerialPort::EvenParity: + currentTermios.c_cflag &= ~PARODD; + currentTermios.c_cflag |= PARENB; + break; + case QSerialPort::OddParity: + currentTermios.c_cflag |= PARENB | PARODD; + break; + default: + currentTermios.c_cflag |= PARENB; + currentTermios.c_iflag |= PARMRK | INPCK; + currentTermios.c_iflag &= ~IGNPAR; + break; + } + + return updateTermios(); +} + +bool QSerialPortPrivate::setStopBits(QSerialPort::StopBits stopBits) +{ + switch (stopBits) { + case QSerialPort::OneStop: + currentTermios.c_cflag &= ~CSTOPB; + break; + case QSerialPort::TwoStop: + currentTermios.c_cflag |= CSTOPB; + break; + default: + currentTermios.c_cflag &= ~CSTOPB; + break; + } + return updateTermios(); +} + +bool QSerialPortPrivate::setFlowControl(QSerialPort::FlowControl flow) +{ + switch (flow) { + case QSerialPort::NoFlowControl: + currentTermios.c_cflag &= ~CRTSCTS; + currentTermios.c_iflag &= ~(IXON | IXOFF | IXANY); + break; + case QSerialPort::HardwareControl: + currentTermios.c_cflag |= CRTSCTS; + currentTermios.c_iflag &= ~(IXON | IXOFF | IXANY); + break; + case QSerialPort::SoftwareControl: + currentTermios.c_cflag &= ~CRTSCTS; + currentTermios.c_iflag |= IXON | IXOFF | IXANY; + break; + default: + currentTermios.c_cflag &= ~CRTSCTS; + currentTermios.c_iflag &= ~(IXON | IXOFF | IXANY); + break; + } + return updateTermios(); +} + +bool QSerialPortPrivate::setDataErrorPolicy(QSerialPort::DataErrorPolicy policy) +{ + tcflag_t parmrkMask = PARMRK; +#ifndef CMSPAR + // in space/mark parity emulation also used PARMRK flag + if (parity == QSerialPort::SpaceParity + || parity == QSerialPort::MarkParity) { + parmrkMask = 0; + } +#endif //CMSPAR + switch (policy) { + case QSerialPort::SkipPolicy: + currentTermios.c_iflag &= ~parmrkMask; + currentTermios.c_iflag |= IGNPAR | INPCK; + break; + case QSerialPort::PassZeroPolicy: + currentTermios.c_iflag &= ~(IGNPAR | parmrkMask); + currentTermios.c_iflag |= INPCK; + break; + case QSerialPort::IgnorePolicy: + currentTermios.c_iflag &= ~INPCK; + break; + case QSerialPort::StopReceivingPolicy: + currentTermios.c_iflag &= ~IGNPAR; + currentTermios.c_iflag |= parmrkMask | INPCK; + break; + default: + currentTermios.c_iflag &= ~INPCK; + break; + } + return updateTermios(); +} + +bool QSerialPortPrivate::readNotification() +{ + // Prevent recursive calls + if (readPortNotifierCalled) { + if (!readPortNotifierStateSet) { + readPortNotifierStateSet = true; + readPortNotifierState = isReadNotificationEnabled(); + setReadNotificationEnabled(false); + } + } + + readPortNotifierCalled = true; + + // Always buffered, read data from the port into the read buffer + qint64 newBytes = readBuffer.size(); + qint64 bytesToRead = policy == QSerialPort::IgnorePolicy ? ReadChunkSize : 1; + + if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - readBuffer.size())) { + bytesToRead = readBufferMaxSize - readBuffer.size(); + if (bytesToRead == 0) { + // Buffer is full. User must read data from the buffer + // before we can read more from the port. + return false; + } + } + + char *ptr = readBuffer.reserve(bytesToRead); + const qint64 readBytes = readFromPort(ptr, bytesToRead); + + if (readBytes <= 0) { + readBuffer.chop(bytesToRead); + return false; + } + + readBuffer.chop(bytesToRead - qMax(readBytes, qint64(0))); + + newBytes = readBuffer.size() - newBytes; + + // If read buffer is full, disable the read port notifier. + if (readBufferMaxSize && readBuffer.size() == readBufferMaxSize) + setReadNotificationEnabled(false); + + // only emit readyRead() when not recursing, and only if there is data available + const bool hasData = newBytes > 0; + + if (!emittedReadyRead && hasData) { + emittedReadyRead = true; + emit q_ptr->readyRead(); + emittedReadyRead = false; + } + + if (!hasData) + setReadNotificationEnabled(true); + + // reset the read port notifier state if we reentered inside the + // readyRead() connected slot. + if (readPortNotifierStateSet + && readPortNotifierState != isReadNotificationEnabled()) { + setReadNotificationEnabled(readPortNotifierState); + readPortNotifierStateSet = false; + } + return true; +} + +bool QSerialPortPrivate::writeNotification(int maxSize) +{ + const int tmp = writeBuffer.size(); + + if (writeBuffer.isEmpty()) { + setWriteNotificationEnabled(false); + return false; + } + + int nextSize = qMin(writeBuffer.nextDataBlockSize(), maxSize); + + const char *ptr = writeBuffer.readPointer(); + + // Attempt to write it chunk. + qint64 written = writeToPort(ptr, nextSize); + if (written < 0) + return false; + + // Remove what we wrote so far. + writeBuffer.free(written); + if (written > 0) { + // Don't emit bytesWritten() recursively. + if (!emittedBytesWritten) { + emittedBytesWritten = true; + emit q_ptr->bytesWritten(written); + emittedBytesWritten = false; + } + } + + if (writeBuffer.isEmpty()) + setWriteNotificationEnabled(false); + + return (writeBuffer.size() < tmp); +} + +bool QSerialPortPrivate::exceptionNotification() +{ + QSerialPort::SerialPortError error = decodeSystemError(); + q_ptr->setError(error); + + return true; +} + +bool QSerialPortPrivate::updateTermios() +{ + if (::tcsetattr(descriptor, TCSANOW, ¤tTermios) == -1) { + q_ptr->setError(decodeSystemError()); + return false; + } + return true; +} + +void QSerialPortPrivate::detectDefaultSettings() +{ + // Detect baud rate. + const speed_t inputUnixBaudRate = ::cfgetispeed(¤tTermios); + const speed_t outputUnixBaudRate = ::cfgetospeed(¤tTermios); + bool isCustomBaudRateCurrentSet = false; + +#ifdef Q_OS_LINUX + // try detect the ability to support custom baud rate + isCustomBaudRateSupported = ::ioctl(descriptor, TIOCGSERIAL, ¤tSerialInfo) != -1 + && ::ioctl(descriptor, TIOCSSERIAL, ¤tSerialInfo) != -1; + + if (isCustomBaudRateSupported) { + restoredSerialInfo = currentSerialInfo; + + // assume that the baud rate is a custom + isCustomBaudRateCurrentSet = inputUnixBaudRate == B38400 && outputUnixBaudRate == B38400; + + if (isCustomBaudRateCurrentSet) { + if ((currentSerialInfo.flags & ASYNC_SPD_CUST) + && currentSerialInfo.custom_divisor > 0) { + + // yes, speed is really custom + inputBaudRate = currentSerialInfo.baud_base / currentSerialInfo.custom_divisor; + outputBaudRate = inputBaudRate; + } else { + // no, we were wrong and the speed is a standard 38400 baud + isCustomBaudRateCurrentSet = false; + } + } + } +#else + // other *nix +#endif + if (!isCustomBaudRateSupported || !isCustomBaudRateCurrentSet) { + inputBaudRate = QSerialPortPrivate::baudRateFromSetting(inputUnixBaudRate); + outputBaudRate = QSerialPortPrivate::baudRateFromSetting(outputUnixBaudRate); + } + + // Detect databits. + switch (currentTermios.c_cflag & CSIZE) { + case CS5: + dataBits = QSerialPort::Data5; + break; + case CS6: + dataBits = QSerialPort::Data6; + break; + case CS7: + dataBits = QSerialPort::Data7; + break; + case CS8: + dataBits = QSerialPort::Data8; + break; + default: + dataBits = QSerialPort::UnknownDataBits; + break; + } + + // Detect parity. +#ifdef CMSPAR + if (currentTermios.c_cflag & CMSPAR) { + parity = currentTermios.c_cflag & PARODD ? + QSerialPort::MarkParity : QSerialPort::SpaceParity; + } else { +#endif + if (currentTermios.c_cflag & PARENB) { + parity = currentTermios.c_cflag & PARODD ? + QSerialPort::OddParity : QSerialPort::EvenParity; + } else { + parity = QSerialPort::NoParity; + } +#ifdef CMSPAR + } +#endif + + // Detect stopbits. + stopBits = currentTermios.c_cflag & CSTOPB ? + QSerialPort::TwoStop : QSerialPort::OneStop; + + // Detect flow control. + if ((!(currentTermios.c_cflag & CRTSCTS)) && (!(currentTermios.c_iflag & (IXON | IXOFF | IXANY)))) + flow = QSerialPort::NoFlowControl; + else if ((!(currentTermios.c_cflag & CRTSCTS)) && (currentTermios.c_iflag & (IXON | IXOFF | IXANY))) + flow = QSerialPort::SoftwareControl; + else if ((currentTermios.c_cflag & CRTSCTS) && (!(currentTermios.c_iflag & (IXON | IXOFF | IXANY)))) + flow = QSerialPort::HardwareControl; + else + flow = QSerialPort::UnknownFlowControl; +} + +QSerialPort::SerialPortError QSerialPortPrivate::decodeSystemError() const +{ + QSerialPort::SerialPortError error; + switch (errno) { + case ENODEV: + error = QSerialPort::DeviceNotFoundError; + break; + case EACCES: + error = QSerialPort::PermissionError; + break; + case EBUSY: + error = QSerialPort::PermissionError; + break; + case EAGAIN: + error = QSerialPort::ResourceError; + break; + case EIO: + error = QSerialPort::ResourceError; + break; + case EBADF: + error = QSerialPort::ResourceError; + break; +#ifdef Q_OS_MAC + case ENXIO: + error = QSerialPort::ResourceError; + break; +#endif + default: + error = QSerialPort::UnknownError; + break; + } + return error; +} + +bool QSerialPortPrivate::isReadNotificationEnabled() const +{ + return readNotifier && readNotifier->isEnabled(); +} + +void QSerialPortPrivate::setReadNotificationEnabled(bool enable) +{ + if (readNotifier) { + readNotifier->setEnabled(enable); + } else if (enable) { + readNotifier = new ReadNotifier(this, q_ptr); + readNotifier->setEnabled(true); + } +} + +bool QSerialPortPrivate::isWriteNotificationEnabled() const +{ + return writeNotifier && writeNotifier->isEnabled(); +} + +void QSerialPortPrivate::setWriteNotificationEnabled(bool enable) +{ + if (writeNotifier) { + writeNotifier->setEnabled(enable); + } else if (enable) { + writeNotifier = new WriteNotifier(this, q_ptr); + writeNotifier->setEnabled(true); + } +} + +bool QSerialPortPrivate::isExceptionNotificationEnabled() const +{ + return exceptionNotifier && exceptionNotifier->isEnabled(); +} + +void QSerialPortPrivate::setExceptionNotificationEnabled(bool enable) +{ + if (exceptionNotifier) { + exceptionNotifier->setEnabled(enable); + } else if (enable) { + exceptionNotifier = new ExceptionNotifier(this, q_ptr); + exceptionNotifier->setEnabled(true); + } +} + +bool QSerialPortPrivate::waitForReadOrWrite(bool *selectForRead, bool *selectForWrite, + bool checkRead, bool checkWrite, + int msecs, bool *timedOut) +{ + Q_ASSERT(selectForRead); + Q_ASSERT(selectForWrite); + Q_ASSERT(timedOut); + + fd_set fdread; + FD_ZERO(&fdread); + if (checkRead) + FD_SET(descriptor, &fdread); + + fd_set fdwrite; + FD_ZERO(&fdwrite); + if (checkWrite) + FD_SET(descriptor, &fdwrite); + + struct timeval tv; + tv.tv_sec = msecs / 1000; + tv.tv_usec = (msecs % 1000) * 1000; + + int ret = ::select(descriptor + 1, &fdread, &fdwrite, 0, msecs < 0 ? 0 : &tv); + if (ret < 0) + return false; + if (ret == 0) { + *timedOut = true; + return false; + } + + *selectForRead = FD_ISSET(descriptor, &fdread); + *selectForWrite = FD_ISSET(descriptor, &fdwrite); + + return ret; +} + +qint64 QSerialPortPrivate::readFromPort(char *data, qint64 maxSize) +{ + qint64 bytesRead = 0; +#if defined (CMSPAR) + if (parity == QSerialPort::NoParity + || policy != QSerialPort::StopReceivingPolicy) { +#else + if (parity != QSerialPort::MarkParity + && parity != QSerialPort::SpaceParity) { +#endif + bytesRead = ::read(descriptor, data, maxSize); + } else {// Perform parity emulation. + bytesRead = readPerChar(data, maxSize); + } + + if (bytesRead <= 0) { + QSerialPort::SerialPortError error = decodeSystemError(); + if (error != QSerialPort::ResourceError) + error = QSerialPort::ReadError; + q_ptr->setError(error); + } + + return bytesRead; +} + +qint64 QSerialPortPrivate::writeToPort(const char *data, qint64 maxSize) +{ + qint64 bytesWritten = 0; +#if defined (CMSPAR) + bytesWritten = ::write(descriptor, data, maxSize); +#else + if (parity != QSerialPort::MarkParity + && parity != QSerialPort::SpaceParity) { + bytesWritten = ::write(descriptor, data, maxSize); + } else {// Perform parity emulation. + bytesWritten = writePerChar(data, maxSize); + } +#endif + + if (bytesWritten < 0) { + QSerialPort::SerialPortError error = decodeSystemError(); + if (error != QSerialPort::ResourceError) + error = QSerialPort::WriteError; + q_ptr->setError(error); + } + + return bytesWritten; +} + +static inline bool evenParity(quint8 c) +{ + c ^= c >> 4; //(c7 ^ c3)(c6 ^ c2)(c5 ^ c1)(c4 ^ c0) + c ^= c >> 2; //[(c7 ^ c3)(c5 ^ c1)][(c6 ^ c2)(c4 ^ c0)] + c ^= c >> 1; + return c & 1; //(c7 ^ c3)(c5 ^ c1)(c6 ^ c2)(c4 ^ c0) +} + +#ifndef CMSPAR + +qint64 QSerialPortPrivate::writePerChar(const char *data, qint64 maxSize) +{ + qint64 ret = 0; + quint8 const charMask = (0xFF >> (8 - dataBits)); + + while (ret < maxSize) { + + bool par = evenParity(*data & charMask); + // False if need EVEN, true if need ODD. + par ^= parity == QSerialPort::MarkParity; + if (par ^ (currentTermios.c_cflag & PARODD)) { // Need switch parity mode? + currentTermios.c_cflag ^= PARODD; + flush(); //force sending already buffered data, because updateTermios() cleares buffers + //todo: add receiving buffered data!!! + if (!updateTermios()) + break; + } + + int r = ::write(descriptor, data, 1); + if (r < 0) + return -1; + if (r > 0) { + data += r; + ret += r; + } + } + return ret; +} + +#endif //CMSPAR + +qint64 QSerialPortPrivate::readPerChar(char *data, qint64 maxSize) +{ + qint64 ret = 0; + quint8 const charMask = (0xFF >> (8 - dataBits)); + + // 0 - prefix not started, + // 1 - received 0xFF, + // 2 - received 0xFF and 0x00 + int prefix = 0; + while (ret < maxSize) { + + qint64 r = ::read(descriptor, data, 1); + if (r < 0) { + if (errno == EAGAIN) // It is ok for nonblocking mode. + break; + return -1; + } + if (r == 0) + break; + + bool par = true; + switch (prefix) { + case 2: // Previously received both 0377 and 0. + par = false; + prefix = 0; + break; + case 1: // Previously received 0377. + if (*data == '\0') { + ++prefix; + continue; + } + prefix = 0; + break; + default: + if (*data == '\377') { + prefix = 1; + continue; + } + break; + } + // Now: par contains parity ok or error, *data contains received character + par ^= evenParity(*data & charMask); //par contains parity bit value for EVEN mode + par ^= (currentTermios.c_cflag & PARODD); //par contains parity bit value for current mode + if (par ^ (parity == QSerialPort::SpaceParity)) { //if parity error + switch (policy) { + case QSerialPort::SkipPolicy: + continue; //ignore received character + case QSerialPort::StopReceivingPolicy: + if (parity != QSerialPort::NoParity) + q_ptr->setError(QSerialPort::ParityError); + else + q_ptr->setError(*data == '\0' ? + QSerialPort::BreakConditionError : QSerialPort::FramingError); + return ++ret; //abort receiving + break; + case QSerialPort::UnknownPolicy: + // Unknown error policy is used! Falling back to PassZeroPolicy + case QSerialPort::PassZeroPolicy: + *data = '\0'; //replace received character by zero + break; + case QSerialPort::IgnorePolicy: + break; //ignore error and pass received character + } + } + ++data; + ++ret; + } + return ret; +} + +#ifdef Q_OS_MAC +static const QLatin1String defaultFilePathPrefix("/dev/cu."); +static const QLatin1String unusedFilePathPrefix("/dev/tty."); +#else +static const QLatin1String defaultFilePathPrefix("/dev/"); +#endif + +QString QSerialPortPrivate::portNameToSystemLocation(const QString &port) +{ + QString ret = port; + +#ifdef Q_OS_MAC + ret.remove(unusedFilePathPrefix); +#endif + + if (!ret.contains(defaultFilePathPrefix)) + ret.prepend(defaultFilePathPrefix); + return ret; +} + +QString QSerialPortPrivate::portNameFromSystemLocation(const QString &location) +{ + QString ret = location; + +#ifdef Q_OS_MAC + ret.remove(unusedFilePathPrefix); +#endif + + ret.remove(defaultFilePathPrefix); + return ret; +} + +typedef QMap BaudRateMap; + +// The OS specific defines can be found in termios.h + +static const BaudRateMap createStandardBaudRateMap() +{ + BaudRateMap baudRateMap; + +#ifdef B50 + baudRateMap.insert(50, B50); +#endif + +#ifdef B75 + baudRateMap.insert(75, B75); +#endif + +#ifdef B110 + baudRateMap.insert(110, B110); +#endif + +#ifdef B134 + baudRateMap.insert(134, B134); +#endif + +#ifdef B150 + baudRateMap.insert(150, B150); +#endif + +#ifdef B200 + baudRateMap.insert(200, B200); +#endif + +#ifdef B300 + baudRateMap.insert(300, B300); +#endif + +#ifdef B600 + baudRateMap.insert(600, B600); +#endif + +#ifdef B1200 + baudRateMap.insert(1200, B1200); +#endif + +#ifdef B1800 + baudRateMap.insert(1800, B1800); +#endif + +#ifdef B2400 + baudRateMap.insert(2400, B2400); +#endif + +#ifdef B4800 + baudRateMap.insert(4800, B4800); +#endif + +#ifdef B9600 + baudRateMap.insert(9600, B9600); +#endif + +#ifdef B19200 + baudRateMap.insert(19200, B19200); +#endif + +#ifdef B38400 + baudRateMap.insert(38400, B38400); +#endif + +#ifdef B57600 + baudRateMap.insert(57600, B57600); +#endif + +#ifdef B115200 + baudRateMap.insert(115200, B115200); +#endif + +#ifdef B230400 + baudRateMap.insert(230400, B230400); +#endif + +#ifdef B460800 + baudRateMap.insert(460800, B460800); +#endif + +#ifdef B500000 + baudRateMap.insert(500000, B500000); +#endif + +#ifdef B576000 + baudRateMap.insert(576000, B576000); +#endif + +#ifdef B921600 + baudRateMap.insert(921600, B921600); +#endif + +#ifdef B1000000 + baudRateMap.insert(1000000, B1000000); +#endif + +#ifdef B1152000 + baudRateMap.insert(1152000, B1152000); +#endif + +#ifdef B1500000 + baudRateMap.insert(1500000, B1500000); +#endif + +#ifdef B2000000 + baudRateMap.insert(2000000, B2000000); +#endif + +#ifdef B2500000 + baudRateMap.insert(2500000, B2500000); +#endif + +#ifdef B3000000 + baudRateMap.insert(3000000, B3000000); +#endif + +#ifdef B3500000 + baudRateMap.insert(3500000, B3500000); +#endif + +#ifdef B4000000 + baudRateMap.insert(4000000, B4000000); +#endif + + return baudRateMap; +} + +static const BaudRateMap& standardBaudRateMap() +{ + static const BaudRateMap baudRateMap = createStandardBaudRateMap(); + return baudRateMap; +} + +qint32 QSerialPortPrivate::baudRateFromSetting(qint32 setting) +{ + return standardBaudRateMap().key(setting); +} + +qint32 QSerialPortPrivate::settingFromBaudRate(qint32 baudRate) +{ + return standardBaudRateMap().value(baudRate); +} + +QList QSerialPortPrivate::standardBaudRates() +{ + return standardBaudRateMap().keys(); +} + +QT_END_NAMESPACE diff --git a/libs/serialport/qserialport_unix_p.h b/libs/serialport/qserialport_unix_p.h new file mode 100644 index 0000000000..ce70c243b3 --- /dev/null +++ b/libs/serialport/qserialport_unix_p.h @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Denis Shienkov +** Copyright (C) 2012 Laszlo Papp +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSERIALPORT_UNIX_P_H +#define QSERIALPORT_UNIX_P_H + +#include "qserialport_p.h" + +#include +#include +#ifdef Q_OS_LINUX +# include +#endif + +QT_BEGIN_NAMESPACE + +class QSocketNotifier; + +class QSerialPortPrivate : public QSerialPortPrivateData +{ +public: + QSerialPortPrivate(QSerialPort *q); + + bool open(QIODevice::OpenMode mode); + void close(); + + QSerialPort::PinoutSignals pinoutSignals() const; + + bool setDataTerminalReady(bool set); + bool setRequestToSend(bool set); + + bool flush(); + bool clear(QSerialPort::Directions dir); + + bool sendBreak(int duration); + bool setBreakEnabled(bool set); + + qint64 systemInputQueueSize () const; + qint64 systemOutputQueueSize () const; + + qint64 bytesAvailable() const; + + qint64 readFromBuffer(char *data, qint64 maxSize); + qint64 writeToBuffer(const char *data, qint64 maxSize); + + bool waitForReadyRead(int msecs); + bool waitForBytesWritten(int msecs); + + bool setBaudRate(qint32 baudRate, QSerialPort::Directions dir); + bool setDataBits(QSerialPort::DataBits dataBits); + bool setParity(QSerialPort::Parity parity); + bool setStopBits(QSerialPort::StopBits stopBits); + bool setFlowControl(QSerialPort::FlowControl flow); + bool setDataErrorPolicy(QSerialPort::DataErrorPolicy policy); + + bool readNotification(); + bool writeNotification(int maxSize = INT_MAX); + bool exceptionNotification(); + + static QString portNameToSystemLocation(const QString &port); + static QString portNameFromSystemLocation(const QString &location); + + static qint32 baudRateFromSetting(qint32 setting); + static qint32 settingFromBaudRate(qint32 baudRate); + + static QList standardBaudRates(); + + struct termios currentTermios; + struct termios restoredTermios; +#ifdef Q_OS_LINUX + struct serial_struct currentSerialInfo; + struct serial_struct restoredSerialInfo; +#endif + int descriptor; + bool isCustomBaudRateSupported; + + QSocketNotifier *readNotifier; + QSocketNotifier *writeNotifier; + QSocketNotifier *exceptionNotifier; + + bool readPortNotifierCalled; + bool readPortNotifierState; + bool readPortNotifierStateSet; + + bool emittedReadyRead; + bool emittedBytesWritten; + +private: + bool updateTermios(); + + void detectDefaultSettings(); + QSerialPort::SerialPortError decodeSystemError() const; + + bool isReadNotificationEnabled() const; + void setReadNotificationEnabled(bool enable); + bool isWriteNotificationEnabled() const; + void setWriteNotificationEnabled(bool enable); + bool isExceptionNotificationEnabled() const; + void setExceptionNotificationEnabled(bool enable); + + bool waitForReadOrWrite(bool *selectForRead, bool *selectForWrite, + bool checkRead, bool checkWrite, + int msecs, bool *timedOut); + + qint64 readFromPort(char *data, qint64 maxSize); + qint64 writeToPort(const char *data, qint64 maxSize); + +#ifndef CMSPAR + qint64 writePerChar(const char *data, qint64 maxSize); +#endif + qint64 readPerChar(char *data, qint64 maxSize); + +}; + +QT_END_NAMESPACE + +#endif // QSERIALPORT_UNIX_P_H diff --git a/libs/serialport/qserialport_win.cpp b/libs/serialport/qserialport_win.cpp new file mode 100644 index 0000000000..e8d4d62adb --- /dev/null +++ b/libs/serialport/qserialport_win.cpp @@ -0,0 +1,1091 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Denis Shienkov +** Copyright (C) 2012 Laszlo Papp +** Copyright (C) 2012 Andre Hartmann +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qserialport_win_p.h" + +#ifndef Q_OS_WINCE +#include +#include +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) +#include +#else +#include "qt4support/qwineventnotifier_p.h" +#endif + +#ifndef CTL_CODE +# define CTL_CODE(DeviceType, Function, Method, Access) ( \ + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ + ) +#endif + +#ifndef FILE_DEVICE_SERIAL_PORT +# define FILE_DEVICE_SERIAL_PORT 27 +#endif + +#ifndef METHOD_BUFFERED +# define METHOD_BUFFERED 0 +#endif + +#ifndef FILE_ANY_ACCESS +# define FILE_ANY_ACCESS 0x00000000 +#endif + +#ifndef IOCTL_SERIAL_GET_DTRRTS +# define IOCTL_SERIAL_GET_DTRRTS \ + CTL_CODE(FILE_DEVICE_SERIAL_PORT, 30, METHOD_BUFFERED, FILE_ANY_ACCESS) +#endif + +#ifndef SERIAL_DTR_STATE +# define SERIAL_DTR_STATE 0x00000001 +#endif + +#ifndef SERIAL_RTS_STATE +# define SERIAL_RTS_STATE 0x00000002 +#endif + +QT_BEGIN_NAMESPACE + +#ifndef Q_OS_WINCE + +class AbstractOverlappedEventNotifier : public QWinEventNotifier +{ +public: + enum Type { CommEvent, ReadCompletionEvent, WriteCompletionEvent }; + + AbstractOverlappedEventNotifier(QSerialPortPrivate *d, Type type, bool manual, QObject *parent) + : QWinEventNotifier(parent), dptr(d), t(type) { + ::memset(&o, 0, sizeof(o)); + o.hEvent = ::CreateEvent(NULL, manual, FALSE, NULL); + setHandle(o.hEvent); + dptr->notifiers[o.hEvent] = this; + } + + virtual bool processCompletionRoutine() = 0; + + virtual ~AbstractOverlappedEventNotifier() { + setEnabled(false); + ::CancelIo(o.hEvent); + ::CloseHandle(o.hEvent); + } + + Type type() const { return t; } + OVERLAPPED *overlappedPointer() { return &o; } + +protected: + bool event(QEvent *e) Q_DECL_OVERRIDE { + const bool ret = QWinEventNotifier::event(e); + processCompletionRoutine(); + return ret; + } + + QSerialPortPrivate *dptr; + Type t; + OVERLAPPED o; +}; + +class CommOverlappedEventNotifier : public AbstractOverlappedEventNotifier +{ +public: + CommOverlappedEventNotifier(QSerialPortPrivate *d, DWORD eventMask, QObject *parent) + : AbstractOverlappedEventNotifier(d, CommEvent, false, parent) + , originalEventMask(eventMask), triggeredEventMask(0) { + ::SetCommMask(dptr->descriptor, originalEventMask); + startWaitCommEvent(); + } + + void startWaitCommEvent() { ::WaitCommEvent(dptr->descriptor, &triggeredEventMask, &o); } + + bool processCompletionRoutine() Q_DECL_OVERRIDE { + DWORD numberOfBytesTransferred = 0; + ::GetOverlappedResult(dptr->descriptor, &o, &numberOfBytesTransferred, FALSE); + + bool error = false; + + // Check for unexpected event. This event triggered when pulled previously + // opened device from the system, when opened as for not to read and not to + // write options and so forth. + if (triggeredEventMask == 0) + error = true; + + // Workaround for standard CDC ACM serial ports, for which triggered an + // unexpected event EV_TXEMPTY at data transmission. + if ((originalEventMask & triggeredEventMask) == 0) { + if ((triggeredEventMask & EV_TXEMPTY) == 0) + error = true; + } + + // Start processing a caught error. + if (error || (EV_ERR & triggeredEventMask)) + dptr->processIoErrors(error); + + if (!error) + dptr->startAsyncRead(); + + return !error; + } + +private: + DWORD originalEventMask; + DWORD triggeredEventMask; +}; + +class ReadOverlappedCompletionNotifier : public AbstractOverlappedEventNotifier +{ +public: + ReadOverlappedCompletionNotifier(QSerialPortPrivate *d, QObject *parent) + : AbstractOverlappedEventNotifier(d, ReadCompletionEvent, false, parent) {} + + bool processCompletionRoutine() Q_DECL_OVERRIDE { + DWORD numberOfBytesTransferred = 0; + ::GetOverlappedResult(dptr->descriptor, &o, &numberOfBytesTransferred, FALSE); + bool ret = dptr->completeAsyncRead(numberOfBytesTransferred); + + // start async read for possible remainder into driver queue + if (ret && (numberOfBytesTransferred > 0) && (dptr->policy == QSerialPort::IgnorePolicy)) { + dptr->startAsyncRead(); + } else { // driver queue is emplty, so startup wait comm event + CommOverlappedEventNotifier *n = + reinterpret_cast(dptr->lookupCommEventNotifier()); + if (n) + n->startWaitCommEvent(); + } + + return ret; + } +}; + +class WriteOverlappedCompletionNotifier : public AbstractOverlappedEventNotifier +{ +public: + WriteOverlappedCompletionNotifier(QSerialPortPrivate *d, QObject *parent) + : AbstractOverlappedEventNotifier(d, WriteCompletionEvent, false, parent) {} + + bool processCompletionRoutine() Q_DECL_OVERRIDE { + setEnabled(false); + DWORD numberOfBytesTransferred = 0; + ::GetOverlappedResult(dptr->descriptor, &o, &numberOfBytesTransferred, FALSE); + return dptr->completeAsyncWrite(numberOfBytesTransferred); + } +}; + +QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) + : QSerialPortPrivateData(q) + , descriptor(INVALID_HANDLE_VALUE) + , parityErrorOccurred(false) + , actualReadBufferSize(0) + , actualWriteBufferSize(0) + , acyncWritePosition(0) + , readyReadEmitted(0) + , writeSequenceStarted(false) +{ +} + +bool QSerialPortPrivate::open(QIODevice::OpenMode mode) +{ + DWORD desiredAccess = 0; + DWORD originalEventMask = EV_ERR; + + if (mode & QIODevice::ReadOnly) { + desiredAccess |= GENERIC_READ; + originalEventMask |= EV_RXCHAR; + } + if (mode & QIODevice::WriteOnly) + desiredAccess |= GENERIC_WRITE; + + descriptor = ::CreateFile(reinterpret_cast(systemLocation.utf16()), + desiredAccess, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + + if (descriptor == INVALID_HANDLE_VALUE) { + q_ptr->setError(decodeSystemError()); + return false; + } + + if (!::GetCommState(descriptor, &restoredDcb)) { + q_ptr->setError(decodeSystemError()); + return false; + } + + currentDcb = restoredDcb; + currentDcb.fBinary = TRUE; + currentDcb.fInX = FALSE; + currentDcb.fOutX = FALSE; + currentDcb.fAbortOnError = FALSE; + currentDcb.fNull = FALSE; + currentDcb.fErrorChar = FALSE; + + if (!updateDcb()) + return false; + + if (!::GetCommTimeouts(descriptor, &restoredCommTimeouts)) { + q_ptr->setError(decodeSystemError()); + return false; + } + + ::memset(¤tCommTimeouts, 0, sizeof(currentCommTimeouts)); + currentCommTimeouts.ReadIntervalTimeout = MAXDWORD; + + if (!updateCommTimeouts()) + return false; + + if (originalEventMask & EV_RXCHAR) { + QWinEventNotifier *n = new ReadOverlappedCompletionNotifier(this, q_ptr); + n->setEnabled(true); + } + + QWinEventNotifier *n = new CommOverlappedEventNotifier(this, originalEventMask, q_ptr); + n->setEnabled(true); + + detectDefaultSettings(); + return true; +} + +void QSerialPortPrivate::close() +{ + ::CancelIo(descriptor); + + qDeleteAll(notifiers); + notifiers.clear(); + + readBuffer.clear(); + actualReadBufferSize = 0; + + writeSequenceStarted = false; + writeBuffer.clear(); + actualWriteBufferSize = 0; + acyncWritePosition = 0; + + readyReadEmitted = false; + parityErrorOccurred = false; + + if (settingsRestoredOnClose) { + ::SetCommState(descriptor, &restoredDcb); + ::SetCommTimeouts(descriptor, &restoredCommTimeouts); + } + + ::CloseHandle(descriptor); + descriptor = INVALID_HANDLE_VALUE; +} + +#endif // #ifndef Q_OS_WINCE + +QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals() const +{ + DWORD modemStat = 0; + QSerialPort::PinoutSignals ret = QSerialPort::NoSignal; + + if (!::GetCommModemStatus(descriptor, &modemStat)) { + q_ptr->setError(decodeSystemError()); + return ret; + } + + if (modemStat & MS_CTS_ON) + ret |= QSerialPort::ClearToSendSignal; + if (modemStat & MS_DSR_ON) + ret |= QSerialPort::DataSetReadySignal; + if (modemStat & MS_RING_ON) + ret |= QSerialPort::RingIndicatorSignal; + if (modemStat & MS_RLSD_ON) + ret |= QSerialPort::DataCarrierDetectSignal; + + DWORD bytesReturned = 0; + if (::DeviceIoControl(descriptor, IOCTL_SERIAL_GET_DTRRTS, NULL, 0, + &modemStat, sizeof(modemStat), + &bytesReturned, NULL)) { + + if (modemStat & SERIAL_DTR_STATE) + ret |= QSerialPort::DataTerminalReadySignal; + if (modemStat & SERIAL_RTS_STATE) + ret |= QSerialPort::RequestToSendSignal; + } + + return ret; +} + +bool QSerialPortPrivate::setDataTerminalReady(bool set) +{ + return ::EscapeCommFunction(descriptor, set ? SETDTR : CLRDTR); +} + +bool QSerialPortPrivate::setRequestToSend(bool set) +{ + return ::EscapeCommFunction(descriptor, set ? SETRTS : CLRRTS); +} + +#ifndef Q_OS_WINCE + +bool QSerialPortPrivate::flush() +{ + return startAsyncWrite() && ::FlushFileBuffers(descriptor); +} + +bool QSerialPortPrivate::clear(QSerialPort::Directions dir) +{ + DWORD flags = 0; + if (dir & QSerialPort::Input) { + flags |= PURGE_RXABORT | PURGE_RXCLEAR; + actualReadBufferSize = 0; + } + if (dir & QSerialPort::Output) { + flags |= PURGE_TXABORT | PURGE_TXCLEAR; + actualWriteBufferSize = 0; + acyncWritePosition = 0; + writeSequenceStarted = false; + } + return ::PurgeComm(descriptor, flags); +} + +#endif + +bool QSerialPortPrivate::sendBreak(int duration) +{ + // FIXME: + if (setBreakEnabled(true)) { + ::Sleep(duration); + if (setBreakEnabled(false)) + return true; + } + return false; +} + +bool QSerialPortPrivate::setBreakEnabled(bool set) +{ + if (set) + return ::SetCommBreak(descriptor); + return ::ClearCommBreak(descriptor); +} + +qint64 QSerialPortPrivate::systemInputQueueSize () const +{ + COMSTAT cs; + ::memset(&cs, 0, sizeof(cs)); + if (!::ClearCommError(descriptor, NULL, &cs)) + return -1; + return cs.cbInQue; +} + +qint64 QSerialPortPrivate::systemOutputQueueSize () const +{ + COMSTAT cs; + ::memset(&cs, 0, sizeof(cs)); + if (!::ClearCommError(descriptor, NULL, &cs)) + return -1; + return cs.cbOutQue; +} + +#ifndef Q_OS_WINCE + +qint64 QSerialPortPrivate::bytesAvailable() const +{ + return actualReadBufferSize; +} + +qint64 QSerialPortPrivate::readFromBuffer(char *data, qint64 maxSize) +{ + if (actualReadBufferSize == 0) + return 0; + + qint64 readSoFar = -1; + if (maxSize == 1 && actualReadBufferSize > 0) { + *data = readBuffer.getChar(); + actualReadBufferSize--; + readSoFar = 1; + } else { + const qint64 bytesToRead = qMin(qint64(actualReadBufferSize), maxSize); + readSoFar = 0; + while (readSoFar < bytesToRead) { + const char *ptr = readBuffer.readPointer(); + const int bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar, + qint64(readBuffer.nextDataBlockSize())); + ::memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock); + readSoFar += bytesToReadFromThisBlock; + readBuffer.free(bytesToReadFromThisBlock); + actualReadBufferSize -= bytesToReadFromThisBlock; + } + } + + return readSoFar; +} + +qint64 QSerialPortPrivate::writeToBuffer(const char *data, qint64 maxSize) +{ + char *ptr = writeBuffer.reserve(maxSize); + if (maxSize == 1) { + *ptr = *data; + actualWriteBufferSize++; + } else { + ::memcpy(ptr, data, maxSize); + actualWriteBufferSize += maxSize; + } + + if (!writeSequenceStarted) + startAsyncWrite(WriteChunkSize); + + return maxSize; +} + +bool QSerialPortPrivate::waitForReadyRead(int msecs) +{ + QElapsedTimer stopWatch; + stopWatch.start(); + + do { + bool timedOut = false; + AbstractOverlappedEventNotifier *n = 0; + + if (!waitAnyEvent(timeoutValue(msecs, stopWatch.elapsed()), &timedOut, &n) || !n) { + // This is occur timeout or another error + q_ptr->setError(decodeSystemError()); + return false; + } + + switch (n->type()) { + case AbstractOverlappedEventNotifier::CommEvent: + if (!n->processCompletionRoutine()) + return false; + break; + case AbstractOverlappedEventNotifier::ReadCompletionEvent: + return n->processCompletionRoutine(); + case AbstractOverlappedEventNotifier::WriteCompletionEvent: + n->processCompletionRoutine(); + break; + default: // newer called + return false; + } + } while (msecs == -1 || timeoutValue(msecs, stopWatch.elapsed()) > 0); + + return false; +} + +bool QSerialPortPrivate::waitForBytesWritten(int msecs) +{ + if (writeBuffer.isEmpty()) + return false; + + QElapsedTimer stopWatch; + stopWatch.start(); + + forever { + bool timedOut = false; + AbstractOverlappedEventNotifier *n = 0; + + if (!waitAnyEvent(timeoutValue(msecs, stopWatch.elapsed()), &timedOut, &n) || !n) { + q_ptr->setError(decodeSystemError()); + return false; + } + + switch (n->type()) { + case AbstractOverlappedEventNotifier::CommEvent: + // do nothing, jump to ReadCompletionEvent case + case AbstractOverlappedEventNotifier::ReadCompletionEvent: + n->processCompletionRoutine(); + break; + case AbstractOverlappedEventNotifier::WriteCompletionEvent: + return n->processCompletionRoutine(); + default: // newer called + return false; + } + } + + return false; +} + +#endif // #ifndef Q_OS_WINCE + +bool QSerialPortPrivate::setBaudRate(qint32 baudRate, QSerialPort::Directions dir) +{ + if (dir != QSerialPort::AllDirections) { + q_ptr->setError(QSerialPort::UnsupportedOperationError); + return false; + } + currentDcb.BaudRate = baudRate; + return updateDcb(); +} + +bool QSerialPortPrivate::setDataBits(QSerialPort::DataBits dataBits) +{ + currentDcb.ByteSize = dataBits; + return updateDcb(); +} + +bool QSerialPortPrivate::setParity(QSerialPort::Parity parity) +{ + currentDcb.fParity = TRUE; + switch (parity) { + case QSerialPort::NoParity: + currentDcb.Parity = NOPARITY; + currentDcb.fParity = FALSE; + break; + case QSerialPort::OddParity: + currentDcb.Parity = ODDPARITY; + break; + case QSerialPort::EvenParity: + currentDcb.Parity = EVENPARITY; + break; + case QSerialPort::MarkParity: + currentDcb.Parity = MARKPARITY; + break; + case QSerialPort::SpaceParity: + currentDcb.Parity = SPACEPARITY; + break; + default: + currentDcb.Parity = NOPARITY; + currentDcb.fParity = FALSE; + break; + } + return updateDcb(); +} + +bool QSerialPortPrivate::setStopBits(QSerialPort::StopBits stopBits) +{ + switch (stopBits) { + case QSerialPort::OneStop: + currentDcb.StopBits = ONESTOPBIT; + break; + case QSerialPort::OneAndHalfStop: + currentDcb.StopBits = ONE5STOPBITS; + break; + case QSerialPort::TwoStop: + currentDcb.StopBits = TWOSTOPBITS; + break; + default: + currentDcb.StopBits = ONESTOPBIT; + break; + } + return updateDcb(); +} + +bool QSerialPortPrivate::setFlowControl(QSerialPort::FlowControl flow) +{ + currentDcb.fInX = FALSE; + currentDcb.fOutX = FALSE; + currentDcb.fOutxCtsFlow = FALSE; + currentDcb.fRtsControl = RTS_CONTROL_DISABLE; + switch (flow) { + case QSerialPort::NoFlowControl: + break; + case QSerialPort::SoftwareControl: + currentDcb.fInX = TRUE; + currentDcb.fOutX = TRUE; + break; + case QSerialPort::HardwareControl: + currentDcb.fOutxCtsFlow = TRUE; + currentDcb.fRtsControl = RTS_CONTROL_HANDSHAKE; + break; + default: + break; + } + return updateDcb(); +} + +bool QSerialPortPrivate::setDataErrorPolicy(QSerialPort::DataErrorPolicy policy) +{ + policy = policy; + return true; +} + +#ifndef Q_OS_WINCE + +bool QSerialPortPrivate::startAsyncRead() +{ + DWORD bytesToRead = policy == QSerialPort::IgnorePolicy ? ReadChunkSize : 1; + + if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - readBuffer.size())) { + bytesToRead = readBufferMaxSize - readBuffer.size(); + if (bytesToRead == 0) { + // Buffer is full. User must read data from the buffer + // before we can read more from the port. + return false; + } + } + + AbstractOverlappedEventNotifier *n = lookupReadCompletionNotifier(); + if (!n) { + q_ptr->setError(QSerialPort::ResourceError); + return false; + } + + char *ptr = readBuffer.reserve(bytesToRead); + + if (::ReadFile(descriptor, ptr, bytesToRead, NULL, n->overlappedPointer())) + return true; + + QSerialPort::SerialPortError error = decodeSystemError(); + if (error != QSerialPort::NoError) { + if (error != QSerialPort::ResourceError) + error = QSerialPort::ReadError; + q_ptr->setError(error); + + readBuffer.truncate(actualReadBufferSize); + return false; + } + + return true; +} + +bool QSerialPortPrivate::startAsyncWrite(int maxSize) +{ + qint64 nextSize = 0; + const char *ptr = writeBuffer.readPointerAtPosition(acyncWritePosition, nextSize); + + nextSize = qMin(nextSize, qint64(maxSize)); + acyncWritePosition += nextSize; + + // no more data to write + if (!ptr || nextSize == 0) + return true; + + writeSequenceStarted = true; + + AbstractOverlappedEventNotifier *n = lookupFreeWriteCompletionNotifier(); + if (!n) { + q_ptr->setError(QSerialPort::ResourceError); + return false; + } + + n->setEnabled(true); + + if (::WriteFile(descriptor, ptr, nextSize, NULL, n->overlappedPointer())) + return true; + + QSerialPort::SerialPortError error = decodeSystemError(); + if (error != QSerialPort::NoError) { + writeSequenceStarted = false; + + if (error != QSerialPort::ResourceError) + error = QSerialPort::WriteError; + + q_ptr->setError(error); + return false; + } + + return true; +} + +#endif // #ifndef Q_OS_WINCE + +bool QSerialPortPrivate::processIoErrors(bool error) +{ + if (error) { + q_ptr->setError(QSerialPort::ResourceError); + return true; + } + + DWORD errors = 0; + const bool ret = ::ClearCommError(descriptor, &errors, NULL); + if (ret && errors) { + if (errors & CE_FRAME) { + q_ptr->setError(QSerialPort::FramingError); + } else if (errors & CE_RXPARITY) { + q_ptr->setError(QSerialPort::ParityError); + parityErrorOccurred = true; + } else if (errors & CE_BREAK) { + q_ptr->setError(QSerialPort::BreakConditionError); + } else { + q_ptr->setError(QSerialPort::UnknownError); + } + } + return ret; +} + +#ifndef Q_OS_WINCE + +bool QSerialPortPrivate::completeAsyncRead(DWORD numberOfBytes) +{ + actualReadBufferSize += qint64(numberOfBytes); + readBuffer.truncate(actualReadBufferSize); + + if (numberOfBytes > 0) { + + // Process emulate policy. + if ((policy != QSerialPort::IgnorePolicy) && parityErrorOccurred) { + + parityErrorOccurred = false; + + // Ignore received character, remove it from buffer + if (policy == QSerialPort::SkipPolicy) { + readBuffer.getChar(); + // Force returning without emitting a readyRead() signal + return true; + } + + // Abort receiving + if (policy == QSerialPort::StopReceivingPolicy) { + readyReadEmitted = true; + emit q_ptr->readyRead(); + return true; + } + + // Replace received character by zero + if (policy == QSerialPort::PassZeroPolicy) { + readBuffer.getChar(); + readBuffer.putChar('\0'); + } + + } + + readyReadEmitted = true; + emit q_ptr->readyRead(); + } + return true; +} + +bool QSerialPortPrivate::completeAsyncWrite(DWORD numberOfBytes) +{ + writeBuffer.free(numberOfBytes); + actualWriteBufferSize -= qint64(numberOfBytes); + acyncWritePosition -= qint64(numberOfBytes); + + if (numberOfBytes > 0) + emit q_ptr->bytesWritten(numberOfBytes); + + if (writeBuffer.isEmpty()) + writeSequenceStarted = false; + else + startAsyncWrite(WriteChunkSize); + + return true; +} + +AbstractOverlappedEventNotifier *QSerialPortPrivate::lookupFreeWriteCompletionNotifier() +{ + // find first free not running write notifier + foreach (AbstractOverlappedEventNotifier *n, notifiers) { + if ((n->type() == AbstractOverlappedEventNotifier::WriteCompletionEvent) + && !n->isEnabled()) { + return n; + } + } + // if all write notifiers in use, then create new write notifier + return new WriteOverlappedCompletionNotifier(this, q_ptr); +} + +AbstractOverlappedEventNotifier *QSerialPortPrivate::lookupCommEventNotifier() +{ + foreach (AbstractOverlappedEventNotifier *n, notifiers) { + if (n->type() == AbstractOverlappedEventNotifier::CommEvent) + return n; + } + return 0; +} + +AbstractOverlappedEventNotifier *QSerialPortPrivate::lookupReadCompletionNotifier() +{ + foreach (AbstractOverlappedEventNotifier *n, notifiers) { + if (n->type() == AbstractOverlappedEventNotifier::ReadCompletionEvent) + return n; + } + return 0; +} + +bool QSerialPortPrivate::updateDcb() +{ + if (!::SetCommState(descriptor, ¤tDcb)) { + q_ptr->setError(decodeSystemError()); + return false; + } + return true; +} + +bool QSerialPortPrivate::updateCommTimeouts() +{ + if (!::SetCommTimeouts(descriptor, ¤tCommTimeouts)) { + q_ptr->setError(decodeSystemError()); + return false; + } + return true; +} + +#endif // #ifndef Q_OS_WINCE + +void QSerialPortPrivate::detectDefaultSettings() +{ + // Detect baud rate. + inputBaudRate = quint32(currentDcb.BaudRate); + outputBaudRate = inputBaudRate; + + // Detect databits. + switch (currentDcb.ByteSize) { + case 5: + dataBits = QSerialPort::Data5; + break; + case 6: + dataBits = QSerialPort::Data6; + break; + case 7: + dataBits = QSerialPort::Data7; + break; + case 8: + dataBits = QSerialPort::Data8; + break; + default: + dataBits = QSerialPort::UnknownDataBits; + break; + } + + // Detect parity. + if ((currentDcb.Parity == NOPARITY) && !currentDcb.fParity) + parity = QSerialPort::NoParity; + else if ((currentDcb.Parity == SPACEPARITY) && currentDcb.fParity) + parity = QSerialPort::SpaceParity; + else if ((currentDcb.Parity == MARKPARITY) && currentDcb.fParity) + parity = QSerialPort::MarkParity; + else if ((currentDcb.Parity == EVENPARITY) && currentDcb.fParity) + parity = QSerialPort::EvenParity; + else if ((currentDcb.Parity == ODDPARITY) && currentDcb.fParity) + parity = QSerialPort::OddParity; + else + parity = QSerialPort::UnknownParity; + + // Detect stopbits. + switch (currentDcb.StopBits) { + case ONESTOPBIT: + stopBits = QSerialPort::OneStop; + break; + case ONE5STOPBITS: + stopBits = QSerialPort::OneAndHalfStop; + break; + case TWOSTOPBITS: + stopBits = QSerialPort::TwoStop; + break; + default: + stopBits = QSerialPort::UnknownStopBits; + break; + } + + // Detect flow control. + if (!currentDcb.fOutxCtsFlow && (currentDcb.fRtsControl == RTS_CONTROL_DISABLE) + && !currentDcb.fInX && !currentDcb.fOutX) { + flow = QSerialPort::NoFlowControl; + } else if (!currentDcb.fOutxCtsFlow && (currentDcb.fRtsControl == RTS_CONTROL_DISABLE) + && currentDcb.fInX && currentDcb.fOutX) { + flow = QSerialPort::SoftwareControl; + } else if (currentDcb.fOutxCtsFlow && (currentDcb.fRtsControl == RTS_CONTROL_HANDSHAKE) + && !currentDcb.fInX && !currentDcb.fOutX) { + flow = QSerialPort::HardwareControl; + } else + flow = QSerialPort::UnknownFlowControl; +} + +QSerialPort::SerialPortError QSerialPortPrivate::decodeSystemError() const +{ + QSerialPort::SerialPortError error; + switch (::GetLastError()) { + case ERROR_IO_PENDING: + error = QSerialPort::NoError; + break; + case ERROR_MORE_DATA: + error = QSerialPort::NoError; + break; + case ERROR_FILE_NOT_FOUND: + error = QSerialPort::DeviceNotFoundError; + break; + case ERROR_ACCESS_DENIED: + error = QSerialPort::PermissionError; + break; + case ERROR_INVALID_HANDLE: + error = QSerialPort::ResourceError; + break; + case ERROR_INVALID_PARAMETER: + error = QSerialPort::UnsupportedOperationError; + break; + case ERROR_BAD_COMMAND: + error = QSerialPort::ResourceError; + break; + case ERROR_DEVICE_REMOVED: + error = QSerialPort::ResourceError; + break; + default: + error = QSerialPort::UnknownError; + break; + } + return error; +} + +#ifndef Q_OS_WINCE + +bool QSerialPortPrivate::waitAnyEvent(int msecs, bool *timedOut, + AbstractOverlappedEventNotifier **triggeredNotifier) +{ + Q_ASSERT(timedOut); + + QVector handles = notifiers.keys().toVector(); + DWORD waitResult = ::WaitForMultipleObjects(handles.count(), + handles.constData(), + FALSE, // wait any event + qMax(msecs, 0)); + if (waitResult == WAIT_TIMEOUT) { + *timedOut = true; + return false; + } + + if (int(waitResult) > (handles.count() - 1)) + return false; + + HANDLE h = handles.at(waitResult - WAIT_OBJECT_0); + *triggeredNotifier = notifiers.value(h); + return true; +} + +static const QLatin1String defaultPathPrefix("\\\\.\\"); + +QString QSerialPortPrivate::portNameToSystemLocation(const QString &port) +{ + QString ret = port; + if (!ret.contains(defaultPathPrefix)) + ret.prepend(defaultPathPrefix); + return ret; +} + +QString QSerialPortPrivate::portNameFromSystemLocation(const QString &location) +{ + QString ret = location; + if (ret.contains(defaultPathPrefix)) + ret.remove(defaultPathPrefix); + return ret; +} + +#endif // #ifndef Q_OS_WINCE + +// This table contains standard values of baud rates that +// are defined in MSDN and/or in Win SDK file winbase.h + +static const QList standardBaudRatePairList() +{ + + static const QList standardBaudRatesTable = QList() + + #ifdef CBR_110 + << CBR_110 + #endif + + #ifdef CBR_300 + << CBR_300 + #endif + + #ifdef CBR_600 + << CBR_600 + #endif + + #ifdef CBR_1200 + << CBR_1200 + #endif + + #ifdef CBR_2400 + << CBR_2400 + #endif + + #ifdef CBR_4800 + << CBR_4800 + #endif + + #ifdef CBR_9600 + << CBR_9600 + #endif + + #ifdef CBR_14400 + << CBR_14400 + #endif + + #ifdef CBR_19200 + << CBR_19200 + #endif + + #ifdef CBR_38400 + << CBR_38400 + #endif + + #ifdef CBR_56000 + << CBR_56000 + #endif + + #ifdef CBR_57600 + << CBR_57600 + #endif + + #ifdef CBR_115200 + << CBR_115200 + #endif + + #ifdef CBR_128000 + << CBR_128000 + #endif + + #ifdef CBR_256000 + << CBR_256000 + #endif + ; + + return standardBaudRatesTable; +}; + +qint32 QSerialPortPrivate::baudRateFromSetting(qint32 setting) +{ + const QList baudRatePairs = standardBaudRatePairList(); + const QList::const_iterator baudRatePairListConstIterator = qFind(baudRatePairs, setting); + + return (baudRatePairListConstIterator != baudRatePairs.constEnd()) ? *baudRatePairListConstIterator : 0; +} + +qint32 QSerialPortPrivate::settingFromBaudRate(qint32 baudRate) +{ + const QList baudRatePairList = standardBaudRatePairList(); + const QList::const_iterator baudRatePairListConstIterator = qFind(baudRatePairList, baudRate); + + return (baudRatePairListConstIterator != baudRatePairList.constEnd()) ? *baudRatePairListConstIterator : 0; +} + +QList QSerialPortPrivate::standardBaudRates() +{ + QList ret; + const QList baudRatePairs = standardBaudRatePairList(); + + foreach (qint32 baudRatePair, baudRatePairs) { + ret.append(baudRatePair); + } + + return ret; +} + +QT_END_NAMESPACE diff --git a/libs/serialport/qserialport_win_p.h b/libs/serialport/qserialport_win_p.h new file mode 100644 index 0000000000..a59ea9a7bc --- /dev/null +++ b/libs/serialport/qserialport_win_p.h @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Denis Shienkov +** Copyright (C) 2012 Laszlo Papp +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSERIALPORT_WIN_P_H +#define QSERIALPORT_WIN_P_H + +#include "qserialport_p.h" + +#include + +#ifndef Q_OS_WINCE +#include +QT_BEGIN_NAMESPACE +class QWinEventNotifier; +#else +#include +QT_BEGIN_NAMESPACE +class QThread; +#endif + +#ifndef Q_OS_WINCE +class AbstractOverlappedEventNotifier; +#endif + +class QSerialPortPrivate : public QSerialPortPrivateData +{ +public: + QSerialPortPrivate(QSerialPort *q); + + bool open(QIODevice::OpenMode mode); + void close(); + + QSerialPort::PinoutSignals pinoutSignals() const; + + bool setDataTerminalReady(bool set); + bool setRequestToSend(bool set); + + bool flush(); + bool clear(QSerialPort::Directions dir); + + bool sendBreak(int duration); + bool setBreakEnabled(bool set); + + qint64 systemInputQueueSize () const; + qint64 systemOutputQueueSize () const; + + qint64 bytesAvailable() const; + + qint64 readFromBuffer(char *data, qint64 maxSize); + qint64 writeToBuffer(const char *data, qint64 maxSize); + + bool waitForReadyRead(int msec); + bool waitForBytesWritten(int msec); + + bool setBaudRate(qint32 baudRate, QSerialPort::Directions dir); + bool setDataBits(QSerialPort::DataBits dataBits); + bool setParity(QSerialPort::Parity parity); + bool setStopBits(QSerialPort::StopBits stopBits); + bool setFlowControl(QSerialPort::FlowControl flowControl); + bool setDataErrorPolicy(QSerialPort::DataErrorPolicy policy); + + bool processIoErrors(bool error); +#ifndef Q_OS_WINCE + bool startAsyncRead(); + bool startAsyncWrite(int maxSize = INT_MAX); + bool completeAsyncRead(DWORD numberOfBytes); + bool completeAsyncWrite(DWORD numberOfBytes); + AbstractOverlappedEventNotifier *lookupFreeWriteCompletionNotifier(); + AbstractOverlappedEventNotifier *lookupCommEventNotifier(); + AbstractOverlappedEventNotifier *lookupReadCompletionNotifier(); +#else + bool notifyRead(); + bool notifyWrite(int maxSize = INT_MAX); +#endif + + static QString portNameToSystemLocation(const QString &port); + static QString portNameFromSystemLocation(const QString &location); + + static qint32 baudRateFromSetting(qint32 setting); + static qint32 settingFromBaudRate(qint32 baudRate); + + static QList standardBaudRates(); + + DCB currentDcb; + DCB restoredDcb; + COMMTIMEOUTS currentCommTimeouts; + COMMTIMEOUTS restoredCommTimeouts; + HANDLE descriptor; + bool parityErrorOccurred; + +#ifndef Q_OS_WINCE + QHash notifiers; + qint64 actualReadBufferSize; + qint64 actualWriteBufferSize; + qint64 acyncWritePosition; + bool readyReadEmitted; + bool writeSequenceStarted; +#else + QThread *eventNotifier; + QMutex settingsChangeMutex; +#endif + +private: + bool updateDcb(); + bool updateCommTimeouts(); + + void detectDefaultSettings(); + QSerialPort::SerialPortError decodeSystemError() const; + +#ifndef Q_OS_WINCE + bool waitAnyEvent(int msecs, bool *timedOut, + AbstractOverlappedEventNotifier **triggeredNotifier); +#else + bool waitForReadOrWrite(bool *selectForRead, bool *selectForWrite, + bool checkRead, bool checkWrite, + int msecs, bool *timedOut); +#endif + +}; + +QT_END_NAMESPACE + +#endif // QSERIALPORT_WIN_P_H diff --git a/libs/serialport/qserialport_wince.cpp b/libs/serialport/qserialport_wince.cpp new file mode 100644 index 0000000000..78d2746b16 --- /dev/null +++ b/libs/serialport/qserialport_wince.cpp @@ -0,0 +1,509 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Denis Shienkov +** Copyright (C) 2012 Laszlo Papp +** Copyright (C) 2012 Andre Hartmann +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qserialport_win_p.h" + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +class QSerialPortPrivate; + +class CommEventNotifier : public QThread +{ + Q_OBJECT +signals: + void eventMask(quint32 mask); + +public: + CommEventNotifier(DWORD mask, QSerialPortPrivate *d, QObject *parent) + : QThread(parent), dptr(d), running(true) { + connect(this, SIGNAL(eventMask(quint32)), this, SLOT(processNotification(quint32))); + ::SetCommMask(dptr->descriptor, mask); + } + + virtual ~CommEventNotifier() { + running = false; + ::SetCommMask(dptr->descriptor, 0); + wait(); + } + +protected: + void run() Q_DECL_OVERRIDE { + DWORD mask = 0; + while (running) { + if (::WaitCommEvent(dptr->descriptor, &mask, FALSE)) { + // Wait until complete the operation changes the port settings, + // see updateDcb(). + dptr->settingsChangeMutex.lock(); + dptr->settingsChangeMutex.unlock(); + emit eventMask(quint32(mask)); + } + } + } + +private slots: + void processNotification(quint32 eventMask) { + + bool error = false; + + // Check for unexpected event. This event triggered when pulled previously + // opened device from the system, when opened as for not to read and not to + // write options and so forth. + if ((eventMask == 0) + || ((eventMask & (EV_ERR | EV_RXCHAR | EV_TXEMPTY)) == 0)) { + error = true; + } + + if (error || (EV_ERR & eventMask)) + dptr->processIoErrors(error); + if (EV_RXCHAR & eventMask) + dptr->notifyRead(); + if (EV_TXEMPTY & eventMask) + dptr->notifyWrite(QSerialPortPrivateData::WriteChunkSize); + } + +private: + QSerialPortPrivate *dptr; + mutable bool running; +}; + +class WaitCommEventBreaker : public QThread +{ + Q_OBJECT +public: + WaitCommEventBreaker(HANDLE descriptor, int timeout, QObject *parent = 0) + : QThread(parent), descriptor(descriptor), timeout(timeout), worked(false) { + start(); + } + + virtual ~WaitCommEventBreaker() { + stop(); + wait(); + } + + void stop() { + exit(0); + } + + bool isWorked() const { + return worked; + } + +protected: + void run() { + QTimer timer; + QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(processTimeout()), Qt::DirectConnection); + timer.start(timeout); + exec(); + worked = true; + } + +private slots: + void processTimeout() { + ::SetCommMask(descriptor, 0); + stop(); + } + +private: + HANDLE descriptor; + int timeout; + mutable bool worked; +}; + +QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) + : QSerialPortPrivateData(q) + , descriptor(INVALID_HANDLE_VALUE) + , parityErrorOccurred(false) + , eventNotifier(0) +{ +} + +bool QSerialPortPrivate::open(QIODevice::OpenMode mode) +{ + DWORD desiredAccess = 0; + DWORD eventMask = EV_ERR; + + if (mode & QIODevice::ReadOnly) { + desiredAccess |= GENERIC_READ; + eventMask |= EV_RXCHAR; + } + if (mode & QIODevice::WriteOnly) { + desiredAccess |= GENERIC_WRITE; + eventMask |= EV_TXEMPTY; + } + + descriptor = ::CreateFile(reinterpret_cast(systemLocation.utf16()), + desiredAccess, 0, NULL, OPEN_EXISTING, 0, NULL); + + if (descriptor == INVALID_HANDLE_VALUE) { + q_ptr->setError(decodeSystemError()); + return false; + } + + if (!::GetCommState(descriptor, &restoredDcb)) { + q_ptr->setError(decodeSystemError()); + return false; + } + + currentDcb = restoredDcb; + currentDcb.fBinary = true; + currentDcb.fInX = false; + currentDcb.fOutX = false; + currentDcb.fAbortOnError = false; + currentDcb.fNull = false; + currentDcb.fErrorChar = false; + + if (!updateDcb()) + return false; + + if (!::GetCommTimeouts(descriptor, &restoredCommTimeouts)) { + q_ptr->setError(decodeSystemError()); + return false; + } + + ::memset(¤tCommTimeouts, 0, sizeof(currentCommTimeouts)); + currentCommTimeouts.ReadIntervalTimeout = MAXDWORD; + + if (!updateCommTimeouts()) + return false; + + eventNotifier = new CommEventNotifier(eventMask, this, q_ptr); + eventNotifier->start(); + + detectDefaultSettings(); + return true; +} + +void QSerialPortPrivate::close() +{ + if (eventNotifier) { + eventNotifier->deleteLater(); + eventNotifier = 0; + } + + if (settingsRestoredOnClose) { + ::SetCommState(descriptor, &restoredDcb); + ::SetCommTimeouts(descriptor, &restoredCommTimeouts); + } + + ::CloseHandle(descriptor); + descriptor = INVALID_HANDLE_VALUE; +} + +bool QSerialPortPrivate::flush() +{ + return notifyWrite() && ::FlushFileBuffers(descriptor); +} + +bool QSerialPortPrivate::clear(QSerialPort::Directions dir) +{ + DWORD flags = 0; + if (dir & QSerialPort::Input) + flags |= PURGE_RXABORT | PURGE_RXCLEAR; + if (dir & QSerialPort::Output) + flags |= PURGE_TXABORT | PURGE_TXCLEAR; + return ::PurgeComm(descriptor, flags); +} + +qint64 QSerialPortPrivate::bytesAvailable() const +{ + return readBuffer.size(); +} + +qint64 QSerialPortPrivate::readFromBuffer(char *data, qint64 maxSize) +{ + if (readBuffer.isEmpty()) + return 0; + + if (maxSize == 1) { + *data = readBuffer.getChar(); + return 1; + } + + const qint64 bytesToRead = qMin(qint64(readBuffer.size()), maxSize); + qint64 readSoFar = 0; + while (readSoFar < bytesToRead) { + const char *ptr = readBuffer.readPointer(); + const int bytesToReadFromThisBlock = qMin(int(bytesToRead - readSoFar), + readBuffer.nextDataBlockSize()); + ::memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock); + readSoFar += bytesToReadFromThisBlock; + readBuffer.free(bytesToReadFromThisBlock); + } + + return readSoFar; +} + +qint64 QSerialPortPrivate::writeToBuffer(const char *data, qint64 maxSize) +{ + char *ptr = writeBuffer.reserve(maxSize); + if (maxSize == 1) + *ptr = *data; + else + ::memcpy(ptr, data, maxSize); + + // trigger write sequence + notifyWrite(QSerialPortPrivateData::WriteChunkSize); + + return maxSize; +} + +bool QSerialPortPrivate::waitForReadyRead(int msec) +{ + if (!readBuffer.isEmpty()) + return true; + + QElapsedTimer stopWatch; + + stopWatch.start(); + + forever { + bool readyToRead = false; + bool readyToWrite = false; + bool timedOut = false; + if (!waitForReadOrWrite(&readyToRead, &readyToWrite, + true, !writeBuffer.isEmpty(), + timeoutValue(msec, stopWatch.elapsed()), + &timedOut)) { + return false; + } + if (readyToRead) { + if (notifyRead()) + return true; + } + if (readyToWrite) + notifyWrite(WriteChunkSize); + } + return false; +} + +bool QSerialPortPrivate::waitForBytesWritten(int msec) +{ + if (writeBuffer.isEmpty()) + return false; + + QElapsedTimer stopWatch; + + stopWatch.start(); + + forever { + bool readyToRead = false; + bool readyToWrite = false; + bool timedOut = false; + if (!waitForReadOrWrite(&readyToRead, &readyToWrite, + true, !writeBuffer.isEmpty(), + timeoutValue(msec, stopWatch.elapsed()), + &timedOut)) { + return false; + } + if (readyToRead) { + if (!notifyRead()) + return false; + } + if (readyToWrite) { + if (notifyWrite(WriteChunkSize)) + return true; + } + } + return false; +} + +bool QSerialPortPrivate::notifyRead() +{ + DWORD bytesToRead = (policy == QSerialPort::IgnorePolicy) ? ReadChunkSize : 1; + + if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - readBuffer.size())) { + bytesToRead = readBufferMaxSize - readBuffer.size(); + if (bytesToRead == 0) { + // Buffer is full. User must read data from the buffer + // before we can read more from the port. + return false; + } + } + + char *ptr = readBuffer.reserve(bytesToRead); + + DWORD readBytes = 0; + BOOL sucessResult = ::ReadFile(descriptor, ptr, bytesToRead, &readBytes, NULL); + + if (!sucessResult) { + readBuffer.truncate(bytesToRead); + q_ptr->setError(QSerialPort::ReadError); + return false; + } + + readBuffer.truncate(readBytes); + + // Process emulate policy. + if ((policy != QSerialPort::IgnorePolicy) && parityErrorOccurred) { + + parityErrorOccurred = false; + + switch (policy) { + case QSerialPort::SkipPolicy: + readBuffer.getChar(); + return true; + case QSerialPort::PassZeroPolicy: + readBuffer.getChar(); + readBuffer.putChar('\0'); + break; + case QSerialPort::StopReceivingPolicy: + // FIXME: Maybe need disable read notifier? + break; + default: + break; + } + } + + if (readBytes > 0) + emit q_ptr->readyRead(); + + return true; +} + +bool QSerialPortPrivate::notifyWrite(int maxSize) +{ + int nextSize = qMin(writeBuffer.nextDataBlockSize(), maxSize); + + const char *ptr = writeBuffer.readPointer(); + + DWORD bytesWritten = 0; + if (!::WriteFile(descriptor, ptr, nextSize, &bytesWritten, NULL)) { + q_ptr->setError(QSerialPort::WriteError); + return false; + } + + writeBuffer.free(bytesWritten); + + if (bytesWritten > 0) + emit q_ptr->bytesWritten(bytesWritten); + + return true; +} + +bool QSerialPortPrivate::waitForReadOrWrite(bool *selectForRead, bool *selectForWrite, + bool checkRead, bool checkWrite, + int msecs, bool *timedOut) +{ + DWORD eventMask = 0; + // FIXME: Here the situation is not properly handled with zero timeout: + // breaker can work out before you call a method WaitCommEvent() + // and so it will loop forever! + WaitCommEventBreaker breaker(descriptor, qMax(msecs, 0)); + ::WaitCommEvent(descriptor, &eventMask, NULL); + breaker.stop(); + + if (breaker.isWorked()) + *timedOut = true; + + if (!breaker.isWorked()) { + if (checkRead) { + Q_ASSERT(selectForRead); + *selectForRead = eventMask & EV_RXCHAR; + } + if (checkWrite) { + Q_ASSERT(selectForWrite); + *selectForWrite = eventMask & EV_TXEMPTY; + } + + return true; + } + + return false; +} + +bool QSerialPortPrivate::updateDcb() +{ + QMutexLocker locker(&settingsChangeMutex); + + DWORD eventMask = 0; + // Save the event mask + if (!::GetCommMask(descriptor, &eventMask)) + return false; + + // Break event notifier from WaitCommEvent + ::SetCommMask(descriptor, 0); + // Change parameters + bool ret = ::SetCommState(descriptor, ¤tDcb); + if (!ret) + q_ptr->setError(decodeSystemError()); + // Restore the event mask + ::SetCommMask(descriptor, eventMask); + + return ret; +} + +bool QSerialPortPrivate::updateCommTimeouts() +{ + if (!::SetCommTimeouts(descriptor, ¤tCommTimeouts)) { + q_ptr->setError(decodeSystemError()); + return false; + } + return true; +} + +static const QLatin1String defaultPathPostfix(":"); + +QString QSerialPortPrivate::portNameToSystemLocation(const QString &port) +{ + QString ret = port; + if (!ret.contains(defaultPathPostfix)) + ret.append(defaultPathPostfix); + return ret; +} + +QString QSerialPortPrivate::portNameFromSystemLocation(const QString &location) +{ + QString ret = location; + if (ret.contains(defaultPathPostfix)) + ret.remove(defaultPathPostfix); + return ret; +} + +#include "qserialport_wince.moc" + +QT_END_NAMESPACE diff --git a/libs/serialport/qserialportglobal.h b/libs/serialport/qserialportglobal.h new file mode 100644 index 0000000000..03cd6a62b7 --- /dev/null +++ b/libs/serialport/qserialportglobal.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Denis Shienkov +** Copyright (C) 2012 Laszlo Papp +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSERIALPORTGLOBAL_H +#define QSERIALPORTGLOBAL_H + +#include + +QT_BEGIN_NAMESPACE + +#ifndef QT_STATIC +# if defined(QT_BUILD_SERIALPORT_LIB) +# define Q_SERIALPORT_EXPORT Q_DECL_EXPORT +# else +# define Q_SERIALPORT_EXPORT Q_DECL_IMPORT +# endif +#else +# define Q_SERIALPORT_EXPORT +#endif + +// The macro has been available only since Qt 5.0 +#ifndef Q_DECL_OVERRIDE +#define Q_DECL_OVERRIDE +#endif + +QT_END_NAMESPACE + +#endif // QSERIALPORTGLOBAL_H diff --git a/libs/serialport/qserialportinfo.cpp b/libs/serialport/qserialportinfo.cpp new file mode 100644 index 0000000000..241d344aea --- /dev/null +++ b/libs/serialport/qserialportinfo.cpp @@ -0,0 +1,259 @@ +/**************************************************************************** +** +** Copyright (C) 2011-2012 Denis Shienkov +** Copyright (C) 2011 Sergey Belyashov +** Copyright (C) 2012 Laszlo Papp +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qserialportinfo.h" +#include "qserialportinfo_p.h" +#include "qserialport.h" + +QT_BEGIN_NAMESPACE + + +/*! + \class QSerialPortInfo + + \brief Provides information about existing serial ports. + + \ingroup serialport-main + \inmodule QtSerialPort + \since 5.1 + + Use the static functions to generate a list of QSerialPortInfo + objects. Each QSerialPortInfo object in the list represents a single + serial port and can be queried for the port name, system location, + description, and manufacturer. The QSerialPortInfo class can also be + used as an input parameter for the setPort() method of the QSerialPort + class. + + \sa QSerialPort +*/ + +/*! + Constructs an empty QSerialPortInfo object. + + \sa isNull() +*/ +QSerialPortInfo::QSerialPortInfo() + : d_ptr(new QSerialPortInfoPrivate) +{ +} + +/*! + Constructs a copy of \a other. +*/ +QSerialPortInfo::QSerialPortInfo(const QSerialPortInfo &other) + : d_ptr(other.d_ptr ? new QSerialPortInfoPrivate(*other.d_ptr) : 0) +{ +} + +/*! + Constructs a QSerialPortInfo object from serial \a port. +*/ +QSerialPortInfo::QSerialPortInfo(const QSerialPort &port) + : d_ptr(new QSerialPortInfoPrivate) +{ + foreach (const QSerialPortInfo &serialPortInfo, availablePorts()) { + if (port.portName() == serialPortInfo.portName()) { + *this = serialPortInfo; + break; + } + } +} + +/*! + Constructs a QSerialPortInfo object from serial port \a name. + + This constructor finds the relevant serial port among the available ones + according to the port name \a name, and constructs the serial port info + instance for that port. +*/ +QSerialPortInfo::QSerialPortInfo(const QString &name) + : d_ptr(new QSerialPortInfoPrivate) +{ + foreach (const QSerialPortInfo &serialPortInfo, availablePorts()) { + if (name == serialPortInfo.portName()) { + *this = serialPortInfo; + break; + } + } +} + +/*! + Destroys the QSerialPortInfo object. References to the values in the + object become invalid. +*/ +QSerialPortInfo::~QSerialPortInfo() +{ +} + +/*! \fn void QSerialPortInfo::swap(QSerialPortInfo &other) + + Swaps QSerialPortInfo \a other with this QSerialPortInfo. This operation is + very fast and never fails. +*/ +void QSerialPortInfo::swap(QSerialPortInfo &other) +{ + d_ptr.swap(other.d_ptr); +} + +/*! + Sets the QSerialPortInfo object to be equal to \a other. +*/ +QSerialPortInfo& QSerialPortInfo::operator=(const QSerialPortInfo &other) +{ + QSerialPortInfo(other).swap(*this); + return *this; +} + +/*! + Returns the name of the serial port. +*/ +QString QSerialPortInfo::portName() const +{ + Q_D(const QSerialPortInfo); + return !d ? QString() : d->portName; +} + +/*! + Returns the system location of the serial port. +*/ +QString QSerialPortInfo::systemLocation() const +{ + Q_D(const QSerialPortInfo); + return !d ? QString() : d->device; +} + +/*! + Returns the description string of the serial port, + if available; otherwise returns an empty string. +*/ +QString QSerialPortInfo::description() const +{ + Q_D(const QSerialPortInfo); + return !d ? QString() : d->description; +} + +/*! + Returns the manufacturer string of the serial port, + if available; otherwise returns an empty string. +*/ +QString QSerialPortInfo::manufacturer() const +{ + Q_D(const QSerialPortInfo); + return !d ? QString() : d->manufacturer; +} + +/*! + Returns the 16-bit vendor number for the serial port, if available; + otherwise returns zero. +*/ +quint16 QSerialPortInfo::vendorIdentifier() const +{ + Q_D(const QSerialPortInfo); + return !d ? 0 : d->vendorIdentifier; +} + +/*! + Returns the 16-bit product number for the serial port, if available; + otherwise returns zero. +*/ +quint16 QSerialPortInfo::productIdentifier() const +{ + Q_D(const QSerialPortInfo); + return !d ? 0 : d->productIdentifier; +} + +/*! + Returns true if there is a valid 16-bit vendor number present; otherwise + returns false. +*/ +bool QSerialPortInfo::hasVendorIdentifier() const +{ + Q_D(const QSerialPortInfo); + return !d ? false : d->hasVendorIdentifier; +} + +/*! + Returns true if there is a valid 16-bit product number present; otherwise + returns false. +*/ +bool QSerialPortInfo::hasProductIdentifier() const +{ + Q_D(const QSerialPortInfo); + return !d ? false : d->hasProductIdentifier; +} + +/*! + \fn bool QSerialPortInfo::isNull() const + + Returns whether this QSerialPortInfo object holds a + serial port definition. +*/ + +/*! + \fn bool QSerialPortInfo::isBusy() const + + Returns true if serial port is busy; + otherwise returns false. +*/ + +/*! + \fn bool QSerialPortInfo::isValid() const + + Returns true if serial port is present on system; + otherwise returns false. +*/ + +/*! + \fn QList QSerialPortInfo::standardBaudRates() + + Returns a list of available standard baud rates supported by + the current serial port. +*/ + +/*! + \fn QList QSerialPortInfo::availablePorts() + + Returns a list of available serial ports on the system. +*/ + +QT_END_NAMESPACE diff --git a/libs/serialport/qserialportinfo.h b/libs/serialport/qserialportinfo.h new file mode 100644 index 0000000000..cf47939e66 --- /dev/null +++ b/libs/serialport/qserialportinfo.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Denis Shienkov +** Copyright (C) 2012 Laszlo Papp +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSERIALPORTINFO_H +#define QSERIALPORTINFO_H + +#include +#include + +#include +//#include + +QT_BEGIN_NAMESPACE + +class QSerialPort; +class QSerialPortInfoPrivate; +class QSerialPortInfoPrivateDeleter; + +class Q_SERIALPORT_EXPORT QSerialPortInfo +{ + Q_DECLARE_PRIVATE(QSerialPortInfo) +public: + QSerialPortInfo(); + explicit QSerialPortInfo(const QSerialPort &port); + explicit QSerialPortInfo(const QString &name); + QSerialPortInfo(const QSerialPortInfo &other); + ~QSerialPortInfo(); + + QSerialPortInfo& operator=(const QSerialPortInfo &other); + void swap(QSerialPortInfo &other); + + QString portName() const; + QString systemLocation() const; + QString description() const; + QString manufacturer() const; + + quint16 vendorIdentifier() const; + quint16 productIdentifier() const; + + bool hasVendorIdentifier() const; + bool hasProductIdentifier() const; + + bool isNull() const; + bool isBusy() const; + bool isValid() const; + + static QList standardBaudRates(); + static QList availablePorts(); + +private: + QScopedPointer d_ptr; +}; + +inline bool QSerialPortInfo::isNull() const +{ return !d_ptr; } + +QT_END_NAMESPACE + +#endif // QSERIALPORTINFO_H diff --git a/libs/serialport/qserialportinfo_mac.cpp b/libs/serialport/qserialportinfo_mac.cpp new file mode 100644 index 0000000000..1a751dfcaf --- /dev/null +++ b/libs/serialport/qserialportinfo_mac.cpp @@ -0,0 +1,272 @@ +/**************************************************************************** +** +** Copyright (C) 2011-2012 Denis Shienkov +** Copyright (C) 2011 Sergey Belyashov +** Copyright (C) 2012 Laszlo Papp +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qserialportinfo.h" +#include "qserialportinfo_p.h" + +#include + +#include +#include + +#include +#include // for kIOPropertyProductNameKey +#include +#if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) +# include +#endif +#include + +QT_BEGIN_NAMESPACE + +enum { MATCHING_PROPERTIES_COUNT = 6 }; + +QList QSerialPortInfo::availablePorts() +{ + QList serialPortInfoList; + + int matchingPropertiesCounter = 0; + + + ::CFMutableDictionaryRef matching = ::IOServiceMatching(kIOSerialBSDServiceValue); + if (!matching) + return serialPortInfoList; + + ::CFDictionaryAddValue(matching, + CFSTR(kIOSerialBSDTypeKey), + CFSTR(kIOSerialBSDAllTypes)); + + io_iterator_t iter = 0; + kern_return_t kr = ::IOServiceGetMatchingServices(kIOMasterPortDefault, + matching, + &iter); + + if (kr != kIOReturnSuccess) + return serialPortInfoList; + + io_registry_entry_t service; + + while ((service = ::IOIteratorNext(iter))) { + + ::CFTypeRef device = 0; + ::CFTypeRef portName = 0; + ::CFTypeRef description = 0; + ::CFTypeRef manufacturer = 0; + ::CFTypeRef vendorIdentifier = 0; + ::CFTypeRef productIdentifier = 0; + + io_registry_entry_t entry = service; + + // Find MacOSX-specific properties names. + do { + + if (!device) { + device = + ::IORegistryEntrySearchCFProperty(entry, + kIOServicePlane, + CFSTR(kIOCalloutDeviceKey), + kCFAllocatorDefault, + 0); + if (device) + ++matchingPropertiesCounter; + } + + if (!portName) { + portName = + ::IORegistryEntrySearchCFProperty(entry, + kIOServicePlane, + CFSTR(kIOTTYDeviceKey), + kCFAllocatorDefault, + 0); + if (portName) + ++matchingPropertiesCounter; + } + + if (!description) { + description = + ::IORegistryEntrySearchCFProperty(entry, + kIOServicePlane, + CFSTR(kIOPropertyProductNameKey), + kCFAllocatorDefault, + 0); + if (!description) + description = + ::IORegistryEntrySearchCFProperty(entry, + kIOServicePlane, + CFSTR(kUSBProductString), + kCFAllocatorDefault, + 0); + if (!description) + description = + ::IORegistryEntrySearchCFProperty(entry, + kIOServicePlane, + CFSTR("BTName"), + kCFAllocatorDefault, + 0); + + if (description) + ++matchingPropertiesCounter; + } + + if (!manufacturer) { + manufacturer = + ::IORegistryEntrySearchCFProperty(entry, + kIOServicePlane, + CFSTR(kUSBVendorString), + kCFAllocatorDefault, + 0); + if (manufacturer) + ++matchingPropertiesCounter; + + } + + if (!vendorIdentifier) { + vendorIdentifier = + ::IORegistryEntrySearchCFProperty(entry, + kIOServicePlane, + CFSTR(kUSBVendorID), + kCFAllocatorDefault, + 0); + if (vendorIdentifier) + ++matchingPropertiesCounter; + + } + + if (!productIdentifier) { + productIdentifier = + ::IORegistryEntrySearchCFProperty(entry, + kIOServicePlane, + CFSTR(kUSBProductID), + kCFAllocatorDefault, + 0); + if (productIdentifier) + ++matchingPropertiesCounter; + + } + + // If all matching properties is found, then force break loop. + if (matchingPropertiesCounter == MATCHING_PROPERTIES_COUNT) + break; + + kr = ::IORegistryEntryGetParentEntry(entry, kIOServicePlane, &entry); + + } while (kr == kIOReturnSuccess); + + (void) ::IOObjectRelease(entry); + + // Convert from MacOSX-specific properties to Qt4-specific. + if (matchingPropertiesCounter > 0) { + + QSerialPortInfo serialPortInfo; + QByteArray buffer(MAXPATHLEN, 0); + + if (device) { + if (::CFStringGetCString(CFStringRef(device), + buffer.data(), + buffer.size(), + kCFStringEncodingUTF8)) { + serialPortInfo.d_ptr->device = QString::fromUtf8(buffer); + } + ::CFRelease(device); + } + + if (portName) { + if (::CFStringGetCString(CFStringRef(portName), + buffer.data(), + buffer.size(), + kCFStringEncodingUTF8)) { + serialPortInfo.d_ptr->portName = QString::fromUtf8(buffer); + } + ::CFRelease(portName); + } + + if (description) { + if (::CFStringGetCString(CFStringRef(description), + buffer.data(), + buffer.size(), + kCFStringEncodingUTF8)) { + serialPortInfo.d_ptr->description = QString::fromUtf8(buffer); + } + ::CFRelease(description); + } + + if (manufacturer) { + if (::CFStringGetCString(CFStringRef(manufacturer), + buffer.data(), + buffer.size(), + kCFStringEncodingUTF8)) { + serialPortInfo.d_ptr->manufacturer = QString::fromUtf8(buffer); + } + ::CFRelease(manufacturer); + } + + quint16 value = 0; + + if (vendorIdentifier) { + serialPortInfo.d_ptr->hasVendorIdentifier = ::CFNumberGetValue(CFNumberRef(vendorIdentifier), kCFNumberIntType, &value); + if (serialPortInfo.d_ptr->hasVendorIdentifier) + serialPortInfo.d_ptr->vendorIdentifier = value; + + ::CFRelease(vendorIdentifier); + } + + if (productIdentifier) { + serialPortInfo.d_ptr->hasProductIdentifier = ::CFNumberGetValue(CFNumberRef(productIdentifier), kCFNumberIntType, &value); + if (serialPortInfo.d_ptr->hasProductIdentifier) + serialPortInfo.d_ptr->productIdentifier = value; + + ::CFRelease(productIdentifier); + } + + serialPortInfoList.append(serialPortInfo); + } + + (void) ::IOObjectRelease(service); + } + + (void) ::IOObjectRelease(iter); + + return serialPortInfoList; +} + +QT_END_NAMESPACE diff --git a/libs/serialport/qserialportinfo_p.h b/libs/serialport/qserialportinfo_p.h new file mode 100644 index 0000000000..1f12e69bac --- /dev/null +++ b/libs/serialport/qserialportinfo_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2011-2012 Denis Shienkov +** Copyright (C) 2011 Sergey Belyashov +** Copyright (C) 2012 Laszlo Papp +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSERIALPORTINFO_P_H +#define QSERIALPORTINFO_P_H + +#include + +QT_BEGIN_NAMESPACE + +class QSerialPortInfoPrivate +{ +public: + QSerialPortInfoPrivate() + : vendorIdentifier(0) + , productIdentifier(0) + , hasVendorIdentifier(false) + , hasProductIdentifier(false) + {} + + ~QSerialPortInfoPrivate() {} + + QString portName; + QString device; + QString description; + QString manufacturer; + + quint16 vendorIdentifier; + quint16 productIdentifier; + + bool hasVendorIdentifier; + bool hasProductIdentifier; +}; + +class QSerialPortInfoPrivateDeleter +{ +public: + static void cleanup(QSerialPortInfoPrivate *p) { + delete p; + } +}; + +QT_END_NAMESPACE + +#endif // QSERIALPORTINFO_P_H diff --git a/libs/serialport/qserialportinfo_symbian.cpp b/libs/serialport/qserialportinfo_symbian.cpp new file mode 100644 index 0000000000..55120485e6 --- /dev/null +++ b/libs/serialport/qserialportinfo_symbian.cpp @@ -0,0 +1,249 @@ +/**************************************************************************** +** +** Copyright (C) 2011-2012 Denis Shienkov +** Copyright (C) 2011 Sergey Belyashov +** Copyright (C) 2012 Laszlo Papp +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qserialportinfo.h" +#include "qserialportinfo_p.h" +#include "qserialport_symbian_p.h" + +#include +//#include +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +// Physical device driver. +#ifdef __WINS__ +_LIT(KPddName, "ECDRV"); +#else // defined (__EPOC32__) +_LIT(KPddName, "EUART"); +#endif + +// Logical native device driver. +_LIT(KLddName,"ECOMM"); + +// Modules names. +_LIT(KRS232ModuleName , "ECUART"); +_LIT(KBluetoothModuleName , "BTCOMM"); +_LIT(KInfraRedModuleName , "IRCOMM"); +_LIT(KACMModuleName, "ECACM"); + +// Return false on error load. +static bool loadDevices() +{ + TInt r = KErrNone; +#ifdef __WINS__ + RFs fileServer; + r = User::LeaveIfError(fileServer.Connect()); + if (r != KErrNone) + return false; + fileServer.Close (); +#endif + + r = User::LoadPhysicalDevice(KPddName); + if (r != KErrNone && r != KErrAlreadyExists) + return false; //User::Leave(r); + + r = User::LoadLogicalDevice(KLddName); + if (r != KErrNone && r != KErrAlreadyExists) + return false; //User::Leave(r); + +#ifndef __WINS__ + r = StartC32(); + if (r != KErrNone && r != KErrAlreadyExists) + return false; //User::Leave(r); +#endif + + return true; +} + +QList QSerialPortInfo::availablePorts() +{ + QList serialPortInfoList; + + if (!loadDevices()) + return serialPortInfoList; + + RCommServ server; + TInt r = server.Connect(); + if (r != KErrNone) + return serialPortInfoList; //User::LeaveIfError(r); + + TSerialInfo nativeSerialInfo; // Native Symbian OS port info class. + QString s("%1::%2"); + + // FIXME: Get info about RS232 ports. + r = server.LoadCommModule(KRS232ModuleName); + //User::LeaveIfError(r); + if (r == KErrNone) { + r = server.GetPortInfo(KRS232ModuleName, nativeSerialInfo); + if (r == KErrNone) { + for (quint32 i = nativeSerialInfo.iLowUnit; i < nativeSerialInfo.iHighUnit + 1; ++i) { + + QSerialPortInfo serialPortInfo; + + serialPortInfo.d_ptr->device = s + .arg(QString::fromUtf16(nativeSerialInfo.iName.Ptr(), nativeSerialInfo.iName.Length())) + .arg(i); + serialPortInfo.d_ptr->portName = serialPortInfo.d_ptr->device; + serialPortInfo.d_ptr->description = + QString::fromUtf16(nativeSerialInfo.iDescription.Ptr(), nativeSerialInfo.iDescription.Length()); + serialPortInfo.d_ptr->manufacturer = QString(QObject::tr("Unknown.")); + serialPortInfoList.append(serialPortInfo); + } + } + } + + // FIXME: Get info about Bluetooth ports. + r = server.LoadCommModule(KBluetoothModuleName); + //User::LeaveIfError(r); + if (r == KErrNone) { + r = server.GetPortInfo(KBluetoothModuleName, nativeSerialInfo); + if (r == KErrNone) { + for (quint32 i = nativeSerialInfo.iLowUnit; i < nativeSerialInfo.iHighUnit + 1; ++i) { + + QSerialPortInfo serialPortInfo; + + serialPortInfo.d_ptr->device = s + .arg(QString::fromUtf16(nativeSerialInfo.iName.Ptr(), nativeSerialInfo.iName.Length())) + .arg(i); + serialPortInfo.d_ptr->portName = serialPortInfo.d_ptr->device; + serialPortInfo.d_ptr->description = + QString::fromUtf16(nativeSerialInfo.iDescription.Ptr(), nativeSerialInfo.iDescription.Length()); + serialPortInfo.d_ptr->manufacturer = QString(QObject::tr("Unknown.")); + serialPortInfoList.append(serialPortInfo); + } + } + } + + // FIXME: Get info about InfraRed ports. + r = server.LoadCommModule(KInfraRedModuleName); + //User::LeaveIfError(r); + if (r == KErrNone) { + r = server.GetPortInfo(KInfraRedModuleName, nativeSerialInfo); + if (r == KErrNone) { + for (quint32 i = nativeSerialInfo.iLowUnit; i < nativeSerialInfo.iHighUnit + 1; ++i) { + + QSerialPortInfo serialPortInfo; + + serialPortInfo.d_ptr->device = s + .arg(QString::fromUtf16(nativeSerialInfo.iName.Ptr(), nativeSerialInfo.iName.Length())) + .arg(i); + serialPortInfo.d_ptr->portName = serialPortInfo.d_ptr->device; + serialPortInfo.d_ptr->description = + QString::fromUtf16(nativeSerialInfo.iDescription.Ptr(), nativeSerialInfo.iDescription.Length()); + serialPortInfo.d_ptr->manufacturer = QString(QObject::tr("Unknown.")); + serialPortInfoList.append(serialPortInfo); + } + } + } + + // FIXME: Get info about ACM ports. + r = server.LoadCommModule(KACMModuleName); + //User::LeaveIfError(r); + if (r == KErrNone) { + r = server.GetPortInfo(KACMModuleName, nativeSerialInfo); + if (r == KErrNone) { + for (quint32 i = nativeSerialInfo.iLowUnit; i < nativeSerialInfo.iHighUnit + 1; ++i) { + + QSerialPortInfo serialPortInfo; + + serialPortInfo.d_ptr->device = s + .arg(QString::fromUtf16(nativeSerialInfo.iName.Ptr(), nativeSerialInfo.iName.Length())) + .arg(i); + serialPortInfo.d_ptr->portName = QSerialPortPrivate::portNameFromSystemLocation(serialPortInfo.d_ptr->device); + serialPortInfo.d_ptr->description = + QString::fromUtf16(nativeSerialInfo.iDescription.Ptr(), nativeSerialInfo.iDescription.Length()); + serialPortInfo.d_ptr->manufacturer = QString(QObject::tr("Unknown.")); + serialPortInfoList.append(serialPortInfo); + } + } + } + + return serialPortInfoList; +} + +QList QSerialPortInfo::standardBaudRates() +{ + return QSerialPortPrivate::standardBaudRates(); +} + +bool QSerialPortInfo::isBusy() const +{ + if (!loadDevices()) + return false; + + RCommServ server; + TInt r = server.Connect(); + if (r != KErrNone) + return false; + + RComm port; + TPtrC portName(static_cast(systemLocation().utf16()), systemLocation().length()); + r = port.Open(server, portName, ECommExclusive); + if (r == KErrNone) + port.Close(); + return r == KErrLocked; +} + +bool QSerialPortInfo::isValid() const +{ + if (!loadDevices()) + return false; + + RCommServ server; + TInt r = server.Connect(); + if (r != KErrNone) + return false; + + RComm port; + TPtrC portName(static_cast(systemLocation().utf16()), systemLocation().length()); + r = port.Open(server, portName, ECommExclusive); + if (r == KErrNone) + port.Close(); + return r == KErrNone || r == KErrLocked; +} + +QT_END_NAMESPACE diff --git a/libs/serialport/qserialportinfo_unix.cpp b/libs/serialport/qserialportinfo_unix.cpp new file mode 100644 index 0000000000..1d56f4e22b --- /dev/null +++ b/libs/serialport/qserialportinfo_unix.cpp @@ -0,0 +1,261 @@ +/**************************************************************************** +** +** Copyright (C) 2011-2012 Denis Shienkov +** Copyright (C) 2011 Sergey Belyashov +** Copyright (C) 2012 Laszlo Papp +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qserialportinfo.h" +#include "qserialportinfo_p.h" +#include "qttylocker_unix_p.h" +#include "qserialport_unix_p.h" +#include + +#ifndef Q_OS_MAC + +#if defined (Q_OS_LINUX) && defined (HAVE_LIBUDEV) +extern "C" +{ +#include +} +#else +#include +#include +#endif + +#endif // Q_OS_MAC + +QT_BEGIN_NAMESPACE + +#ifndef Q_OS_MAC + +#if !(defined (Q_OS_LINUX) && defined (HAVE_LIBUDEV)) + +static inline const QStringList& filtersOfDevices() +{ + static const QStringList deviceFileNameFilterList = QStringList() + +# ifdef Q_OS_LINUX + << QLatin1String("ttyS*") // Standart UART 8250 and etc. + << QLatin1String("ttyUSB*") // Usb/serial converters PL2303 and etc. + << QLatin1String("ttyACM*") // CDC_ACM converters (i.e. Mobile Phones). + << QLatin1String("ttyGS*") // Gadget serial device (i.e. Mobile Phones with gadget serial driver). + << QLatin1String("ttyMI*") // MOXA pci/serial converters. + << QLatin1String("ttyAMA*") // AMBA serial device for embedded platform on ARM (i.e. Raspberry Pi). + << QLatin1String("rfcomm*") // Bluetooth serial device. + << QLatin1String("ircomm*"); // IrDA serial device. +# elif defined (Q_OS_FREEBSD) + << QLatin1String("cu*"); +# else + ; // Here for other *nix OS. +# endif + + return deviceFileNameFilterList; +} + +#endif + +QList QSerialPortInfo::availablePorts() +{ + QList serialPortInfoList; + +#if defined (Q_OS_LINUX) && defined (HAVE_LIBUDEV) + + // White list for devices without a parent + static const QString rfcommDeviceName(QLatin1String("rfcomm")); + + struct ::udev *udev = ::udev_new(); + if (udev) { + + struct ::udev_enumerate *enumerate = + ::udev_enumerate_new(udev); + + if (enumerate) { + + ::udev_enumerate_add_match_subsystem(enumerate, "tty"); + ::udev_enumerate_scan_devices(enumerate); + + struct ::udev_list_entry *devices = + ::udev_enumerate_get_list_entry(enumerate); + + struct ::udev_list_entry *dev_list_entry; + udev_list_entry_foreach(dev_list_entry, devices) { + + struct ::udev_device *dev = + ::udev_device_new_from_syspath(udev, + ::udev_list_entry_get_name(dev_list_entry)); + + if (dev) { + + QSerialPortInfo serialPortInfo; + + serialPortInfo.d_ptr->device = + QLatin1String(::udev_device_get_devnode(dev)); + serialPortInfo.d_ptr->portName = + QLatin1String(::udev_device_get_sysname(dev)); + + struct ::udev_device *parentdev = ::udev_device_get_parent(dev); + + bool canAppendToList = true; + + if (parentdev) { + + QLatin1String subsys(::udev_device_get_subsystem(parentdev)); + + if (subsys == QLatin1String("usb-serial") + || subsys == QLatin1String("usb")) { // USB bus type + // Append this devices and try get additional information about them. + serialPortInfo.d_ptr->description = QString( + QLatin1String(::udev_device_get_property_value(dev, + "ID_MODEL"))).replace('_', ' '); + serialPortInfo.d_ptr->manufacturer = QString( + QLatin1String(::udev_device_get_property_value(dev, + "ID_VENDOR"))).replace('_', ' '); + + serialPortInfo.d_ptr->vendorIdentifier = + QString::fromLatin1(::udev_device_get_property_value(dev, + "ID_VENDOR_ID")).toInt(&serialPortInfo.d_ptr->hasVendorIdentifier, 16); + + serialPortInfo.d_ptr->productIdentifier = + QString::fromLatin1(::udev_device_get_property_value(dev, + "ID_MODEL_ID")).toInt(&serialPortInfo.d_ptr->hasProductIdentifier, 16); + + } else if (subsys == QLatin1String("pnp")) { // PNP bus type + // Append this device. + // FIXME: How to get additional information about serial devices + // with this subsystem? + } else if (subsys == QLatin1String("platform")) { // Platform 'pseudo' bus for legacy device. + // Skip this devices because this type of subsystem does + // not include a real physical serial device. + canAppendToList = false; + } else { // Others types of subsystems. + // Append this devices because we believe that any other types of + // subsystems provide a real serial devices. For example, for devices + // such as ttyGSx, its driver provide an empty subsystem name, but it + // devices is a real physical serial devices. + // FIXME: How to get additional information about serial devices + // with this subsystems? + } + } else { // Devices without a parent + if (serialPortInfo.d_ptr->portName.startsWith(rfcommDeviceName)) { // Bluetooth device + bool ok; + // Check for an unsigned decimal integer at the end of the device name: "rfcomm0", "rfcomm15" + // devices with negative and invalid numbers in the name are rejected + int portNumber = serialPortInfo.d_ptr->portName.mid(rfcommDeviceName.length()).toInt(&ok); + + if (!ok || (portNumber < 0) || (portNumber > 255)) { + canAppendToList = false; + } + } else { + canAppendToList = false; + } + } + + if (canAppendToList) + serialPortInfoList.append(serialPortInfo); + + ::udev_device_unref(dev); + } + + } + + ::udev_enumerate_unref(enumerate); + } + + ::udev_unref(udev); + } + +#elif defined (Q_OS_FREEBSD) && defined (HAVE_LIBUSB) + // TODO: Implement me. +#else + + QDir devDir(QLatin1String("/dev")); + if (devDir.exists()) { + + devDir.setNameFilters(filtersOfDevices()); + devDir.setFilter(QDir::Files | QDir::System | QDir::NoSymLinks); + + QStringList foundDevices; // Found devices list. + + foreach (const QFileInfo &deviceFileInfo, devDir.entryInfoList()) { + QString deviceFilePath = deviceFileInfo.absoluteFilePath(); + if (!foundDevices.contains(deviceFilePath)) { + foundDevices.append(deviceFilePath); + + QSerialPortInfo serialPortInfo; + + serialPortInfo.d_ptr->device = deviceFilePath; + serialPortInfo.d_ptr->portName = QSerialPortPrivate::portNameFromSystemLocation(deviceFilePath); + + // Get description, manufacturer, vendor identifier, product + // identifier are not supported. + + serialPortInfoList.append(serialPortInfo); + + } + } + } + +#endif + + return serialPortInfoList; +} + +#endif // Q_OS_MAC + +// common part + +QList QSerialPortInfo::standardBaudRates() +{ + return QSerialPortPrivate::standardBaudRates(); +} + +bool QSerialPortInfo::isBusy() const +{ + bool currentPid = false; + return QTtyLocker::isLocked(portName().toLocal8Bit().constData(), ¤tPid); +} + +bool QSerialPortInfo::isValid() const +{ + QFile f(systemLocation()); + return f.exists(); +} + +QT_END_NAMESPACE diff --git a/libs/serialport/qserialportinfo_win.cpp b/libs/serialport/qserialportinfo_win.cpp new file mode 100644 index 0000000000..7ca1f5ef4c --- /dev/null +++ b/libs/serialport/qserialportinfo_win.cpp @@ -0,0 +1,233 @@ +/**************************************************************************** +** +** Copyright (C) 2011-2012 Denis Shienkov +** Copyright (C) 2011 Sergey Belyashov +** Copyright (C) 2012 Laszlo Papp +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qserialportinfo.h" +#include "qserialportinfo_p.h" +#include "qserialport_win_p.h" + +#ifndef Q_OS_WINCE +#include +#include +#endif + +#include +#include + +QT_BEGIN_NAMESPACE + +#ifndef Q_OS_WINCE + +static const GUID guidsArray[] = +{ + // Windows Ports Class GUID + { 0x4D36E978, 0xE325, 0x11CE, { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }, + // Virtual Ports Class GUID (i.e. com0com and etc) + { 0xDF799E12, 0x3C56, 0x421B, { 0xB2, 0x98, 0xB6, 0xD3, 0x64, 0x2B, 0xC8, 0x78 } }, + // Windows Modems Class GUID + { 0x4D36E96D, 0xE325, 0x11CE, { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }, + // Eltima Virtual Serial Port Driver v4 GUID + { 0xCC0EF009, 0xB820, 0x42F4, { 0x95, 0xA9, 0x9B, 0xFA, 0x6A, 0x5A, 0xB7, 0xAB } }, + // Advanced Virtual COM Port GUID + { 0x9341CD95, 0x4371, 0x4A37, { 0xA5, 0xAF, 0xFD, 0xB0, 0xA9, 0xD1, 0x96, 0x31 } }, +}; + +static QVariant deviceRegistryProperty(HDEVINFO deviceInfoSet, + PSP_DEVINFO_DATA deviceInfoData, + DWORD property) +{ + DWORD dataType = 0; + DWORD dataSize = 0; + ::SetupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, + property, &dataType, NULL, 0, &dataSize); + QByteArray data(dataSize, 0); + if (!::SetupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, NULL, + reinterpret_cast(data.data()), + dataSize, NULL) + || !dataSize) { + return QVariant(); + } + + switch (dataType) { + + case REG_EXPAND_SZ: + case REG_SZ: { + return QVariant(QString::fromWCharArray(reinterpret_cast(data.constData()))); + } + + case REG_MULTI_SZ: { + QStringList list; + int i = 0; + forever { + QString s = QString::fromWCharArray(reinterpret_cast(data.constData()) + i); + i += s.length() + 1; + if (s.isEmpty()) + break; + list.append(s); + } + return QVariant(list); + } + + default: + break; + } + + return QVariant(); +} + +static QString devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData) +{ + static const wchar_t portKeyName[] = L"PortName"; + + const HKEY key = ::SetupDiOpenDevRegKey(deviceInfoSet, deviceInfoData, DICS_FLAG_GLOBAL, + 0, DIREG_DEV, KEY_READ); + if (key == INVALID_HANDLE_VALUE) + return QString(); + + DWORD dataSize; + if (::RegQueryValueEx(key, portKeyName, NULL, NULL, NULL, &dataSize) != ERROR_SUCCESS) { + ::RegCloseKey(key); + return QString(); + } + + QByteArray data(dataSize, 0); + + if (::RegQueryValueEx(key, portKeyName, NULL, NULL, + reinterpret_cast(data.data()), &dataSize) != ERROR_SUCCESS) { + ::RegCloseKey(key); + return QString(); + } + ::RegCloseKey(key); + return QString::fromWCharArray(((const wchar_t *)data.constData())); +} + +QList QSerialPortInfo::availablePorts() +{ + static const QString vendorIdentifierPrefix(QLatin1String("VID_")); + static const int vendorIdentifierSize = 4; + static const QString productIdentifierPrefix(QLatin1String("PID_")); + static const int productIdentifierSize = 4; + + QList serialPortInfoList; + static const int guidCount = sizeof(guidsArray)/sizeof(guidsArray[0]); + + for (int i = 0; i < guidCount; ++i) { + const HDEVINFO deviceInfoSet = ::SetupDiGetClassDevs(&guidsArray[i], NULL, 0, DIGCF_PRESENT); + if (deviceInfoSet == INVALID_HANDLE_VALUE) + return serialPortInfoList; + + SP_DEVINFO_DATA deviceInfoData; + ::memset(&deviceInfoData, 0, sizeof(deviceInfoData)); + deviceInfoData.cbSize = sizeof(deviceInfoData); + + DWORD index = 0; + while (::SetupDiEnumDeviceInfo(deviceInfoSet, index++, &deviceInfoData)) { + QSerialPortInfo serialPortInfo; + + QString s = devicePortName(deviceInfoSet, &deviceInfoData); + if (s.isEmpty() || s.contains(QLatin1String("LPT"))) + continue; + + serialPortInfo.d_ptr->portName = s; + serialPortInfo.d_ptr->device = QSerialPortPrivate::portNameToSystemLocation(s); + serialPortInfo.d_ptr->description = + deviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_DEVICEDESC).toString(); + serialPortInfo.d_ptr->manufacturer = + deviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_MFG).toString(); + + s = deviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_HARDWAREID).toStringList().first().toUpper(); + + int index = s.indexOf(vendorIdentifierPrefix); + if (index != -1) + serialPortInfo.d_ptr->vendorIdentifier = s.mid(index + vendorIdentifierPrefix.size(), vendorIdentifierSize) + .toInt(&serialPortInfo.d_ptr->hasVendorIdentifier, 16); + + index = s.indexOf(productIdentifierPrefix); + if (index != -1) + serialPortInfo.d_ptr->productIdentifier = s.mid(index + productIdentifierPrefix.size(), productIdentifierSize) + .toInt(&serialPortInfo.d_ptr->hasProductIdentifier, 16); + + serialPortInfoList.append(serialPortInfo); + } + ::SetupDiDestroyDeviceInfoList(deviceInfoSet); + } + return serialPortInfoList; +} + +#endif + +// common part + +QList QSerialPortInfo::standardBaudRates() +{ + return QSerialPortPrivate::standardBaudRates(); +} + +bool QSerialPortInfo::isBusy() const +{ + const HANDLE descriptor = ::CreateFile(reinterpret_cast(systemLocation().utf16()), + GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + + if (descriptor == INVALID_HANDLE_VALUE) { + if (::GetLastError() == ERROR_ACCESS_DENIED) + return true; + } else { + ::CloseHandle(descriptor); + } + return false; +} + +bool QSerialPortInfo::isValid() const +{ + const HANDLE descriptor = ::CreateFile(reinterpret_cast(systemLocation().utf16()), + GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + + if (descriptor == INVALID_HANDLE_VALUE) { + if (::GetLastError() != ERROR_ACCESS_DENIED) + return false; + } else { + ::CloseHandle(descriptor); + } + return true; +} + +QT_END_NAMESPACE diff --git a/libs/serialport/qserialportinfo_wince.cpp b/libs/serialport/qserialportinfo_wince.cpp new file mode 100644 index 0000000000..279aceae41 --- /dev/null +++ b/libs/serialport/qserialportinfo_wince.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2011-2012 Denis Shienkov +** Copyright (C) 2011 Sergey Belyashov +** Copyright (C) 2012 Laszlo Papp +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qserialportinfo.h" +#include "qserialportinfo_p.h" +#include "qserialport_win_p.h" + +#include + +QT_BEGIN_NAMESPACE + +static QString findDescription(HKEY parentKeyHandle, const QString &subKey) +{ + const static QString valueName(QLatin1String("FriendlyName")); + + QString result; + HKEY hSubKey = 0; + LONG res = ::RegOpenKeyEx(parentKeyHandle, reinterpret_cast(subKey.utf16()), + 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hSubKey); + + if (res == ERROR_SUCCESS) { + + DWORD dataType = 0; + DWORD dataSize = 0; + res = ::RegQueryValueEx(hSubKey, reinterpret_cast(valueName.utf16()), + NULL, &dataType, NULL, &dataSize); + + if (res == ERROR_SUCCESS) { + QByteArray data(dataSize, 0); + res = ::RegQueryValueEx(hSubKey, reinterpret_cast(valueName.utf16()), + NULL, NULL, + reinterpret_cast(data.data()), + &dataSize); + + if (res == ERROR_SUCCESS) { + switch (dataType) { + case REG_EXPAND_SZ: + case REG_SZ: + if (dataSize) + result = QString::fromWCharArray(reinterpret_cast(data.constData())); + break; + default: + break; + } + } + } else { + DWORD index = 0; + dataSize = 255; // Max. key length (see MSDN). + QByteArray data(dataSize, 0); + while (::RegEnumKeyEx(hSubKey, index++, + reinterpret_cast(data.data()), &dataSize, + NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { + + result = findDescription(hSubKey, + QString::fromUtf16(reinterpret_cast(data.data()), dataSize)); + if (!result.isEmpty()) + break; + } + } + ::RegCloseKey(hSubKey); + } + return result; +} + +QList QSerialPortInfo::availablePorts() +{ + QList serialPortInfoList; + + DEVMGR_DEVICE_INFORMATION di; + di.dwSize = sizeof(di); + const HANDLE hSearch = ::FindFirstDevice(DeviceSearchByLegacyName, + L"COM*", + &di); + if (hSearch != INVALID_HANDLE_VALUE) { + do { + QSerialPortInfo serialPortInfo; + serialPortInfo.d_ptr->device = QString::fromWCharArray(di.szLegacyName); + serialPortInfo.d_ptr->portName = QSerialPortPrivate::portNameFromSystemLocation(serialPortInfo.d_ptr->device); + serialPortInfo.d_ptr->description = findDescription(HKEY_LOCAL_MACHINE, + QString::fromWCharArray(di.szDeviceKey)); + + // Get manufacturer, vendor identifier, product identifier are not + // possible. + + serialPortInfoList.append(serialPortInfo); + + } while (::FindNextDevice(hSearch, &di)); + ::FindClose(hSearch); + } + + return serialPortInfoList; +} + +QT_END_NAMESPACE diff --git a/libs/serialport/qt4support/install-helper.pri b/libs/serialport/qt4support/install-helper.pri new file mode 100644 index 0000000000..52577095e3 --- /dev/null +++ b/libs/serialport/qt4support/install-helper.pri @@ -0,0 +1,43 @@ +QTSERIALPORT_PROJECT_INCLUDEDIR = $$QTSERIALPORT_BUILD_ROOT/include/QtSerialPort +QTSERIALPORT_PROJECT_INCLUDEDIR ~=s,/,$$QMAKE_DIR_SEP, + +system("$$QMAKE_MKDIR $$QTSERIALPORT_PROJECT_INCLUDEDIR") + +for(header_file, PUBLIC_HEADERS) { + header_file ~=s,/,$$QMAKE_DIR_SEP, + system("$$QMAKE_COPY \"$${header_file}\" \"$$QTSERIALPORT_PROJECT_INCLUDEDIR\"") +} + +# This is a quick workaround for generating forward header with Qt4. + +unix { + system("echo \'$${LITERAL_HASH}include \"qserialport.h\"\' > \"$$QTSERIALPORT_PROJECT_INCLUDEDIR/QSerialPort\"") + system("echo \'$${LITERAL_HASH}include \"qserialportinfo.h\"\' > \"$$QTSERIALPORT_PROJECT_INCLUDEDIR/QSerialPortInfo\"") +} win32 { + system("echo $${LITERAL_HASH}include \"qserialport.h\" > \"$$QTSERIALPORT_PROJECT_INCLUDEDIR/QSerialPort\"") + system("echo $${LITERAL_HASH}include \"qserialportinfo.h\" > \"$$QTSERIALPORT_PROJECT_INCLUDEDIR/QSerialPortInfo\"") +} + +PUBLIC_HEADERS += \ + $$PUBLIC_HEADERS \ + \"$$QTSERIALPORT_PROJECT_INCLUDEDIR/QSerialPort\" \ + \"$$QTSERIALPORT_PROJECT_INCLUDEDIR/QSerialPortInfo\" + +target_headers.files = $$PUBLIC_HEADERS +target_headers.path = $$[QT_INSTALL_PREFIX]/include/QtSerialPort +INSTALLS += target_headers + +mkspecs_features.files = $$QTSERIALPORT_PROJECT_ROOT/src/serialport/qt4support/serialport.prf +mkspecs_features.path = $$[QT_INSTALL_DATA]/mkspecs/features +INSTALLS += mkspecs_features + +win32 { + dlltarget.path = $$[QT_INSTALL_BINS] + INSTALLS += dlltarget +} + +target.path = $$[QT_INSTALL_LIBS] +INSTALLS += target + +INCLUDEPATH += $$QTSERIALPORT_BUILD_ROOT/include $$QTSERIALPORT_BUILD_ROOT/include/QtSerialPort +DEFINES += QT_BUILD_SERIALPORT_LIB diff --git a/libs/serialport/qt4support/qringbuffer_p.h b/libs/serialport/qt4support/qringbuffer_p.h new file mode 100644 index 0000000000..ddd10e5435 --- /dev/null +++ b/libs/serialport/qt4support/qringbuffer_p.h @@ -0,0 +1,451 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QRINGBUFFER_P_H +#define QRINGBUFFER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of a number of Qt sources files. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +QT_BEGIN_NAMESPACE + +class QRingBuffer +{ +public: + explicit inline QRingBuffer(int growth = 4096) : basicBlockSize(growth) { + buffers << QByteArray(); + clear(); + } + + inline int nextDataBlockSize() const { + return (tailBuffer == 0 ? tail : buffers.first().size()) - head; + } + + inline const char *readPointer() const { + return buffers.isEmpty() ? 0 : (buffers.first().constData() + head); + } + + // access the bytes at a specified position + // the out-variable length will contain the amount of bytes readable + // from there, e.g. the amount still the same QByteArray + inline const char *readPointerAtPosition(qint64 pos, qint64 &length) const { + if (buffers.isEmpty()) { + length = 0; + return 0; + } + + if (pos >= bufferSize) { + length = 0; + return 0; + } + + // special case: it is in the first buffer + int nextDataBlockSizeValue = nextDataBlockSize(); + if (pos - head < nextDataBlockSizeValue) { + length = nextDataBlockSizeValue - pos; + return buffers.at(0).constData() + head + pos; + } + + // special case: we only had one buffer and tried to read over it + if (buffers.length() == 1) { + length = 0; + return 0; + } + + // skip the first + pos -= nextDataBlockSizeValue; + + // normal case: it is somewhere in the second to the-one-before-the-tailBuffer + for (int i = 1; i < tailBuffer; i++) { + if (pos >= buffers[i].size()) { + pos -= buffers[i].size(); + continue; + } + + length = buffers[i].length() - pos; + return buffers[i].constData() + pos; + } + + // it is in the tail buffer + length = tail - pos; + return buffers[tailBuffer].constData() + pos; + } + + inline void free(int bytes) { + bufferSize -= bytes; + if (bufferSize < 0) + bufferSize = 0; + + for (;;) { + int nextBlockSize = nextDataBlockSize(); + if (bytes < nextBlockSize) { + head += bytes; + if (head == tail && tailBuffer == 0) + head = tail = 0; + break; + } + + bytes -= nextBlockSize; + if (buffers.count() == 1) { + if (buffers.at(0).size() != basicBlockSize) + buffers[0].resize(basicBlockSize); + head = tail = 0; + tailBuffer = 0; + break; + } + + buffers.removeAt(0); + --tailBuffer; + head = 0; + } + + if (isEmpty()) + clear(); // try to minify/squeeze us + } + + inline char *reserve(int bytes) { + // if this is a fresh empty QRingBuffer + if (bufferSize == 0) { + buffers[0].resize(qMax(basicBlockSize, bytes)); + bufferSize += bytes; + tail = bytes; + return buffers[tailBuffer].data(); + } + + bufferSize += bytes; + + // if there is already enough space, simply return. + if (tail + bytes <= buffers.at(tailBuffer).size()) { + char *writePtr = buffers[tailBuffer].data() + tail; + tail += bytes; + return writePtr; + } + + // if our buffer isn't half full yet, simply resize it. + if (tail < buffers.at(tailBuffer).size() / 2) { + buffers[tailBuffer].resize(tail + bytes); + char *writePtr = buffers[tailBuffer].data() + tail; + tail += bytes; + return writePtr; + } + + // shrink this buffer to its current size + buffers[tailBuffer].resize(tail); + + // create a new QByteArray with the right size + buffers << QByteArray(); + ++tailBuffer; + buffers[tailBuffer].resize(qMax(basicBlockSize, bytes)); + tail = bytes; + return buffers[tailBuffer].data(); + } + + inline void truncate(int pos) { + if (pos < size()) + chop(size() - pos); + } + + inline void chop(int bytes) { + bufferSize -= bytes; + if (bufferSize < 0) + bufferSize = 0; + + for (;;) { + // special case: head and tail are in the same buffer + if (tailBuffer == 0) { + tail -= bytes; + if (tail <= head) + tail = head = 0; + return; + } + + if (bytes <= tail) { + tail -= bytes; + return; + } + + bytes -= tail; + buffers.removeAt(tailBuffer); + + --tailBuffer; + tail = buffers.at(tailBuffer).size(); + } + + if (isEmpty()) + clear(); // try to minify/squeeze us + } + + inline bool isEmpty() const { + return tailBuffer == 0 && tail == 0; + } + + inline int getChar() { + if (isEmpty()) + return -1; + char c = *readPointer(); + free(1); + return int(uchar(c)); + } + + inline void putChar(char c) { + char *ptr = reserve(1); + *ptr = c; + } + + inline void ungetChar(char c) { + --head; + if (head < 0) { + buffers.prepend(QByteArray()); + buffers[0].resize(basicBlockSize); + head = basicBlockSize - 1; + ++tailBuffer; + } + buffers[0][head] = c; + ++bufferSize; + } + + inline int size() const { + return bufferSize; + } + + inline void clear() { + buffers.erase(buffers.begin() + 1, buffers.end()); + buffers[0].resize(0); + buffers[0].squeeze(); + + head = tail = 0; + tailBuffer = 0; + bufferSize = 0; + } + + inline int indexOf(char c) const { + int index = 0; + for (int i = 0; i < buffers.size(); ++i) { + int start = 0; + int end = buffers.at(i).size(); + + if (i == 0) + start = head; + if (i == tailBuffer) + end = tail; + const char *ptr = buffers.at(i).data() + start; + for (int j = start; j < end; ++j) { + if (*ptr++ == c) + return index; + ++index; + } + } + return -1; + } + + inline int indexOf(char c, int maxLength) const { + int index = 0; + int remain = qMin(size(), maxLength); + for (int i = 0; remain && i < buffers.size(); ++i) { + int start = 0; + int end = buffers.at(i).size(); + + if (i == 0) + start = head; + if (i == tailBuffer) + end = tail; + if (remain < end - start) { + end = start + remain; + remain = 0; + } else { + remain -= end - start; + } + const char *ptr = buffers.at(i).data() + start; + for (int j = start; j < end; ++j) { + if (*ptr++ == c) + return index; + ++index; + } + } + return -1; + } + + inline int read(char *data, int maxLength) { + int bytesToRead = qMin(size(), maxLength); + int readSoFar = 0; + while (readSoFar < bytesToRead) { + const char *ptr = readPointer(); + int bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar, nextDataBlockSize()); + if (data) + memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock); + readSoFar += bytesToReadFromThisBlock; + free(bytesToReadFromThisBlock); + } + return readSoFar; + } + + inline QByteArray read(int maxLength) { + QByteArray tmp; + tmp.resize(qMin(maxLength, size())); + read(tmp.data(), tmp.size()); + return tmp; + } + + inline QByteArray readAll() { + return read(size()); + } + + // read an unspecified amount (will read the first buffer) + inline QByteArray read() { + if (bufferSize == 0) + return QByteArray(); + + // multiple buffers, just take the first one + if (head == 0 && tailBuffer != 0) { + QByteArray qba = buffers.takeFirst(); + --tailBuffer; + bufferSize -= qba.length(); + return qba; + } + + // one buffer with good value for head. Just take it. + if (head == 0 && tailBuffer == 0) { + QByteArray qba = buffers.takeFirst(); + qba.resize(tail); + buffers << QByteArray(); + bufferSize = 0; + tail = 0; + return qba; + } + + // Bad case: We have to memcpy. + // We can avoid by initializing the QRingBuffer with basicBlockSize of 0 + // and only using this read() function. + QByteArray qba(readPointer(), nextDataBlockSize()); + buffers.removeFirst(); + head = 0; + if (tailBuffer == 0) { + buffers << QByteArray(); + tail = 0; + } else { + --tailBuffer; + } + bufferSize -= qba.length(); + return qba; + } + + // append a new buffer to the end + inline void append(const QByteArray &qba) { + buffers[tailBuffer].resize(tail); + buffers << qba; + ++tailBuffer; + tail = qba.length(); + bufferSize += qba.length(); + } + + inline QByteArray peek(int maxLength) const { + int bytesToRead = qMin(size(), maxLength); + if (maxLength <= 0) + return QByteArray(); + QByteArray ret; + ret.resize(bytesToRead); + int readSoFar = 0; + for (int i = 0; readSoFar < bytesToRead && i < buffers.size(); ++i) { + int start = 0; + int end = buffers.at(i).size(); + if (i == 0) + start = head; + if (i == tailBuffer) + end = tail; + const int len = qMin(ret.size()-readSoFar, end-start); + memcpy(ret.data()+readSoFar, buffers.at(i).constData()+start, len); + readSoFar += len; + } + Q_ASSERT(readSoFar == ret.size()); + return ret; + } + + inline int skip(int length) { + return read(0, length); + } + + inline int readLine(char *data, int maxLength) { + int index = indexOf('\n'); + if (index == -1) + return read(data, maxLength); + if (maxLength <= 0) + return -1; + + int readSoFar = 0; + while (readSoFar < index + 1 && readSoFar < maxLength - 1) { + int bytesToRead = qMin((index + 1) - readSoFar, nextDataBlockSize()); + bytesToRead = qMin(bytesToRead, (maxLength - 1) - readSoFar); + memcpy(data + readSoFar, readPointer(), bytesToRead); + readSoFar += bytesToRead; + free(bytesToRead); + } + + // Terminate it. + data[readSoFar] = '\0'; + return readSoFar; + } + + inline bool canReadLine() const { + return indexOf('\n') != -1; + } + +private: + QList buffers; + int head, tail; + int tailBuffer; // always buffers.size() - 1 + int basicBlockSize; + int bufferSize; +}; + +QT_END_NAMESPACE + +#endif // QRINGBUFFER_P_H diff --git a/libs/serialport/qt4support/qwineventnotifier_p.h b/libs/serialport/qt4support/qwineventnotifier_p.h new file mode 100644 index 0000000000..bd1203e59c --- /dev/null +++ b/libs/serialport/qt4support/qwineventnotifier_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINEVENTNOTIFIER_P_H +#define QWINEVENTNOTIFIER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "QtCore/qobject.h" +#include "QtCore/qt_windows.h" + +QT_BEGIN_NAMESPACE + +class Q_CORE_EXPORT QWinEventNotifier : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QObject) + +public: + explicit QWinEventNotifier(QObject *parent = 0); + explicit QWinEventNotifier(HANDLE hEvent, QObject *parent = 0); + ~QWinEventNotifier(); + + void setHandle(HANDLE hEvent); + HANDLE handle() const; + + bool isEnabled() const; + +public Q_SLOTS: + void setEnabled(bool enable); + +Q_SIGNALS: + void activated(HANDLE hEvent); + +protected: + bool event(QEvent * e); + +private: + Q_DISABLE_COPY(QWinEventNotifier) + + HANDLE handleToEvent; + bool enabled; +}; + +QT_END_NAMESPACE + +#endif // QWINEVENTNOTIFIER_P_H diff --git a/libs/serialport/qt4support/serialport.prf b/libs/serialport/qt4support/serialport.prf new file mode 100644 index 0000000000..9779b4c822 --- /dev/null +++ b/libs/serialport/qt4support/serialport.prf @@ -0,0 +1,27 @@ +qtAddLibrary(QtSerialPort) + +!isEmpty(QTSERIALPORT_BUILD_ROOT) { + INCLUDEPATH -= $$QMAKE_INCDIR_QT/QtSerialPort + QMAKE_INCDIR += $$QTSERIALPORT_BUILD_ROOT/include $$QTSERIALPORT_BUILD_ROOT/include/QtSerialPort + + QTSERIALPORT_BUILD_SUBDIR = src/serialport + debug_and_release_target { + CONFIG(debug, debug|release) { + QTSERIALPORT_BUILD_SUBDIR = $$QTSERIALPORT_BUILD_SUBDIR/debug + } else { + QTSERIALPORT_BUILD_SUBDIR = $$QTSERIALPORT_BUILD_SUBDIR/release + } + } + + QMAKE_LIBDIR += $$QTSERIALPORT_BUILD_ROOT/$$QTSERIALPORT_BUILD_SUBDIR +} + +mac { + LIBS -= -framework QtSerialPort$${QT_LIBINFIX} + + if(!debug_and_release|build_pass):CONFIG(debug, debug|release) { + LIBS += -lQtSerialPort$${QT_LIBINFIX}_debug + } else { + LIBS += -lQtSerialPort$${QT_LIBINFIX} + } +} diff --git a/libs/serialport/qttylocker_unix.cpp b/libs/serialport/qttylocker_unix.cpp new file mode 100644 index 0000000000..8184bd9c03 --- /dev/null +++ b/libs/serialport/qttylocker_unix.cpp @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Denis Shienkov +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qttylocker_unix_p.h" + +#ifdef HAVE_BAUDBOY_H +# include +# include +#elif defined (HAVE_LOCKDEV_H) +# include +# include +#else +# include +# include +# include +# include +# include +# include +# include +# include +#endif // defined (HAVE_BAUDBOY_H) + +QT_BEGIN_NAMESPACE + +#if !(defined (HAVE_BAUDBOY_H) || defined (HAVE_LOCKDEV_H)) + +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# define QStringLiteral QLatin1String +#endif + +static inline const QStringList& lockDirectoryList() +{ + static const QStringList lockDirectoryEntries = QStringList() + << QStringLiteral("/var/lock") + << QStringLiteral("/etc/locks") + << QStringLiteral("/var/spool/locks") + << QStringLiteral("/var/spool/uucp") + << QStringLiteral("/tmp"); + + return lockDirectoryEntries; +} + +// Returns the full path first found in the directory where you can create a lock file +// (ie a directory with access to the read/write). +// Verification of directories is of the order in accordance with the order +// of records in the variable lockDirList. +static +QString lookupFirstSharedLockDir() +{ + QStringList directoryList = lockDirectoryList(); + + foreach (const QString &lockDirectory, directoryList) { + if (::access(lockDirectory.toLocal8Bit().constData(), R_OK | W_OK) == 0) + return lockDirectory; + } + return QString(); +} + +// Returns the name of the lock file which is tied to the +// device name, eg "LCK..ttyS0", etc. +static +QString generateLockFileNameAsNamedForm(const char *portName) +{ + QString result(lookupFirstSharedLockDir()); + if (!result.isEmpty()) { + result.append(QLatin1String("/LCK..")); + result.append(QString::fromLatin1(portName).replace(QLatin1Char('/'), QLatin1Char('_'))); + } + return result; +} + +#endif //!(defined (HAVE_BAUDBOY_H) || defined (HAVE_LOCKDEV_H)) + +// Try lock serial device. However, other processes can not access it. +bool QTtyLocker::lock(const char *portName) +{ +#ifdef HAVE_BAUDBOY_H + if (::ttylock(portName) + ::ttywait(portName); + return ::ttylock(portName) != -1; +#elif defined (HAVE_LOCKDEV_H) + return ::dev_lock(portName) != -1; +#else + QFile f(generateLockFileNameAsNamedForm(portName)); + if (f.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + QString content(QLatin1String(" %1 %2\x0A")); + content = content.arg(::getpid()).arg(::getuid()); + if (f.write(content.toLocal8Bit()) > 0) { + f.close(); + return true; + } + f.close(); + } + return false; +#endif +} + +// Try unlock serial device. However, other processes can access it. +bool QTtyLocker::unlock(const char *portName) +{ +#ifdef HAVE_BAUDBOY_H + return ::ttyunlock(portName != -1; +#elif defined (HAVE_LOCKDEV_H) + return ::dev_unlock(portName, ::getpid()) != -1; +#else + QFile f(generateLockFileNameAsNamedForm(portName)); + return f.remove(); +#endif +} + +// Verifies the device is locked or not. +// If returned currentPid = true - this means that the device is locked the current process. +bool QTtyLocker::isLocked(const char *portName, bool *currentPid) +{ + if (!currentPid) + return true; + + *currentPid = false; + +#ifdef HAVE_BAUDBOY_H + return ::ttylocked(portName) != -1; +#elif defined (HAVE_LOCKDEV_H) + return ::dev_testlock(portName) != -1; +#else + + QFile f(generateLockFileNameAsNamedForm(portName)); + if (!f.exists()) + return false; + if (!f.open(QIODevice::ReadOnly)) + return true; + + QString content(QLatin1String(f.readAll())); + f.close(); + + const pid_t pid = content.section(' ', 0, 0, QString::SectionSkipEmpty).toInt(); + + if (::kill(pid, 0) == -1) { + if (errno == ESRCH) // Process does not exists + return false; + } else { + if (::getpid() == pid) // Process exists and it is "their", i.e current + *currentPid = true; + } + + return true; + +#endif +} + +QT_END_NAMESPACE diff --git a/libs/serialport/qttylocker_unix_p.h b/libs/serialport/qttylocker_unix_p.h new file mode 100644 index 0000000000..9dce5d05de --- /dev/null +++ b/libs/serialport/qttylocker_unix_p.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Denis Shienkov +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#ifndef TTYLOCKER_UNIX_P_H +#define TTYLOCKER_UNIX_P_H + +QT_BEGIN_NAMESPACE + +class QTtyLocker +{ +public: + static bool lock(const char *portName); + static bool unlock(const char *portName); + static bool isLocked(const char *portName, bool *currentPid); +}; + +QT_END_NAMESPACE + +#endif // TTYLOCKER_UNIX_P_H diff --git a/libs/serialport/serialport-lib.pri b/libs/serialport/serialport-lib.pri new file mode 100644 index 0000000000..db8ff74604 --- /dev/null +++ b/libs/serialport/serialport-lib.pri @@ -0,0 +1,87 @@ +INCLUDEPATH += $$PWD + +unix { + CONFIG += link_pkgconfig + + packagesExist(libudev) { + DEFINES += HAVE_LIBUDEV + PKGCONFIG += libudev + } +} + +PUBLIC_HEADERS += \ + $$PWD/qserialportglobal.h \ + $$PWD/qserialport.h \ + $$PWD/qserialportinfo.h + +PRIVATE_HEADERS += \ + $$PWD/qserialport_p.h \ + $$PWD/qserialportinfo_p.h + +SOURCES += \ + $$PWD/qserialport.cpp \ + $$PWD/qserialportinfo.cpp + +win32 { + PRIVATE_HEADERS += \ + $$PWD/qserialport_win_p.h + + SOURCES += \ + $$PWD/qserialport_win.cpp \ + $$PWD/qserialportinfo_win.cpp + + !wince*: { + LIBS += -lsetupapi -ladvapi32 + } else { + SOURCES += \ + $$PWD/qserialport_wince.cpp \ + $$PWD/qserialportinfo_wince.cpp + } +} + +symbian { + MMP_RULES += EXPORTUNFROZEN + #MMP_RULES += DEBUGGABLE_UDEBONLY + TARGET.UID3 = 0xE7E62DFD + TARGET.CAPABILITY = + TARGET.EPOCALLOWDLLDATA = 1 + addFiles.sources = QtSerialPort.dll + addFiles.path = !:/sys/bin + DEPLOYMENT += addFiles + + # FIXME !!! + #INCLUDEPATH += c:/Nokia/devices/Nokia_Symbian3_SDK_v1.0/epoc32/include/platform + INCLUDEPATH += c:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/include/platform + + PRIVATE_HEADERS += \ + $$PWD/qserialport_symbian_p.h + + SOURCES += \ + $$PWD/qserialport_symbian.cpp \ + $$PWD/qserialportinfo_symbian.cpp + + LIBS += -leuser -lefsrv -lc32 +} + +unix:!symbian { + PRIVATE_HEADERS += \ + $$PWD/qttylocker_unix_p.h \ + $$PWD/qserialport_unix_p.h + + SOURCES += \ + $$PWD/qttylocker_unix.cpp \ + $$PWD/qserialport_unix.cpp \ + $$PWD/qserialportinfo_unix.cpp + + macx { + SOURCES += $$PWD/qserialportinfo_mac.cpp + + LIBS += -framework IOKit -framework CoreFoundation + } else { + linux*:contains( DEFINES, HAVE_LIBUDEV ) { + LIBS += -ludev + } + } +} + +HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS diff --git a/libs/serialport/serialport.pro b/libs/serialport/serialport.pro new file mode 100644 index 0000000000..d329a0b782 --- /dev/null +++ b/libs/serialport/serialport.pro @@ -0,0 +1,17 @@ +QT = core + +QMAKE_DOCS = $$PWD/doc/qtserialport.qdocconf +include($$PWD/serialport-lib.pri) + +greaterThan(QT_MAJOR_VERSION, 4) { + load(qt_build_config) + QT += core-private + TARGET = QtSerialPort + load(qt_module) +} else { + TEMPLATE = lib + TARGET = $$qtLibraryTarget(QtSerialPort$$QT_LIBINFIX) + include($$PWD/qt4support/install-helper.pri) + CONFIG += module create_prl + mac:QMAKE_FRAMEWORK_BUNDLE_NAME = $$TARGET +} diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index bf6c51e0fa..ca12227451 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -20,7 +20,8 @@ # Qt configuration CONFIG += qt \ - thread + thread \ + QT += network \ opengl \ svg \ @@ -93,7 +94,7 @@ DEPENDPATH += \ INCLUDEPATH += \ libs/utils \ libs \ - libs/opmapcontrol + libs/opmapcontrol \ # If the user config file exists, it will be included. # if the variable MAVLINK_CONF contains the name of an @@ -135,30 +136,22 @@ INCLUDEPATH += \ include(src/apps/mavlinkgen/mavlinkgen.pri) - - # Include QWT plotting library include(libs/qwt/qwt.pri) + DEPENDPATH += . \ - plugins \ - libs/thirdParty/qserialport/include \ - libs/thirdParty/qserialport/include/QtSerialPort \ - libs/thirdParty/qserialport \ - libs/qextserialport - -INCLUDEPATH += . \ - libs/thirdParty/qserialport/include \ - libs/thirdParty/qserialport/include/QtSerialPort \ - libs/thirdParty/qserialport/src \ - libs/qextserialport -# Include serial port library (QSerial) -include(qserialport.pri) - -# Serial port detection (ripped-off from qextserialport library) -macx|macx-g++|macx-g++42::SOURCES += libs/qextserialport/qextserialenumerator_osx.cpp -linux-g++::SOURCES += libs/qextserialport/qextserialenumerator_unix.cpp -linux-g++-64::SOURCES += libs/qextserialport/qextserialenumerator_unix.cpp -win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += libs/qextserialport/qextserialenumerator_win.cpp + plugins + +INCLUDEPATH += . + +# Include serial port library (QSerialPort) +include(libs/serialport/apmserial.pri) + +## Serial port detection (ripped-off from qextserialport library) +#macx|macx-g++|macx-g++42::SOURCES += libs/qextserialport/qextserialenumerator_osx.cpp +#linux-g++::SOURCES += libs/qextserialport/qextserialenumerator_unix.cpp +#linux-g++-64::SOURCES += libs/qextserialport/qextserialenumerator_unix.cpp +#win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += libs/qextserialport/qextserialenumerator_win.cpp # Input FORMS += src/ui/MainWindow.ui \ src/ui/CommSettings.ui \ @@ -345,7 +338,7 @@ HEADERS += src/MG.h \ src/ui/map/Waypoint2DIcon.h \ src/ui/map/QGCMapTool.h \ src/ui/map/QGCMapToolBar.h \ - libs/qextserialport/qextserialenumerator.h \ +# libs/qextserialport/qextserialenumerator.h \ src/QGCGeo.h \ src/ui/QGCToolBar.h \ src/ui/QGCStatusBar.h \ diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 4865ecf6ea..a0e52ae981 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -12,257 +12,62 @@ #include #include #include +#include +#include #include "SerialLink.h" #include "LinkManager.h" #include "QGC.h" #include -#include -#ifdef _WIN32 -#include "windows.h" -#endif -#ifdef _WIN32 -#include -#endif -#if defined (__APPLE__) && defined (__MACH__) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __MWERKS__ -#define __CF_USE_FRAMEWORK_INCLUDES__ -#endif - - -#include - -#include -#include -#if defined(MAC_OS_X_VERSION_10_3) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3) -#include -#endif -#include - -// Apple internal modems default to local echo being on. If your modem has local echo disabled, -// undefine the following macro. -#define LOCAL_ECHO - -#define kATCommandString "AT\r" - -#ifdef LOCAL_ECHO -#define kOKResponseString "AT\r\r\nOK\r\n" -#else -#define kOKResponseString "\r\nOK\r\n" -#endif -#endif - - -// Some helper functions for serial port enumeration -#if defined (__APPLE__) && defined (__MACH__) - -enum { - kNumRetries = 3 -}; - -// Function prototypes -static kern_return_t FindModems(io_iterator_t *matchingServices); -static kern_return_t GetModemPath(io_iterator_t serialPortIterator, char *bsdPath, CFIndex maxPathSize); - -// Returns an iterator across all known modems. Caller is responsible for -// releasing the iterator when iteration is complete. -static kern_return_t FindModems(io_iterator_t *matchingServices) -{ - kern_return_t kernResult; - CFMutableDictionaryRef classesToMatch; - - /*! @function IOServiceMatching - @abstract Create a matching dictionary that specifies an IOService class match. - @discussion A very common matching criteria for IOService is based on its class. IOServiceMatching will create a matching dictionary that specifies any IOService of a class, or its subclasses. The class is specified by C-string name. - @param name The class name, as a const C-string. Class matching is successful on IOService's of this class or any subclass. - @result The matching dictionary created, is returned on success, or zero on failure. The dictionary is commonly passed to IOServiceGetMatchingServices or IOServiceAddNotification which will consume a reference, otherwise it should be released with CFRelease by the caller. */ - - // Serial devices are instances of class IOSerialBSDClient - classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); - if (classesToMatch == NULL) { - printf("IOServiceMatching returned a NULL dictionary.\n"); - } else { - /*! - @function CFDictionarySetValue - Sets the value of the key in the dictionary. - @param theDict The dictionary to which the value is to be set. If this - parameter is not a valid mutable CFDictionary, the behavior is - undefined. If the dictionary is a fixed-capacity dictionary and - it is full before this operation, and the key does not exist in - the dictionary, the behavior is undefined. - @param key The key of the value to set into the dictionary. If a key - which matches this key is already present in the dictionary, only - the value is changed ("add if absent, replace if present"). If - no key matches the given key, the key-value pair is added to the - dictionary. If added, the key is retained by the dictionary, - using the retain callback provided - when the dictionary was created. If the key is not of the sort - expected by the key retain callback, the behavior is undefined. - @param value The value to add to or replace into the dictionary. The value - is retained by the dictionary using the retain callback provided - when the dictionary was created, and the previous value if any is - released. If the value is not of the sort expected by the - retain or release callbacks, the behavior is undefined. - */ - CFDictionarySetValue(classesToMatch, - CFSTR(kIOSerialBSDTypeKey), - CFSTR(kIOSerialBSDModemType)); - - // Each serial device object has a property with key - // kIOSerialBSDTypeKey and a value that is one of kIOSerialBSDAllTypes, - // kIOSerialBSDModemType, or kIOSerialBSDRS232Type. You can experiment with the - // matching by changing the last parameter in the above call to CFDictionarySetValue. - - // As shipped, this sample is only interested in modems, - // so add this property to the CFDictionary we're matching on. - // This will find devices that advertise themselves as modems, - // such as built-in and USB modems. However, this match won't find serial modems. - } - - /*! @function IOServiceGetMatchingServices - @abstract Look up registered IOService objects that match a matching dictionary. - @discussion This is the preferred method of finding IOService objects currently registered by IOKit. IOServiceAddNotification can also supply this information and install a notification of new IOServices. The matching information used in the matching dictionary may vary depending on the class of service being looked up. - @param masterPort The master port obtained from IOMasterPort(). - @param matching A CF dictionary containing matching information, of which one reference is consumed by this function. IOKitLib can contruct matching dictionaries for common criteria with helper functions such as IOServiceMatching, IOOpenFirmwarePathMatching. - @param existing An iterator handle is returned on success, and should be released by the caller when the iteration is finished. - @result A kern_return_t error code. */ - - kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, matchingServices); - if (KERN_SUCCESS != kernResult) { - printf("IOServiceGetMatchingServices returned %d\n", kernResult); - goto exit; - } - -exit: - return kernResult; -} - -/** Given an iterator across a set of modems, return the BSD path to the first one. - * If no modems are found the path name is set to an empty string. - */ -static kern_return_t GetModemPath(io_iterator_t serialPortIterator, char *bsdPath, CFIndex maxPathSize) -{ - io_object_t modemService; - kern_return_t kernResult = KERN_FAILURE; - Boolean modemFound = false; - - // Initialize the returned path - *bsdPath = '\0'; - - // Iterate across all modems found. In this example, we bail after finding the first modem. - - while ((modemService = IOIteratorNext(serialPortIterator)) && !modemFound) { - CFTypeRef bsdPathAsCFString; - - // Get the callout device's path (/dev/cu.xxxxx). The callout device should almost always be - // used: the dialin device (/dev/tty.xxxxx) would be used when monitoring a serial port for - // incoming calls, e.g. a fax listener. - - bsdPathAsCFString = IORegistryEntryCreateCFProperty(modemService, - CFSTR(kIOCalloutDeviceKey), - kCFAllocatorDefault, - 0); - if (bsdPathAsCFString) { - Boolean result; - - // Convert the path from a CFString to a C (NUL-terminated) string for use - // with the POSIX open() call. - - result = CFStringGetCString((CFStringRef)bsdPathAsCFString, - bsdPath, - maxPathSize, - kCFStringEncodingUTF8); - CFRelease(bsdPathAsCFString); - - if (result) { - //printf("Modem found with BSD path: %s", bsdPath); - modemFound = true; - kernResult = KERN_SUCCESS; - } - } - - printf("\n"); - - // Release the io_service_t now that we are done with it. - - (void) IOObjectRelease(modemService); - } - - return kernResult; -} -#endif - -using namespace TNX; SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, bool parity, int dataBits, int stopBits) : - port(NULL), - ports(new QVector()), + m_bytesRead(0), + m_port(NULL), + m_ports(new QVector()), m_stopp(false), - bytesRead(0), m_reqReset(false) { // Setup settings - this->porthandle = portname.trimmed(); + m_portName = portname.trimmed(); - if (this->porthandle == "" && getCurrentPorts()->size() > 0) + if (m_portName == "" && getCurrentPorts()->size() > 0) { - this->porthandle = getCurrentPorts()->first().trimmed(); + m_portName = m_ports->first().trimmed(); } -#ifdef _WIN32 - // Port names above 20 need the network path format - if the port name is not already in this format - // catch this special case - if (this->porthandle.size() > 0 && !this->porthandle.startsWith("\\")) { - // Append \\.\ before the port handle. Additional backslashes are used for escaping. - this->porthandle = "\\\\.\\" + this->porthandle; - } -#endif // Set unique ID and add link to the list of links - this->id = getNextLinkId(); + m_id = getNextLinkId(); + + m_baud = baudRate; - setBaudRate(baudRate); if (hardwareFlowControl) { - portSettings.setFlowControl(QPortSettings::FLOW_HARDWARE); + m_flowControl = QSerialPort::HardwareControl; } else { - portSettings.setFlowControl(QPortSettings::FLOW_OFF); + m_flowControl = QSerialPort::NoFlowControl; } if (parity) { - portSettings.setParity(QPortSettings::PAR_EVEN); + m_parity = QSerialPort::EvenParity; } else { - portSettings.setParity(QPortSettings::PAR_NONE); + m_parity = QSerialPort::NoParity; } - setDataBits(dataBits); - setStopBits(stopBits); + + m_dataBits = dataBits; + m_stopBits = stopBits; // Set the port name - if (porthandle == "") + if (m_portName == "") { - name = tr("Serial Link ") + QString::number(getId()); + m_name = tr("Serial Link ") + QString::number(getId()); } else { - name = portname.trimmed(); + m_name = portname.trimmed(); } loadSettings(); } @@ -275,91 +80,26 @@ void SerialLink::requestReset() SerialLink::~SerialLink() { disconnect(); - if(port) delete port; - port = NULL; - if (ports) delete ports; - ports = NULL; + if(m_port) delete m_port; + m_port = NULL; + if (m_ports) delete m_ports; + m_ports = NULL; } QVector* SerialLink::getCurrentPorts() { - ports->clear(); -#ifdef __linux - - // TODO Linux has no standard way of enumerating serial ports - // However the device files are only present when the physical - // device is connected, therefore listing the files should be - // sufficient. - - QString devdir = "/dev"; - QDir dir(devdir); - dir.setFilter(QDir::System); - - QFileInfoList list = dir.entryInfoList(); - for (int i = 0; i < list.size(); ++i) { - QFileInfo fileInfo = list.at(i); - if (fileInfo.fileName().contains(QString("ttyUSB")) || fileInfo.fileName().contains(QString("ttyS")) || fileInfo.fileName().contains(QString("ttyACM"))) - { - ports->append(fileInfo.canonicalFilePath()); - } - } -#endif - -#if defined (__APPLE__) && defined (__MACH__) - - // Enumerate serial ports - kern_return_t kernResult; // on PowerPC this is an int (4 bytes) - io_iterator_t serialPortIterator; - char bsdPath[MAXPATHLEN]; - kernResult = FindModems(&serialPortIterator); - kernResult = GetModemPath(serialPortIterator, bsdPath, sizeof(bsdPath)); - IOObjectRelease(serialPortIterator); // Release the iterator. - - // Add found modems - if (bsdPath[0]) + Q_ASSERT_X(m_ports != NULL, "getCurrentPorts", "m_ports is NULL"); + m_ports->clear(); + // Example use QSerialPortInfo + foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { - ports->append(QString(bsdPath)); - } +// qDebug() << "PortName : " << info.portName() +// << "Description : " << info.description(); +// qDebug() << "Manufacturer: " << info.manufacturer(); - // Add USB serial port adapters - // TODO Strangely usb serial port adapters are not enumerated, even when connected - QString devdir = "/dev"; - QDir dir(devdir); - dir.setFilter(QDir::System); - - QFileInfoList list = dir.entryInfoList(); - for (int i = list.size() - 1; i >= 0; i--) { - QFileInfo fileInfo = list.at(i); - if (fileInfo.fileName().contains(QString("ttyUSB")) || - fileInfo.fileName().contains(QString("tty.")) || - fileInfo.fileName().contains(QString("ttyS")) || - fileInfo.fileName().contains(QString("ttyACM"))) - { - ports->append(fileInfo.canonicalFilePath()); - } + m_ports->append(info.portName()); } -#endif - -#ifdef _WIN32 - // Get the ports available on this system - QList ports = QextSerialEnumerator::getPorts(); - - // Add the ports in reverse order, because we prepend them to the list - for (int i = ports.size() - 1; i >= 0; i--) - { - QextPortInfo portInfo = ports.at(i); - QString portString = QString(portInfo.portName.toLocal8Bit().constData());// + " - " + QString(ports.at(i).friendName.toLocal8Bit().constData()).split("(").first(); - // Prepend newly found port to the list - this->ports->append(portString); - } - - //printf("port name: %s\n", ports.at(i).portName.toLocal8Bit().constData()); - //printf("friendly name: %s\n", ports.at(i).friendName.toLocal8Bit().constData()); - //printf("physical name: %s\n", ports.at(i).physName.toLocal8Bit().constData()); - //printf("enumerator name: %s\n", ports.at(i).enumName.toLocal8Bit().constData()); - //printf("===================================\n\n"); -#endif - return this->ports; + return m_ports; } void SerialLink::loadSettings() @@ -369,12 +109,12 @@ void SerialLink::loadSettings() settings.sync(); if (settings.contains("SERIALLINK_COMM_PORT")) { - setPortName(settings.value("SERIALLINK_COMM_PORT").toString()); - setBaudRateType(settings.value("SERIALLINK_COMM_BAUD").toInt()); - setParityType(settings.value("SERIALLINK_COMM_PARITY").toInt()); - setStopBits(settings.value("SERIALLINK_COMM_STOPBITS").toInt()); - setDataBits(settings.value("SERIALLINK_COMM_DATABITS").toInt()); - setFlowType(settings.value("SERIALLINK_COMM_FLOW_CONTROL").toInt()); + m_portName = settings.value("SERIALLINK_COMM_PORT").toString(); + m_baud = settings.value("SERIALLINK_COMM_BAUD").toInt(); + m_parity = settings.value("SERIALLINK_COMM_PARITY").toInt(); + m_stopBits = settings.value("SERIALLINK_COMM_STOPBITS").toInt(); + m_dataBits = settings.value("SERIALLINK_COMM_DATABITS").toInt(); + m_flowControl = settings.value("SERIALLINK_COMM_FLOW_CONTROL").toInt(); } } @@ -402,18 +142,19 @@ void SerialLink::run() if (!hardwareConnect()) { //Need to error out here. - emit communicationError(getName(),"Error connecting: " + port->errorString()); + emit communicationError(getName(),"Error connecting: " + m_port->errorString()); return; } // Qt way to make clear what a while(1) loop does - quint64 msecs = QDateTime::currentMSecsSinceEpoch(); - quint64 initialmsecs = QDateTime::currentMSecsSinceEpoch(); + qint64 msecs = QDateTime::currentMSecsSinceEpoch(); + qint64 initialmsecs = QDateTime::currentMSecsSinceEpoch(); quint64 bytes = 0; bool triedreset = false; bool triedDTR = false; - int timeout = 5000; + qint64 timeout = 5000; + forever { { @@ -427,16 +168,16 @@ void SerialLink::run() { this->m_reqReset = false; communicationUpdate(getName(),"Reset requested via DTR signal"); - port->setDtr(true); + m_port->setDataTerminalReady(true); this->msleep(250); - port->setDtr(false); + m_port->setDataTerminalReady(false); } } // Check if new bytes have arrived, if yes, emit the notification signal checkForBytes(); - if (bytes != bytesRead) + if (bytes != m_bytesRead) { - bytes = bytesRead; + bytes = m_bytesRead; msecs = QDateTime::currentMSecsSinceEpoch(); } else @@ -459,15 +200,15 @@ void SerialLink::run() triedDTR = true; communicationUpdate(getName(),"No data to receive on COM port. Attempting to reset via DTR signal"); qDebug() << "No data!!! Attempting reset via DTR."; - port->setDtr(true); + m_port->setDataTerminalReady(true); this->msleep(250); - port->setDtr(false); + m_port->setDataTerminalReady(false); } else if (!triedreset) { qDebug() << "No data!!! Attempting reset via reboot command."; communicationUpdate(getName(),"No data to receive on COM port. Assuming possible terminal mode, attempting to reset via \"reboot\" command"); - port->write("reboot\r\n",8); + m_port->write("reboot\r\n",8); triedreset = true; } else @@ -481,13 +222,12 @@ void SerialLink::run() * from consuming too much processing time */ MG::SLEEP::msleep(SerialLink::poll_interval); - } - if (port) { - port->flushInBuffer(); - port->flushOutBuffer(); - port->close(); - delete port; - port = NULL; + } // end forever loop + + if (m_port) { + m_port->close(); + delete m_port; + m_port = NULL; } } @@ -495,23 +235,23 @@ void SerialLink::run() void SerialLink::checkForBytes() { /* Check if bytes are available */ - if(port && port->isOpen() && port->isWritable()) + if(m_port && m_port->isOpen() && m_port->isWritable()) { - dataMutex.lock(); - qint64 available = port->bytesAvailable(); - dataMutex.unlock(); + m_dataMutex.lock(); + qint64 available = m_port->bytesAvailable(); + m_dataMutex.unlock(); if(available > 0) { readBytes(); - bytesRead += available; + m_bytesRead += available; } else if (available < 0) { /* Error, close port */ - port->close(); + m_port->close(); emit disconnected(); emit connected(false); - emit communicationError(this->getName(), tr("Could not send data - link %1 is disconnected!").arg(this->getName())); + emit communicationError(this->getName(), tr("Could not read data - link %1 is disconnected!").arg(this->getName())); } } // else @@ -524,27 +264,26 @@ void SerialLink::checkForBytes() void SerialLink::writeBytes(const char* data, qint64 size) { - if(port && port->isOpen()) { - int b = port->write(data, size); + if(m_port && m_port->isOpen()) { + qDebug() << "writeBytes" << m_portName << "attempting to tx " << size << "bytes."; + int b = m_port->write(data, size); if (b > 0) { + Q_ASSERT_X(b = size, "writeBytes", "failed to write all bytes"); - // qDebug() << "Serial link " << this->getName() << "transmitted" << b << "bytes:"; + qDebug() << "writeBytes " << m_portName << "tx'd" << b << "bytes:"; // Increase write counter - bitsSentTotal += size * 8; + m_bitsSentTotal += size * 8; + QByteArray* byteArray = new QByteArray(data,size); + + qDebug() << byteArray->toHex(); + delete byteArray; - // int i; - // for (i=0; igetName(), tr("Could not send data - link %1 is disconnected!").arg(this->getName())); + emit communicationError(getName(), tr("Could not send data - link %1 is disconnected!").arg(getName())); } } } @@ -557,18 +296,18 @@ void SerialLink::writeBytes(const char* data, qint64 size) **/ void SerialLink::readBytes() { - dataMutex.lock(); - if(port && port->isOpen()) { + m_dataMutex.lock(); + if(m_port && m_port->isOpen()) { const qint64 maxLength = 2048; char data[maxLength]; - qint64 numBytes = port->bytesAvailable(); + qint64 numBytes = m_port->bytesAvailable(); //qDebug() << "numBytes: " << numBytes; if(numBytes > 0) { /* Read as much data in buffer as possible without overflow */ if(maxLength < numBytes) numBytes = maxLength; - port->read(data, numBytes); + m_port->read(data, numBytes); QByteArray b(data, numBytes); emit bytesReceived(this, b); @@ -580,10 +319,10 @@ void SerialLink::readBytes() // fprintf(stderr,"%02x ", v); // } // fprintf(stderr,"\n"); - bitsReceivedTotal += numBytes * 8; + m_bitsReceivedTotal += numBytes * 8; } } - dataMutex.unlock(); + m_dataMutex.unlock(); } @@ -594,8 +333,8 @@ void SerialLink::readBytes() **/ qint64 SerialLink::bytesAvailable() { - if (port) { - return port->bytesAvailable(); + if (m_port) { + return m_port->bytesAvailable(); } else { return 0; } @@ -608,44 +347,24 @@ qint64 SerialLink::bytesAvailable() **/ bool SerialLink::disconnect() { - if(this->isRunning()) + qDebug() << "disconnect" << m_port->portName(); + Q_ASSERT_X(m_port != NULL, "disconnect", "m_port is NULL"); + + if (isRunning()) { { - QMutexLocker locker(&this->m_stoppMutex); - this->m_stopp = true; + QMutexLocker locker(&m_stoppMutex); + m_stopp = true; } - this->wait(); - - // if (port) { - //#if !defined _WIN32 || !defined _WIN64 - /* Block the thread until it returns from run() */ - //#endif - // port->flushInBuffer(); - // port->flushOutBuffer(); - // port->close(); - // delete port; - // port = NULL; - - // if(this->isRunning()) this->terminate(); //stop running the thread, restart it upon connect - - bool closed = true; - //port->isOpen(); + wait(); // This will terminate the thread and close the serial port - emit disconnected(); + emit disconnected(); // [TODO] There are signals from QSerialPort we should use emit connected(false); - if (port) { - port->close(); - } - return closed; - } - else { - // not running - if (port) { - port->close(); - } + return true; + } else { + m_port->close(); return true; } - } /** @@ -655,12 +374,14 @@ bool SerialLink::disconnect() **/ bool SerialLink::connect() { - if (this->isRunning()) this->disconnect(); + if (isRunning()) + disconnect(); { QMutexLocker locker(&this->m_stoppMutex); - this->m_stopp = false; + m_stopp = false; } - this->start(LowPriority); + + start(LowPriority); return true; } @@ -674,36 +395,52 @@ bool SerialLink::connect() **/ bool SerialLink::hardwareConnect() { - if(port) { - port->close(); - delete port; + if(m_port) + { + qDebug() << "SerialLink:" << QString::number((long)this, 16) << "closing port"; + m_port->close(); + delete m_port; + m_port = NULL; } - port = new QSerialPort(porthandle, portSettings); - QObject::connect(port,SIGNAL(aboutToClose()),this,SIGNAL(disconnected())); - port->setCommTimeouts(QSerialPort::CtScheme_NonBlockingRead); - connectionStartTime = MG::TIME::getGroundTimeNow(); + qDebug() << "SerialLink: hardwareConnect to " << m_portName; + m_port = new QSerialPort(m_portName); - if (!port->open()) + if (m_port == NULL) { - emit communicationUpdate(getName(),"Error opening port: " + port->errorString()); + emit communicationUpdate(getName(),"Error opening port: " + m_port->errorString()); + return false; // couldn't create serial port. } - else + + QObject::connect(m_port,SIGNAL(aboutToClose()),this,SIGNAL(disconnected())); + +// port->setCommTimeouts(QSerialPort::CtScheme_NonBlockingRead); + m_connectionStartTime = MG::TIME::getGroundTimeNow(); + + if (!m_port->open(QIODevice::ReadWrite)) { - emit communicationUpdate(getName(),"Opened port!"); + emit communicationUpdate(getName(),"Error opening port: " + m_port->errorString()); + m_port->close(); + return false; // couldn't open serial port } - bool connectionUp = isConnected(); - if(connectionUp) { - emit connected(); - emit connected(true); - } + emit communicationUpdate(getName(),"Opened port!"); - //qDebug() << "CONNECTING LINK: " << __FILE__ << __LINE__ << "with settings" << port->portName() << getBaudRate() << getDataBits() << getParityType() << getStopBits(); + // Need to configure the port + m_port->setBaudRate(m_baud); + m_port->setDataBits(static_cast(m_dataBits)); + m_port->setFlowControl(static_cast(m_flowControl)); + m_port->setStopBits(static_cast(m_stopBits)); + m_port->setParity(static_cast(m_parity)); + emit connected(); + emit connected(true); + + qDebug() << "CONNECTING LINK: " << __FILE__ << __LINE__ << "with settings" << m_port->portName() + << getBaudRate() << getDataBits() << getParityType() << getStopBits(); writeSettings(); - return connectionUp; + return true; // successful connection } @@ -714,138 +451,82 @@ bool SerialLink::hardwareConnect() **/ bool SerialLink::isConnected() { - if (port) { - return port->isOpen(); + + if (m_port) { + bool isConnected = m_port->isOpen(); + qDebug() << "SerialLink #" << __LINE__ << ":"<< m_port->portName() + << " isConnected =" << QString::number(isConnected); + return isConnected; } else { + qDebug() << "SerialLink #" << __LINE__ << ":" << m_portName + << " isConnected = NULL"; return false; } } int SerialLink::getId() { - return id; + return m_id; } QString SerialLink::getName() { - return name; -} - -void SerialLink::setName(QString name) -{ - this->name = name; - emit nameChanged(this->name); + return m_name; } - /** * This function maps baud rate constants to numerical equivalents. * It relies on the mapping given in qportsettings.h from the QSerialPort library. */ qint64 SerialLink::getNominalDataRate() { - qint64 dataRate = 0; - switch (portSettings.baudRate()) { - - // Baud rates supported only by POSIX systems -#if defined(Q_OS_UNIX) || defined(Q_OS_LINUX) || defined(Q_OS_DARWIN) - case QPortSettings::BAUDR_50: - dataRate = 50; - break; - case QPortSettings::BAUDR_75: - dataRate = 75; - break; - case QPortSettings::BAUDR_134: - dataRate = 134; - break; - case QPortSettings::BAUDR_150: - dataRate = 150; - break; - case QPortSettings::BAUDR_200: - dataRate = 200; - break; - case QPortSettings::BAUDR_1800: - dataRate = 1800; - break; -#endif - - // Baud rates supported only by Windows -#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) - case QPortSettings::BAUDR_14400: - dataRate = 14400; - break; - case QPortSettings::BAUDR_56000: - dataRate = 56000; - break; - case QPortSettings::BAUDR_128000: - dataRate = 128000; - break; - case QPortSettings::BAUDR_256000: - dataRate = 256000; -#endif - - case QPortSettings::BAUDR_110: - dataRate = 110; - break; - case QPortSettings::BAUDR_300: - dataRate = 300; - break; - case QPortSettings::BAUDR_600: - dataRate = 600; - break; - case QPortSettings::BAUDR_1200: - dataRate = 1200; - break; - case QPortSettings::BAUDR_2400: - dataRate = 2400; - break; - case QPortSettings::BAUDR_4800: - dataRate = 4800; - break; - case QPortSettings::BAUDR_9600: - dataRate = 9600; - break; - case QPortSettings::BAUDR_19200: - dataRate = 19200; - break; - case QPortSettings::BAUDR_38400: - dataRate = 38400; - break; - case QPortSettings::BAUDR_57600: - dataRate = 57600; - break; - case QPortSettings::BAUDR_115200: - dataRate = 115200; - break; - case QPortSettings::BAUDR_230400: - dataRate = 230400; - break; - case QPortSettings::BAUDR_460800: - dataRate = 460800; - break; - case QPortSettings::BAUDR_500000: - dataRate = 500000; - break; - case QPortSettings::BAUDR_576000: - dataRate = 576000; - break; - case QPortSettings::BAUDR_921600: - dataRate = 921600; - break; - - // Otherwise do nothing. - case QPortSettings::BAUDR_UNKNOWN: - default: - break; + int baudRate; + if (m_port) { + baudRate = m_port->baudRate(); + } else { + baudRate = m_baud; + } + qint64 dataRate; + switch (baudRate) + { + case QSerialPort::Baud1200: + dataRate = 1200; + break; + case QSerialPort::Baud2400: + dataRate = 2400; + break; + case QSerialPort::Baud4800: + dataRate = 4800; + break; + case QSerialPort::Baud9600: + dataRate = 9600; + break; + case QSerialPort::Baud19200: + dataRate = 19200; + break; + case QSerialPort::Baud38400: + dataRate = 38400; + break; + case QSerialPort::Baud57600: + dataRate = 57600; + break; + case QSerialPort::Baud115200: + dataRate = 115200; + break; + // Otherwise do nothing. + case QSerialPort::UnknownBaud: + default: + dataRate = -1; + break; } return dataRate; } qint64 SerialLink::getTotalUpstream() { - statisticsMutex.lock(); - return bitsSentTotal / ((MG::TIME::getGroundTimeNow() - connectionStartTime) / 1000); - statisticsMutex.unlock(); + m_statisticsMutex.lock(); + return m_bitsSentTotal / ((MG::TIME::getGroundTimeNow() - m_connectionStartTime) / 1000); + m_statisticsMutex.unlock(); } qint64 SerialLink::getCurrentUpstream() @@ -860,19 +541,19 @@ qint64 SerialLink::getMaxUpstream() qint64 SerialLink::getBitsSent() { - return bitsSentTotal; + return m_bitsSentTotal; } qint64 SerialLink::getBitsReceived() { - return bitsReceivedTotal; + return m_bitsReceivedTotal; } qint64 SerialLink::getTotalDownstream() { - statisticsMutex.lock(); - return bitsReceivedTotal / ((MG::TIME::getGroundTimeNow() - connectionStartTime) / 1000); - statisticsMutex.unlock(); + m_statisticsMutex.lock(); + return m_bitsReceivedTotal / ((MG::TIME::getGroundTimeNow() - m_connectionStartTime) / 1000); + m_statisticsMutex.unlock(); } qint64 SerialLink::getCurrentDownstream() @@ -899,9 +580,11 @@ int SerialLink::getLinkQuality() QString SerialLink::getPortName() { - return porthandle; + return m_portName; } +// We should replace the accessors below with one to get the QSerialPort + int SerialLink::getBaudRate() { return getNominalDataRate(); @@ -909,43 +592,80 @@ int SerialLink::getBaudRate() int SerialLink::getBaudRateType() { - return portSettings.baudRate(); + int baudRate; + if (m_port) { + baudRate = m_port->baudRate(); + } else { + baudRate = m_baud; + } + return baudRate; } int SerialLink::getFlowType() { - return portSettings.flowControl(); + int flowControl; + if (m_port) { + flowControl = m_port->flowControl(); + } else { + flowControl = m_flowControl; + } + return flowControl; } int SerialLink::getParityType() { - return portSettings.parity(); + int parity; + if (m_port) { + parity = m_port->parity(); + } else { + parity = m_parity; + } + return parity; } int SerialLink::getDataBitsType() { - return portSettings.dataBits(); + int dataBits; + if (m_port) { + dataBits = m_port->dataBits(); + } else { + dataBits = m_dataBits; + } + return dataBits; } int SerialLink::getStopBitsType() { - return portSettings.stopBits(); + int stopBits; + if (m_port) { + stopBits = m_port->stopBits(); + } else { + stopBits = m_stopBits; + } + return stopBits; } int SerialLink::getDataBits() { - int ret = -1; - switch (portSettings.dataBits()) { - case QPortSettings::DB_5: + int ret; + int dataBits; + if (m_port) { + dataBits = m_port->dataBits(); + } else { + dataBits = m_dataBits; + } + + switch (dataBits) { + case QSerialPort::Data5: ret = 5; break; - case QPortSettings::DB_6: + case QSerialPort::Data6: ret = 6; break; - case QPortSettings::DB_7: + case QSerialPort::Data7: ret = 7; break; - case QPortSettings::DB_8: + case QSerialPort::Data8: ret = 8; break; default: @@ -957,12 +677,18 @@ int SerialLink::getDataBits() int SerialLink::getStopBits() { + int stopBits; + if (m_port) { + stopBits = m_port->stopBits(); + } else { + stopBits = m_stopBits; + } int ret = -1; - switch (portSettings.stopBits()) { - case QPortSettings::STOP_1: + switch (stopBits) { + case QSerialPort::OneStop: ret = 1; break; - case QPortSettings::STOP_2: + case QSerialPort::TwoStop: ret = 2; break; default: @@ -974,56 +700,36 @@ int SerialLink::getStopBits() bool SerialLink::setPortName(QString portName) { - if(portName.trimmed().length() > 0) { - bool reconnect = false; - if (isConnected()) reconnect = true; - disconnect(); - - this->porthandle = portName.trimmed(); - setName(tr("serial port ") + portName.trimmed()); -#ifdef _WIN32 - // Port names above 20 need the network path format - if the port name is not already in this format - // catch this special case - if (!this->porthandle.startsWith("\\")) { - // Append \\.\ before the port handle. Additional backslashes are used for escaping. - this->porthandle = "\\\\.\\" + this->porthandle; - } -#endif + qDebug() << "current portName " << m_portName; + qDebug() << "setPortName to " << portName; + bool accepted = false; + if ((portName != m_portName) + && (portName.trimmed().length() > 0)) { + m_portName = portName.trimmed(); + m_name = tr("serial port ") + portName.trimmed(); // [TODO] Do we need this? + if(m_port) + m_port->setPortName(portName); - if(reconnect) connect(); - return true; - } else { - return false; + emit nameChanged(m_name); // [TODO] maybe we can eliminate this + return accepted; } + return false; } bool SerialLink::setBaudRateType(int rateIndex) { - bool reconnect = false; - bool accepted = true; // This is changed if none of the data rates matches - if(isConnected()) reconnect = true; - disconnect(); + Q_ASSERT_X(m_port != NULL, "setBaudRateType", "m_port is NULL"); + // These minimum and maximum baud rates were based on those enumerated in qserialport.h + const int minBaud = (int)QSerialPort::Baud1200; + const int maxBaud = (int)QSerialPort::Baud115200; - // These minimum and maximum baud rates were based on those enumerated in qportsettings.h. -#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) - const int minBaud = (int)QPortSettings::BAUDR_110; - const int maxBaud = (int)QPortSettings::BAUDR_921600; -#elif defined(Q_OS_LINUX) - const int minBaud = (int)QPortSettings::BAUDR_50; - const int maxBaud = (int)QPortSettings::BAUDR_921600; -#elif defined(Q_OS_UNIX) || defined(Q_OS_DARWIN) - const int minBaud = (int)QPortSettings::BAUDR_50; - const int maxBaud = (int)QPortSettings::BAUDR_921600; -#endif - - if (rateIndex >= minBaud && rateIndex <= maxBaud) + if (m_port && (rateIndex >= minBaud && rateIndex <= maxBaud)) { - portSettings.setBaudRate((QPortSettings::BaudRate)rateIndex); + return m_port->setBaudRate(static_cast(rateIndex)); } - if(reconnect) connect(); - return accepted; + return false; } bool SerialLink::setBaudRateString(const QString& rate) @@ -1036,260 +742,104 @@ bool SerialLink::setBaudRateString(const QString& rate) bool SerialLink::setBaudRate(int rate) { - bool reconnect = false; - bool accepted = true; // This is changed if none of the data rates matches - if(isConnected()) { - reconnect = true; - } - disconnect(); - - // This switch-statment relies on the mapping given in qportsettings.h from the QSerialPort library. - switch (rate) { - - // Baud rates supported only by non-Windows systems -#if defined(Q_OS_UNIX) || defined(Q_OS_LINUX) || defined(Q_OS_DARWIN) - case 50: - portSettings.setBaudRate(QPortSettings::BAUDR_50); - break; - case 75: - portSettings.setBaudRate(QPortSettings::BAUDR_75); - break; - case 134: - portSettings.setBaudRate(QPortSettings::BAUDR_134); - break; - case 150: - portSettings.setBaudRate(QPortSettings::BAUDR_150); - break; - case 200: - portSettings.setBaudRate(QPortSettings::BAUDR_200); - break; - case 1800: - portSettings.setBaudRate(QPortSettings::BAUDR_1800); - break; -#endif - - // Baud rates supported only by windows -#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) - case 14400: - portSettings.setBaudRate(QPortSettings::BAUDR_14400); - break; - case 56000: - portSettings.setBaudRate(QPortSettings::BAUDR_56000); - break; - case 128000: - portSettings.setBaudRate(QPortSettings::BAUDR_128000); - break; - case 256000: - portSettings.setBaudRate(QPortSettings::BAUDR_256000); - break; -#endif - - // Supported by all OSes: - case 110: - portSettings.setBaudRate(QPortSettings::BAUDR_110); - break; - case 300: - portSettings.setBaudRate(QPortSettings::BAUDR_300); - break; - case 600: - portSettings.setBaudRate(QPortSettings::BAUDR_600); - break; - case 1200: - portSettings.setBaudRate(QPortSettings::BAUDR_1200); - break; - case 2400: - portSettings.setBaudRate(QPortSettings::BAUDR_2400); - break; - case 4800: - portSettings.setBaudRate(QPortSettings::BAUDR_4800); - break; - case 9600: - portSettings.setBaudRate(QPortSettings::BAUDR_9600); - break; - case 19200: - portSettings.setBaudRate(QPortSettings::BAUDR_19200); - break; - case 38400: - portSettings.setBaudRate(QPortSettings::BAUDR_38400); - break; - case 57600: - portSettings.setBaudRate(QPortSettings::BAUDR_57600); - break; - case 115200: - portSettings.setBaudRate(QPortSettings::BAUDR_115200); - break; - case 230400: - portSettings.setBaudRate(QPortSettings::BAUDR_230400); - break; - case 460800: - portSettings.setBaudRate(QPortSettings::BAUDR_460800); - break; - case 500000: - portSettings.setBaudRate(QPortSettings::BAUDR_500000); - break; - case 576000: - portSettings.setBaudRate(QPortSettings::BAUDR_576000); - break; - case 921600: - portSettings.setBaudRate(QPortSettings::BAUDR_921600); - break; - default: - // If none of the above cases matches, there must be an error - accepted = false; - break; + bool accepted = false; + if (rate != m_baud) { + m_baud = rate; + accepted = true; + if (m_port) + accepted = m_port->setBaudRate(rate); } - - if(reconnect) connect(); return accepted; - } bool SerialLink::setFlowType(int flow) { - bool reconnect = false; - bool accepted = true; - if(isConnected()) reconnect = true; - disconnect(); - - switch (flow) { - case (int)QPortSettings::FLOW_OFF: - portSettings.setFlowControl(QPortSettings::FLOW_OFF); - break; - case (int)QPortSettings::FLOW_HARDWARE: - portSettings.setFlowControl(QPortSettings::FLOW_HARDWARE); - break; - case (int)QPortSettings::FLOW_XONXOFF: - portSettings.setFlowControl(QPortSettings::FLOW_XONXOFF); - break; - default: - // If none of the above cases matches, there must be an error - accepted = false; - break; + bool accepted = false; + if (flow != m_flowControl) { + m_flowControl = static_cast(flow); + accepted = true; + if (m_port) + accepted = m_port->setFlowControl(static_cast(flow)); } - - if(reconnect) connect(); return accepted; } bool SerialLink::setParityType(int parity) { - bool reconnect = false; - bool accepted = true; - if (isConnected()) reconnect = true; - disconnect(); - - switch (parity) { - case (int)QPortSettings::PAR_NONE: - portSettings.setParity(QPortSettings::PAR_NONE); - break; - case (int)QPortSettings::PAR_ODD: - portSettings.setParity(QPortSettings::PAR_ODD); - break; - case (int)QPortSettings::PAR_EVEN: - portSettings.setParity(QPortSettings::PAR_EVEN); - break; - case (int)QPortSettings::PAR_SPACE: - portSettings.setParity(QPortSettings::PAR_SPACE); - break; - default: - // If none of the above cases matches, there must be an error - accepted = false; - break; + bool accepted = false; + if (parity != m_parity) { + m_parity = static_cast(parity); + accepted = true; + if (m_port) { + switch (parity) { + case QSerialPort::NoParity: + accepted = m_port->setParity(QSerialPort::NoParity); + break; + case 1: // Odd Parity setting for backwards compatibilty + accepted = m_port->setParity(QSerialPort::OddParity); + break; + case QSerialPort::EvenParity: + accepted = m_port->setParity(QSerialPort::EvenParity); + break; + case QSerialPort::OddParity: + accepted = m_port->setParity(QSerialPort::OddParity); + break; + default: + // If none of the above cases matches, there must be an error + accepted = false; + break; + } + } } - - if (reconnect) connect(); return accepted; } bool SerialLink::setDataBits(int dataBits) { - //qDebug() << "Setting" << dataBits << "data bits"; - bool reconnect = false; - if (isConnected()) reconnect = true; - bool accepted = true; - disconnect(); - - switch (dataBits) { - case 5: - portSettings.setDataBits(QPortSettings::DB_5); - break; - case 6: - portSettings.setDataBits(QPortSettings::DB_6); - break; - case 7: - portSettings.setDataBits(QPortSettings::DB_7); - break; - case 8: - portSettings.setDataBits(QPortSettings::DB_8); - break; - default: - // If none of the above cases matches, there must be an error - accepted = false; - break; + bool accepted = false; + if (dataBits != m_dataBits) { + m_dataBits = static_cast(dataBits); + accepted = true; + if (m_port) + accepted = m_port->setDataBits(static_cast(dataBits)); } - - if(reconnect) connect(); - return accepted; } bool SerialLink::setStopBits(int stopBits) { - bool reconnect = false; - bool accepted = true; - if(isConnected()) reconnect = true; - disconnect(); - - switch (stopBits) { - case 1: - portSettings.setStopBits(QPortSettings::STOP_1); - break; - case 2: - portSettings.setStopBits(QPortSettings::STOP_2); - break; - default: - // If none of the above cases matches, there must be an error - accepted = false; - break; + // Note 3 is OneAndAHalf stopbits. + bool accepted = false; + if (stopBits != m_stopBits) { + m_stopBits = static_cast(stopBits); + accepted = true; + if (m_port) + accepted = m_port->setStopBits(static_cast(stopBits)); } - - if(reconnect) connect(); return accepted; } bool SerialLink::setDataBitsType(int dataBits) { - bool reconnect = false; bool accepted = false; - - if (isConnected()) reconnect = true; - disconnect(); - - if (dataBits >= (int)QPortSettings::DB_5 && dataBits <= (int)QPortSettings::DB_8) { - portSettings.setDataBits((QPortSettings::DataBits) dataBits); - - if(reconnect) connect(); + if (dataBits != m_dataBits) { + m_dataBits = static_cast(dataBits); accepted = true; + if (m_port) + accepted = m_port->setDataBits(static_cast(dataBits)); } - return accepted; } bool SerialLink::setStopBitsType(int stopBits) { - bool reconnect = false; bool accepted = false; - if(isConnected()) reconnect = true; - disconnect(); - - if (stopBits >= (int)QPortSettings::STOP_1 && stopBits <= (int)QPortSettings::STOP_2) { - portSettings.setStopBits((QPortSettings::StopBits) stopBits); - - if(reconnect) connect(); + if (stopBits != m_stopBits) { + m_stopBits = static_cast(stopBits); accepted = true; + if (m_port) + accepted = m_port->setStopBits(static_cast(stopBits)); } - - if(reconnect) connect(); return accepted; } diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index d1f0aa2392..883ffad9fc 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -36,13 +36,9 @@ This file is part of the QGROUNDCONTROL project #include #include #include -#include "qserialport.h" +#include #include #include "SerialLinkInterface.h" -#ifdef _WIN32 -#include "windows.h" -#endif - /** * @brief The SerialLink class provides cross-platform access to serial links. @@ -146,37 +142,36 @@ protected slots: void checkForBytes(); protected: - quint64 bytesRead; - TNX::QSerialPort * port; - TNX::QPortSettings portSettings; -#ifdef _WIN32 - HANDLE winPort; - DCB winPortSettings; -#endif - QString porthandle; - QString name; - int timeout; - int id; - - quint64 bitsSentTotal; - quint64 bitsSentShortTerm; - quint64 bitsSentCurrent; - quint64 bitsSentMax; - quint64 bitsReceivedTotal; - quint64 bitsReceivedShortTerm; - quint64 bitsReceivedCurrent; - quint64 bitsReceivedMax; - quint64 connectionStartTime; - QMutex statisticsMutex; - QMutex dataMutex; - QVector* ports; + quint64 m_bytesRead; + QSerialPort* m_port; + int m_baud; + int m_dataBits; + int m_flowControl; + int m_stopBits; + int m_parity; + QString m_portName; + QString m_name; + int m_timeout; + int m_id; + + quint64 m_bitsSentTotal; + quint64 m_bitsSentShortTerm; + quint64 m_bitsSentCurrent; + quint64 m_bitsSentMax; + quint64 m_bitsReceivedTotal; + quint64 m_bitsReceivedShortTerm; + quint64 m_bitsReceivedCurrent; + quint64 m_bitsReceivedMax; + quint64 m_connectionStartTime; + QMutex m_statisticsMutex; + QMutex m_dataMutex; + QVector* m_ports; private: volatile bool m_stopp; volatile bool m_reqReset; QMutex m_stoppMutex; - void setName(QString name); bool hardwareConnect(); signals: diff --git a/src/ui/SerialConfigurationWindow.cc b/src/ui/SerialConfigurationWindow.cc index 499188ea2d..3354deb6cd 100644 --- a/src/ui/SerialConfigurationWindow.cc +++ b/src/ui/SerialConfigurationWindow.cc @@ -259,7 +259,7 @@ void SerialConfigurationWindow::setParityNone(bool accept) void SerialConfigurationWindow::setParityOdd(bool accept) { - if (accept) link->setParityType(1); + if (accept) link->setParityType(1); // [TODO] This needs to be Fixed [BB] } void SerialConfigurationWindow::setParityEven(bool accept) -- GitLab From 7f13132c4b46c1df953c0ad6f97d9a6490ba7ca1 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 28 Jun 2013 14:26:00 -0400 Subject: [PATCH 031/460] Fix for erronious error message due to connecting a signal in the wrong order on SonarConfig --- src/ui/configuration/BatteryMonitorConfig.cc | 4 +++- src/ui/configuration/SonarConfig.cc | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ui/configuration/BatteryMonitorConfig.cc b/src/ui/configuration/BatteryMonitorConfig.cc index 39556ca202..84c4d014b2 100644 --- a/src/ui/configuration/BatteryMonitorConfig.cc +++ b/src/ui/configuration/BatteryMonitorConfig.cc @@ -18,6 +18,8 @@ BatteryMonitorConfig::BatteryMonitorConfig(QWidget *parent) : AP2ConfigWidget(pa ui.apmVerComboBox->addItem("1: APM2 - 2.5 non 3DR"); ui.apmVerComboBox->addItem("2: APM2.5 - 3DR Power Module"); ui.apmVerComboBox->addItem("3: PX4"); + ui.alertOnLowCheckBox->setVisible(false); + connect(ui.monitorComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(monitorCurrentIndexChanged(int))); connect(ui.sensorComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(sensorCurrentIndexChanged(int))); @@ -27,7 +29,7 @@ BatteryMonitorConfig::BatteryMonitorConfig(QWidget *parent) : AP2ConfigWidget(pa connect(ui.ampsPerVoltsLineEdit,SIGNAL(editingFinished()),this,SLOT(ampsPerVoltSet())); connect(ui.battCapacityLineEdit,SIGNAL(editingFinished()),this,SLOT(batteryCapacitySet())); - ui.alertOnLowCheckBox->setVisible(false); + } void BatteryMonitorConfig::calcDividerSet() diff --git a/src/ui/configuration/SonarConfig.cc b/src/ui/configuration/SonarConfig.cc index fb3481d908..6c04a3bed8 100644 --- a/src/ui/configuration/SonarConfig.cc +++ b/src/ui/configuration/SonarConfig.cc @@ -4,13 +4,12 @@ SonarConfig::SonarConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); - connect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(checkBoxToggled(bool))); - connect(ui.sonarTypeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(sonarTypeChanged(int))); - ui.sonarTypeComboBox->addItem("XL-EZ0 / XL-EZ4"); ui.sonarTypeComboBox->addItem("LV-EZ0"); ui.sonarTypeComboBox->addItem("XL-EZL0"); ui.sonarTypeComboBox->addItem("HRLV"); + connect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(checkBoxToggled(bool))); + connect(ui.sonarTypeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(sonarTypeChanged(int))); } SonarConfig::~SonarConfig() -- GitLab From fad0c692be016b6957d595d274079d1c5be9742c Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 28 Jun 2013 18:25:37 -0400 Subject: [PATCH 032/460] Implementation of Camera Gimbal configuration --- files/images/devices/Shutter.png | Bin 0 -> 14696 bytes files/images/devices/cameraGimalPitch1.png | Bin 0 -> 10738 bytes files/images/devices/cameraGimalRoll1.png | Bin 0 -> 11116 bytes files/images/devices/cameraGimalYaw.png | Bin 0 -> 11251 bytes qgroundcontrol.qrc | 4 + src/ui/QGCParamWidget.cc | 5 + src/ui/configuration/CameraGimbalConfig.cc | 211 ++++++- src/ui/configuration/CameraGimbalConfig.h | 11 +- src/ui/configuration/CameraGimbalConfig.ui | 700 ++++++++++++++++++++- 9 files changed, 924 insertions(+), 7 deletions(-) create mode 100644 files/images/devices/Shutter.png create mode 100644 files/images/devices/cameraGimalPitch1.png create mode 100644 files/images/devices/cameraGimalRoll1.png create mode 100644 files/images/devices/cameraGimalYaw.png diff --git a/files/images/devices/Shutter.png b/files/images/devices/Shutter.png new file mode 100644 index 0000000000000000000000000000000000000000..0362734d5762771d2b98bcfe55fe6c08138cf412 GIT binary patch literal 14696 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 WTll!`CowQEFnGH9xvX*=(}_ literal 0 HcmV?d00001 diff --git a/files/images/devices/cameraGimalPitch1.png b/files/images/devices/cameraGimalPitch1.png new file mode 100644 index 0000000000000000000000000000000000000000..158429893b5aa82506f4ca902b7d8acdec03253f GIT binary patch literal 10738 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¥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 literal 0 HcmV?d00001 diff --git a/files/images/devices/cameraGimalYaw.png b/files/images/devices/cameraGimalYaw.png new file mode 100644 index 0000000000000000000000000000000000000000..0375add2c31bf2c7a5926ce864037bd43a550068 GIT binary patch literal 11251 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/images/devices/BR-0004-03-2.jpg files/images/devices/BR-0016-01-3T.jpg files/images/devices/MinimOSD.jpg + files/images/devices/cameraGimalPitch1.png + files/images/devices/cameraGimalRoll1.png + files/images/devices/cameraGimalYaw.png + files/images/devices/Shutter.png files/styles/Vera.ttf diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 068dbebb9d..b0be69dbe9 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -1017,6 +1017,11 @@ void QGCParamWidget::setParameter(int component, QString parameterName, QVariant statusLabel->setText(tr("REJ. %1 > max").arg(value.toDouble())); return; } + if (parameters.value(component)->value(parameterName) == value) + { + qDebug() << "Value not changed, not sending:" << parameterName << value; + return; + } switch (parameters.value(component)->value(parameterName).type()) { diff --git a/src/ui/configuration/CameraGimbalConfig.cc b/src/ui/configuration/CameraGimbalConfig.cc index 377cbdd8f5..64b20d250f 100644 --- a/src/ui/configuration/CameraGimbalConfig.cc +++ b/src/ui/configuration/CameraGimbalConfig.cc @@ -1,11 +1,218 @@ #include "CameraGimbalConfig.h" +#include +#include +CameraGimbalConfig::CameraGimbalConfig(QWidget *parent) : AP2ConfigWidget(parent) +{ + ui.setupUi(this); + ui.tiltChannelComboBox->addItem("Disable"); + ui.tiltChannelComboBox->addItem("RC5"); + ui.tiltChannelComboBox->addItem("RC6"); + ui.tiltChannelComboBox->addItem("RC7"); + ui.tiltChannelComboBox->addItem("RC8"); + ui.tiltChannelComboBox->addItem("RC10"); + ui.tiltChannelComboBox->addItem("RC11"); + + ui.tiltInputChannelComboBox->addItem("Disable"); + ui.tiltInputChannelComboBox->addItem("RC5"); + ui.tiltInputChannelComboBox->addItem("RC6"); + ui.tiltInputChannelComboBox->addItem("RC7"); + ui.tiltInputChannelComboBox->addItem("RC8"); + + ui.rollChannelComboBox->addItem("Disable"); + ui.rollChannelComboBox->addItem("RC5"); + ui.rollChannelComboBox->addItem("RC6"); + ui.rollChannelComboBox->addItem("RC7"); + ui.rollChannelComboBox->addItem("RC8"); + ui.rollChannelComboBox->addItem("RC10"); + ui.rollChannelComboBox->addItem("RC11"); + + ui.rollInputChannelComboBox->addItem("Disable"); + ui.rollInputChannelComboBox->addItem("RC5"); + ui.rollInputChannelComboBox->addItem("RC6"); + ui.rollInputChannelComboBox->addItem("RC7"); + ui.rollInputChannelComboBox->addItem("RC8"); + + + ui.panChannelComboBox->addItem("Disable"); + ui.panChannelComboBox->addItem("RC5"); + ui.panChannelComboBox->addItem("RC6"); + ui.panChannelComboBox->addItem("RC7"); + ui.panChannelComboBox->addItem("RC8"); + ui.panChannelComboBox->addItem("RC10"); + ui.panChannelComboBox->addItem("RC11"); + + ui.panInputChannelComboBox->addItem("Disable"); + ui.panInputChannelComboBox->addItem("RC5"); + ui.panInputChannelComboBox->addItem("RC6"); + ui.panInputChannelComboBox->addItem("RC7"); + ui.panInputChannelComboBox->addItem("RC8"); + + + ui.shutterChannelComboBox->addItem("Disable"); + ui.shutterChannelComboBox->addItem("Relay"); + ui.shutterChannelComboBox->addItem("Transistor"); + ui.shutterChannelComboBox->addItem("RC5"); + ui.shutterChannelComboBox->addItem("RC6"); + ui.shutterChannelComboBox->addItem("RC7"); + ui.shutterChannelComboBox->addItem("RC8"); + ui.shutterChannelComboBox->addItem("RC10"); + ui.shutterChannelComboBox->addItem("RC11"); + + connect(ui.tiltServoMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); + connect(ui.tiltServoMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); + connect(ui.tiltAngleMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); + connect(ui.tiltAngleMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); + connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + connect(ui.tiltInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + connect(ui.tiltReverseCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateTilt())); + connect(ui.tiltStabilizeCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateTilt())); + + connect(ui.rollServoMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); + connect(ui.rollServoMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); + connect(ui.rollAngleMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); + connect(ui.rollAngleMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); + connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + connect(ui.rollInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + connect(ui.rollReverseCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateTilt())); + connect(ui.rollStabilizeCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateTilt())); + + connect(ui.panServoMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); + connect(ui.panServoMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); + connect(ui.panAngleMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); + connect(ui.panAngleMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); + connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + connect(ui.panInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + connect(ui.panReverseCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateTilt())); + connect(ui.panStabilizeCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateTilt())); + + + connect(ui.shutterServoMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateShutter())); + connect(ui.shutterServoMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updateShutter())); + connect(ui.shutterPushedSpinBox,SIGNAL(editingFinished()),this,SLOT(updateShutter())); + connect(ui.shutterNotPushedSpinBox,SIGNAL(editingFinished()),this,SLOT(updateShutter())); + connect(ui.shutterDurationSpinBox,SIGNAL(editingFinished()),this,SLOT(updateShutter())); + connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + + +} +void CameraGimbalConfig::updateTilt() +{ + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } + if (ui.tiltChannelComboBox->currentIndex() == 0) + { + //Disabled + return; + } + for (QMap::const_iterator i = m_uas->getComponents().constBegin(); i != m_uas->getComponents().constEnd();i++) + { + qDebug() << "Component:" << i.key() << "Name:" << i.value(); + } + m_uas->getParamManager()->setParameter(1,ui.tiltChannelComboBox->currentText() + "_FUNCTION",7); + m_uas->getParamManager()->setParameter(1,ui.tiltChannelComboBox->currentText() + "_MIN",ui.tiltServoMinSpinBox->value()); + m_uas->getParamManager()->setParameter(1,ui.tiltChannelComboBox->currentText() + "_MAX",ui.tiltServoMaxSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_ANGMIN_TIL",ui.tiltAngleMinSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_ANGMAX_TIL",ui.tiltAngleMaxSpinBox->value()); + m_uas->getParamManager()->setParameter(1,ui.tiltChannelComboBox->currentText() + "_REV",(ui.tiltReverseCheckBox->isChecked() ? 1 : 0)); + if (ui.tiltInputChannelComboBox->currentIndex() == 0) + { + m_uas->getParamManager()->setParameter(1,"MNT_RC_IN_TILT",0); + } + else + { + m_uas->getParamManager()->setParameter(1,"MNT_RC_IN_TILT",ui.tiltInputChannelComboBox->currentIndex()+4); + } +} -CameraGimbalConfig::CameraGimbalConfig(QWidget *parent) : QWidget(parent) +void CameraGimbalConfig::updateRoll() { - ui.setupUi(this); + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } + m_uas->getParamManager()->setParameter(1,ui.rollChannelComboBox->currentText() + "_FUNCTION",8); + m_uas->getParamManager()->setParameter(1,ui.rollChannelComboBox->currentText() + "_MIN",ui.rollServoMinSpinBox->value()); + m_uas->getParamManager()->setParameter(1,ui.rollChannelComboBox->currentText() + "_MAX",ui.rollServoMaxSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_ANGMIN_ROL",ui.rollAngleMinSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_ANGMAX_ROL",ui.rollAngleMaxSpinBox->value()); + m_uas->getParamManager()->setParameter(1,ui.rollChannelComboBox->currentText() + "_REV",(ui.rollReverseCheckBox->isChecked() ? 1 : 0)); + if (ui.rollInputChannelComboBox->currentIndex() == 0) + { + m_uas->getParamManager()->setParameter(1,"MNT_RC_IN_ROLL",0); + } + else + { + m_uas->getParamManager()->setParameter(1,"MNT_RC_IN_ROLL",ui.rollInputChannelComboBox->currentIndex()+4); + } } +void CameraGimbalConfig::updatePan() +{ + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } + m_uas->getParamManager()->setParameter(1,ui.panChannelComboBox->currentText() + "_FUNCTION",6); + m_uas->getParamManager()->setParameter(1,ui.panChannelComboBox->currentText() + "_MIN",ui.panServoMinSpinBox->value()); + m_uas->getParamManager()->setParameter(1,ui.panChannelComboBox->currentText() + "_MAX",ui.panServoMaxSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_ANGMIN_PAN",ui.panAngleMinSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_ANGMAX_PAN",ui.panAngleMaxSpinBox->value()); + m_uas->getParamManager()->setParameter(1,ui.panChannelComboBox->currentText() + "_REV",(ui.panReverseCheckBox->isChecked() ? 1 : 0)); + if (ui.panInputChannelComboBox->currentIndex() == 0) + { + m_uas->getParamManager()->setParameter(1,"MNT_RC_IN_PAN",0); + } + else + { + m_uas->getParamManager()->setParameter(1,"MNT_RC_IN_PAN",ui.panInputChannelComboBox->currentIndex()+4); + } +} + +void CameraGimbalConfig::updateShutter() +{ + if (!m_uas) + { + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + return; + } + if (ui.shutterChannelComboBox->currentIndex() == 0) //Disabled + { + m_uas->getParamManager()->setParameter(1,"CAM_TRIGG_TYPE",0); + } + else if (ui.shutterChannelComboBox->currentIndex() == 1) //Relay + { + m_uas->getParamManager()->setParameter(1,"CAM_TRIGG_TYPE",1); + } + else if (ui.shutterChannelComboBox->currentIndex() == 2) //Transistor + { + m_uas->getParamManager()->setParameter(1,"CAM_TRIGG_TYPE",4); + } + else + { + m_uas->getParamManager()->setParameter(1,ui.shutterChannelComboBox->currentText() + "_FUNCTION",10); + m_uas->getParamManager()->setParameter(1,"CAM_TRIGG_TYPE",0); + } + m_uas->getParamManager()->setParameter(1,ui.shutterChannelComboBox->currentText() + "_MIN",ui.shutterServoMinSpinBox->value()); + m_uas->getParamManager()->setParameter(1,ui.shutterChannelComboBox->currentText() + "_MAX",ui.shutterServoMaxSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"CAM_SERVO_ON",ui.shutterPushedSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"CAM_SERVO_OFF",ui.shutterNotPushedSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"CAM_DURATION",ui.shutterDurationSpinBox->value()); + + +} + + CameraGimbalConfig::~CameraGimbalConfig() { } + +void CameraGimbalConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + +} diff --git a/src/ui/configuration/CameraGimbalConfig.h b/src/ui/configuration/CameraGimbalConfig.h index 4373fbf5f1..92714f4fbf 100644 --- a/src/ui/configuration/CameraGimbalConfig.h +++ b/src/ui/configuration/CameraGimbalConfig.h @@ -2,16 +2,23 @@ #define CAMERAGIMBALCONFIG_H #include +#include "AP2ConfigWidget.h" #include "ui_CameraGimbalConfig.h" -class CameraGimbalConfig : public QWidget +class CameraGimbalConfig : public AP2ConfigWidget { Q_OBJECT public: explicit CameraGimbalConfig(QWidget *parent = 0); ~CameraGimbalConfig(); - +private slots: + void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void updateTilt(); + void updateRoll(); + void updatePan(); + void updateShutter(); + private: Ui::CameraGimbalConfig ui; }; diff --git a/src/ui/configuration/CameraGimbalConfig.ui b/src/ui/configuration/CameraGimbalConfig.ui index b2b7f607b3..7b1feb4389 100644 --- a/src/ui/configuration/CameraGimbalConfig.ui +++ b/src/ui/configuration/CameraGimbalConfig.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 300 + 959 + 813 @@ -29,7 +29,701 @@ false + + + + 30 + 60 + 541 + 151 + + + + + + + Min + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Max + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + <h3>Input Ch</h3> + + + + + + + Reverse + + + + + + + <h3>Angle Limits</h3> + + + + + + + <h3>Servo Limits</h3> + + + + + + + Max + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Min + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + <h2>Tilt</h2> + + + Qt::AlignCenter + + + + + + + CheckBox + + + + + + + + 250 + 120 + + + + + 250 + 120 + + + + + + + :/files/images/devices/cameraGimalPitch1.png + + + true + + + + + + + 3000 + + + 1000 + + + + + + + 3000 + + + 2000 + + + + + + + 3000 + + + 1000 + + + + + + + 3000 + + + 2000 + + + + + + + + + + + + 30 + 230 + 541 + 149 + + + + + + + Min + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Max + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + <h3>Input Ch</h3> + + + + + + + Reverse + + + + + + + <h3>Angle Limits</h3> + + + + + + + <h3>Servo Limits</h3> + + + + + + + Max + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Min + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + <h2>Roll</h2> + + + Qt::AlignCenter + + + + + + + CheckBox + + + + + + + + 250 + 120 + + + + + 250 + 120 + + + + + + + :/files/images/devices/cameraGimalRoll1.png + + + true + + + + + + + 3000 + + + 1000 + + + + + + + 3000 + + + 2000 + + + + + + + 3000 + + + 1000 + + + + + + + 3000 + + + 2000 + + + + + + + + + 30 + 390 + 541 + 149 + + + + + + + Min + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Max + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + <h3>Input Ch</h3> + + + + + + + Reverse + + + + + + + <h3>Angle Limits</h3> + + + + + + + <h3>Servo Limits</h3> + + + + + + + Max + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Min + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + <h2>Pan</h2> + + + Qt::AlignCenter + + + + + + + CheckBox + + + + + + + + 250 + 120 + + + + + 250 + 120 + + + + + + + :/files/images/devices/cameraGimalYaw.png + + + true + + + + + + + 3000 + + + 1000 + + + + + + + 3000 + + + 1000 + + + + + + + 3000 + + + 2000 + + + + + + + 3000 + + + 2000 + + + + + + + + + 30 + 550 + 541 + 181 + + + + + + + + 250 + 120 + + + + + 250 + 120 + + + + + + + :/files/images/devices/Shutter.png + + + true + + + + + + + Duration +(1/10th sec) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Pushed + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Not Pushed + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + <h3>Shutter</h3> + + + + + + + <h3>Servo Limits</h3> + + + + + + + Max + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Min + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + <h2>Shutter</h2> + + + Qt::AlignCenter + + + + + + + <h2>Please set the Ch7 Option to Camera Trigger</h2> + + + Qt::AlignCenter + + + + + + + 3000 + + + 1000 + + + + + + + 3000 + + + 2000 + + + + + + + 100 + + + 20 + + + + + + + 3000 + + + 1000 + + + + + + + 3000 + + + 2000 + + + + + + + + + 720 + 70 + 120 + 80 + + + + GroupBox + + - + + + -- GitLab From e477661549558d6d6f8f7d6596dbfffbb421dc9c Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 28 Jun 2013 18:31:23 -0400 Subject: [PATCH 033/460] Change for all config widgets to use the Parameter Manager for setting parameters --- src/ui/QGCParamWidget.cc | 2 +- src/ui/configuration/AirspeedConfig.cc | 8 ++--- src/ui/configuration/BatteryMonitorConfig.cc | 34 +++++++++---------- src/ui/configuration/CompassConfig.cc | 8 ++--- src/ui/configuration/FlightModeConfig.cc | 34 +++++++++---------- src/ui/configuration/FrameTypeConfig.cc | 6 ++-- src/ui/configuration/OpticalFlowConfig.cc | 2 +- src/ui/configuration/OsdConfig.cc | 32 ++++++++--------- .../configuration/RadioCalibrationConfig.cc | 4 +-- src/ui/configuration/SonarConfig.cc | 4 +-- 10 files changed, 67 insertions(+), 67 deletions(-) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index b0be69dbe9..50a0180ab4 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -1019,7 +1019,7 @@ void QGCParamWidget::setParameter(int component, QString parameterName, QVariant } if (parameters.value(component)->value(parameterName) == value) { - qDebug() << "Value not changed, not sending:" << parameterName << value; + statusLabel->setText(tr("REJ. %1 > max").arg(value.toDouble())); return; } diff --git a/src/ui/configuration/AirspeedConfig.cc b/src/ui/configuration/AirspeedConfig.cc index 8402622ee6..dfdc1e08d8 100644 --- a/src/ui/configuration/AirspeedConfig.cc +++ b/src/ui/configuration/AirspeedConfig.cc @@ -56,11 +56,11 @@ void AirspeedConfig::useCheckBoxClicked(bool checked) } if (checked) { - m_uas->setParameter(0,"ARSPD_USE",1); + m_uas->getParamManager()->setParameter(1,"ARSPD_USE",1); } else { - m_uas->setParameter(0,"ARSPD_USE",0); + m_uas->getParamManager()->setParameter(1,"ARSPD_USE",0); } } @@ -73,10 +73,10 @@ void AirspeedConfig::enableCheckBoxClicked(bool checked) } if (checked) { - m_uas->setParameter(0,"ARSPD_ENABLE",1); + m_uas->getParamManager()->setParameter(1,"ARSPD_ENABLE",1); } else { - m_uas->setParameter(0,"ARSPD_ENABLE",0); + m_uas->getParamManager()->setParameter(1,"ARSPD_ENABLE",0); } } diff --git a/src/ui/configuration/BatteryMonitorConfig.cc b/src/ui/configuration/BatteryMonitorConfig.cc index 84c4d014b2..5e74cedde2 100644 --- a/src/ui/configuration/BatteryMonitorConfig.cc +++ b/src/ui/configuration/BatteryMonitorConfig.cc @@ -47,7 +47,7 @@ void BatteryMonitorConfig::calcDividerSet() QMessageBox::information(0,"Error","Invalid number entered for voltage divider. Please try again"); return; } - m_uas->setParameter(0,"VOLT_DIVIDER",newval); + m_uas->getParamManager()->setParameter(1,"VOLT_DIVIDER",newval); } void BatteryMonitorConfig::ampsPerVoltSet() { @@ -64,7 +64,7 @@ void BatteryMonitorConfig::ampsPerVoltSet() QMessageBox::information(0,"Error","Invalid number entered for amps per volts. Please try again"); return; } - m_uas->setParameter(0,"AMPS_PER_VOLT",newval); + m_uas->getParamManager()->setParameter(1,"AMPS_PER_VOLT",newval); } void BatteryMonitorConfig::batteryCapacitySet() { @@ -81,7 +81,7 @@ void BatteryMonitorConfig::batteryCapacitySet() QMessageBox::information(0,"Error","Invalid number entered for amps per volts. Please try again"); return; } - m_uas->setParameter(0,"BATT_CAPACITY",newval); + m_uas->getParamManager()->setParameter(1,"BATT_CAPACITY",newval); } void BatteryMonitorConfig::monitorCurrentIndexChanged(int index) @@ -93,9 +93,9 @@ void BatteryMonitorConfig::monitorCurrentIndexChanged(int index) } if (index == 0) { - m_uas->setParameter(0,"BATT_VOLT_PIN",-1); - m_uas->setParameter(0,"BATT_CURR_PIN",-1); - m_uas->setParameter(0,"BATT_MONITOR",0); + m_uas->getParamManager()->setParameter(1,"BATT_VOLT_PIN",-1); + m_uas->getParamManager()->setParameter(1,"BATT_CURR_PIN",-1); + m_uas->getParamManager()->setParameter(1,"BATT_MONITOR",0); ui.sensorComboBox->setEnabled(false); ui.apmVerComboBox->setEnabled(false); ui.measuredVoltsLineEdit->setEnabled(false); @@ -106,7 +106,7 @@ void BatteryMonitorConfig::monitorCurrentIndexChanged(int index) } else if (index == 1) { - m_uas->setParameter(0,"BATT_MONITOR",3); + m_uas->getParamManager()->setParameter(1,"BATT_MONITOR",3); ui.sensorComboBox->setEnabled(false); ui.apmVerComboBox->setEnabled(true); ui.measuredVoltsLineEdit->setEnabled(true); @@ -116,7 +116,7 @@ void BatteryMonitorConfig::monitorCurrentIndexChanged(int index) } else if (index == 2) { - m_uas->setParameter(0,"BATT_MONITOR",4); + m_uas->getParamManager()->setParameter(1,"BATT_MONITOR",4); ui.sensorComboBox->setEnabled(true); ui.apmVerComboBox->setEnabled(true); ui.measuredVoltsLineEdit->setEnabled(true); @@ -197,24 +197,24 @@ void BatteryMonitorConfig::apmVerCurrentIndexChanged(int index) } if (index == 0) //APM1 { - m_uas->setParameter(0,"BATT_VOLT_PIN",0); - m_uas->setParameter(0,"BATT_CURR_PIN",1); + m_uas->getParamManager()->setParameter(1,"BATT_VOLT_PIN",0); + m_uas->getParamManager()->setParameter(1,"BATT_CURR_PIN",1); } else if (index == 1) //APM2 { - m_uas->setParameter(0,"BATT_VOLT_PIN",1); - m_uas->setParameter(0,"BATT_CURR_PIN",2); + m_uas->getParamManager()->setParameter(1,"BATT_VOLT_PIN",1); + m_uas->getParamManager()->setParameter(1,"BATT_CURR_PIN",2); } else if (index == 2) //APM2.5 { - m_uas->setParameter(0,"BATT_VOLT_PIN",13); - m_uas->setParameter(0,"BATT_CURR_PIN",12); + m_uas->getParamManager()->setParameter(1,"BATT_VOLT_PIN",13); + m_uas->getParamManager()->setParameter(1,"BATT_CURR_PIN",12); } else if (index == 3) //PX4 { - m_uas->setParameter(0,"BATT_VOLT_PIN",100); - m_uas->setParameter(0,"BATT_CURR_PIN",101); - m_uas->setParameter(0,"VOLT_DIVIDER",1); + m_uas->getParamManager()->setParameter(1,"BATT_VOLT_PIN",100); + m_uas->getParamManager()->setParameter(1,"BATT_CURR_PIN",101); + m_uas->getParamManager()->setParameter(1,"VOLT_DIVIDER",1); ui.calcDividerLineEdit->setText("1"); } } diff --git a/src/ui/configuration/CompassConfig.cc b/src/ui/configuration/CompassConfig.cc index fda95b6620..5c37b0cbf6 100644 --- a/src/ui/configuration/CompassConfig.cc +++ b/src/ui/configuration/CompassConfig.cc @@ -71,7 +71,7 @@ void CompassConfig::enableClicked(bool enabled) { if (enabled) { - m_uas->setParameter(0,"MAG_ENABLE",QVariant(1)); + m_uas->getParamManager()->setParameter(1,"MAG_ENABLE",QVariant(1)); ui.autoDecCheckBox->setEnabled(true); if (!ui.autoDecCheckBox->isChecked()) { @@ -80,7 +80,7 @@ void CompassConfig::enableClicked(bool enabled) } else { - m_uas->setParameter(0,"MAG_ENABLE",QVariant(0)); + m_uas->getParamManager()->setParameter(1,"MAG_ENABLE",QVariant(0)); ui.autoDecCheckBox->setEnabled(false); ui.declinationLineEdit->setEnabled(false); } @@ -93,11 +93,11 @@ void CompassConfig::autoDecClicked(bool enabled) { if (enabled) { - m_uas->setParameter(0,"COMPASS_AUTODEC",QVariant(1)); + m_uas->getParamManager()->setParameter(1,"COMPASS_AUTODEC",QVariant(1)); } else { - m_uas->setParameter(0,"COMPASS_AUTODEC",QVariant(0)); + m_uas->getParamManager()->setParameter(1,"COMPASS_AUTODEC",QVariant(0)); } } } diff --git a/src/ui/configuration/FlightModeConfig.cc b/src/ui/configuration/FlightModeConfig.cc index 9e10175efd..e0a04572ab 100644 --- a/src/ui/configuration/FlightModeConfig.cc +++ b/src/ui/configuration/FlightModeConfig.cc @@ -135,29 +135,29 @@ void FlightModeConfig::saveButtonClicked() { if (m_uas->getSystemType() == MAV_TYPE_FIXED_WING) { - m_uas->setParameter(0,"FLTMODE1",(char)planeModeUiIndexToIndex[ui.mode1ComboBox->currentIndex()]); - m_uas->setParameter(0,"FLTMODE2",(char)planeModeUiIndexToIndex[ui.mode2ComboBox->currentIndex()]); - m_uas->setParameter(0,"FLTMODE3",(char)planeModeUiIndexToIndex[ui.mode3ComboBox->currentIndex()]); - m_uas->setParameter(0,"FLTMODE4",(char)planeModeUiIndexToIndex[ui.mode4ComboBox->currentIndex()]); - m_uas->setParameter(0,"FLTMODE5",(char)planeModeUiIndexToIndex[ui.mode5ComboBox->currentIndex()]); - m_uas->setParameter(0,"FLTMODE6",(char)planeModeUiIndexToIndex[ui.mode6ComboBox->currentIndex()]); + m_uas->getParamManager()->setParameter(1,"FLTMODE1",(char)planeModeUiIndexToIndex[ui.mode1ComboBox->currentIndex()]); + m_uas->getParamManager()->setParameter(1,"FLTMODE2",(char)planeModeUiIndexToIndex[ui.mode2ComboBox->currentIndex()]); + m_uas->getParamManager()->setParameter(1,"FLTMODE3",(char)planeModeUiIndexToIndex[ui.mode3ComboBox->currentIndex()]); + m_uas->getParamManager()->setParameter(1,"FLTMODE4",(char)planeModeUiIndexToIndex[ui.mode4ComboBox->currentIndex()]); + m_uas->getParamManager()->setParameter(1,"FLTMODE5",(char)planeModeUiIndexToIndex[ui.mode5ComboBox->currentIndex()]); + m_uas->getParamManager()->setParameter(1,"FLTMODE6",(char)planeModeUiIndexToIndex[ui.mode6ComboBox->currentIndex()]); } else if (m_uas->getSystemType() == MAV_TYPE_GROUND_ROVER) { - m_uas->setParameter(0,"MODE1",(char)roverModeUiIndexToIndex[ui.mode1ComboBox->currentIndex()]); - m_uas->setParameter(0,"MODE2",(char)roverModeUiIndexToIndex[ui.mode2ComboBox->currentIndex()]); - m_uas->setParameter(0,"MODE3",(char)roverModeUiIndexToIndex[ui.mode3ComboBox->currentIndex()]); - m_uas->setParameter(0,"MODE4",(char)roverModeUiIndexToIndex[ui.mode4ComboBox->currentIndex()]); - m_uas->setParameter(0,"MODE5",(char)roverModeUiIndexToIndex[ui.mode5ComboBox->currentIndex()]); + m_uas->getParamManager()->setParameter(1,"MODE1",(char)roverModeUiIndexToIndex[ui.mode1ComboBox->currentIndex()]); + m_uas->getParamManager()->setParameter(1,"MODE2",(char)roverModeUiIndexToIndex[ui.mode2ComboBox->currentIndex()]); + m_uas->getParamManager()->setParameter(1,"MODE3",(char)roverModeUiIndexToIndex[ui.mode3ComboBox->currentIndex()]); + m_uas->getParamManager()->setParameter(1,"MODE4",(char)roverModeUiIndexToIndex[ui.mode4ComboBox->currentIndex()]); + m_uas->getParamManager()->setParameter(1,"MODE5",(char)roverModeUiIndexToIndex[ui.mode5ComboBox->currentIndex()]); } else if (m_uas->getSystemType() == MAV_TYPE_QUADROTOR) { - m_uas->setParameter(0,"FLTMODE1",(char)ui.mode1ComboBox->currentIndex()+1); - m_uas->setParameter(0,"FLTMODE2",(char)ui.mode2ComboBox->currentIndex()+1); - m_uas->setParameter(0,"FLTMODE3",(char)ui.mode3ComboBox->currentIndex()+1); - m_uas->setParameter(0,"FLTMODE4",(char)ui.mode4ComboBox->currentIndex()+1); - m_uas->setParameter(0,"FLTMODE5",(char)ui.mode5ComboBox->currentIndex()+1); - m_uas->setParameter(0,"FLTMODE6",(char)ui.mode6ComboBox->currentIndex()+1); + m_uas->getParamManager()->setParameter(1,"FLTMODE1",(char)ui.mode1ComboBox->currentIndex()+1); + m_uas->getParamManager()->setParameter(1,"FLTMODE2",(char)ui.mode2ComboBox->currentIndex()+1); + m_uas->getParamManager()->setParameter(1,"FLTMODE3",(char)ui.mode3ComboBox->currentIndex()+1); + m_uas->getParamManager()->setParameter(1,"FLTMODE4",(char)ui.mode4ComboBox->currentIndex()+1); + m_uas->getParamManager()->setParameter(1,"FLTMODE5",(char)ui.mode5ComboBox->currentIndex()+1); + m_uas->getParamManager()->setParameter(1,"FLTMODE6",(char)ui.mode6ComboBox->currentIndex()+1); } } diff --git a/src/ui/configuration/FrameTypeConfig.cc b/src/ui/configuration/FrameTypeConfig.cc index 571c10073b..1e4fc5f79e 100644 --- a/src/ui/configuration/FrameTypeConfig.cc +++ b/src/ui/configuration/FrameTypeConfig.cc @@ -88,7 +88,7 @@ void FrameTypeConfig::xFrameSelected() { if (m_uas) { - m_uas->setParameter(0,"FRAME",QVariant(1)); + m_uas->getParamManager()->setParameter(1,"FRAME",QVariant(1)); } } @@ -96,7 +96,7 @@ void FrameTypeConfig::plusFrameSelected() { if (m_uas) { - m_uas->setParameter(0,"FRAME",QVariant(0)); + m_uas->getParamManager()->setParameter(1,"FRAME",QVariant(0)); } } @@ -104,6 +104,6 @@ void FrameTypeConfig::vFrameSelected() { if (m_uas) { - m_uas->setParameter(0,"FRAME",QVariant(2)); + m_uas->getParamManager()->setParameter(1,"FRAME",QVariant(2)); } } diff --git a/src/ui/configuration/OpticalFlowConfig.cc b/src/ui/configuration/OpticalFlowConfig.cc index 7c39431174..085a83f3f1 100644 --- a/src/ui/configuration/OpticalFlowConfig.cc +++ b/src/ui/configuration/OpticalFlowConfig.cc @@ -32,5 +32,5 @@ void OpticalFlowConfig::enableCheckBoxClicked(bool checked) QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); return; } - m_uas->setParameter(0,"FLOW_ENABLE",checked ? 1 : 0); + m_uas->getParamManager()->setParameter(1,"FLOW_ENABLE",checked ? 1 : 0); } diff --git a/src/ui/configuration/OsdConfig.cc b/src/ui/configuration/OsdConfig.cc index d71430e3ca..8fd0d9f367 100644 --- a/src/ui/configuration/OsdConfig.cc +++ b/src/ui/configuration/OsdConfig.cc @@ -17,21 +17,21 @@ void OsdConfig::enableButtonClicked() QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); return; } - m_uas->setParameter(0,"SR0_EXT_STAT",2); - m_uas->setParameter(0,"SR0_EXTRA1",10); - m_uas->setParameter(0,"SR0_EXTRA2",10); - m_uas->setParameter(0,"SR0_EXTRA3",2); - m_uas->setParameter(0,"SR0_POSITION",3); - m_uas->setParameter(0,"SR0_RAW_CTRL",2); - m_uas->setParameter(0,"SR0_RAW_SENS",2); - m_uas->setParameter(0,"SR0_RC_CHAN",2); + m_uas->getParamManager()->setParameter(1,"SR0_EXT_STAT",2); + m_uas->getParamManager()->setParameter(1,"SR0_EXTRA1",10); + m_uas->getParamManager()->setParameter(1,"SR0_EXTRA2",10); + m_uas->getParamManager()->setParameter(1,"SR0_EXTRA3",2); + m_uas->getParamManager()->setParameter(1,"SR0_POSITION",3); + m_uas->getParamManager()->setParameter(1,"SR0_RAW_CTRL",2); + m_uas->getParamManager()->setParameter(1,"SR0_RAW_SENS",2); + m_uas->getParamManager()->setParameter(1,"SR0_RC_CHAN",2); - m_uas->setParameter(0,"SR3_EXT_STAT",2); - m_uas->setParameter(0,"SR3_EXTRA1",10); - m_uas->setParameter(0,"SR3_EXTRA2",10); - m_uas->setParameter(0,"SR3_EXTRA3",2); - m_uas->setParameter(0,"SR3_POSITION",3); - m_uas->setParameter(0,"SR3_RAW_CTRL",2); - m_uas->setParameter(0,"SR3_RAW_SENS",2); - m_uas->setParameter(0,"SR3_RC_CHAN",2); + m_uas->getParamManager()->setParameter(1,"SR3_EXT_STAT",2); + m_uas->getParamManager()->setParameter(1,"SR3_EXTRA1",10); + m_uas->getParamManager()->setParameter(1,"SR3_EXTRA2",10); + m_uas->getParamManager()->setParameter(1,"SR3_EXTRA3",2); + m_uas->getParamManager()->setParameter(1,"SR3_POSITION",3); + m_uas->getParamManager()->setParameter(1,"SR3_RAW_CTRL",2); + m_uas->getParamManager()->setParameter(1,"SR3_RAW_SENS",2); + m_uas->getParamManager()->setParameter(1,"SR3_RC_CHAN",2); } diff --git a/src/ui/configuration/RadioCalibrationConfig.cc b/src/ui/configuration/RadioCalibrationConfig.cc index 047ffadc5d..0de51073a2 100644 --- a/src/ui/configuration/RadioCalibrationConfig.cc +++ b/src/ui/configuration/RadioCalibrationConfig.cc @@ -213,11 +213,11 @@ void RadioCalibrationConfig::calibrateButtonClicked() { qDebug() << "SENDING MIN" << minTpl.arg(i+1) << rcMin[i]; qDebug() << "SENDING MAX" << maxTpl.arg(i+1) << rcMax[i]; - m_uas->setParameter(0, minTpl.arg(i+1), (float)rcMin[i]); + m_uas->getParamManager()->setParameter(1, minTpl.arg(i+1), (float)rcMin[i]); QGC::SLEEP::usleep(50000); //m_uas->setParameter(0, trimTpl.arg(i+1), rcTrim[i]); //QGC::SLEEP::usleep(50000); - m_uas->setParameter(0, maxTpl.arg(i+1), (float)rcMax[i]); + m_uas->getParamManager()->setParameter(1, maxTpl.arg(i+1), (float)rcMax[i]); QGC::SLEEP::usleep(50000); } ui.rollWidget->setMin(800); diff --git a/src/ui/configuration/SonarConfig.cc b/src/ui/configuration/SonarConfig.cc index 6c04a3bed8..586a7f9ab5 100644 --- a/src/ui/configuration/SonarConfig.cc +++ b/src/ui/configuration/SonarConfig.cc @@ -26,7 +26,7 @@ void SonarConfig::checkBoxToggled(bool enabled) QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); return; } - m_uas->setParameter(0,"SONAR_ENABLE",ui.enableCheckBox->isChecked() ? 1 : 0); + m_uas->getParamManager()->setParameter(1,"SONAR_ENABLE",ui.enableCheckBox->isChecked() ? 1 : 0); } void SonarConfig::sonarTypeChanged(int index) { @@ -35,7 +35,7 @@ void SonarConfig::sonarTypeChanged(int index) QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); return; } - m_uas->setParameter(0,"SONAR_TYPE",ui.sonarTypeComboBox->currentIndex()); + m_uas->getParamManager()->setParameter(1,"SONAR_TYPE",ui.sonarTypeComboBox->currentIndex()); } void SonarConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) -- GitLab From ee16284dc763a8899bdabd59448997f6cfcfc07b Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Mon, 1 Jul 2013 09:43:58 -0400 Subject: [PATCH 034/460] Addition of baud rate combo box on the toolbar --- src/ui/QGCToolBar.cc | 18 ++++++++++++++++++ src/ui/QGCToolBar.h | 1 + 2 files changed, 19 insertions(+) diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 777a70aa12..649072640f 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -166,6 +166,22 @@ void QGCToolBar::createUI() portComboBox->setEnabled(true); portComboBox->setMinimumWidth(200); addWidget(portComboBox); + + baudcomboBox = new QComboBox(this); + baudcomboBox->setToolTip(tr("Choose what baud rate to use")); + baudcomboBox->setEnabled(true); + baudcomboBox->setMinimumWidth(80); + baudcomboBox->addItem("9600"); + baudcomboBox->addItem("14400"); + baudcomboBox->addItem("19200"); + baudcomboBox->addItem("38400"); + baudcomboBox->addItem("57600"); + baudcomboBox->addItem("115200"); + baudcomboBox->setCurrentIndex(5); + addWidget(baudcomboBox); + + + connectButton = new QPushButton(tr("Connect"), this); connectButton->setToolTip(tr("Connect wireless link to MAV")); connectButton->setCheckable(true); @@ -610,6 +626,8 @@ void QGCToolBar::connectLink(bool connect) QString portname = portComboBox->currentText().split(":")[2]; link->setPortName(portname.trimmed()); } + int baud = baudcomboBox->currentText().toInt(); + link->setBaudRate(baud); link->connect(); } else diff --git a/src/ui/QGCToolBar.h b/src/ui/QGCToolBar.h index 887c73e836..8f268d3492 100644 --- a/src/ui/QGCToolBar.h +++ b/src/ui/QGCToolBar.h @@ -105,6 +105,7 @@ protected: QLabel* toolBarBatteryVoltageLabel; QGCMAVLinkLogPlayer* player; QComboBox *portComboBox; + QComboBox *baudcomboBox; bool changed; float batteryPercent; float batteryVoltage; -- GitLab From aedaa844a860195d4056c071d214c38f0276db7c Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Mon, 1 Jul 2013 11:26:16 -0700 Subject: [PATCH 035/460] Stability improvements and error fixes --- libs/serialport/apmserial.pri | 1 - qgroundcontrol.pro | 3 +- src/comm/SerialLink.cc | 182 +++++++++++++++++++++++++++++++--- src/comm/SerialLink.h | 1 + 4 files changed, 172 insertions(+), 15 deletions(-) diff --git a/libs/serialport/apmserial.pri b/libs/serialport/apmserial.pri index 738c482946..9de6a7ab05 100644 --- a/libs/serialport/apmserial.pri +++ b/libs/serialport/apmserial.pri @@ -1,4 +1,3 @@ - INCLUDEPATH += $$PWD unix { diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index ca12227451..0c3dfb7548 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -20,7 +20,8 @@ # Qt configuration CONFIG += qt \ - thread \ + thread +# serialport QT += network \ opengl \ diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index a0e52ae981..3b1039aa10 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -137,6 +137,114 @@ void SerialLink::writeSettings() * **/ void SerialLink::run() +{ + // Initialize the connection + if (!hardwareConnect()) + { + //Need to error out here. + emit communicationError(getName(),"Error connecting: " + m_port->errorString()); + return; + } + + // Qt way to make clear what a while(1) loop does + qint64 msecs = QDateTime::currentMSecsSinceEpoch(); + qint64 initialmsecs = QDateTime::currentMSecsSinceEpoch(); + quint64 bytes = 0; + bool triedreset = false; + bool triedDTR = false; + qint64 timeout = 5000; + + forever + { + if(m_stopp) + { + m_stopp = false; + break; // exit the thread + } + + if (m_reqReset) + { + m_reqReset = false; + communicationUpdate(getName(),"Reset requested via DTR signal"); + m_port->setDataTerminalReady(true); + msleep(250); + m_port->setDataTerminalReady(false); + } + bool error = m_port->waitForReadyRead(500); + + if(error) { // Waits for 1/2 second [TODO][BB] lower to SerialLink::poll_interval? + QByteArray readData = m_port->readAll(); + while (m_port->waitForReadyRead(10)) + readData += m_port->readAll(); + if (readData.length() > 0) { + emit bytesReceived(this, readData); +// qDebug() << "rx of length " << QString::number(readData.length()); + + m_bytesRead += readData.length(); + m_bitsReceivedTotal += readData.length() * 8; + } + } else { + qDebug() << "readyReadTime #"<< __LINE__; + + } + + if (bytes != m_bytesRead) // i.e things are good and data is being read. + { + bytes = m_bytesRead; + msecs = QDateTime::currentMSecsSinceEpoch(); + } + else + { + if (QDateTime::currentMSecsSinceEpoch() - msecs > timeout) + { + //It's been 10 seconds since the last data came in. Reset and try again + msecs = QDateTime::currentMSecsSinceEpoch(); + if (msecs - initialmsecs > 25000) + { + //After initial 25 seconds, timeouts are increased to 30 seconds. + //This prevents temporary silences from things like calibration commands + //from screwing things up. In all reality, timeouts should be enabled/disabled + //for events like that on a case by case basis. + //TODO ^^ + timeout = 30000; + } + if (!triedDTR && triedreset) + { + triedDTR = true; + communicationUpdate(getName(),"No data to receive on COM port. Attempting to reset via DTR signal"); + qDebug() << "No data!!! Attempting reset via DTR."; + m_port->setDataTerminalReady(true); + msleep(250); + m_port->setDataTerminalReady(false); + } + else if (!triedreset) + { + qDebug() << "No data!!! Attempting reset via reboot command."; + communicationUpdate(getName(),"No data to receive on COM port. Assuming possible terminal mode, attempting to reset via \"reboot\" command"); + m_port->write("reboot\r\n",8); + triedreset = true; + } + else + { + communicationUpdate(getName(),"No data to receive on COM port...."); + qDebug() << "No data!!!"; + } + } + } + MG::SLEEP::msleep(SerialLink::poll_interval); + } // end of forever + + if (m_port) { // [TODO][BB] Not sure we need to close the port here + qDebug() << "Closing Port #"<< __LINE__ << m_port->portName(); + m_port->close(); + delete m_port; + m_port = NULL; + + emit disconnected(); + emit connected(false); + } +} +void SerialLink::run2() { // Initialize the connection if (!hardwareConnect()) @@ -174,7 +282,60 @@ void SerialLink::run() } } // Check if new bytes have arrived, if yes, emit the notification signal - checkForBytes(); + /* Check if bytes are available */ +// checkForBytes(); + { + if(m_port && m_port->isOpen() && m_port->isWritable()) + { + m_dataMutex.lock(); + qint64 available = m_port->bytesAvailable(); + m_dataMutex.unlock(); + + if(available > 0) + { + //readBytes(); + { + m_dataMutex.lock(); + if(m_port && m_port->isOpen()) { + const qint64 maxLength = 2048; + char data[maxLength]; + qint64 numBytes = m_port->bytesAvailable(); + //qDebug() << "numBytes: " << numBytes; + + if(numBytes > 0) { + /* Read as much data in buffer as possible without overflow */ + if(maxLength < numBytes) numBytes = maxLength; + + m_port->read(data, numBytes); + QByteArray b(data, numBytes); + emit bytesReceived(this, b); + + //qDebug() << "SerialLink::readBytes()" << std::hex << data; + // int i; + // for (i=0; iclose(); + emit disconnected(); + emit connected(false); + emit communicationError(this->getName(), tr("Could not read data - link %1 is disconnected!").arg(this->getName())); + } + }; + } + if (bytes != m_bytesRead) { bytes = m_bytesRead; @@ -254,31 +415,26 @@ void SerialLink::checkForBytes() emit communicationError(this->getName(), tr("Could not read data - link %1 is disconnected!").arg(this->getName())); } } -// else -// { -// emit disconnected(); -// emit connected(false); -// } - } void SerialLink::writeBytes(const char* data, qint64 size) { if(m_port && m_port->isOpen()) { - qDebug() << "writeBytes" << m_portName << "attempting to tx " << size << "bytes."; +// qDebug() << "writeBytes" << m_portName << "attempting to tx " << size << "bytes."; int b = m_port->write(data, size); if (b > 0) { Q_ASSERT_X(b = size, "writeBytes", "failed to write all bytes"); - qDebug() << "writeBytes " << m_portName << "tx'd" << b << "bytes:"; +// qDebug() << "writeBytes " << m_portName << "tx'd" << b << "bytes:"; // Increase write counter m_bitsSentTotal += size * 8; - QByteArray* byteArray = new QByteArray(data,size); - qDebug() << byteArray->toHex(); - delete byteArray; + // Extra debug logging +// QByteArray* byteArray = new QByteArray(data,size); +// qDebug() << byteArray->toHex(); +// delete byteArray; } else { disconnect(); @@ -373,7 +529,7 @@ bool SerialLink::disconnect() * @return True if connection has been established, false if connection couldn't be established. **/ bool SerialLink::connect() -{ +{ if (isRunning()) disconnect(); { diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index 883ffad9fc..3b4f053f13 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -106,6 +106,7 @@ public: void writeSettings(); void run(); + void run2(); int getLinkQuality(); bool isFullDuplex(); -- GitLab From 2d63bb400aa557a6877f1b1106abce0283866227 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Mon, 1 Jul 2013 11:46:42 -0700 Subject: [PATCH 036/460] removed unused code and fixed disconnect problem --- src/comm/SerialLink.cc | 184 ++--------------------------------------- src/comm/SerialLink.h | 3 - 2 files changed, 7 insertions(+), 180 deletions(-) diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 3b1039aa10..c5c1fcd6e3 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -244,178 +244,6 @@ void SerialLink::run() emit connected(false); } } -void SerialLink::run2() -{ - // Initialize the connection - if (!hardwareConnect()) - { - //Need to error out here. - emit communicationError(getName(),"Error connecting: " + m_port->errorString()); - return; - - } - - // Qt way to make clear what a while(1) loop does - qint64 msecs = QDateTime::currentMSecsSinceEpoch(); - qint64 initialmsecs = QDateTime::currentMSecsSinceEpoch(); - quint64 bytes = 0; - bool triedreset = false; - bool triedDTR = false; - qint64 timeout = 5000; - - forever - { - { - QMutexLocker locker(&this->m_stoppMutex); - if(this->m_stopp) - { - this->m_stopp = false; - break; - } - if (m_reqReset) - { - this->m_reqReset = false; - communicationUpdate(getName(),"Reset requested via DTR signal"); - m_port->setDataTerminalReady(true); - this->msleep(250); - m_port->setDataTerminalReady(false); - } - } - // Check if new bytes have arrived, if yes, emit the notification signal - /* Check if bytes are available */ -// checkForBytes(); - { - if(m_port && m_port->isOpen() && m_port->isWritable()) - { - m_dataMutex.lock(); - qint64 available = m_port->bytesAvailable(); - m_dataMutex.unlock(); - - if(available > 0) - { - //readBytes(); - { - m_dataMutex.lock(); - if(m_port && m_port->isOpen()) { - const qint64 maxLength = 2048; - char data[maxLength]; - qint64 numBytes = m_port->bytesAvailable(); - //qDebug() << "numBytes: " << numBytes; - - if(numBytes > 0) { - /* Read as much data in buffer as possible without overflow */ - if(maxLength < numBytes) numBytes = maxLength; - - m_port->read(data, numBytes); - QByteArray b(data, numBytes); - emit bytesReceived(this, b); - - //qDebug() << "SerialLink::readBytes()" << std::hex << data; - // int i; - // for (i=0; iclose(); - emit disconnected(); - emit connected(false); - emit communicationError(this->getName(), tr("Could not read data - link %1 is disconnected!").arg(this->getName())); - } - }; - } - - if (bytes != m_bytesRead) - { - bytes = m_bytesRead; - msecs = QDateTime::currentMSecsSinceEpoch(); - } - else - { - if (QDateTime::currentMSecsSinceEpoch() - msecs > timeout) - { - //It's been 10 seconds since the last data came in. Reset and try again - msecs = QDateTime::currentMSecsSinceEpoch(); - if (msecs - initialmsecs > 25000) - { - //After initial 25 seconds, timeouts are increased to 30 seconds. - //This prevents temporary silences from things like calibration commands - //from screwing things up. In all reality, timeouts should be enabled/disabled - //for events like that on a case by case basis. - //TODO ^^ - timeout = 30000; - } - if (!triedDTR && triedreset) - { - triedDTR = true; - communicationUpdate(getName(),"No data to receive on COM port. Attempting to reset via DTR signal"); - qDebug() << "No data!!! Attempting reset via DTR."; - m_port->setDataTerminalReady(true); - this->msleep(250); - m_port->setDataTerminalReady(false); - } - else if (!triedreset) - { - qDebug() << "No data!!! Attempting reset via reboot command."; - communicationUpdate(getName(),"No data to receive on COM port. Assuming possible terminal mode, attempting to reset via \"reboot\" command"); - m_port->write("reboot\r\n",8); - triedreset = true; - } - else - { - communicationUpdate(getName(),"No data to receive on COM port...."); - qDebug() << "No data!!!"; - } - } - } - /* Serial data isn't arriving that fast normally, this saves the thread - * from consuming too much processing time - */ - MG::SLEEP::msleep(SerialLink::poll_interval); - } // end forever loop - - if (m_port) { - m_port->close(); - delete m_port; - m_port = NULL; - } -} - - -void SerialLink::checkForBytes() -{ - /* Check if bytes are available */ - if(m_port && m_port->isOpen() && m_port->isWritable()) - { - m_dataMutex.lock(); - qint64 available = m_port->bytesAvailable(); - m_dataMutex.unlock(); - - if(available > 0) - { - readBytes(); - m_bytesRead += available; - } - else if (available < 0) { - /* Error, close port */ - m_port->close(); - emit disconnected(); - emit connected(false); - emit communicationError(this->getName(), tr("Could not read data - link %1 is disconnected!").arg(this->getName())); - } - } -} void SerialLink::writeBytes(const char* data, qint64 size) { @@ -503,11 +331,13 @@ qint64 SerialLink::bytesAvailable() **/ bool SerialLink::disconnect() { - qDebug() << "disconnect" << m_port->portName(); - Q_ASSERT_X(m_port != NULL, "disconnect", "m_port is NULL"); + qDebug() << "disconnect"; + if (m_port) + qDebug() << m_port->portName(); if (isRunning()) { + qDebug() << "running so disconnect" << m_port->portName(); { QMutexLocker locker(&m_stoppMutex); m_stopp = true; @@ -517,10 +347,10 @@ bool SerialLink::disconnect() emit disconnected(); // [TODO] There are signals from QSerialPort we should use emit connected(false); return true; - } else { - m_port->close(); - return true; } + + qDebug() << "already disconnected"; + return true; } /** diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index 3b4f053f13..3ada34e743 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -139,9 +139,6 @@ public slots: bool connect(); bool disconnect(); -protected slots: - void checkForBytes(); - protected: quint64 m_bytesRead; QSerialPort* m_port; -- GitLab From 7680355bdc724257f493eca34f5bd5b4f6b421f1 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Mon, 1 Jul 2013 12:17:03 -0700 Subject: [PATCH 037/460] adds back in mutex for stop flag changes --- src/comm/SerialLink.cc | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index c5c1fcd6e3..51ebb0b718 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -156,19 +156,22 @@ void SerialLink::run() forever { - if(m_stopp) { - m_stopp = false; - break; // exit the thread - } + QMutexLocker locker(&this->m_stoppMutex); + if(m_stopp) + { + m_stopp = false; + break; // exit the thread + } - if (m_reqReset) - { - m_reqReset = false; - communicationUpdate(getName(),"Reset requested via DTR signal"); - m_port->setDataTerminalReady(true); - msleep(250); - m_port->setDataTerminalReady(false); + if (m_reqReset) + { + m_reqReset = false; + communicationUpdate(getName(),"Reset requested via DTR signal"); + m_port->setDataTerminalReady(true); + msleep(250); + m_port->setDataTerminalReady(false); + } } bool error = m_port->waitForReadyRead(500); @@ -440,12 +443,12 @@ bool SerialLink::isConnected() if (m_port) { bool isConnected = m_port->isOpen(); - qDebug() << "SerialLink #" << __LINE__ << ":"<< m_port->portName() - << " isConnected =" << QString::number(isConnected); +// qDebug() << "SerialLink #" << __LINE__ << ":"<< m_port->portName() +// << " isConnected =" << QString::number(isConnected); return isConnected; } else { - qDebug() << "SerialLink #" << __LINE__ << ":" << m_portName - << " isConnected = NULL"; +// qDebug() << "SerialLink #" << __LINE__ << ":" << m_portName +// << " isConnected = NULL"; return false; } } -- GitLab From 40807732f6c1878a1f584f9229890854b4e83f7a Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 2 Jul 2013 08:38:48 -0400 Subject: [PATCH 038/460] Change in implementation details for Camera Gimbal Config, usable now, but needs more error checking. --- src/ui/configuration/ApmHardwareConfig.ui | 8 +- src/ui/configuration/CameraGimbalConfig.cc | 471 +++++++++++++++++++-- src/ui/configuration/CameraGimbalConfig.h | 4 + src/ui/configuration/CameraGimbalConfig.ui | 39 +- 4 files changed, 479 insertions(+), 43 deletions(-) diff --git a/src/ui/configuration/ApmHardwareConfig.ui b/src/ui/configuration/ApmHardwareConfig.ui index 87e2230ed7..bb3818e769 100644 --- a/src/ui/configuration/ApmHardwareConfig.ui +++ b/src/ui/configuration/ApmHardwareConfig.ui @@ -6,8 +6,8 @@ 0 0 - 984 - 553 + 1225 + 827 @@ -313,8 +313,8 @@ 200 30 - 721 - 491 + 921 + 761 diff --git a/src/ui/configuration/CameraGimbalConfig.cc b/src/ui/configuration/CameraGimbalConfig.cc index 64b20d250f..7aef99903a 100644 --- a/src/ui/configuration/CameraGimbalConfig.cc +++ b/src/ui/configuration/CameraGimbalConfig.cc @@ -67,23 +67,23 @@ CameraGimbalConfig::CameraGimbalConfig(QWidget *parent) : AP2ConfigWidget(parent connect(ui.tiltReverseCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateTilt())); connect(ui.tiltStabilizeCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateTilt())); - connect(ui.rollServoMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); - connect(ui.rollServoMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); - connect(ui.rollAngleMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); - connect(ui.rollAngleMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); - connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - connect(ui.rollInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - connect(ui.rollReverseCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateTilt())); - connect(ui.rollStabilizeCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateTilt())); - - connect(ui.panServoMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); - connect(ui.panServoMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); - connect(ui.panAngleMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); - connect(ui.panAngleMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updateTilt())); - connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - connect(ui.panInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - connect(ui.panReverseCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateTilt())); - connect(ui.panStabilizeCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateTilt())); + connect(ui.rollServoMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateRoll())); + connect(ui.rollServoMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updateRoll())); + connect(ui.rollAngleMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateRoll())); + connect(ui.rollAngleMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updateRoll())); + connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + connect(ui.rollInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + connect(ui.rollReverseCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateRoll())); + connect(ui.rollStabilizeCheckBox,SIGNAL(clicked(bool)),this,SLOT(updateRoll())); + + connect(ui.panServoMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updatePan())); + connect(ui.panServoMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updatePan())); + connect(ui.panAngleMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updatePan())); + connect(ui.panAngleMaxSpinBox,SIGNAL(editingFinished()),this,SLOT(updatePan())); + connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + connect(ui.panInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + connect(ui.panReverseCheckBox,SIGNAL(clicked(bool)),this,SLOT(updatePan())); + connect(ui.panStabilizeCheckBox,SIGNAL(clicked(bool)),this,SLOT(updatePan())); connect(ui.shutterServoMinSpinBox,SIGNAL(editingFinished()),this,SLOT(updateShutter())); @@ -103,20 +103,22 @@ void CameraGimbalConfig::updateTilt() QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); return; } + if (!tiltPrefix.isEmpty()) + { + //We need to set this to 0 for disabled. + m_uas->getParamManager()->setParameter(1,tiltPrefix + "FUNCTION",0); + } if (ui.tiltChannelComboBox->currentIndex() == 0) { //Disabled return; } - for (QMap::const_iterator i = m_uas->getComponents().constBegin(); i != m_uas->getComponents().constEnd();i++) - { - qDebug() << "Component:" << i.key() << "Name:" << i.value(); - } + m_uas->getParamManager()->setParameter(1,ui.tiltChannelComboBox->currentText() + "_FUNCTION",7); m_uas->getParamManager()->setParameter(1,ui.tiltChannelComboBox->currentText() + "_MIN",ui.tiltServoMinSpinBox->value()); m_uas->getParamManager()->setParameter(1,ui.tiltChannelComboBox->currentText() + "_MAX",ui.tiltServoMaxSpinBox->value()); - m_uas->getParamManager()->setParameter(1,"MNT_ANGMIN_TIL",ui.tiltAngleMinSpinBox->value()); - m_uas->getParamManager()->setParameter(1,"MNT_ANGMAX_TIL",ui.tiltAngleMaxSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_ANGMIN_TIL",ui.tiltAngleMinSpinBox->value() * 100); + m_uas->getParamManager()->setParameter(1,"MNT_ANGMAX_TIL",ui.tiltAngleMaxSpinBox->value() * 100); m_uas->getParamManager()->setParameter(1,ui.tiltChannelComboBox->currentText() + "_REV",(ui.tiltReverseCheckBox->isChecked() ? 1 : 0)); if (ui.tiltInputChannelComboBox->currentIndex() == 0) { @@ -138,8 +140,8 @@ void CameraGimbalConfig::updateRoll() m_uas->getParamManager()->setParameter(1,ui.rollChannelComboBox->currentText() + "_FUNCTION",8); m_uas->getParamManager()->setParameter(1,ui.rollChannelComboBox->currentText() + "_MIN",ui.rollServoMinSpinBox->value()); m_uas->getParamManager()->setParameter(1,ui.rollChannelComboBox->currentText() + "_MAX",ui.rollServoMaxSpinBox->value()); - m_uas->getParamManager()->setParameter(1,"MNT_ANGMIN_ROL",ui.rollAngleMinSpinBox->value()); - m_uas->getParamManager()->setParameter(1,"MNT_ANGMAX_ROL",ui.rollAngleMaxSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_ANGMIN_ROL",ui.rollAngleMinSpinBox->value() * 100); + m_uas->getParamManager()->setParameter(1,"MNT_ANGMAX_ROL",ui.rollAngleMaxSpinBox->value() * 100); m_uas->getParamManager()->setParameter(1,ui.rollChannelComboBox->currentText() + "_REV",(ui.rollReverseCheckBox->isChecked() ? 1 : 0)); if (ui.rollInputChannelComboBox->currentIndex() == 0) { @@ -161,8 +163,8 @@ void CameraGimbalConfig::updatePan() m_uas->getParamManager()->setParameter(1,ui.panChannelComboBox->currentText() + "_FUNCTION",6); m_uas->getParamManager()->setParameter(1,ui.panChannelComboBox->currentText() + "_MIN",ui.panServoMinSpinBox->value()); m_uas->getParamManager()->setParameter(1,ui.panChannelComboBox->currentText() + "_MAX",ui.panServoMaxSpinBox->value()); - m_uas->getParamManager()->setParameter(1,"MNT_ANGMIN_PAN",ui.panAngleMinSpinBox->value()); - m_uas->getParamManager()->setParameter(1,"MNT_ANGMAX_PAN",ui.panAngleMaxSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_ANGMIN_PAN",ui.panAngleMinSpinBox->value() * 100); + m_uas->getParamManager()->setParameter(1,"MNT_ANGMAX_PAN",ui.panAngleMaxSpinBox->value() * 100); m_uas->getParamManager()->setParameter(1,ui.panChannelComboBox->currentText() + "_REV",(ui.panReverseCheckBox->isChecked() ? 1 : 0)); if (ui.panInputChannelComboBox->currentIndex() == 0) { @@ -214,5 +216,420 @@ CameraGimbalConfig::~CameraGimbalConfig() void CameraGimbalConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { + connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + connect(ui.tiltInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + disconnect(ui.tiltInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + connect(ui.panInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + disconnect(ui.panInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + + connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + connect(ui.rollInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + disconnect(ui.rollInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + + connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + + if (parameterName == "MNT_ANGMIN_TIL") //TILT + { + ui.tiltAngleMinSpinBox->setValue(value.toInt() / 100.0); + } + else if (parameterName == "MNT_ANGMAX_TIL") + { + ui.tiltAngleMaxSpinBox->setValue(value.toInt() / 100.0); + } + else if (parameterName == "MNT_RC_IN_TILT") + { + disconnect(ui.tiltInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + if (value.toInt() == 0) + { + ui.tiltInputChannelComboBox->setCurrentIndex(0); + } + else + { + ui.tiltInputChannelComboBox->setCurrentIndex(value.toInt()-4); + } + connect(ui.tiltInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + } + else if (parameterName == "MNT_ANGMIN_ROL") //ROLL + { + ui.rollAngleMinSpinBox->setValue(value.toInt() / 100.0); + } + else if (parameterName == "MNT_ANGMAX_ROL") + { + ui.rollAngleMaxSpinBox->setValue(value.toInt() / 100.0); + } + else if (parameterName == "MNT_RC_IN_ROLL") + { + disconnect(ui.rollInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + if (value.toInt() == 0) + { + ui.rollInputChannelComboBox->setCurrentIndex(0); + } + else + { + ui.rollInputChannelComboBox->setCurrentIndex(value.toInt()-4); + } + connect(ui.rollInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + } + else if (parameterName == "MNT_ANGMIN_PAN") //PAN + { + ui.panAngleMinSpinBox->setValue(value.toInt() / 100.0); + } + else if (parameterName == "MNT_ANGMAX_PAN") + { + ui.panAngleMaxSpinBox->setValue(value.toInt() / 100.0); + } + else if (parameterName == "MNT_RC_IN_PAN") + { + disconnect(ui.panInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + if (value.toInt() == 0) + { + ui.panInputChannelComboBox->setCurrentIndex(0); + } + else + { + ui.panInputChannelComboBox->setCurrentIndex(value.toInt()-4); + } + connect(ui.panInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + } + if (parameterName == "CAM_DURATION") + { + ui.shutterDurationSpinBox->setValue(value.toInt()); + } + else if (parameterName == "CAM_SERVO_OFF") + { + ui.shutterNotPushedSpinBox->setValue(value.toInt()); + } + else if (parameterName == "CAM_SERVO_ON") + { + ui.shutterPushedSpinBox->setValue(value.toInt()); + } + else if (parameterName == "CAM_TRIGG_TYPE") + { + disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + if (value.toInt() == 0) //Disabled + { + ui.shutterChannelComboBox->setCurrentIndex(0); + ///TODO: Request all _FUNCTIONs here to find out if shutter is actually disabled. + } + else if (value.toInt() == 1) // Relay + { + ui.shutterChannelComboBox->setCurrentIndex(1); + } + else if (value.toInt() == 4) //Transistor + { + ui.shutterChannelComboBox->setCurrentIndex(2); + } + connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + } + if (parameterName.startsWith(shutterPrefix) && !shutterPrefix.isEmpty()) + { + if (parameterName.endsWith("MIN")) + { + ui.shutterServoMinSpinBox->setValue(value.toInt()); + } + else if (parameterName.endsWith("MAX")) + { + ui.shutterServoMaxSpinBox->setValue(value.toInt()); + } + } + else if (parameterName.startsWith(tiltPrefix) && !tiltPrefix.isEmpty()) + { + if (parameterName.endsWith("MIN")) + { + ui.tiltServoMinSpinBox->setValue(value.toInt()); + } + else if (parameterName.endsWith("MAX")) + { + ui.tiltServoMaxSpinBox->setValue(value.toInt()); + } + else if (parameterName.endsWith("REV")) + { + if (value.toInt() == 0) + { + ui.tiltReverseCheckBox->setChecked(false); + } + else + { + ui.tiltReverseCheckBox->setChecked(true); + } + } + } + else if (parameterName.startsWith(rollPrefix) && !rollPrefix.isEmpty()) + { + if (parameterName.endsWith("MIN")) + { + ui.rollServoMinSpinBox->setValue(value.toInt()); + } + else if (parameterName.endsWith("MAX")) + { + ui.rollServoMaxSpinBox->setValue(value.toInt()); + } + else if (parameterName.endsWith("REV")) + { + if (value.toInt() == 0) + { + ui.rollReverseCheckBox->setChecked(false); + } + else + { + ui.rollReverseCheckBox->setChecked(true); + } + } + } + else if (parameterName.startsWith(panPrefix) && !panPrefix.isEmpty()) + { + if (parameterName.endsWith("MIN")) + { + ui.panServoMinSpinBox->setValue(value.toInt()); + } + else if (parameterName.endsWith("MAX")) + { + ui.panServoMaxSpinBox->setValue(value.toInt()); + } + else if (parameterName.endsWith("REV")) + { + if (value.toInt() == 0) + { + ui.panReverseCheckBox->setChecked(false); + } + else + { + ui.panReverseCheckBox->setChecked(true); + } + } + } + else if (parameterName == "RC5_FUNCTION") + { + if (value.toInt() == 10) + { + //RC5 is shutter. + disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + ui.shutterChannelComboBox->setCurrentIndex(3); + connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + shutterPrefix = "RC5_"; + } + else if (value.toInt() == 8) + { + //RC5 is roll + disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + ui.rollChannelComboBox->setCurrentIndex(1); + connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + rollPrefix = "RC5_"; + } + else if (value.toInt() == 7) + { + //RC5 is tilt + disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + ui.tiltChannelComboBox->setCurrentIndex(1); + connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + tiltPrefix = "RC5_"; + } + else if (value.toInt() == 6) + { + //RC5 is pan + disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + ui.panChannelComboBox->setCurrentIndex(1); + connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + panPrefix = "RC5_"; + } + m_uas->getParamManager()->requestParameterUpdate(1,"RC5_MIN"); + m_uas->getParamManager()->requestParameterUpdate(1,"RC5_MAX"); + m_uas->getParamManager()->requestParameterUpdate(1,"RC5_REV"); + } + else if (parameterName == "RC6_FUNCTION") + { + if (value.toInt() == 10) + { + //RC6 is shutter. + disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + ui.shutterChannelComboBox->setCurrentIndex(4); + connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + shutterPrefix = "RC6_"; + } + else if (value.toInt() == 8) + { + //RC6 is roll + disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + ui.rollChannelComboBox->setCurrentIndex(2); + connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + rollPrefix = "RC6_"; + } + else if (value.toInt() == 7) + { + //RC6 is tilt + disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + ui.tiltChannelComboBox->setCurrentIndex(2); + connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + tiltPrefix = "RC6_"; + } + else if (value.toInt() == 6) + { + //RC6 is pan + disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + ui.panChannelComboBox->setCurrentIndex(2); + connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + panPrefix = "RC6_"; + } + m_uas->getParamManager()->requestParameterUpdate(1,"RC6_MIN"); + m_uas->getParamManager()->requestParameterUpdate(1,"RC6_MAX"); + m_uas->getParamManager()->requestParameterUpdate(1,"RC6_REV"); + } + else if (parameterName == "RC7_FUNCTION") + { + if (value.toInt() == 10) + { + //RC7 is shutter. + disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + ui.shutterChannelComboBox->setCurrentIndex(5); + connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + shutterPrefix = "RC7_"; + } + else if (value.toInt() == 8) + { + //RC7 is roll + disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + ui.rollChannelComboBox->setCurrentIndex(3); + connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + rollPrefix = "RC7_"; + } + else if (value.toInt() == 7) + { + //RC7 is tilt + disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + ui.tiltChannelComboBox->setCurrentIndex(3); + connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + tiltPrefix = "RC7_"; + } + else if (value.toInt() == 6) + { + //RC7 is pan + disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + ui.panChannelComboBox->setCurrentIndex(3); + connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + panPrefix = "RC7_"; + } + m_uas->getParamManager()->requestParameterUpdate(1,"RC7_MIN"); + m_uas->getParamManager()->requestParameterUpdate(1,"RC7_MAX"); + m_uas->getParamManager()->requestParameterUpdate(1,"RC7_REV"); + } + else if (parameterName == "RC8_FUNCTION") + { + if (value.toInt() == 10) + { + //RC8 is shutter. + disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + ui.shutterChannelComboBox->setCurrentIndex(6); + connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + shutterPrefix = "RC8_"; + } + else if (value.toInt() == 8) + { + //RC8 is roll + disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + ui.rollChannelComboBox->setCurrentIndex(4); + connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + rollPrefix = "RC8_"; + } + else if (value.toInt() == 7) + { + //RC8 is tilt + disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + ui.tiltChannelComboBox->setCurrentIndex(4); + connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + tiltPrefix = "RC8_"; + } + else if (value.toInt() == 6) + { + //RC8 is pan + disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + ui.panChannelComboBox->setCurrentIndex(4); + connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + panPrefix = "RC8_"; + } + m_uas->getParamManager()->requestParameterUpdate(1,"RC8_MIN"); + m_uas->getParamManager()->requestParameterUpdate(1,"RC8_MAX"); + m_uas->getParamManager()->requestParameterUpdate(1,"RC8_REV"); + } + else if (parameterName == "RC10_FUNCTION") + { + if (value.toInt() == 10) + { + //RC10 is shutter. + disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + ui.shutterChannelComboBox->setCurrentIndex(7); + connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + shutterPrefix = "RC10_"; + } + else if (value.toInt() == 8) + { + //RC10 is roll + disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + ui.rollChannelComboBox->setCurrentIndex(5); + connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + rollPrefix = "RC10_"; + } + else if (value.toInt() == 7) + { + //RC10 is tilt + disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + ui.tiltChannelComboBox->setCurrentIndex(5); + connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + tiltPrefix = "RC10_"; + } + else if (value.toInt() == 6) + { + //RC10 is pan + disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + ui.panChannelComboBox->setCurrentIndex(5); + connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + panPrefix = "RC10_"; + } + m_uas->getParamManager()->requestParameterUpdate(1,"RC10_MIN"); + m_uas->getParamManager()->requestParameterUpdate(1,"RC10_MAX"); + m_uas->getParamManager()->requestParameterUpdate(1,"RC10_REV"); + } + else if (parameterName == "RC11_FUNCTION") + { + if (value.toInt() == 10) + { + //RC11 is shutter. + disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + ui.shutterChannelComboBox->setCurrentIndex(8); + connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + shutterPrefix = "RC11_"; + } + else if (value.toInt() == 8) + { + //RC11 is roll + disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + ui.rollChannelComboBox->setCurrentIndex(6); + connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); + rollPrefix = "RC11_"; + } + else if (value.toInt() == 7) + { + //RC11 is tilt + disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + ui.tiltChannelComboBox->setCurrentIndex(6); + connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); + tiltPrefix = "RC11_"; + } + else if (value.toInt() == 6) + { + //RC11 is pan + disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + ui.panChannelComboBox->setCurrentIndex(6); + connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); + panPrefix = "RC11_"; + } + m_uas->getParamManager()->requestParameterUpdate(1,"RC11_MIN"); + m_uas->getParamManager()->requestParameterUpdate(1,"RC11_MAX"); + m_uas->getParamManager()->requestParameterUpdate(1,"RC11_REV"); + } } diff --git a/src/ui/configuration/CameraGimbalConfig.h b/src/ui/configuration/CameraGimbalConfig.h index 92714f4fbf..2608752b17 100644 --- a/src/ui/configuration/CameraGimbalConfig.h +++ b/src/ui/configuration/CameraGimbalConfig.h @@ -21,6 +21,10 @@ private slots: private: Ui::CameraGimbalConfig ui; + QString shutterPrefix; + QString rollPrefix; + QString tiltPrefix; + QString panPrefix; }; #endif // CAMERAGIMBALCONFIG_H diff --git a/src/ui/configuration/CameraGimbalConfig.ui b/src/ui/configuration/CameraGimbalConfig.ui index 7b1feb4389..75dec1117b 100644 --- a/src/ui/configuration/CameraGimbalConfig.ui +++ b/src/ui/configuration/CameraGimbalConfig.ui @@ -174,21 +174,24 @@ + + -100 + - 3000 + 100 - 1000 + 100 - 3000 + 100 - 2000 + -100 @@ -345,21 +348,27 @@ + + -100 + - 3000 + 100 - 1000 + 100 + + -100 + - 3000 + 100 - 2000 + 100 @@ -503,21 +512,27 @@ + + -100 + - 3000 + 100 - 1000 + 100 + + -100 + - 3000 + 100 - 2000 + 100 -- GitLab From df137979321e0409fcde0c4471b479bf6214ad0b Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 2 Jul 2013 12:43:49 -0400 Subject: [PATCH 039/460] UI for Antenna Tracker config, no backend. --- src/ui/configuration/AntennaTrackerConfig.ui | 284 ++++++++++++++++++- 1 file changed, 280 insertions(+), 4 deletions(-) diff --git a/src/ui/configuration/AntennaTrackerConfig.ui b/src/ui/configuration/AntennaTrackerConfig.ui index e259e1fcef..f355fc4ca9 100644 --- a/src/ui/configuration/AntennaTrackerConfig.ui +++ b/src/ui/configuration/AntennaTrackerConfig.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 300 + 1171 + 560 @@ -16,8 +16,8 @@ - 30 - 30 + 20 + 10 151 31 @@ -29,6 +29,282 @@ false + + + + 20 + 50 + 46 + 13 + + + + Interface + + + + + + 80 + 50 + 69 + 22 + + + + + + + 160 + 50 + 69 + 22 + + + + + + + 240 + 50 + 69 + 22 + + + + + + + 320 + 50 + 75 + 23 + + + + Connect + + + + + + 20 + 80 + 581 + 131 + + + + Pan + + + + + + + + + + Angle + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + PWM + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Center PWM + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + + + + + + + + + + Trim + + + Qt::AlignCenter + + + + + + + -180 + + + 0 + + + Qt::Horizontal + + + + + + + 0 + + + Qt::AlignCenter + + + + + + + + + Rev + + + + + + + + + + + 20 + 220 + 581 + 131 + + + + Tilt + + + + + + + + + + Angle + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + PWM + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Center PWM + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + + + + + + + + + + Trim + + + Qt::AlignCenter + + + + + + + -180 + + + 180 + + + Qt::Horizontal + + + + + + + 0 + + + Qt::AlignCenter + + + + + + + + + Rev + + + + + + + -- GitLab From a3f043af1df8ae07247e4e1a2cbd0393ebe6bdbd Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 2 Jul 2013 13:56:48 -0400 Subject: [PATCH 040/460] Addition of Software configuraion pages -- GitLab From 771d74b7e8eeb4232a78e6db5fdafe1da5dd5c99 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 2 Jul 2013 13:57:10 -0400 Subject: [PATCH 041/460] UI for a bunch of software configuration pages --- qgroundcontrol.pro | 24 +++- src/ui/configuration/AdvancedParamConfig.cc | 11 ++ src/ui/configuration/AdvancedParamConfig.h | 19 +++ src/ui/configuration/AdvancedParamConfig.ui | 32 +++++ src/ui/configuration/ApmHardwareConfig.cc | 6 - src/ui/configuration/ApmHardwareConfig.h | 2 - src/ui/configuration/ApmHardwareConfig.ui | 18 +-- src/ui/configuration/ApmSoftwareConfig.cc | 74 +++++++++++ src/ui/configuration/ApmSoftwareConfig.h | 22 +++- src/ui/configuration/ApmSoftwareConfig.ui | 128 ++++++++++++++++++++ src/ui/configuration/ArduCopterPidConfig.cc | 14 +++ src/ui/configuration/ArduCopterPidConfig.h | 22 ++++ src/ui/configuration/ArduCopterPidConfig.ui | 32 +++++ src/ui/configuration/BasicPidConfig.cc | 11 ++ src/ui/configuration/BasicPidConfig.h | 19 +++ src/ui/configuration/BasicPidConfig.ui | 32 +++++ src/ui/configuration/FailSafeConfig.cc | 11 ++ src/ui/configuration/FailSafeConfig.h | 19 +++ src/ui/configuration/FailSafeConfig.ui | 32 +++++ src/ui/configuration/GeoFenceConfig.cc | 11 ++ src/ui/configuration/GeoFenceConfig.h | 19 +++ src/ui/configuration/GeoFenceConfig.ui | 32 +++++ src/ui/configuration/StandardParamConfig.cc | 11 ++ src/ui/configuration/StandardParamConfig.h | 19 +++ src/ui/configuration/StandardParamConfig.ui | 32 +++++ 25 files changed, 623 insertions(+), 29 deletions(-) create mode 100644 src/ui/configuration/AdvancedParamConfig.cc create mode 100644 src/ui/configuration/AdvancedParamConfig.h create mode 100644 src/ui/configuration/AdvancedParamConfig.ui create mode 100644 src/ui/configuration/ArduCopterPidConfig.cc create mode 100644 src/ui/configuration/ArduCopterPidConfig.h create mode 100644 src/ui/configuration/ArduCopterPidConfig.ui create mode 100644 src/ui/configuration/BasicPidConfig.cc create mode 100644 src/ui/configuration/BasicPidConfig.h create mode 100644 src/ui/configuration/BasicPidConfig.ui create mode 100644 src/ui/configuration/FailSafeConfig.cc create mode 100644 src/ui/configuration/FailSafeConfig.h create mode 100644 src/ui/configuration/FailSafeConfig.ui create mode 100644 src/ui/configuration/GeoFenceConfig.cc create mode 100644 src/ui/configuration/GeoFenceConfig.h create mode 100644 src/ui/configuration/GeoFenceConfig.ui create mode 100644 src/ui/configuration/StandardParamConfig.cc create mode 100644 src/ui/configuration/StandardParamConfig.h create mode 100644 src/ui/configuration/StandardParamConfig.ui diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 2e0d9c43d0..8b796850b0 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -250,7 +250,13 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/OpticalFlowConfig.ui \ src/ui/configuration/OsdConfig.ui \ src/ui/configuration/AntennaTrackerConfig.ui \ - src/ui/configuration/CameraGimbalConfig.ui + src/ui/configuration/CameraGimbalConfig.ui \ + src/ui/configuration/BasicPidConfig.ui \ + src/ui/configuration/StandardParamConfig.ui \ + src/ui/configuration/GeoFenceConfig.ui \ + src/ui/configuration/FailSafeConfig.ui \ + src/ui/configuration/AdvancedParamConfig.ui \ + src/ui/configuration/ArduCopterPidConfig.ui INCLUDEPATH += src \ src/ui \ src/ui/linechart \ @@ -425,7 +431,13 @@ HEADERS += src/MG.h \ src/ui/configuration/OsdConfig.h \ src/ui/configuration/AntennaTrackerConfig.h \ src/ui/configuration/CameraGimbalConfig.h \ - src/ui/configuration/AP2ConfigWidget.h + src/ui/configuration/AP2ConfigWidget.h \ + src/ui/configuration/BasicPidConfig.h \ + src/ui/configuration/StandardParamConfig.h \ + src/ui/configuration/GeoFenceConfig.h \ + src/ui/configuration/FailSafeConfig.h \ + src/ui/configuration/AdvancedParamConfig.h \ + src/ui/configuration/ArduCopterPidConfig.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -618,7 +630,13 @@ SOURCES += src/main.cc \ src/ui/configuration/OsdConfig.cc \ src/ui/configuration/AntennaTrackerConfig.cc \ src/ui/configuration/CameraGimbalConfig.cc \ - src/ui/configuration/AP2ConfigWidget.cc + src/ui/configuration/AP2ConfigWidget.cc \ + src/ui/configuration/BasicPidConfig.cc \ + src/ui/configuration/StandardParamConfig.cc \ + src/ui/configuration/GeoFenceConfig.cc \ + src/ui/configuration/FailSafeConfig.cc \ + src/ui/configuration/AdvancedParamConfig.cc \ + src/ui/configuration/ArduCopterPidConfig.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/configuration/AdvancedParamConfig.cc b/src/ui/configuration/AdvancedParamConfig.cc new file mode 100644 index 0000000000..4ab92e0b75 --- /dev/null +++ b/src/ui/configuration/AdvancedParamConfig.cc @@ -0,0 +1,11 @@ +#include "AdvancedParamConfig.h" + + +AdvancedParamConfig::AdvancedParamConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +AdvancedParamConfig::~AdvancedParamConfig() +{ +} diff --git a/src/ui/configuration/AdvancedParamConfig.h b/src/ui/configuration/AdvancedParamConfig.h new file mode 100644 index 0000000000..5cf8b9fafb --- /dev/null +++ b/src/ui/configuration/AdvancedParamConfig.h @@ -0,0 +1,19 @@ +#ifndef ADVANCEDPARAMCONFIG_H +#define ADVANCEDPARAMCONFIG_H + +#include +#include "ui_AdvancedParamConfig.h" + +class AdvancedParamConfig : public QWidget +{ + Q_OBJECT + +public: + explicit AdvancedParamConfig(QWidget *parent = 0); + ~AdvancedParamConfig(); + +private: + Ui::AdvancedParamConfig ui; +}; + +#endif // ADVANCEDPARAMCONFIG_H diff --git a/src/ui/configuration/AdvancedParamConfig.ui b/src/ui/configuration/AdvancedParamConfig.ui new file mode 100644 index 0000000000..d49c182d9e --- /dev/null +++ b/src/ui/configuration/AdvancedParamConfig.ui @@ -0,0 +1,32 @@ + + + AdvancedParamConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 10 + 10 + 181 + 31 + + + + <h2>Advanced Params</h2> + + + + + + diff --git a/src/ui/configuration/ApmHardwareConfig.cc b/src/ui/configuration/ApmHardwareConfig.cc index 909db3ad5b..07c28f12f0 100644 --- a/src/ui/configuration/ApmHardwareConfig.cc +++ b/src/ui/configuration/ApmHardwareConfig.cc @@ -40,7 +40,6 @@ ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) ui.compassButton->setVisible(false); ui.accelCalibrateButton->setVisible(false); ui.radioCalibrateButton->setVisible(false); - ui.flightModesButton->setVisible(false); ui.optionalHardwareButton->setVisible(false); //ui.radio3DRButton->setVisible(false); ui.batteryMonitorButton->setVisible(false); @@ -55,7 +54,6 @@ ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.compassButton,SLOT(setShown(bool))); connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.accelCalibrateButton,SLOT(setShown(bool))); connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.radioCalibrateButton,SLOT(setShown(bool))); - connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.flightModesButton,SLOT(setShown(bool))); connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.radio3DRButton,SLOT(setShown(bool))); connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.batteryMonitorButton,SLOT(setShown(bool))); @@ -94,10 +92,6 @@ ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) buttonToConfigWidgetMap[ui.radioCalibrateButton] = radioConfig; connect(ui.radioCalibrateButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - flightConfig = new FlightModeConfig(this); - ui.stackedWidget->addWidget(flightConfig); - buttonToConfigWidgetMap[ui.flightModesButton] = flightConfig; - connect(ui.flightModesButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); radio3drConfig = new Radio3DRConfig(this); ui.stackedWidget->addWidget(radio3drConfig); diff --git a/src/ui/configuration/ApmHardwareConfig.h b/src/ui/configuration/ApmHardwareConfig.h index 8a2beacff3..e21fe05d70 100644 --- a/src/ui/configuration/ApmHardwareConfig.h +++ b/src/ui/configuration/ApmHardwareConfig.h @@ -40,7 +40,6 @@ This file is part of the QGROUNDCONTROL project #include "CompassConfig.h" #include "AccelCalibrationConfig.h" #include "RadioCalibrationConfig.h" -#include "FlightModeConfig.h" #include "Radio3DRConfig.h" #include "BatteryMonitorConfig.h" #include "SonarConfig.h" @@ -62,7 +61,6 @@ private: CompassConfig *compassConfig; AccelCalibrationConfig *accelConfig; RadioCalibrationConfig *radioConfig; - FlightModeConfig *flightConfig; Radio3DRConfig *radio3drConfig; BatteryMonitorConfig *batteryConfig; diff --git a/src/ui/configuration/ApmHardwareConfig.ui b/src/ui/configuration/ApmHardwareConfig.ui index bb3818e769..1a514ede92 100644 --- a/src/ui/configuration/ApmHardwareConfig.ui +++ b/src/ui/configuration/ApmHardwareConfig.ui @@ -43,7 +43,7 @@ 0 0 156 - 676 + 635 @@ -154,22 +154,6 @@ - - - - - 0 - 35 - - - - Flight Modes - - - false - - - diff --git a/src/ui/configuration/ApmSoftwareConfig.cc b/src/ui/configuration/ApmSoftwareConfig.cc index f8ae035ab8..cfecf5de17 100644 --- a/src/ui/configuration/ApmSoftwareConfig.cc +++ b/src/ui/configuration/ApmSoftwareConfig.cc @@ -4,8 +4,82 @@ ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) { ui.setupUi(this); + + ui.basicPidsButton->setVisible(false); + ui.flightModesButton->setVisible(false); + ui.standardParamButton->setVisible(false); + ui.geoFenceButton->setVisible(false); + ui.failSafeButton->setVisible(false); + ui.advancedParamButton->setVisible(false); + ui.advParamListButton->setVisible(false); + ui.arduCoperPidButton->setVisible(false); + + basicPidConfig = new BasicPidConfig(this); + ui.stackedWidget->addWidget(basicPidConfig); + buttonToConfigWidgetMap[ui.basicPidsButton] = basicPidConfig; + connect(ui.basicPidsButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + flightConfig = new FlightModeConfig(this); + ui.stackedWidget->addWidget(flightConfig); + buttonToConfigWidgetMap[ui.flightModesButton] = flightConfig; + connect(ui.flightModesButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + standardParamConfig = new StandardParamConfig(this); + ui.stackedWidget->addWidget(standardParamConfig); + buttonToConfigWidgetMap[ui.standardParamButton] = standardParamConfig; + connect(ui.standardParamButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + geoFenceConfig = new GeoFenceConfig(this); + ui.stackedWidget->addWidget(geoFenceConfig); + buttonToConfigWidgetMap[ui.geoFenceButton] = geoFenceConfig; + connect(ui.geoFenceButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + failSafeConfig = new FailSafeConfig(this); + ui.stackedWidget->addWidget(failSafeConfig); + buttonToConfigWidgetMap[ui.failSafeButton] = failSafeConfig; + connect(ui.failSafeButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + advancedParamConfig = new AdvancedParamConfig(this); + ui.stackedWidget->addWidget(advancedParamConfig); + buttonToConfigWidgetMap[ui.advancedParamButton] = advancedParamConfig; + connect(ui.advancedParamButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + arduCoperPidConfig = new ArduCopterPidConfig(this); + ui.stackedWidget->addWidget(arduCoperPidConfig); + buttonToConfigWidgetMap[ui.arduCoperPidButton] = arduCoperPidConfig; + connect(ui.arduCoperPidButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); + if (UASManager::instance()->getActiveUAS()) + { + activeUASSet(UASManager::instance()->getActiveUAS()); + } } ApmSoftwareConfig::~ApmSoftwareConfig() { } +void ApmSoftwareConfig::activateStackedWidget() +{ + if (buttonToConfigWidgetMap.contains(sender())) + { + ui.stackedWidget->setCurrentWidget(buttonToConfigWidgetMap[sender()]); + } +} +void ApmSoftwareConfig::activeUASSet(UASInterface *uas) +{ + if (!uas) + { + return; + } + + ui.basicPidsButton->setVisible(true); + ui.flightModesButton->setVisible(true); + ui.standardParamButton->setVisible(true); + ui.geoFenceButton->setVisible(true); + ui.failSafeButton->setVisible(true); + ui.advancedParamButton->setVisible(true); + ui.advParamListButton->setVisible(true); + + ui.arduCoperPidButton->setVisible(true); +} diff --git a/src/ui/configuration/ApmSoftwareConfig.h b/src/ui/configuration/ApmSoftwareConfig.h index 35eabfd5d6..c28d366b0e 100644 --- a/src/ui/configuration/ApmSoftwareConfig.h +++ b/src/ui/configuration/ApmSoftwareConfig.h @@ -3,6 +3,16 @@ #include #include "ui_ApmSoftwareConfig.h" +#include "FlightModeConfig.h" +#include "BasicPidConfig.h" +#include "StandardParamConfig.h" +#include "GeoFenceConfig.h" +#include "FailSafeConfig.h" +#include "AdvancedParamConfig.h" +#include "ArduCopterPidConfig.h" + +#include "UASInterface.h" +#include "UASManager.h" class ApmSoftwareConfig : public QWidget { @@ -11,9 +21,19 @@ class ApmSoftwareConfig : public QWidget public: explicit ApmSoftwareConfig(QWidget *parent = 0); ~ApmSoftwareConfig(); - +private slots: + void activateStackedWidget(); + void activeUASSet(UASInterface *uas); private: Ui::ApmSoftwareConfig ui; + BasicPidConfig *basicPidConfig; + FlightModeConfig *flightConfig; + StandardParamConfig *standardParamConfig; + GeoFenceConfig *geoFenceConfig; + FailSafeConfig *failSafeConfig; + AdvancedParamConfig *advancedParamConfig; + ArduCopterPidConfig *arduCoperPidConfig; + QMap buttonToConfigWidgetMap; }; #endif // APMSOFTWARECONFIG_H diff --git a/src/ui/configuration/ApmSoftwareConfig.ui b/src/ui/configuration/ApmSoftwareConfig.ui index 0132c2f5c2..ab26e10fbe 100644 --- a/src/ui/configuration/ApmSoftwareConfig.ui +++ b/src/ui/configuration/ApmSoftwareConfig.ui @@ -65,6 +65,134 @@ + + + + + 0 + 35 + + + + Basic Pids + + + false + + + + + + + + 0 + 35 + + + + Flight Modes + + + false + + + + + + + + 0 + 35 + + + + Standard Params + + + false + + + + + + + + 0 + 35 + + + + GeoFence + + + false + + + + + + + + 0 + 35 + + + + FailSafe + + + false + + + + + + + + 0 + 35 + + + + Advanced Params + + + false + + + + + + + + 0 + 35 + + + + Adv Parameter List + + + false + + + + + + + + 0 + 35 + + + + ArduCoper Pids + + + false + + + diff --git a/src/ui/configuration/ArduCopterPidConfig.cc b/src/ui/configuration/ArduCopterPidConfig.cc new file mode 100644 index 0000000000..1674ae2362 --- /dev/null +++ b/src/ui/configuration/ArduCopterPidConfig.cc @@ -0,0 +1,14 @@ +#include "ArduCopterPidConfig.h" +#include "ui_ArduCopterPidConfig.h" + +ArduCopterPidConfig::ArduCopterPidConfig(QWidget *parent) : + QWidget(parent), + ui(new Ui::ArduCopterPidConfig) +{ + ui->setupUi(this); +} + +ArduCopterPidConfig::~ArduCopterPidConfig() +{ + delete ui; +} diff --git a/src/ui/configuration/ArduCopterPidConfig.h b/src/ui/configuration/ArduCopterPidConfig.h new file mode 100644 index 0000000000..6f7eae7e85 --- /dev/null +++ b/src/ui/configuration/ArduCopterPidConfig.h @@ -0,0 +1,22 @@ +#ifndef ARDUCOPTERPIDCONFIG_H +#define ARDUCOPTERPIDCONFIG_H + +#include + +namespace Ui { +class ArduCopterPidConfig; +} + +class ArduCopterPidConfig : public QWidget +{ + Q_OBJECT + +public: + explicit ArduCopterPidConfig(QWidget *parent = 0); + ~ArduCopterPidConfig(); + +private: + Ui::ArduCopterPidConfig *ui; +}; + +#endif // ARDUCOPTERPIDCONFIG_H diff --git a/src/ui/configuration/ArduCopterPidConfig.ui b/src/ui/configuration/ArduCopterPidConfig.ui new file mode 100644 index 0000000000..a472f6a8f7 --- /dev/null +++ b/src/ui/configuration/ArduCopterPidConfig.ui @@ -0,0 +1,32 @@ + + + ArduCopterPidConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 10 + 181 + 51 + + + + <h2>ArduCopter Pids</h2> + + + + + + diff --git a/src/ui/configuration/BasicPidConfig.cc b/src/ui/configuration/BasicPidConfig.cc new file mode 100644 index 0000000000..938940e5f0 --- /dev/null +++ b/src/ui/configuration/BasicPidConfig.cc @@ -0,0 +1,11 @@ +#include "BasicPidConfig.h" + + +BasicPidConfig::BasicPidConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +BasicPidConfig::~BasicPidConfig() +{ +} diff --git a/src/ui/configuration/BasicPidConfig.h b/src/ui/configuration/BasicPidConfig.h new file mode 100644 index 0000000000..3129239416 --- /dev/null +++ b/src/ui/configuration/BasicPidConfig.h @@ -0,0 +1,19 @@ +#ifndef BASICPIDCONFIG_H +#define BASICPIDCONFIG_H + +#include +#include "ui_BasicPidConfig.h" + +class BasicPidConfig : public QWidget +{ + Q_OBJECT + +public: + explicit BasicPidConfig(QWidget *parent = 0); + ~BasicPidConfig(); + +private: + Ui::BasicPidConfig ui; +}; + +#endif // BASICPIDCONFIG_H diff --git a/src/ui/configuration/BasicPidConfig.ui b/src/ui/configuration/BasicPidConfig.ui new file mode 100644 index 0000000000..4be479c989 --- /dev/null +++ b/src/ui/configuration/BasicPidConfig.ui @@ -0,0 +1,32 @@ + + + BasicPidConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 30 + 20 + 141 + 31 + + + + <h2> Basic Pids</h2> + + + + + + diff --git a/src/ui/configuration/FailSafeConfig.cc b/src/ui/configuration/FailSafeConfig.cc new file mode 100644 index 0000000000..5f7ff81b06 --- /dev/null +++ b/src/ui/configuration/FailSafeConfig.cc @@ -0,0 +1,11 @@ +#include "FailSafeConfig.h" + + +FailSafeConfig::FailSafeConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +FailSafeConfig::~FailSafeConfig() +{ +} diff --git a/src/ui/configuration/FailSafeConfig.h b/src/ui/configuration/FailSafeConfig.h new file mode 100644 index 0000000000..a22e96493e --- /dev/null +++ b/src/ui/configuration/FailSafeConfig.h @@ -0,0 +1,19 @@ +#ifndef FAILSAFECONFIG_H +#define FAILSAFECONFIG_H + +#include +#include "ui_FailSafeConfig.h" + +class FailSafeConfig : public QWidget +{ + Q_OBJECT + +public: + explicit FailSafeConfig(QWidget *parent = 0); + ~FailSafeConfig(); + +private: + Ui::FailSafeConfig ui; +}; + +#endif // FAILSAFECONFIG_H diff --git a/src/ui/configuration/FailSafeConfig.ui b/src/ui/configuration/FailSafeConfig.ui new file mode 100644 index 0000000000..fe4eef1cb8 --- /dev/null +++ b/src/ui/configuration/FailSafeConfig.ui @@ -0,0 +1,32 @@ + + + FailSafeConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 20 + 141 + 31 + + + + <h2>Fail Safe</h2> + + + + + + diff --git a/src/ui/configuration/GeoFenceConfig.cc b/src/ui/configuration/GeoFenceConfig.cc new file mode 100644 index 0000000000..ea01a4b248 --- /dev/null +++ b/src/ui/configuration/GeoFenceConfig.cc @@ -0,0 +1,11 @@ +#include "GeoFenceConfig.h" + + +GeoFenceConfig::GeoFenceConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +GeoFenceConfig::~GeoFenceConfig() +{ +} diff --git a/src/ui/configuration/GeoFenceConfig.h b/src/ui/configuration/GeoFenceConfig.h new file mode 100644 index 0000000000..71624346d7 --- /dev/null +++ b/src/ui/configuration/GeoFenceConfig.h @@ -0,0 +1,19 @@ +#ifndef GEOFENCECONFIG_H +#define GEOFENCECONFIG_H + +#include +#include "ui_GeoFenceConfig.h" + +class GeoFenceConfig : public QWidget +{ + Q_OBJECT + +public: + explicit GeoFenceConfig(QWidget *parent = 0); + ~GeoFenceConfig(); + +private: + Ui::GeoFenceConfig ui; +}; + +#endif // GEOFENCECONFIG_H diff --git a/src/ui/configuration/GeoFenceConfig.ui b/src/ui/configuration/GeoFenceConfig.ui new file mode 100644 index 0000000000..b51ea2e508 --- /dev/null +++ b/src/ui/configuration/GeoFenceConfig.ui @@ -0,0 +1,32 @@ + + + GeoFenceConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 20 + 141 + 51 + + + + <h2>Geo Fence</h2> + + + + + + diff --git a/src/ui/configuration/StandardParamConfig.cc b/src/ui/configuration/StandardParamConfig.cc new file mode 100644 index 0000000000..d67891bbfb --- /dev/null +++ b/src/ui/configuration/StandardParamConfig.cc @@ -0,0 +1,11 @@ +#include "StandardParamConfig.h" + + +StandardParamConfig::StandardParamConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +StandardParamConfig::~StandardParamConfig() +{ +} diff --git a/src/ui/configuration/StandardParamConfig.h b/src/ui/configuration/StandardParamConfig.h new file mode 100644 index 0000000000..9e43a9bd99 --- /dev/null +++ b/src/ui/configuration/StandardParamConfig.h @@ -0,0 +1,19 @@ +#ifndef STANDARDPARAMCONFIG_H +#define STANDARDPARAMCONFIG_H + +#include +#include "ui_StandardParamConfig.h" + +class StandardParamConfig : public QWidget +{ + Q_OBJECT + +public: + explicit StandardParamConfig(QWidget *parent = 0); + ~StandardParamConfig(); + +private: + Ui::StandardParamConfig ui; +}; + +#endif // STANDARDPARAMCONFIG_H diff --git a/src/ui/configuration/StandardParamConfig.ui b/src/ui/configuration/StandardParamConfig.ui new file mode 100644 index 0000000000..cdbb320c0e --- /dev/null +++ b/src/ui/configuration/StandardParamConfig.ui @@ -0,0 +1,32 @@ + + + StandardParamConfig + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 20 + 201 + 41 + + + + <h2>Standard Params</h2> + + + + + + -- GitLab From b22d40239118b6a57830bf59146bea14a3379bc0 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Mon, 8 Jul 2013 11:19:33 -0400 Subject: [PATCH 042/460] ArduPlane level configuration widget --- qgroundcontrol.pro | 9 ++- src/ui/configuration/ApmPlaneLevel.cc | 59 ++++++++++++++++ src/ui/configuration/ApmPlaneLevel.h | 23 +++++++ src/ui/configuration/ApmPlaneLevel.ui | 99 +++++++++++++++++++++++++++ 4 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 src/ui/configuration/ApmPlaneLevel.cc create mode 100644 src/ui/configuration/ApmPlaneLevel.h create mode 100644 src/ui/configuration/ApmPlaneLevel.ui diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 8b796850b0..31f08c1fba 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -256,7 +256,8 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/GeoFenceConfig.ui \ src/ui/configuration/FailSafeConfig.ui \ src/ui/configuration/AdvancedParamConfig.ui \ - src/ui/configuration/ArduCopterPidConfig.ui + src/ui/configuration/ArduCopterPidConfig.ui \ + src/ui/configuration/ApmPlaneLevel.ui INCLUDEPATH += src \ src/ui \ src/ui/linechart \ @@ -437,7 +438,8 @@ HEADERS += src/MG.h \ src/ui/configuration/GeoFenceConfig.h \ src/ui/configuration/FailSafeConfig.h \ src/ui/configuration/AdvancedParamConfig.h \ - src/ui/configuration/ArduCopterPidConfig.h + src/ui/configuration/ArduCopterPidConfig.h \ + src/ui/configuration/ApmPlaneLevel.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -636,7 +638,8 @@ SOURCES += src/main.cc \ src/ui/configuration/GeoFenceConfig.cc \ src/ui/configuration/FailSafeConfig.cc \ src/ui/configuration/AdvancedParamConfig.cc \ - src/ui/configuration/ArduCopterPidConfig.cc + src/ui/configuration/ArduCopterPidConfig.cc \ + src/ui/configuration/ApmPlaneLevel.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/configuration/ApmPlaneLevel.cc b/src/ui/configuration/ApmPlaneLevel.cc new file mode 100644 index 0000000000..7b00374834 --- /dev/null +++ b/src/ui/configuration/ApmPlaneLevel.cc @@ -0,0 +1,59 @@ +#include "ApmPlaneLevel.h" +#include + +ApmPlaneLevel::ApmPlaneLevel(QWidget *parent) : AP2ConfigWidget(parent) +{ + ui.setupUi(this); + connect(ui.levelPushButton,SIGNAL(clicked()),this,SLOT(levelClicked())); + connect(ui.manualLevelCheckBox,SIGNAL(toggled(bool)),this,SLOT(manualCheckBoxToggled(bool))); +} + +ApmPlaneLevel::~ApmPlaneLevel() +{ +} +void ApmPlaneLevel::levelClicked() +{ + QMessageBox::information(0,"Warning","Be sure the plane is completly level, then click ok"); + MAV_CMD command = MAV_CMD_PREFLIGHT_CALIBRATION; + int confirm = 0; + float param1 = 1; + float param2 = 0; + float param3 = 1; + float param4 = 0; + float param5 = 0; + float param6 = 0; + float param7 = 0; + int component = 1; + m_uas->executeCommand(command, confirm, param1, param2, param3, param4, param5, param6, param7, component); + QMessageBox::information(0,"Warning","Leveling completed"); +} + +void ApmPlaneLevel::manualCheckBoxToggled(bool checked) +{ + if (!m_uas) + { + return; + } + if (checked) + { + m_uas->getParamManager()->setParameter(1,"MANUAL_LEVEL",1); + } + else + { + m_uas->getParamManager()->setParameter(1,"MANUAL_LEVEL",0); + } +} +void ApmPlaneLevel::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + if (parameterName == "MANUAL_LEVEL") + { + if (value.toInt() == 1) + { + ui.manualLevelCheckBox->setChecked(true); + } + else + { + ui.manualLevelCheckBox->setChecked(false); + } + } +} diff --git a/src/ui/configuration/ApmPlaneLevel.h b/src/ui/configuration/ApmPlaneLevel.h new file mode 100644 index 0000000000..a6a38078f3 --- /dev/null +++ b/src/ui/configuration/ApmPlaneLevel.h @@ -0,0 +1,23 @@ +#ifndef APMPLANELEVEL_H +#define APMPLANELEVEL_H + +#include +#include "ui_ApmPlaneLevel.h" +#include "AP2ConfigWidget.h" + +class ApmPlaneLevel : public AP2ConfigWidget +{ + Q_OBJECT + +public: + explicit ApmPlaneLevel(QWidget *parent = 0); + ~ApmPlaneLevel(); +private slots: + void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void levelClicked(); + void manualCheckBoxToggled(bool checked); +private: + Ui::ApmPlaneLevel ui; +}; + +#endif // APMPLANELEVEL_H diff --git a/src/ui/configuration/ApmPlaneLevel.ui b/src/ui/configuration/ApmPlaneLevel.ui new file mode 100644 index 0000000000..ef22b19992 --- /dev/null +++ b/src/ui/configuration/ApmPlaneLevel.ui @@ -0,0 +1,99 @@ + + + ApmPlaneLevel + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 10 + 10 + 141 + 31 + + + + <h2>ArduPlane Level</h2> + + + + + + 50 + 70 + 271 + 41 + + + + By Default your plane will autolevel on every boot. +To disable this action you need to turn on manual +level and perform a level to calibrate the accel offsets. + + + + + + 50 + 150 + 291 + 16 + + + + Level your plane and click Level to set default accel offsets + + + + + + 160 + 180 + 75 + 23 + + + + Level + + + + + + 120 + 230 + 151 + 51 + + + + For advanced users ONLY + + + + + 30 + 20 + 91 + 17 + + + + Manual Level + + + + + + + -- GitLab From aa582da29dadedc15734240c75b6ed7dabd130f7 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Mon, 8 Jul 2013 17:41:48 -0700 Subject: [PATCH 043/460] First commit of the new APM Toolbar --- .gitignore | 107 +++++++++--------- qgroundcontrol.pri | 13 +++ qgroundcontrol.pro | 38 ++++++- qml/ApmToolBar.qml | 75 ++++++++++++ qml/components/Button.qml | 70 ++++++++++++ qml/resources/apmplanner/toolbar/connect.png | Bin 0 -> 3335 bytes .../apmplanner/toolbar/disconnect.png | Bin 0 -> 2471 bytes qml/resources/apmplanner/toolbar/donate.png | Bin 0 -> 2872 bytes .../apmplanner/toolbar/flightdata.png | Bin 0 -> 3428 bytes .../apmplanner/toolbar/flightplanner.png | Bin 0 -> 4343 bytes .../apmplanner/toolbar/hardwareconfig.png | Bin 0 -> 4030 bytes .../apmplanner/toolbar/helpwizard.png | Bin 0 -> 2059 bytes .../apmplanner/toolbar/simulation.png | Bin 0 -> 3901 bytes .../apmplanner/toolbar/softwareconfig.png | Bin 0 -> 3434 bytes qml/resources/apmplanner/toolbar/terminal.png | Bin 0 -> 2885 bytes src/ui/MainWindow.cc | 24 +++- src/ui/MainWindow.h | 2 + src/ui/MainWindow.ui | 12 +- src/ui/QGCToolBar.cc | 2 + src/ui/apmtoolbar.cpp | 81 +++++++++++++ src/ui/apmtoolbar.h | 41 +++++++ 21 files changed, 400 insertions(+), 65 deletions(-) create mode 100644 qml/ApmToolBar.qml create mode 100644 qml/components/Button.qml create mode 100644 qml/resources/apmplanner/toolbar/connect.png create mode 100644 qml/resources/apmplanner/toolbar/disconnect.png create mode 100644 qml/resources/apmplanner/toolbar/donate.png create mode 100644 qml/resources/apmplanner/toolbar/flightdata.png create mode 100644 qml/resources/apmplanner/toolbar/flightplanner.png create mode 100644 qml/resources/apmplanner/toolbar/hardwareconfig.png create mode 100644 qml/resources/apmplanner/toolbar/helpwizard.png create mode 100644 qml/resources/apmplanner/toolbar/simulation.png create mode 100644 qml/resources/apmplanner/toolbar/softwareconfig.png create mode 100644 qml/resources/apmplanner/toolbar/terminal.png create mode 100644 src/ui/apmtoolbar.cpp create mode 100644 src/ui/apmtoolbar.h diff --git a/.gitignore b/.gitignore index cf34ac8aad..3184e1aaa0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,55 +1,52 @@ -*.swp -*.nfs -CMakeFiles -*Makefile* -tags -build*/ -Info.plist -obj -.DS_Store -*.log -*~ -*~.skp -bin/*.exe -bin/*.txt -bin/mac -*pro.user* -qrc_*.cpp -*.Debug -*.Release -tmp -debug -release -qgroundcontrol -mavlinkgen-build-desktop -qgroundcontrol.xcodeproj/** -doc/html -doc/doxy.log -deploy/mac -deploy/linux -deploy/qgroundcontrol* -controller_log* -user_config.pri -*.app -*.ncb -*.vcproj -*.vcxproj* -*.sdf -*.ipch -*.pdb -*.sln -*.sln -*.vcproj -*.user -*.ncb -*.idb -*.project -*.cproject -*.sln -*.suo -*.uhf.txt -*.opensdf - -thirdParty/qserialport-build-desktop/ -thirdParty/qserialport/bin/ -thirdParty/qserialport/lib/ +*.swp +*.nfs +CMakeFiles +*Makefile* +tags +build*/ +Info.plist +obj +.DS_Store +*.log +*~ +*~.skp +bin/*.exe +bin/*.txt +bin/mac +*pro.user* +qrc_*.cpp +*.Debug +*.Release +tmp +debug +release +qgroundcontrol +mavlinkgen-build-desktop +qgroundcontrol.xcodeproj/** +doc/html +doc/doxy.log +deploy/mac +deploy/linux +deploy/qgroundcontrol* +controller_log* +user_config.pri +*.app +*.ncb +*.vcproj +*.vcxproj* +*.sdf +*.ipch +*.pdb +*.sln +*.sln +*.vcproj +*.user +*.ncb +*.idb +*.project +*.cproject +*.sln +*.suo +*.uhf.txt +*.opensdf +apmplanner2.xcodeproj/ diff --git a/qgroundcontrol.pri b/qgroundcontrol.pri index d8ec27616b..02ca75f2fd 100644 --- a/qgroundcontrol.pri +++ b/qgroundcontrol.pri @@ -65,6 +65,19 @@ macx|macx-g++42|macx-g++|macx-llvm: { QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/apmplanner2.app/Contents/Frameworks QMAKE_POST_LINK += && cp -rf $$BASEDIR/libs/lib/Frameworks/* $$TARGETDIR/apmplanner2.app/Contents/Frameworks +# # Copy QML stuff +message(BASEDIR $$BASEDIR) + QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/apmplanner2.app/Contents/MacOS/qml + QMAKE_POST_LINK += && cp -rf $$BASEDIR/qml/*.qml $$TARGETDIR/apmplanner2.app/Contents/MacOS/qml + + QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/apmplanner2.app/Contents/MacOS/qml/components/ + QMAKE_POST_LINK += && cp -rf $$BASEDIR/qml/components/*.qml $$TARGETDIR/apmplanner2.app/Contents/MacOS/qml/components + + QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/apmplanner2.app/Contents/MacOS/qml/resources + QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/apmplanner2.app/Contents/MacOS/qml/resources/apmplanner + QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/apmplanner2.app/Contents/MacOS/qml/resources/apmplanner/toolbar + QMAKE_POST_LINK += && cp -rf $$BASEDIR/qml/resources/apmplanner/toolbar/*.png $$TARGETDIR/apmplanner2.app/Contents/MacOS/qml/resources/apmplanner/toolbar + # Fix library paths inside executable QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/apmplanner2.app/Contents/MacOS/apmplanner2 diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 9d1ca11b58..01475e1127 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -29,7 +29,8 @@ QT += network \ xml \ phonon \ webkit \ - sql + sql \ + declarative TEMPLATE = app TARGET = apmplanner2 @@ -47,6 +48,9 @@ linux-g++|linux-g++-64{ TARGETDIR = $${OUT_PWD} BUILDDIR = $${OUT_PWD}/build } + +DESTDIR = $${TARGETDIR} + LANGUAGE = C++ OBJECTS_DIR = $${BUILDDIR}/obj MOC_DIR = $${BUILDDIR}/moc @@ -153,6 +157,7 @@ include(libs/serialport/apmserial.pri) #linux-g++::SOURCES += libs/qextserialport/qextserialenumerator_unix.cpp #linux-g++-64::SOURCES += libs/qextserialport/qextserialenumerator_unix.cpp #win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += libs/qextserialport/qextserialenumerator_win.cpp + # Input FORMS += src/ui/MainWindow.ui \ src/ui/CommSettings.ui \ @@ -431,7 +436,8 @@ HEADERS += src/MG.h \ src/ui/configuration/GeoFenceConfig.h \ src/ui/configuration/FailSafeConfig.h \ src/ui/configuration/AdvancedParamConfig.h \ - src/ui/configuration/ArduCopterPidConfig.h + src/ui/configuration/ArduCopterPidConfig.h \ + src/ui/apmtoolbar.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -630,7 +636,8 @@ SOURCES += src/main.cc \ src/ui/configuration/GeoFenceConfig.cc \ src/ui/configuration/FailSafeConfig.cc \ src/ui/configuration/AdvancedParamConfig.cc \ - src/ui/configuration/ArduCopterPidConfig.cc + src/ui/configuration/ArduCopterPidConfig.cc \ + src/ui/apmtoolbar.cpp # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc @@ -767,3 +774,28 @@ unix:!macx:!symbian: LIBS += -losg OTHER_FILES += \ dongfang_notes.txt \ src/ui/dongfang-scrapyard.txt + +OTHER_FILES += \ + qml/ApmToolBar.qml \ + qml/components/Button.qml \ + qml/resources/apmplanner/toolbar/connect.png \ + qml/resources/apmplanner/toolbar/flightplanner.png \ + qml/resources/apmplanner/toolbar/helpwizard.png \ + qml/resources/apmplanner/toolbar/softwareconfig.png \ + qml/resources/apmplanner/toolbar/terminal.png \ + qml/resources/apmplanner/toolbar/simulation.png \ + qml/resources/apmplanner/toolbar/hardwareconfig.png \ + qml/resources/apmplanner/toolbar/flightdata.png \ + qml/resources/apmplanner/toolbar/disconnect.png \ + qml/resources/apmplanner/toolbar/donate.png \ + + +#qmlcomponents.path += $${DESTDIR}$${TARGET}/components +#qmlcomponents.files += ./components/Button.qml + +#sources.files += ApmToolBar.qml +#sources.path += $$DESTDIR/qml +#target.path += apmplanner2 +#INSTALLS += sources target + +message( BASEDIR $$BASEDIR DESTDIR $$DESTDIR TARGET $$TARGET TARGETDIR $$TARGETDIR) diff --git a/qml/ApmToolBar.qml b/qml/ApmToolBar.qml new file mode 100644 index 0000000000..6748a651af --- /dev/null +++ b/qml/ApmToolBar.qml @@ -0,0 +1,75 @@ +import QtQuick 1.1 +import "./components" + + +Rectangle { + id: toolbar + width: parent.width + height: 72 + color: "black" + border.color: "black" + + Row { + anchors.left: parent.left + spacing: 2 + + Button { + id: flightDataView + label: "FLIGHT DATA" + image: "./resources/apmplanner/toolbar/flightdata.png" + onClicked: { + globalObj.selectFlightView() + } + } + + Button { + id: flightPlanView + label: "FLIGHT PLAN" + image: "./resources/apmplanner/toolbar/flightplanner.png" + onClicked: globalObj.selectFlightPlanView() + } + + Button { + id: hardwareConfigView + label: "HARDWARE" + image: "./resources/apmplanner/toolbar/hardwareconfig.png" + margins: 8 + onClicked: globalObj.selectHardwareView() + } + + Button { + id: softwareConfigView + label: "SOFTWARE" + image: "./resources/apmplanner/toolbar/softwareconfig.png" + margins: 8 + onClicked: globalObj.selectSoftwareView() + } + + Button { + id: simualtionView + label: "SIMULATION" + image: "./resources/apmplanner/toolbar/simulation.png" + onClicked: globalObj.selectSimulationView() + } + + Button { + id: terminalView + label: "TERMINAL" + image: "./resources/apmplanner/toolbar/terminal.png" + onClicked: globalObj.selectTerminalView() + } + } + + Row { + anchors.left: parent.right + spacing: 2 + + Button { + id: connectButton + label: "CONNECT" + image: "./resources/apmplanner/toolbar/connect.png" + onClicked: globalObj.connect() + } + } +} + diff --git a/qml/components/Button.qml b/qml/components/Button.qml new file mode 100644 index 0000000000..567eca2ee2 --- /dev/null +++ b/qml/components/Button.qml @@ -0,0 +1,70 @@ +import QtQuick 1.1 + +Rectangle { + signal clicked + + property string label: "button label" + property alias image: buttonImage.source + property int margins: 2 + + id: button + width: 72 + height: 72 + radius: 3 + smooth: true + border.width: 2 + + Text { + id: buttonLabel + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: 2 + text: label + color: "white" + font.pointSize: 10 + } + + Image { + id: buttonImage + anchors.horizontalCenter: button.horizontalCenter + anchors.top: buttonLabel.bottom + anchors.margins: margins + source: image + fillMode: Image.PreserveAspectFit + width: image.width + height: image.height + } + + signal buttonClick() + + onButtonClick: { + console.log(buttonLabel.text + " clicked.") + clicked() + } + + // Highlighting and ativation section + property color buttonColor: "black" + property color onHoverbuttonColor: "lightblue" + property color onHoverColor: "darkblue" + property color borderColor: "black" + + MouseArea { + id: buttonMouseArea + anchors.fill: parent + onClicked: buttonClick() + hoverEnabled: true + onEntered: { + parent.border.color = onHoverColor + parent.color = onHoverbuttonColor + } + onExited: { + parent.border.color = borderColor + parent.color = buttonColor + } + onPressed: parent.color = Qt.darker(onHoverbuttonColor, 1.5) + onReleased: parent.color = buttonColor + } + color: buttonColor + border.color: borderColor +} + diff --git a/qml/resources/apmplanner/toolbar/connect.png b/qml/resources/apmplanner/toolbar/connect.png new file mode 100644 index 0000000000000000000000000000000000000000..8572674974bcefde8dc4b54972a423a5a19837ff GIT binary patch literal 3335 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 My85}Sb4q9e0O7Z*6aWAK literal 0 HcmV?d00001 diff --git a/qml/resources/apmplanner/toolbar/disconnect.png b/qml/resources/apmplanner/toolbar/disconnect.png new file mode 100644 index 0000000000000000000000000000000000000000..57f2f505da1eb32c90369f4fc9b154f7de5646f8 GIT binary patch literal 2471 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 YgId4AOSeh?r-0hBp00i_>zopr0M}*3)c^nh literal 0 HcmV?d00001 diff --git a/qml/resources/apmplanner/toolbar/flightdata.png b/qml/resources/apmplanner/toolbar/flightdata.png new file mode 100644 index 0000000000000000000000000000000000000000..aa8fb3663f815da198374f57b40db001778dc462 GIT binary patch literal 3428 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 literal 0 HcmV?d00001 diff --git a/qml/resources/apmplanner/toolbar/flightplanner.png b/qml/resources/apmplanner/toolbar/flightplanner.png new file mode 100644 index 0000000000000000000000000000000000000000..72e1b40ec8414bb24275b5f8d592b4284184e764 GIT binary patch literal 4343 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 literal 0 HcmV?d00001 diff --git a/qml/resources/apmplanner/toolbar/helpwizard.png b/qml/resources/apmplanner/toolbar/helpwizard.png new file mode 100644 index 0000000000000000000000000000000000000000..ac5c20a2a7c52fcb60a407c395919addf6202452 GIT binary patch literal 2059 zcmeAS@N?(olHy`uVBq!ia0y~yU@&7~V9@1YV_;x-8Zx7mfq_A?#5JNMI6tkVJh3R1 z!7(L2DOJHUH!(dmC^a#qvhZZ84FdynN@hqzNrbPDRdRl=ULr`1UPW#J0|?mIR}>^B zXQ!4ZB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT8h zBDWwnwIorYA~z?m*s8)-32d%aUa=KOSYJs2tfVB{Rte&$2;Tq&=lr5n1yel(-DCqZ z0|hffJwsy?b8~YY1tSAP1APM{eM2K%Lvt%*BP#;~1t?ImQ?MyYNwW%aaf8}bl#*tv zlu=SrV5P5LUS6(OZmgGIl&)`RX=w>E!^lXtC?!p|xH7LKu|hYmSQ%!5OKNd)QD#9& zW`3Rm$i&2?{L&IzB_*h_6}bhzzHo!{ilG6OoS&;-kyxN_sAr&`n+x(6*u%voL8%C5 zU{zflQdy9yACy|0Us{x$8kCx*jARvli$Dqse0{C_i!#$Q^AdAh@{>z*Q}aqZU2K&q zatriQGE=O~oh^(EOf5}JO0H#4*_FfcSXwuG61O|Pq=g`=a3xw(s} zsgt3htC6Lnse!YrxudbAvzw8liz!U6XI^nhVqS78%-+n*6f3A+GrW4OoQqNuOY)0C z^7C_GDIg#tza+mnBfmhwIoMPoJTosPzq}X}IpC1Da!D=9EK5ysE6UGR0EezsCKlVx z-3a*_qBn({5Yx9)u+ax44Wy(36AE&112Ms=8kEBA6cAY_H7~_hsYuD*?p<7_2m=F) zt*47)NX4x;v)*Ulc9S^nKQSe;Ea~(#@#CAtwBN>bY0msDZ&7Fsl*aH1&CrVPk zxQa`AeQOrAeyj1D)i2@wHbL{m4dsRLYw}m`_4=08w3fSfvu=-?ff&DP=7M#}ndehE zcg$TYrY_X=k-0tfe&oLMcR$y@+c}vt_IjXolz3KfcC^8(1?CDIho)ZnqV){7w|uetmm3bmz<|9nD#1cs6)nZ_bnzjBKC$;Ey7EQL)G(Nv6zO z^-F(AEYuBke!4a5S56 z&i+RRo`PQe^PT=0h8xMGzK{E1a7cESwwzIjP@Kv`mgbthCS|s%Z_a$mj44m`>d2p# z{p$DgXe9x#zt03?;RiB|9$v$ za7=v^mz?V<<9ybE&+PX0N1 z)akP1ZRS~Rla^#kRod95ZGPKr!l`$RQ(fk3>2u?FuENs2YORZTKCxx2*%)5H%CIiy z&)()5#iH#CH_w)7p58Q3+mAV*sGvZA^>g69JE#l<&6_m`Y}n;X%-wRpR9%=v?peD|#r&$UdBkNv%xgS%jJWbmB4OX~BIf@_(5gx4DZ^!hFwL)|1%h!H*P?yRPw4!SJlO1tdym>PO{OkmI)z#YGFYPd?A_IOhydEttK+0Gfpxr;NG_0IpjH(>t%$X(6bZl&d& z?T9G0*nY&DWlBtRL!!p??z3&IjI7NEZ|52(-!KR#`+@T&?vA|s{PWtThs?+SI{({ap|EJ}S>NchY)?AA*4E~2SednT*3sj) zZzOG;5xdvd^wuSl8jXz`HYhkw>O6nwu^H>3+2=bQ6gDLNY~KI%Yw2R?$9_-wnm0xM z_wDWyD6x8Y?^D73Gim8*kAF|xe6&D*=KT5oQ>J;jaVVM}R6TpT`njxgN@xNAm$pH! literal 0 HcmV?d00001 diff --git a/qml/resources/apmplanner/toolbar/simulation.png b/qml/resources/apmplanner/toolbar/simulation.png new file mode 100644 index 0000000000000000000000000000000000000000..e8a1c31a04ab6f9f9267abbf1c0bd08771ef97ce GIT binary patch literal 3901 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 A*Z=?k literal 0 HcmV?d00001 diff --git a/qml/resources/apmplanner/toolbar/softwareconfig.png b/qml/resources/apmplanner/toolbar/softwareconfig.png new file mode 100644 index 0000000000000000000000000000000000000000..e2516db4060dee69ff7486243576d3749edfe97f GIT binary patch literal 3434 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 literal 0 HcmV?d00001 diff --git a/qml/resources/apmplanner/toolbar/terminal.png b/qml/resources/apmplanner/toolbar/terminal.png new file mode 100644 index 0000000000000000000000000000000000000000..bb639d3bd4c15454884a44cc664ca7585e99e3b7 GIT binary patch literal 2885 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 #include #include +#include #include "dockwidgettitlebareventfilter.h" #include "QGC.h" #include "MAVLinkSimulationLink.h" @@ -63,6 +64,7 @@ This file is part of the QGROUNDCONTROL project #include "QGCTabbedInfoView.h" #include "UASRawStatusView.h" #include "PrimaryFlightDisplay.h" +#include "apmtoolbar.h" #ifdef QGC_OSG_ENABLED #include "Q3DWidgetFactory.h" @@ -179,6 +181,15 @@ MainWindow::MainWindow(QWidget *parent): actions << ui.actionSoftwareConfig; toolBar->setPerspectiveChangeActions(actions); + // We only want one of these. + apmToolBar = new APMToolBar(this); + apmToolBar->setFlightViewAction(ui.actionFlightView); + apmToolBar->setFlightPlanViewAction(ui.actionMissionView); + apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); + apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); + apmToolBar->setSimulationViewAction(ui.actionSimulation_View); + apmToolBar->setTerminalViewAction(ui.actionSimulation_View); + // Add actions for advanced users (displayed in dropdown under "advanced") QList advancedActions; advancedActions << ui.actionSimulation_View; @@ -598,10 +609,16 @@ void MainWindow::buildCommonWidgets() } createDockWidget(engineeringView,new HUD(320,240,this),tr("Video Downlink"),"HEAD_UP_DISPLAY_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea,this->width()/1.5); - createDockWidget(simView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_SIMULATION,Qt::RightDockWidgetArea,this->width()/1.5); + createDockWidget(engineeringView,new HUD(320,240,this),tr("Video Downlink"),"HEAD_UP_DISPLAY_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea,this->width()/1.5); + + createDockWidget(simView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_SIMULATION,Qt::RightDockWidgetArea,this->width()/1.5); createDockWidget(pilotView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea,this->width()/1.8); + // Add Our new 'toolbar' + qDebug() << "width" << this->width(); + createDockWidget(pilotView,apmToolBar,tr("APM Tool Bar"),"APM_TOOLBAR_DOCKWIDGET",VIEW_FLIGHT,Qt::TopDockWidgetArea,this->width(), 70); + QGCTabbedInfoView *infoview = new QGCTabbedInfoView(this); infoview->addSource(mavlinkDecoder); createDockWidget(pilotView,infoview,tr("Info View"),"UAS_INFO_INFOVIEW_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea); @@ -844,6 +861,11 @@ void MainWindow::loadDockWidget(QString name) { createDockWidget(centerStack->currentWidget(),new UASQuickView(this),tr("Quick View"),"UAS_INFO_QUICKVIEW_DOCKWIDGET",currentView,Qt::LeftDockWidgetArea); } + else if (name == "APM_TOOLBAR_DOCKWIDGET") + { + // Add Our new 'toolbar' + createDockWidget(centerStack->currentWidget(),apmToolBar,tr("APM Tool Bar"),"APM_TOOLBAR_DOCKWIDGET",VIEW_FLIGHT,Qt::TopDockWidgetArea,this->width(), 70); + } else { if (customWidgetNameToFilenameMap.contains(name)) diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 4435268f1c..5d765debe2 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -84,6 +84,7 @@ This file is part of the QGROUNDCONTROL project #include "MAVLinkDecoder.h" #include "ApmHardwareConfig.h" #include "ApmSoftwareConfig.h" +#include "apmtoolbar.h" class QGCMapTool; class QGCMAVLinkMessageSender; @@ -403,6 +404,7 @@ protected: QPointer toolBar; QPointer customStatusBar; + QPointer apmToolBar; QPointer debugConsole; diff --git a/src/ui/MainWindow.ui b/src/ui/MainWindow.ui index f51da403fb..99a69c43d2 100644 --- a/src/ui/MainWindow.ui +++ b/src/ui/MainWindow.ui @@ -6,14 +6,14 @@ 0 0 - 800 - 500 + 1024 + 600 - 800 - 500 + 1024 + 600 @@ -50,8 +50,8 @@ 0 0 - 800 - 21 + 1024 + 22 diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 649072640f..1a7414bd87 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -229,8 +229,10 @@ void QGCToolBar::setPerspectiveChangeActions(const QList &actions) first->setToolTip(actions.first()->toolTip()); first->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); first->setCheckable(true); + connect(first, SIGNAL(clicked(bool)), actions.first(), SIGNAL(triggered(bool))); connect(actions.first(),SIGNAL(triggered(bool)),first,SLOT(setChecked(bool))); + first->setStyleSheet("QToolButton { min-height: 24px; max-height: 24px; min-width: 60px; color: #222222; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #A2A3A4, stop: 1 #B6B7B8); margin-left: 8px; margin-right: 0px; padding-left: 4px; padding-right: 8px; border-radius: 0px; border : 0px solid blue; border-bottom-left-radius: 6px; border-top-left-radius: 6px; border-left: 1px solid #484848; border-top: 1px solid #484848; border-bottom: 1px solid #484848; } QToolButton:checked { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #555555, stop: 1 #787878); color: #DDDDDD; }"); addWidget(first); group->addButton(first); diff --git a/src/ui/apmtoolbar.cpp b/src/ui/apmtoolbar.cpp new file mode 100644 index 0000000000..71e3e9ab7d --- /dev/null +++ b/src/ui/apmtoolbar.cpp @@ -0,0 +1,81 @@ +#include +#include +#include + +#include "apmtoolbar.h" + +APMToolBar::APMToolBar(QWidget *parent) : + QDeclarativeView(parent) +{ + // Configure our QML object + this->rootContext()->setContextProperty("globalObj", this); + setSource(QUrl::fromLocalFile("qml/ApmToolBar.qml")); + setResizeMode(QDeclarativeView::SizeRootObjectToView); +} + +void APMToolBar::setFlightViewAction(QAction *action) +{ + connect(this, SIGNAL(selectFlightView()), action, SIGNAL(triggered())); +} + +void APMToolBar::setFlightPlanViewAction(QAction *action) +{ + connect(this, SIGNAL(selectFlightPlanView()), action, SIGNAL(triggered())); +} + +void APMToolBar::setHardwareViewAction(QAction *action) +{ + connect(this, SIGNAL(selectHardwareView()), action, SIGNAL(triggered())); +} + +void APMToolBar::setSoftwareViewAction(QAction *action) +{ + connect(this, SIGNAL(selectSoftwareView()), action, SIGNAL(triggered())); +} + +void APMToolBar::setSimulationViewAction(QAction *action) +{ + connect(this, SIGNAL(selectSimualtionView()), action, SIGNAL(triggered())); +} + +void APMToolBar::setTerminalViewAction(QAction *action) +{ + connect(this, SIGNAL(selectTerminalView()), action, SIGNAL(triggered())); +} + +void APMToolBar::selectFlightView() +{ + qDebug() << "APMToolBar: SelectFlightView"; +// emit triggerFlightView(); +} + +void APMToolBar::selectFlightPlanView() +{ + qDebug() << "APMToolBar: SelectFlightPlanView"; +} + +void APMToolBar::selectHardwareView() +{ + qDebug() << "APMToolBar: selectHardwareView"; +} + +void APMToolBar::selectSoftwareView() +{ + qDebug() << "APMToolBar: selectSoftwareView"; +} + +void APMToolBar::selectSimulationView() +{ + qDebug() << "APMToolBar: selectSimulationView"; +} + +void APMToolBar::selectTerminalView() +{ + qDebug() << "APMToolBar: selectTerminalView"; +} + +void APMToolBar::connectMAV() +{ + qDebug() << "APMToolBar: connect"; +} + diff --git a/src/ui/apmtoolbar.h b/src/ui/apmtoolbar.h new file mode 100644 index 0000000000..e7d0386991 --- /dev/null +++ b/src/ui/apmtoolbar.h @@ -0,0 +1,41 @@ +#ifndef APMTOOLBAR_H +#define APMTOOLBAR_H + +#include +#include + +class APMToolBar : public QDeclarativeView +{ + Q_OBJECT +public: + explicit APMToolBar(QWidget *parent = 0); + + void setFlightViewAction(QAction *action); + void setFlightPlanViewAction(QAction *action); + void setHardwareViewAction(QAction *action); + void setSoftwareViewAction(QAction *action); + void setSimulationViewAction(QAction *action); + void setTerminalViewAction(QAction *action); + +signals: + void triggerFlightView(); + void triggerFlightPlanView(); + void triggerHardwareView(); + void triggerSoftwareView(); + void triggerSimulationView(); + void triggerTerminalView(); + +public slots: +//signals: + void selectFlightView(); + void selectFlightPlanView(); + void selectHardwareView(); + void selectSoftwareView(); + void selectSimulationView(); + void selectTerminalView(); + +public slots: + void connectMAV(); +}; + +#endif // APMTOOLBAR_H -- GitLab From 897ee64f60292ca61dc90ee0f6be67ca4c45d818 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 9 Jul 2013 06:34:17 -0400 Subject: [PATCH 044/460] Changes for ArduPlane level to be shown when ArduPlane firmware is loaded --- src/ui/configuration/ApmHardwareConfig.cc | 33 ++++++++++++++++++++--- src/ui/configuration/ApmHardwareConfig.h | 2 ++ src/ui/configuration/ApmHardwareConfig.ui | 21 ++++++++++++++- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/ui/configuration/ApmHardwareConfig.cc b/src/ui/configuration/ApmHardwareConfig.cc index 07c28f12f0..bb1ab1a783 100644 --- a/src/ui/configuration/ApmHardwareConfig.cc +++ b/src/ui/configuration/ApmHardwareConfig.cc @@ -39,6 +39,7 @@ ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) ui.frameTypeButton->setVisible(false); ui.compassButton->setVisible(false); ui.accelCalibrateButton->setVisible(false); + ui.arduPlaneLevelButton->setVisible(false); ui.radioCalibrateButton->setVisible(false); ui.optionalHardwareButton->setVisible(false); //ui.radio3DRButton->setVisible(false); @@ -50,10 +51,6 @@ ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) ui.cameraGimbalButton->setVisible(false); //ui.antennaTrackerButton->setVisible(false); - connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.frameTypeButton,SLOT(setShown(bool))); - connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.compassButton,SLOT(setShown(bool))); - connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.accelCalibrateButton,SLOT(setShown(bool))); - connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.radioCalibrateButton,SLOT(setShown(bool))); connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.radio3DRButton,SLOT(setShown(bool))); connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.batteryMonitorButton,SLOT(setShown(bool))); @@ -87,6 +84,11 @@ ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) buttonToConfigWidgetMap[ui.accelCalibrateButton] = accelConfig; connect(ui.accelCalibrateButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + planeLevel = new ApmPlaneLevel(this); + ui.stackedWidget->addWidget(planeLevel); + buttonToConfigWidgetMap[ui.arduPlaneLevelButton] = planeLevel; + connect(ui.arduPlaneLevelButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + radioConfig = new RadioCalibrationConfig(this); ui.stackedWidget->addWidget(radioConfig); buttonToConfigWidgetMap[ui.radioCalibrateButton] = radioConfig; @@ -159,6 +161,29 @@ void ApmHardwareConfig::activeUASSet(UASInterface *uas) { return; } + if (uas->getSystemType() == MAV_TYPE_FIXED_WING) + { + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.compassButton,SLOT(setShown(bool))); + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.arduPlaneLevelButton,SLOT(setShown(bool))); + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.radioCalibrateButton,SLOT(setShown(bool))); + } + else if (uas->getSystemType() == MAV_TYPE_QUADROTOR) + { + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.frameTypeButton,SLOT(setShown(bool))); + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.compassButton,SLOT(setShown(bool))); + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.accelCalibrateButton,SLOT(setShown(bool))); + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.radioCalibrateButton,SLOT(setShown(bool))); + } + else if (uas->getSystemType() == MAV_TYPE_GROUND_ROVER) + { + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.compassButton,SLOT(setShown(bool))); + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.radioCalibrateButton,SLOT(setShown(bool))); + } + else + { + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.compassButton,SLOT(setShown(bool))); + connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.radioCalibrateButton,SLOT(setShown(bool))); + } ui.firmwareButton->setVisible(true); ui.manditoryHardware->setVisible(true); ui.manditoryHardware->setChecked(false); diff --git a/src/ui/configuration/ApmHardwareConfig.h b/src/ui/configuration/ApmHardwareConfig.h index e21fe05d70..6d48bf9547 100644 --- a/src/ui/configuration/ApmHardwareConfig.h +++ b/src/ui/configuration/ApmHardwareConfig.h @@ -48,6 +48,7 @@ This file is part of the QGROUNDCONTROL project #include "OsdConfig.h" #include "CameraGimbalConfig.h" #include "AntennaTrackerConfig.h" +#include "ApmPlaneLevel.h" class ApmHardwareConfig : public QWidget { @@ -70,6 +71,7 @@ private: OsdConfig *osdConfig; CameraGimbalConfig *cameraGimbalConfig; AntennaTrackerConfig *antennaTrackerConfig; + ApmPlaneLevel *planeLevel; private slots: void activeUASSet(UASInterface *uas); void activateStackedWidget(); diff --git a/src/ui/configuration/ApmHardwareConfig.ui b/src/ui/configuration/ApmHardwareConfig.ui index 1a514ede92..e4a711b060 100644 --- a/src/ui/configuration/ApmHardwareConfig.ui +++ b/src/ui/configuration/ApmHardwareConfig.ui @@ -43,7 +43,7 @@ 0 0 156 - 635 + 676 @@ -129,6 +129,25 @@ + + + + + 0 + 35 + + + + Qt::LeftToRight + + + false + + + ArduPlane Level + + + -- GitLab From 3e383c01151b896cac8c6f3980bf2c38d4283f26 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 9 Jul 2013 12:51:52 -0400 Subject: [PATCH 045/460] Standard and Advanced param pages, auto-generated from xml file --- qgroundcontrol.pro | 9 +- src/ui/configuration/AdvancedParamConfig.cc | 26 +- src/ui/configuration/AdvancedParamConfig.h | 11 +- src/ui/configuration/AdvancedParamConfig.ui | 48 ++- src/ui/configuration/ApmHardwareConfig.cc | 7 +- src/ui/configuration/ApmSoftwareConfig.cc | 355 +++++++++++++++++ src/ui/configuration/ApmSoftwareConfig.ui | 403 ++++++++++---------- src/ui/configuration/StandardParamConfig.cc | 35 +- src/ui/configuration/StandardParamConfig.h | 12 +- src/ui/configuration/StandardParamConfig.ui | 48 ++- 10 files changed, 703 insertions(+), 251 deletions(-) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 31f08c1fba..edbfbe65d6 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -257,7 +257,8 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/FailSafeConfig.ui \ src/ui/configuration/AdvancedParamConfig.ui \ src/ui/configuration/ArduCopterPidConfig.ui \ - src/ui/configuration/ApmPlaneLevel.ui + src/ui/configuration/ApmPlaneLevel.ui \ + src/ui/configuration/ParamWidget.ui INCLUDEPATH += src \ src/ui \ src/ui/linechart \ @@ -439,7 +440,8 @@ HEADERS += src/MG.h \ src/ui/configuration/FailSafeConfig.h \ src/ui/configuration/AdvancedParamConfig.h \ src/ui/configuration/ArduCopterPidConfig.h \ - src/ui/configuration/ApmPlaneLevel.h + src/ui/configuration/ApmPlaneLevel.h \ + src/ui/configuration/ParamWidget.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -639,7 +641,8 @@ SOURCES += src/main.cc \ src/ui/configuration/FailSafeConfig.cc \ src/ui/configuration/AdvancedParamConfig.cc \ src/ui/configuration/ArduCopterPidConfig.cc \ - src/ui/configuration/ApmPlaneLevel.cc + src/ui/configuration/ApmPlaneLevel.cc \ + src/ui/configuration/ParamWidget.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/configuration/AdvancedParamConfig.cc b/src/ui/configuration/AdvancedParamConfig.cc index 4ab92e0b75..5f4102c242 100644 --- a/src/ui/configuration/AdvancedParamConfig.cc +++ b/src/ui/configuration/AdvancedParamConfig.cc @@ -1,7 +1,7 @@ #include "AdvancedParamConfig.h" -AdvancedParamConfig::AdvancedParamConfig(QWidget *parent) : QWidget(parent) +AdvancedParamConfig::AdvancedParamConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); } @@ -9,3 +9,27 @@ AdvancedParamConfig::AdvancedParamConfig(QWidget *parent) : QWidget(parent) AdvancedParamConfig::~AdvancedParamConfig() { } +void AdvancedParamConfig::addRange(QString title,QString description,QString param,double min,double max) +{ + ParamWidget *widget = new ParamWidget(ui.scrollAreaWidgetContents); + paramToWidgetMap[param] = widget; + widget->setupDouble(title + "(" + param + ")",description,0,min,max); + ui.verticalLayout->addWidget(widget); + widget->show(); +} + +void AdvancedParamConfig::addCombo(QString title,QString description,QString param,QList > valuelist) +{ + ParamWidget *widget = new ParamWidget(ui.scrollAreaWidgetContents); + paramToWidgetMap[param] = widget; + widget->setupCombo(title + "(" + param + ")",description,valuelist); + ui.verticalLayout->addWidget(widget); + widget->show(); +} +void AdvancedParamConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + if (paramToWidgetMap.contains(parameterName)) + { + paramToWidgetMap[parameterName]->setValue(value.toDouble()); + } +} diff --git a/src/ui/configuration/AdvancedParamConfig.h b/src/ui/configuration/AdvancedParamConfig.h index 5cf8b9fafb..9c69156d89 100644 --- a/src/ui/configuration/AdvancedParamConfig.h +++ b/src/ui/configuration/AdvancedParamConfig.h @@ -3,16 +3,21 @@ #include #include "ui_AdvancedParamConfig.h" - -class AdvancedParamConfig : public QWidget +#include "AP2ConfigWidget.h" +#include "ParamWidget.h" +class AdvancedParamConfig : public AP2ConfigWidget { Q_OBJECT public: explicit AdvancedParamConfig(QWidget *parent = 0); ~AdvancedParamConfig(); - + void addRange(QString title,QString description,QString param,double min,double max); + void addCombo(QString title,QString description,QString param,QList > valuelist); +private slots: + void parameterChanged(int uas, int component, QString parameterName, QVariant value); private: + QMap paramToWidgetMap; Ui::AdvancedParamConfig ui; }; diff --git a/src/ui/configuration/AdvancedParamConfig.ui b/src/ui/configuration/AdvancedParamConfig.ui index d49c182d9e..596861a3a2 100644 --- a/src/ui/configuration/AdvancedParamConfig.ui +++ b/src/ui/configuration/AdvancedParamConfig.ui @@ -6,26 +6,44 @@ 0 0 - 400 - 300 + 725 + 632 Form - - - - 10 - 10 - 181 - 31 - - - - <h2>Advanced Params</h2> - - + + + + + <h2>Advanced Params</h2> + + + + + + + true + + + + + 0 + 0 + 705 + 585 + + + + + + + + + + + diff --git a/src/ui/configuration/ApmHardwareConfig.cc b/src/ui/configuration/ApmHardwareConfig.cc index bb1ab1a783..3b9c5655d7 100644 --- a/src/ui/configuration/ApmHardwareConfig.cc +++ b/src/ui/configuration/ApmHardwareConfig.cc @@ -30,7 +30,6 @@ This file is part of the QGROUNDCONTROL project */ #include "ApmHardwareConfig.h" - ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) { ui.setupUi(this); @@ -191,4 +190,10 @@ void ApmHardwareConfig::activeUASSet(UASInterface *uas) ui.optionalHardwareButton->setChecked(false); ui.radio3DRButton->setVisible(false); ui.antennaTrackerButton->setVisible(false); + + + + + + } diff --git a/src/ui/configuration/ApmSoftwareConfig.cc b/src/ui/configuration/ApmSoftwareConfig.cc index cfecf5de17..a8a2e4ddd8 100644 --- a/src/ui/configuration/ApmSoftwareConfig.cc +++ b/src/ui/configuration/ApmSoftwareConfig.cc @@ -1,4 +1,7 @@ #include "ApmSoftwareConfig.h" +#include +#include +#include ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) @@ -82,4 +85,356 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) ui.advParamListButton->setVisible(true); ui.arduCoperPidButton->setVisible(true); + + + QDir autopilotdir(qApp->applicationDirPath() + "/files/" + uas->getAutopilotTypeName().toLower()); + QFile xmlfile(autopilotdir.absolutePath() + "/arduplane.pdef.xml"); + if (xmlfile.exists() && !xmlfile.open(QIODevice::ReadOnly)) + { + return; + } + + QXmlStreamReader xml(xmlfile.readAll()); + xmlfile.close(); + + //TODO: Testing to ensure that incorrectly formated XML won't break this. + while (!xml.atEnd()) + { + if (xml.isStartElement() && xml.name() == "paramfile") + { + xml.readNext(); + while ((xml.name() != "paramfile") && !xml.atEnd()) + { + QString valuetype = ""; + if (xml.isStartElement() && (xml.name() == "vehicles" || xml.name() == "libraries")) //Enter into the vehicles loop + { + valuetype = xml.name().toString(); + xml.readNext(); + while ((xml.name() != valuetype) && !xml.atEnd()) + { + if (xml.isStartElement() && xml.name() == "parameters") //This is a parameter block + { + QString parametersname = ""; + if (xml.attributes().hasAttribute("name")) + { + parametersname = xml.attributes().value("name").toString(); + } + QVariantMap genset; + QVariantMap advset; + + QString setname = parametersname; + xml.readNext(); + int genarraycount = 0; + int advarraycount = 0; + while ((xml.name() != "parameters") && !xml.atEnd()) + { + if (xml.isStartElement() && xml.name() == "param") + { + QString humanname = xml.attributes().value("humanName").toString(); + QString name = xml.attributes().value("name").toString(); + QString tab= xml.attributes().value("user").toString(); + if (tab == "Advanced") + { + advset["title"] = parametersname; + } + else + { + genset["title"] = parametersname; + } + if (name.contains(":")) + { + name = name.split(":")[1]; + } + QString docs = xml.attributes().value("documentation").toString(); + //paramTooltips[name] = name + " - " + docs; + + int type = -1; //Type of item + QMap fieldmap; + QMap valuemap; + xml.readNext(); + while ((xml.name() != "param") && !xml.atEnd()) + { + if (xml.isStartElement() && xml.name() == "values") + { + type = 1; //1 is a combobox + if (tab == "Advanced") + { + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "TYPE"] = "COMBO"; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_COMBOBOX_DESCRIPTION"] = humanname; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_COMBOBOX_PARAMID"] = name; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_COMBOBOX_COMPONENTID"] = 1; + } + else + { + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "TYPE"] = "COMBO"; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_COMBOBOX_DESCRIPTION"] = humanname; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_COMBOBOX_PARAMID"] = name; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_COMBOBOX_COMPONENTID"] = 1; + } + int paramcount = 0; + xml.readNext(); + while ((xml.name() != "values") && !xml.atEnd()) + { + if (xml.isStartElement() && xml.name() == "value") + { + + QString code = xml.attributes().value("code").toString(); + QString arg = xml.readElementText(); + valuemap[code] = arg; + if (tab == "Advanced") + { + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(paramcount) + "_TEXT"] = arg; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(paramcount) + "_VAL"] = code.toInt(); + } + else + { + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(paramcount) + "_TEXT"] = arg; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(paramcount) + "_VAL"] = code.toInt(); + } + paramcount++; + } + xml.readNext(); + } + if (tab == "Advanced") + { + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_COMBOBOX_COUNT"] = paramcount; + } + else + { + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_COMBOBOX_COUNT"] = paramcount; + } + } + if (xml.isStartElement() && xml.name() == "field") + { + type = 2; //2 is a slider + QString fieldtype = xml.attributes().value("name").toString(); + QString text = xml.readElementText(); + fieldmap[fieldtype] = text; + } + xml.readNext(); + } + if (type == -1) + { + //Nothing inside! Assume it's a value, give it a default range. + type = 2; + QString fieldtype = "Range"; + QString text = "0 100"; //TODO: Determine a better way of figuring out default ranges. + fieldmap[fieldtype] = text; + } + if (type == 2) + { + if (tab == "Advanced") + { + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "TYPE"] = "SLIDER"; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_SLIDER_DESCRIPTION"] = humanname; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_SLIDER_PARAMID"] = name; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_SLIDER_COMPONENTID"] = 1; + } + else + { + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "TYPE"] = "SLIDER"; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_SLIDER_DESCRIPTION"] = humanname; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_SLIDER_PARAMID"] = name; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_SLIDER_COMPONENTID"] = 1; + } + if (fieldmap.contains("Range")) + { + float min = 0; + float max = 0; + //Some range fields list "0-10" and some list "0 10". Handle both. + if (fieldmap["Range"].split(" ").size() > 1) + { + min = fieldmap["Range"].split(" ")[0].trimmed().toFloat(); + max = fieldmap["Range"].split(" ")[1].trimmed().toFloat(); + } + else if (fieldmap["Range"].split("-").size() > 1) + { + min = fieldmap["Range"].split("-")[0].trimmed().toFloat(); + max = fieldmap["Range"].split("-")[1].trimmed().toFloat(); + } + if (tab == "Advanced") + { + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_SLIDER_MIN"] = min; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_SLIDER_MAX"] = max; + } + else + { + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_SLIDER_MIN"] = min; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_SLIDER_MAX"] = max; + } + } + } + if (tab == "Advanced") + { + advarraycount++; + advset["count"] = advarraycount; + } + else + { + genarraycount++; + genset["count"] = genarraycount; + } + //Right here we have a single param in memory + name; + docs; + valuemap; + fieldmap; + //standardParamConfig + if (valuemap.size() > 0) + { + QList > valuelist; + for (QMap::const_iterator i = valuemap.constBegin();i!=valuemap.constEnd();i++) + { + valuelist.append(QPair(i.key().toInt(),i.value())); + } + if (tab == "Standard") + { + standardParamConfig->addCombo(humanname,docs,name,valuelist); + } + else if (tab == "Advanced") + { + advancedParamConfig->addCombo(humanname,docs,name,valuelist); + } + } + else if (fieldmap.size() > 0) + { + float min = 0; + float max = 100; + if (fieldmap.contains("Range")) + { + float min = 0; + float max = 0; + //Some range fields list "0-10" and some list "0 10". Handle both. + if (fieldmap["Range"].split(" ").size() > 1) + { + min = fieldmap["Range"].split(" ")[0].trimmed().toFloat(); + max = fieldmap["Range"].split(" ")[1].trimmed().toFloat(); + } + else if (fieldmap["Range"].split("-").size() > 1) + { + min = fieldmap["Range"].split("-")[0].trimmed().toFloat(); + max = fieldmap["Range"].split("-")[1].trimmed().toFloat(); + } + } + if (tab == "Standard") + { + standardParamConfig->addRange(humanname,docs,name,min,max); + } + else if (tab == "Advanced") + { + advancedParamConfig->addRange(humanname,docs,name,max,min); + } + } + + } + xml.readNext(); + } + if (genarraycount > 0) + { + /* + tool = new QGCToolWidget("", this); + tool->addUAS(mav); + tool->setTitle(parametersname); + tool->setObjectName(parametersname); + tool->setSettings(genset); + QList paramlist = tool->getParamList(); + for (int i=0;iinsert(paramlist[i],tool); + } + else if (parametersname == "ArduCopter") //MAV_TYPE_QUADROTOR "QUADROTOR + { + systemTypeToParamMap["QUADROTOR"]->insert(paramlist[i],tool); + } + else if (parametersname == "APMrover2") //MAV_TYPE_GROUND_ROVER GROUND_ROVER + { + systemTypeToParamMap["GROUND_ROVER"]->insert(paramlist[i],tool); + } + else + { + libParamToWidgetMap->insert(paramlist[i],tool); + } + } + + toolWidgets.append(tool); + QGroupBox *box = new QGroupBox(this); + box->setTitle(tool->objectName()); + box->setLayout(new QVBoxLayout()); + box->layout()->addWidget(tool); + if (valuetype == "vehicles") + { + ui->leftGeneralLayout->addWidget(box); + } + else if (valuetype == "libraries") + { + ui->rightGeneralLayout->addWidget(box); + } + box->hide(); + toolToBoxMap[tool] = box;*/ + } + if (advarraycount > 0) + { + /* + tool = new QGCToolWidget("", this); + tool->addUAS(mav); + tool->setTitle(parametersname); + tool->setObjectName(parametersname); + tool->setSettings(advset); + QList paramlist = tool->getParamList(); + for (int i=0;iinsert(paramlist[i],tool); + } + else if (parametersname == "ArduCopter") //MAV_TYPE_QUADROTOR "QUADROTOR + { + systemTypeToParamMap["QUADROTOR"]->insert(paramlist[i],tool); + } + else if (parametersname == "APMrover2") //MAV_TYPE_GROUND_ROVER GROUND_ROVER + { + systemTypeToParamMap["GROUND_ROVER"]->insert(paramlist[i],tool); + } + else + { + libParamToWidgetMap->insert(paramlist[i],tool); + } + } + + toolWidgets.append(tool); + QGroupBox *box = new QGroupBox(this); + box->setTitle(tool->objectName()); + box->setLayout(new QVBoxLayout()); + box->layout()->addWidget(tool); + if (valuetype == "vehicles") + { + ui->leftAdvancedLayout->addWidget(box); + } + else if (valuetype == "libraries") + { + ui->rightAdvancedLayout->addWidget(box); + } + box->hide(); + toolToBoxMap[tool] = box;*/ + } + + + + + } + xml.readNext(); + } + + } + + xml.readNext(); + } + } + xml.readNext(); + } + } diff --git a/src/ui/configuration/ApmSoftwareConfig.ui b/src/ui/configuration/ApmSoftwareConfig.ui index ab26e10fbe..e6fc845632 100644 --- a/src/ui/configuration/ApmSoftwareConfig.ui +++ b/src/ui/configuration/ApmSoftwareConfig.ui @@ -6,221 +6,210 @@ 0 0 - 718 - 531 + 853 + 619 Form - - - - 20 - 10 - 175 - 531 - - - - - 175 - 0 - - - - - 175 - 16777215 - - - - true - - - - - 0 - 0 - 173 - 529 - - - - - - - QLayout::SetMinAndMaxSize - + + + + + + 175 + 0 + + + + + 175 + 16777215 + + + + true + + + + + 0 + 0 + 173 + 599 + + + - - - - 100 - 35 - - - - APM Planner 2.0 Config - - - - - - - - 0 - 35 - - - - Basic Pids - - - false - - - - - - - - 0 - 35 - - - - Flight Modes - - - false - - - - - - - - 0 - 35 - - - - Standard Params - - - false - - - - - - - - 0 - 35 - - - - GeoFence - - - false - - - - - - - - 0 - 35 - - - - FailSafe - - - false - - - - - - - - 0 - 35 - - - - Advanced Params - - - false - - - - - - - - 0 - 35 - - - - Adv Parameter List - - - false - - - - - - - - 0 - 35 - - - - ArduCoper Pids - - - false - - - - - - - Qt::Vertical - - - - 20 - 40 - - - + + + QLayout::SetMinAndMaxSize + + + + + + 100 + 35 + + + + APM Planner 2.0 Config + + + + + + + + 0 + 35 + + + + Basic Pids + + + false + + + + + + + + 0 + 35 + + + + Flight Modes + + + false + + + + + + + + 0 + 35 + + + + Standard Params + + + false + + + + + + + + 0 + 35 + + + + GeoFence + + + false + + + + + + + + 0 + 35 + + + + FailSafe + + + false + + + + + + + + 0 + 35 + + + + Advanced Params + + + false + + + + + + + + 0 + 35 + + + + Adv Parameter List + + + false + + + + + + + + 0 + 35 + + + + ArduCoper Pids + + + false + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + - - - - - - - - 220 - 20 - 471 - 491 - - - + + + + + + + diff --git a/src/ui/configuration/StandardParamConfig.cc b/src/ui/configuration/StandardParamConfig.cc index d67891bbfb..0be1d02f22 100644 --- a/src/ui/configuration/StandardParamConfig.cc +++ b/src/ui/configuration/StandardParamConfig.cc @@ -1,11 +1,40 @@ #include "StandardParamConfig.h" +#include "ParamWidget.h" +StandardParamConfig::StandardParamConfig(QWidget *parent) : AP2ConfigWidget(parent) +{ + ui.setupUi(this); +} +StandardParamConfig::~StandardParamConfig() +{ +} -StandardParamConfig::StandardParamConfig(QWidget *parent) : QWidget(parent) +void StandardParamConfig::activeUASSet(UASInterface *uas) { - ui.setupUi(this); + + AP2ConfigWidget::activeUASSet(uas); +} +void StandardParamConfig::addRange(QString title,QString description,QString param,double min,double max) +{ + ParamWidget *widget = new ParamWidget(ui.scrollAreaWidgetContents); + paramToWidgetMap[param] = widget; + widget->setupDouble(title + "(" + param + ")",description,0,min,max); + ui.verticalLayout->addWidget(widget); + widget->show(); } -StandardParamConfig::~StandardParamConfig() +void StandardParamConfig::addCombo(QString title,QString description,QString param,QList > valuelist) +{ + ParamWidget *widget = new ParamWidget(ui.scrollAreaWidgetContents); + paramToWidgetMap[param] = widget; + widget->setupCombo(title + "(" + param + ")",description,valuelist); + ui.verticalLayout->addWidget(widget); + widget->show(); +} +void StandardParamConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { + if (paramToWidgetMap.contains(parameterName)) + { + paramToWidgetMap[parameterName]->setValue(value.toDouble()); + } } diff --git a/src/ui/configuration/StandardParamConfig.h b/src/ui/configuration/StandardParamConfig.h index 9e43a9bd99..d337b9b4f2 100644 --- a/src/ui/configuration/StandardParamConfig.h +++ b/src/ui/configuration/StandardParamConfig.h @@ -3,16 +3,22 @@ #include #include "ui_StandardParamConfig.h" - -class StandardParamConfig : public QWidget +#include "AP2ConfigWidget.h" +#include "ParamWidget.h" +class StandardParamConfig : public AP2ConfigWidget { Q_OBJECT public: explicit StandardParamConfig(QWidget *parent = 0); ~StandardParamConfig(); - + void addRange(QString title,QString description,QString param,double min,double max); + void addCombo(QString title,QString description,QString param,QList > valuelist); +private slots: + void parameterChanged(int uas, int component, QString parameterName, QVariant value); private: + QMap paramToWidgetMap; + void activeUASSet(UASInterface *uas); Ui::StandardParamConfig ui; }; diff --git a/src/ui/configuration/StandardParamConfig.ui b/src/ui/configuration/StandardParamConfig.ui index cdbb320c0e..53a96d9847 100644 --- a/src/ui/configuration/StandardParamConfig.ui +++ b/src/ui/configuration/StandardParamConfig.ui @@ -6,26 +6,44 @@ 0 0 - 400 - 300 + 651 + 552 Form - - - - 20 - 20 - 201 - 41 - - - - <h2>Standard Params</h2> - - + + + + + <h2>Standard Params</h2> + + + + + + + true + + + + + 0 + 0 + 631 + 505 + + + + + + + + + + + -- GitLab From 0c45b7f0917319224c47a587d5b20d02e43d1944 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 9 Jul 2013 17:49:05 -0400 Subject: [PATCH 046/460] Initial implementation of FailSafe configuration --- src/ui/configuration/FailSafeConfig.cc | 225 ++++++++++++- src/ui/configuration/FailSafeConfig.h | 11 +- src/ui/configuration/FailSafeConfig.ui | 424 ++++++++++++++++++++++++- 3 files changed, 654 insertions(+), 6 deletions(-) diff --git a/src/ui/configuration/FailSafeConfig.cc b/src/ui/configuration/FailSafeConfig.cc index 5f7ff81b06..fe3199ba8b 100644 --- a/src/ui/configuration/FailSafeConfig.cc +++ b/src/ui/configuration/FailSafeConfig.cc @@ -1,11 +1,234 @@ #include "FailSafeConfig.h" -FailSafeConfig::FailSafeConfig(QWidget *parent) : QWidget(parent) +FailSafeConfig::FailSafeConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); + ui.radio1In->setName("Radio 1"); + ui.radio1In->setMin(800); + ui.radio1In->setMax(2200); + ui.radio1In->setOrientation(Qt::Horizontal); + ui.radio2In->setName("Radio 2"); + ui.radio2In->setMin(800); + ui.radio2In->setMax(2200); + ui.radio2In->setOrientation(Qt::Horizontal); + ui.radio3In->setName("Radio 3"); + ui.radio3In->setMin(800); + ui.radio3In->setMax(2200); + ui.radio3In->setOrientation(Qt::Horizontal); + ui.radio4In->setName("Radio 4"); + ui.radio4In->setMin(800); + ui.radio4In->setMax(2200); + ui.radio4In->setOrientation(Qt::Horizontal); + ui.radio5In->setName("Radio 5"); + ui.radio5In->setMin(800); + ui.radio5In->setMax(2200); + ui.radio5In->setOrientation(Qt::Horizontal); + ui.radio6In->setName("Radio 6"); + ui.radio6In->setMin(800); + ui.radio6In->setMax(2200); + ui.radio6In->setOrientation(Qt::Horizontal); + ui.radio7In->setName("Radio 7"); + ui.radio7In->setMin(800); + ui.radio7In->setMax(2200); + ui.radio7In->setOrientation(Qt::Horizontal); + ui.radio8In->setName("Radio 8"); + ui.radio8In->setMin(800); + ui.radio8In->setMax(2200); + ui.radio8In->setOrientation(Qt::Horizontal); + + ui.radio1Out->setName("Radio 1"); + ui.radio1Out->setMin(800); + ui.radio1Out->setMax(2200); + ui.radio1Out->setOrientation(Qt::Horizontal); + ui.radio2Out->setName("Radio 2"); + ui.radio2Out->setMin(800); + ui.radio2Out->setMax(2200); + ui.radio2Out->setOrientation(Qt::Horizontal); + ui.radio3Out->setName("Radio 3"); + ui.radio3Out->setMin(800); + ui.radio3Out->setMax(2200); + ui.radio3Out->setOrientation(Qt::Horizontal); + ui.radio4Out->setName("Radio 4"); + ui.radio4Out->setMin(800); + ui.radio4Out->setMax(2200); + ui.radio4Out->setOrientation(Qt::Horizontal); + ui.radio5Out->setName("Radio 5"); + ui.radio5Out->setMin(800); + ui.radio5Out->setMax(2200); + ui.radio5Out->setOrientation(Qt::Horizontal); + ui.radio6Out->setName("Radio 6"); + ui.radio6Out->setMin(800); + ui.radio6Out->setMax(2200); + ui.radio6Out->setOrientation(Qt::Horizontal); + ui.radio7Out->setName("Radio 7"); + ui.radio7Out->setMin(800); + ui.radio7Out->setMax(2200); + ui.radio7Out->setOrientation(Qt::Horizontal); + ui.radio8Out->setName("Radio 8"); + ui.radio8Out->setMin(800); + ui.radio8Out->setMax(2200); + ui.radio8Out->setOrientation(Qt::Horizontal); + + ui.throttleFailSafeComboBox->addItem("Disable"); + ui.throttleFailSafeComboBox->addItem("Enabled - Always TRL"); + ui.throttleFailSafeComboBox->addItem("Enabled - Continue in auto"); } FailSafeConfig::~FailSafeConfig() { } +void FailSafeConfig::activeUASSet(UASInterface *uas) +{ + AP2ConfigWidget::activeUASSet(uas); + connect(uas,SIGNAL(remoteControlChannelRawChanged(int,float)),this,SLOT(remoteControlChannelRawChanges(int,float))); + connect(uas,SIGNAL(hilActuatorsChanged(uint64_t,float,float,float,float,float,float,float,float)),this,SLOT(hilActuatorsChanged(uint64_t,float,float,float,float,float,float,float,float))); + connect(uas,SIGNAL(armingChanged(bool)),this,SLOT(armingChanged(bool))); +} +void FailSafeConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + //Arducopter + if (parameterName == "FS_THR_ENABLE") + { + ui.throttleFailSafeComboBox->setCurrentIndex(value.toInt()); + } + else if (parameterName == "FS_THR_VALUE") + { + ui.throttlePwmSpinBox->setValue(value.toFloat()); + } + else if (parameterName == "FS_BATT_ENABLE") + { + if (value.toInt() == 0) + { + ui.batteryFailCheckBox->setChecked(false); + } + else + { + ui.batteryFailCheckBox->setChecked(true); + } + } + else if (parameterName == "LOW_VOLT") + { + ui.batteryVoltSpinBox->setValue(value.toFloat()); + } + //Arduplane + else if (parameterName == "THR_FAILSAFE") + { + if (value.toInt() == 0) + { + ui.throttleCheckBox->setChecked(false); + } + else + { + ui.throttleCheckBox->setChecked(true); + } + } + else if (parameterName == "THR_FS_VALUE") + { + ui.throttlePwmSpinBox->setValue(value.toFloat()); + } + else if (parameterName == "THR_FS_ACTION") + { + if (value.toInt() == 0) + { + ui.throttleActionCheckBox->setChecked(false); + } + else + { + ui.throttleActionCheckBox->setChecked(true); + } + } + else if (parameterName == "FS_GCS_ENABL") + { + if (value.toInt() == 0) + { + ui.gcsCheckBox->setChecked(false); + } + else + { + ui.gcsCheckBox->setChecked(true); + } + } + else if (parameterName == "FS_SHORT_ACTN") + { + if (value.toInt() == 0) + { + ui.fsShortCheckBox->setChecked(false); + } + else + { + ui.fsShortCheckBox->setChecked(true); + } + } + else if (parameterName == "FS_LONG_ACTN") + { + if (value.toInt() == 0) + { + ui.fsLongCheckBox->setChecked(false); + } + else + { + ui.fsLongCheckBox->setChecked(true); + } + } + +} + +void FailSafeConfig::armingChanged(bool armed) +{ + if (armed) + { + ui.armedLabel->setText("

ARMED

"); + } + else + { + ui.armedLabel->setText("

DISARMED

"); + } +} + +void FailSafeConfig::remoteControlChannelRawChanges(int chan,float value) +{ + if (chan == 0) + { + ui.radio1In->setValue(value); + } + else if (chan == 1) + { + ui.radio2In->setValue(value); + } + else if (chan == 2) + { + ui.radio3In->setValue(value); + } + else if (chan == 3) + { + ui.radio4In->setValue(value); + } + else if (chan == 4) + { + ui.radio5In->setValue(value); + } + else if (chan == 5) + { + ui.radio6In->setValue(value); + } + else if (chan == 6) + { + ui.radio7In->setValue(value); + } + else if (chan == 7) + { + ui.radio8In->setValue(value); + } +} +void FailSafeConfig::hilActuatorsChanged(uint64_t time, float act1, float act2, float act3, float act4, float act5, float act6, float act7, float act8) +{ + ui.radio1Out->setValue(act1); + ui.radio2Out->setValue(act2); + ui.radio3Out->setValue(act3); + ui.radio4Out->setValue(act4); + ui.radio5Out->setValue(act5); + ui.radio6Out->setValue(act6); + ui.radio7Out->setValue(act7); + ui.radio8Out->setValue(act8); +} diff --git a/src/ui/configuration/FailSafeConfig.h b/src/ui/configuration/FailSafeConfig.h index a22e96493e..83085fb172 100644 --- a/src/ui/configuration/FailSafeConfig.h +++ b/src/ui/configuration/FailSafeConfig.h @@ -3,15 +3,20 @@ #include #include "ui_FailSafeConfig.h" - -class FailSafeConfig : public QWidget +#include "AP2ConfigWidget.h" +class FailSafeConfig : public AP2ConfigWidget { Q_OBJECT public: explicit FailSafeConfig(QWidget *parent = 0); ~FailSafeConfig(); - +private slots: + void activeUASSet(UASInterface *uas); + void remoteControlChannelRawChanges(int chan,float value); + void hilActuatorsChanged(uint64_t time, float act1, float act2, float act3, float act4, float act5, float act6, float act7, float act8); + void armingChanged(bool armed); + void parameterChanged(int uas, int component, QString parameterName, QVariant value); private: Ui::FailSafeConfig ui; }; diff --git a/src/ui/configuration/FailSafeConfig.ui b/src/ui/configuration/FailSafeConfig.ui index fe4eef1cb8..69375dd535 100644 --- a/src/ui/configuration/FailSafeConfig.ui +++ b/src/ui/configuration/FailSafeConfig.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 300 + 822 + 536 @@ -26,7 +26,427 @@ <h2>Fail Safe</h2> + + + + 20 + 70 + 252 + 441 + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + + 300 + 70 + 252 + 441 + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + + 570 + 60 + 181 + 181 + + + + Status + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + + + 570 + 250 + 161 + 261 + + + + Failsafe Options + + + + + + Throttle FailSafe + + + + + + + + + + + + FS Pwm + + + + + + + 3000 + + + + + + + + + Throttle FailSafe Action + + + + + + + GCS FailSafe + + + + + + + FailSafe Short (1 sec) + + + + + + + FailSafe Long (20 sec) + + + + + + + Battery Failsafe + + + + + + + + + Low Battery + + + + + + + 100.000000000000000 + + + + + + + + + + QGCRadioChannelDisplay + QWidget +
ui/designer/QGCRadioChannelDisplay.h
+ 1 +
+
-- GitLab From a1eda05fa3134f73490086f5aad598d66db0baa1 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 10 Jul 2013 09:24:35 -0400 Subject: [PATCH 047/460] More implementation of FailSafe configuration --- src/ui/configuration/FailSafeConfig.cc | 166 +++++++++++++++++++++++++ src/ui/configuration/FailSafeConfig.h | 8 ++ 2 files changed, 174 insertions(+) diff --git a/src/ui/configuration/FailSafeConfig.cc b/src/ui/configuration/FailSafeConfig.cc index fe3199ba8b..2517a322ca 100644 --- a/src/ui/configuration/FailSafeConfig.cc +++ b/src/ui/configuration/FailSafeConfig.cc @@ -73,6 +73,128 @@ FailSafeConfig::FailSafeConfig(QWidget *parent) : AP2ConfigWidget(parent) ui.throttleFailSafeComboBox->addItem("Disable"); ui.throttleFailSafeComboBox->addItem("Enabled - Always TRL"); ui.throttleFailSafeComboBox->addItem("Enabled - Continue in auto"); + + connect(ui.batteryFailCheckBox,SIGNAL(clicked(bool)),this,SLOT(batteryFailChecked(bool))); + connect(ui.fsLongCheckBox,SIGNAL(clicked(bool)),this,SLOT(fsLongClicked(bool))); + connect(ui.fsShortCheckBox,SIGNAL(clicked(bool)),this,SLOT(fsShortClicked(bool))); + connect(ui.gcsCheckBox,SIGNAL(clicked(bool)),this,SLOT(gcsChecked(bool))); + connect(ui.throttleActionCheckBox,SIGNAL(clicked(bool)),this,SLOT(throttleActionChecked(bool))); + connect(ui.throttleCheckBox,SIGNAL(clicked(bool)),this,SLOT(throttleChecked(bool))); + connect(ui.throttlePwmSpinBox,SIGNAL(editingFinished()),this,SLOT(throttlePwmChanged())); + connect(ui.throttleFailSafeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(throttleFailSafeChanged(int))); +} +void FailSafeConfig::gcsChecked(bool checked) +{ + if (!m_uas) + { + return; + } + if (checked) + { + m_uas->setParameter(1,"FS_GCS_ENABL",1); + } + else + { + m_uas->setParameter(1,"FS_GCS_ENABL",0); + } +} + +void FailSafeConfig::throttleActionChecked(bool checked) +{ + if (!m_uas) + { + return; + } + if (checked) + { + m_uas->setParameter(1,"THR_FS_ACTION",1); + } + else + { + m_uas->setParameter(1,"THR_FS_ACTION",0); + } +} + +void FailSafeConfig::throttleChecked(bool checked) +{ + if (!m_uas) + { + return; + } + if (checked) + { + m_uas->setParameter(1,"THR_FAILSAFE",1); + } + else + { + m_uas->setParameter(1,"THR_FAILSAFE",0); + } +} + +void FailSafeConfig::throttlePwmChanged() +{ + if (!m_uas) + { + return; + } + m_uas->setParameter(1,"THR_FS_VALUE",ui.throttlePwmSpinBox->value()); +} + +void FailSafeConfig::throttleFailSafeChanged(int index) +{ + if (!m_uas) + { + return; + } + m_uas->setParameter(1,"FS_THR_ENABLE",index); +} + +void FailSafeConfig::fsLongClicked(bool checked) +{ + if (!m_uas) + { + return; + } + if (checked) + { + m_uas->setParameter(1,"FS_LONG_ACTN",1); + } + else + { + m_uas->setParameter(1,"FS_LONG_ACTN",0); + } +} + +void FailSafeConfig::fsShortClicked(bool checked) +{ + if (!m_uas) + { + return; + } + if (checked) + { + m_uas->setParameter(1,"FS_SHORT_ACTN",1); + } + else + { + m_uas->setParameter(1,"FS_SHORT_ACTN",0); + } +} + +void FailSafeConfig::batteryFailChecked(bool checked) +{ + if (!m_uas) + { + return; + } + if (checked) + { + m_uas->setParameter(1,"FS_BATT_ENABLE",1); + } + else + { + m_uas->setParameter(1,"FS_BATT_ENABLE",0); + } } FailSafeConfig::~FailSafeConfig() @@ -84,6 +206,50 @@ void FailSafeConfig::activeUASSet(UASInterface *uas) connect(uas,SIGNAL(remoteControlChannelRawChanged(int,float)),this,SLOT(remoteControlChannelRawChanges(int,float))); connect(uas,SIGNAL(hilActuatorsChanged(uint64_t,float,float,float,float,float,float,float,float)),this,SLOT(hilActuatorsChanged(uint64_t,float,float,float,float,float,float,float,float))); connect(uas,SIGNAL(armingChanged(bool)),this,SLOT(armingChanged(bool))); + if (uas->getSystemType() == MAV_TYPE_FIXED_WING) + { + ui.batteryFailCheckBox->setVisible(false); + ui.throttleFailSafeComboBox->setVisible(false); + ui.batteryVoltSpinBox->setVisible(false); + ui.label_6->setVisible(false); + + ui.throttlePwmSpinBox->setVisible(true); //Both + + ui.throttleCheckBox->setVisible(true); + ui.throttleActionCheckBox->setVisible(true); + ui.gcsCheckBox->setVisible(true); + ui.fsLongCheckBox->setVisible(true); + ui.fsShortCheckBox->setVisible(true); + } + else if (uas->getSystemType() == MAV_TYPE_QUADROTOR) + { + ui.batteryFailCheckBox->setVisible(true); + ui.throttleFailSafeComboBox->setVisible(true); + ui.batteryVoltSpinBox->setVisible(true); + ui.label_6->setVisible(true); + + ui.throttlePwmSpinBox->setVisible(true); //Both + + ui.throttleCheckBox->setVisible(false); + ui.throttleActionCheckBox->setVisible(false); + ui.gcsCheckBox->setVisible(false); + ui.fsLongCheckBox->setVisible(false); + ui.fsShortCheckBox->setVisible(false); + } + else + { + //Show all, just in case + ui.batteryFailCheckBox->setVisible(true); + ui.throttleFailSafeComboBox->setVisible(true); + ui.batteryVoltSpinBox->setVisible(true); + ui.throttlePwmSpinBox->setVisible(true); //Both + ui.throttleCheckBox->setVisible(true); + ui.throttleActionCheckBox->setVisible(true); + ui.gcsCheckBox->setVisible(true); + ui.fsLongCheckBox->setVisible(true); + ui.fsShortCheckBox->setVisible(true); + } + } void FailSafeConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { diff --git a/src/ui/configuration/FailSafeConfig.h b/src/ui/configuration/FailSafeConfig.h index 83085fb172..162246e899 100644 --- a/src/ui/configuration/FailSafeConfig.h +++ b/src/ui/configuration/FailSafeConfig.h @@ -17,6 +17,14 @@ private slots: void hilActuatorsChanged(uint64_t time, float act1, float act2, float act3, float act4, float act5, float act6, float act7, float act8); void armingChanged(bool armed); void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void batteryFailChecked(bool checked); + void fsLongClicked(bool checked); + void fsShortClicked(bool checked); + void gcsChecked(bool checked); + void throttleActionChecked(bool checked); + void throttleChecked(bool checked); + void throttlePwmChanged(); + void throttleFailSafeChanged(int index); private: Ui::FailSafeConfig ui; }; -- GitLab From f7ec760794c09ce3d14ef20622684f1393423204 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 10 Jul 2013 12:09:38 -0400 Subject: [PATCH 048/460] ArduPlane pid screen visuals --- qgroundcontrol.pro | 9 +- src/ui/configuration/ApmSoftwareConfig.cc | 8 +- src/ui/configuration/ArduCopterPidConfig.cc | 8 +- src/ui/configuration/ArduCopterPidConfig.h | 9 +- src/ui/configuration/ArduPlanePidConfig.cc | 18 + src/ui/configuration/ArduPlanePidConfig.h | 21 + src/ui/configuration/ArduPlanePidConfig.ui | 957 ++++++++++++++++++++ 7 files changed, 1012 insertions(+), 18 deletions(-) create mode 100644 src/ui/configuration/ArduPlanePidConfig.cc create mode 100644 src/ui/configuration/ArduPlanePidConfig.h create mode 100644 src/ui/configuration/ArduPlanePidConfig.ui diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index edbfbe65d6..9032232290 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -258,7 +258,8 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/AdvancedParamConfig.ui \ src/ui/configuration/ArduCopterPidConfig.ui \ src/ui/configuration/ApmPlaneLevel.ui \ - src/ui/configuration/ParamWidget.ui + src/ui/configuration/ParamWidget.ui \ + src/ui/configuration/ArduPlanePidConfig.ui INCLUDEPATH += src \ src/ui \ src/ui/linechart \ @@ -441,7 +442,8 @@ HEADERS += src/MG.h \ src/ui/configuration/AdvancedParamConfig.h \ src/ui/configuration/ArduCopterPidConfig.h \ src/ui/configuration/ApmPlaneLevel.h \ - src/ui/configuration/ParamWidget.h + src/ui/configuration/ParamWidget.h \ + src/ui/configuration/ArduPlanePidConfig.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -642,7 +644,8 @@ SOURCES += src/main.cc \ src/ui/configuration/AdvancedParamConfig.cc \ src/ui/configuration/ArduCopterPidConfig.cc \ src/ui/configuration/ApmPlaneLevel.cc \ - src/ui/configuration/ParamWidget.cc + src/ui/configuration/ParamWidget.cc \ + src/ui/configuration/ArduPlanePidConfig.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/configuration/ApmSoftwareConfig.cc b/src/ui/configuration/ApmSoftwareConfig.cc index a8a2e4ddd8..c0010ad8e0 100644 --- a/src/ui/configuration/ApmSoftwareConfig.cc +++ b/src/ui/configuration/ApmSoftwareConfig.cc @@ -17,10 +17,10 @@ ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) ui.advParamListButton->setVisible(false); ui.arduCoperPidButton->setVisible(false); - basicPidConfig = new BasicPidConfig(this); + /*basicPidConfig = new BasicPidConfig(this); ui.stackedWidget->addWidget(basicPidConfig); buttonToConfigWidgetMap[ui.basicPidsButton] = basicPidConfig; - connect(ui.basicPidsButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + connect(ui.basicPidsButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget()));*/ flightConfig = new FlightModeConfig(this); ui.stackedWidget->addWidget(flightConfig); @@ -32,10 +32,10 @@ ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) buttonToConfigWidgetMap[ui.standardParamButton] = standardParamConfig; connect(ui.standardParamButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - geoFenceConfig = new GeoFenceConfig(this); + /*geoFenceConfig = new GeoFenceConfig(this); ui.stackedWidget->addWidget(geoFenceConfig); buttonToConfigWidgetMap[ui.geoFenceButton] = geoFenceConfig; - connect(ui.geoFenceButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + connect(ui.geoFenceButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget()));*/ failSafeConfig = new FailSafeConfig(this); ui.stackedWidget->addWidget(failSafeConfig); diff --git a/src/ui/configuration/ArduCopterPidConfig.cc b/src/ui/configuration/ArduCopterPidConfig.cc index 1674ae2362..0a1dfc69a1 100644 --- a/src/ui/configuration/ArduCopterPidConfig.cc +++ b/src/ui/configuration/ArduCopterPidConfig.cc @@ -1,14 +1,10 @@ #include "ArduCopterPidConfig.h" -#include "ui_ArduCopterPidConfig.h" -ArduCopterPidConfig::ArduCopterPidConfig(QWidget *parent) : - QWidget(parent), - ui(new Ui::ArduCopterPidConfig) +ArduCopterPidConfig::ArduCopterPidConfig(QWidget *parent) : AP2ConfigWidget(parent) { - ui->setupUi(this); + ui.setupUi(this); } ArduCopterPidConfig::~ArduCopterPidConfig() { - delete ui; } diff --git a/src/ui/configuration/ArduCopterPidConfig.h b/src/ui/configuration/ArduCopterPidConfig.h index 6f7eae7e85..339b8c4725 100644 --- a/src/ui/configuration/ArduCopterPidConfig.h +++ b/src/ui/configuration/ArduCopterPidConfig.h @@ -2,12 +2,11 @@ #define ARDUCOPTERPIDCONFIG_H #include +#include "ui_ArduCopterPidConfig.h" -namespace Ui { -class ArduCopterPidConfig; -} +#include "AP2ConfigWidget.h" -class ArduCopterPidConfig : public QWidget +class ArduCopterPidConfig : public AP2ConfigWidget { Q_OBJECT @@ -16,7 +15,7 @@ public: ~ArduCopterPidConfig(); private: - Ui::ArduCopterPidConfig *ui; + Ui::ArduCopterPidConfig ui; }; #endif // ARDUCOPTERPIDCONFIG_H diff --git a/src/ui/configuration/ArduPlanePidConfig.cc b/src/ui/configuration/ArduPlanePidConfig.cc new file mode 100644 index 0000000000..276a689b49 --- /dev/null +++ b/src/ui/configuration/ArduPlanePidConfig.cc @@ -0,0 +1,18 @@ +#include "ArduPlanePidConfig.h" + + +ArduPlanePidConfig::ArduPlanePidConfig(QWidget *parent) : AP2ConfigWidget(parent) +{ + ui.setupUi(this); +} + +ArduPlanePidConfig::~ArduPlanePidConfig() +{ +} +void ArduPlanePidconfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + if (parameterName == "") + { + + } +} diff --git a/src/ui/configuration/ArduPlanePidConfig.h b/src/ui/configuration/ArduPlanePidConfig.h new file mode 100644 index 0000000000..dcb75eef00 --- /dev/null +++ b/src/ui/configuration/ArduPlanePidConfig.h @@ -0,0 +1,21 @@ +#ifndef ARDUPLANEPIDCONFIG_H +#define ARDUPLANEPIDCONFIG_H + +#include +#include "ui_ArduPlanePidConfig.h" +#include "AP2ConfigWidget.h" + +class ArduPlanePidConfig : public AP2ConfigWidget +{ + Q_OBJECT + +public: + explicit ArduPlanePidConfig(QWidget *parent = 0); + ~ArduPlanePidConfig(); +private slots: + void parameterChanged(int uas, int component, QString parameterName, QVariant value); +private: + Ui::ArduPlanePidConfig ui; +}; + +#endif // ARDUPLANEPIDCONFIG_H diff --git a/src/ui/configuration/ArduPlanePidConfig.ui b/src/ui/configuration/ArduPlanePidConfig.ui new file mode 100644 index 0000000000..b1cb38fd2f --- /dev/null +++ b/src/ui/configuration/ArduPlanePidConfig.ui @@ -0,0 +1,957 @@ + + + ArduPlanePidConfig + + + + 0 + 0 + 733 + 641 + + + + Form + + + + + 20 + 10 + 681 + 581 + + + + + + + L1 Control - Turn Control + + + + + + + + + + Period + + + + + + + Damping + + + + + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Servo Roll Pid + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 100.000000000000000 + + + + + + + + + + + + + + Nav Pitch Alt Pid + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 100.000000000000000 + + + + + + + + + + + + + + Nav Pitch AS Pid + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 100.000000000000000 + + + + + + + + + + + + + + Servo Yaw Pid + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 100.000000000000000 + + + + + + + + + + + + + + Throttle 0-100% + + + + + + + + + + Cruise + + + + + + + Min + + + + + + + Max + + + + + + + FS Value + + + + + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 100.000000000000000 + + + + + + + + + + + + + + Servo Pitch Pid + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 100.000000000000000 + + + + + + + + + + + + + + Aiespeed m/s + + + + + + + + + + Cruise + + + + + + + FBW min + + + + + + + FBW max + + + + + + + Ratio + + + + + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 100.000000000000000 + + + + + + + + + + + + + + Other Mix's + + + + + + + + + + P to T + + + + + + + Pitch Comp + + + + + + + Rudder Mix + + + + + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + + + + + + + + Navigation Angles + + + + + + + + + + Bank Max + + + + + + + Pitch Max + + + + + + + Pitch Min + + + + + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + + + + + + + + Energy/Alt Pid + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 3 + + + 100.000000000000000 + + + + + + + 100.000000000000000 + + + + + + + + + + + + + + + + 260 + 600 + 75 + 23 + + + + Write Params + + + + + + 350 + 600 + 75 + 23 + + + + Refresh Params + + + + + + -- GitLab From 5796a5a84d72cc8e212dfb09479daa860991c962 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 10 Jul 2013 14:09:26 -0400 Subject: [PATCH 049/460] Implementation of ArduPlanePid configuration write/refresh, and value ranges --- src/ui/configuration/ApmSoftwareConfig.cc | 29 ++++++-- src/ui/configuration/ApmSoftwareConfig.h | 4 +- src/ui/configuration/ApmSoftwareConfig.ui | 17 ++++- src/ui/configuration/ArduPlanePidConfig.cc | 80 +++++++++++++++++++++- src/ui/configuration/ArduPlanePidConfig.h | 3 + src/ui/configuration/ArduPlanePidConfig.ui | 24 ++++--- 6 files changed, 137 insertions(+), 20 deletions(-) diff --git a/src/ui/configuration/ApmSoftwareConfig.cc b/src/ui/configuration/ApmSoftwareConfig.cc index c0010ad8e0..a12719cf74 100644 --- a/src/ui/configuration/ApmSoftwareConfig.cc +++ b/src/ui/configuration/ApmSoftwareConfig.cc @@ -15,7 +15,7 @@ ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) ui.failSafeButton->setVisible(false); ui.advancedParamButton->setVisible(false); ui.advParamListButton->setVisible(false); - ui.arduCoperPidButton->setVisible(false); + ui.arduCopterPidButton->setVisible(false); /*basicPidConfig = new BasicPidConfig(this); ui.stackedWidget->addWidget(basicPidConfig); @@ -47,10 +47,18 @@ ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) buttonToConfigWidgetMap[ui.advancedParamButton] = advancedParamConfig; connect(ui.advancedParamButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - arduCoperPidConfig = new ArduCopterPidConfig(this); - ui.stackedWidget->addWidget(arduCoperPidConfig); - buttonToConfigWidgetMap[ui.arduCoperPidButton] = arduCoperPidConfig; - connect(ui.arduCoperPidButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + arduCopterPidConfig = new ArduCopterPidConfig(this); + ui.stackedWidget->addWidget(arduCopterPidConfig); + buttonToConfigWidgetMap[ui.arduCopterPidButton] = arduCopterPidConfig; + connect(ui.arduCopterPidButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + + arduPlanePidConfig = new ArduPlanePidConfig(this); + ui.stackedWidget->addWidget(arduPlanePidConfig); + buttonToConfigWidgetMap[ui.arduPlanePidButton] = arduPlanePidConfig; + connect(ui.arduPlanePidButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); if (UASManager::instance()->getActiveUAS()) @@ -84,7 +92,16 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) ui.advancedParamButton->setVisible(true); ui.advParamListButton->setVisible(true); - ui.arduCoperPidButton->setVisible(true); + if (uas->getSystemType() == MAV_TYPE_FIXED_WING) + { + ui.arduPlanePidButton->setVisible(true); + ui.arduCopterPidButton->setVisible(false); + } + else if (uas->getSystemType() == MAV_TYPE_QUADROTOR) + { + ui.arduCopterPidButton->setVisible(true); + ui.arduPlanePidButton->setVisible(false); + } QDir autopilotdir(qApp->applicationDirPath() + "/files/" + uas->getAutopilotTypeName().toLower()); diff --git a/src/ui/configuration/ApmSoftwareConfig.h b/src/ui/configuration/ApmSoftwareConfig.h index c28d366b0e..d314450e25 100644 --- a/src/ui/configuration/ApmSoftwareConfig.h +++ b/src/ui/configuration/ApmSoftwareConfig.h @@ -10,6 +10,7 @@ #include "FailSafeConfig.h" #include "AdvancedParamConfig.h" #include "ArduCopterPidConfig.h" +#include "ArduPlanePidConfig.h" #include "UASInterface.h" #include "UASManager.h" @@ -32,7 +33,8 @@ private: GeoFenceConfig *geoFenceConfig; FailSafeConfig *failSafeConfig; AdvancedParamConfig *advancedParamConfig; - ArduCopterPidConfig *arduCoperPidConfig; + ArduCopterPidConfig *arduCopterPidConfig; + ArduPlanePidConfig *arduPlanePidConfig; QMap buttonToConfigWidgetMap; }; diff --git a/src/ui/configuration/ApmSoftwareConfig.ui b/src/ui/configuration/ApmSoftwareConfig.ui index e6fc845632..b25f61577e 100644 --- a/src/ui/configuration/ApmSoftwareConfig.ui +++ b/src/ui/configuration/ApmSoftwareConfig.ui @@ -172,7 +172,7 @@ - + 0 @@ -180,13 +180,26 @@ - ArduCoper Pids + ArduCopter Pids false + + + + + 0 + 35 + + + + ArduPlane Pids + + + diff --git a/src/ui/configuration/ArduPlanePidConfig.cc b/src/ui/configuration/ArduPlanePidConfig.cc index 276a689b49..ac6d4da28d 100644 --- a/src/ui/configuration/ArduPlanePidConfig.cc +++ b/src/ui/configuration/ArduPlanePidConfig.cc @@ -4,15 +4,91 @@ ArduPlanePidConfig::ArduPlanePidConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); + + nameToBoxMap["RLL2SRV_P"] = ui.servoRollPSpinBox; + nameToBoxMap["RLL2SRV_I"] = ui.servoRollISpinBox; + nameToBoxMap["RLL2SRV_D"] = ui.servoRollDSpinBox; + nameToBoxMap["RLL2SRV_IMAX"] = ui.servoRollIMAXSpinBox; + + nameToBoxMap["PTCH2SRV_P"] = ui.servoPitchPSpinBox; + nameToBoxMap["PTCH2SRV_I"] = ui.servoPitchISpinBox; + nameToBoxMap["PTCH2SRV_D"] = ui.servoPitchDSpinBox; + nameToBoxMap["PTCH2SRV_IMAX"] = ui.servoPitchIMAXSpinBox; + + nameToBoxMap["YW2SRV_P"] = ui.servoYawPSpinBox; + nameToBoxMap["YW2SRV_I"] = ui.servoYawISpinBox; + nameToBoxMap["YW2SRV_D"] = ui.servoYawDSpinBox; + nameToBoxMap["YW2SRV_IMAX"] = ui.servoYawIMAXSpinBox; + + nameToBoxMap["ALT2PTCH_P"] = ui.navAltPSpinBox; + nameToBoxMap["ALT2PTCH_I"] = ui.navAltISpinBox; + nameToBoxMap["ALT2PTCH_D"] = ui.navAltDSpinBox; + nameToBoxMap["ALT2PTCH_IMAX"] = ui.navAltIMAXSpinBox; + + nameToBoxMap["ARSP2PTCH_P"] = ui.navASPSpinBox; + nameToBoxMap["ARSP2PTCH_I"] = ui.navASISpinBox; + nameToBoxMap["ARSP2PTCH_D"] = ui.navASDSpinBox; + nameToBoxMap["ARSP2PTCH_IMAX"] = ui.navASIMAXSpinBox; + + nameToBoxMap["ENRGY2THR_P"] = ui.energyPSpinBox; + nameToBoxMap["ENRGY2THR_I"] = ui.energyISpinBox; + nameToBoxMap["ENRGY2THR_D"] = ui.energyDSpinBox; + nameToBoxMap["ENRGY2THR_IMAX"] = ui.energyIMAXSpinBox; + + nameToBoxMap["KFF_PTCH2THR"] = ui.otherPitchCompSpinBox; + nameToBoxMap["KFF_PTCHCOMP"] = ui.otherPtTSpinBox; + nameToBoxMap["KFF_RDDRMIX"] = ui.otherRudderMixSpinBox; + + nameToBoxMap["TRIM_THROTTLE"] = ui.throttleCruiseSpinBox; + nameToBoxMap["THR_FS_VALUE"] = ui.throttleFSSpinBox; + nameToBoxMap["THR_MAX"] = ui.throttleMaxSpinBox; + nameToBoxMap["THR_MIN"] = ui.throttleMinSpinBox; + + nameToBoxMap["TRIM_ARSPD_CM"] = ui.airspeedCruiseSpinBox; + nameToBoxMap["ARSPD_FBW_MAX"] = ui.airspeedFBWMaxSpinBox; + nameToBoxMap["ARSPD_FBW_MIN"] = ui.airspeedFBWMinSpinBox; + nameToBoxMap["ARSPD_RATIO"] = ui.airspeedRatioSpinBox; + + nameToBoxMap["NAVL1_DAMPING"] = ui.l1DampingSpinBox; + nameToBoxMap["NAVL1_PERIOD"] = ui.l1PeriodSpinBox; + + nameToBoxMap["LIM_ROLL_CD"] = ui.navBankMaxSpinBox; + nameToBoxMap["LIM_PITCH_MAX"] = ui.navPitchMaxSpinBox; + nameToBoxMap["LIM_PITCH_MIN"] = ui.navPitchMinSpinBox; + } ArduPlanePidConfig::~ArduPlanePidConfig() { } -void ArduPlanePidconfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +void ArduPlanePidConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { - if (parameterName == "") + if (nameToBoxMap.contains(parameterName)) { + nameToBoxMap[parameterName]->setValue(value.toDouble()); + } +} +void ArduPlanePidConfig::writeButtonClicked() +{ + if (!m_uas) + { + return; + } + for (QMap::const_iterator i=nameToBoxMap.constBegin();i!=nameToBoxMap.constEnd();i++) + { + m_uas->getParamManager()->setParameter(1,i.key(),i.value()->value()); + } +} +void ArduPlanePidConfig::refreshButtonClicked() +{ + if (!m_uas) + { + return; } + for (QMap::const_iterator i=nameToBoxMap.constBegin();i!=nameToBoxMap.constEnd();i++) + { + m_uas->getParamManager()->requestParameterUpdate(1,i.key()); + } + } diff --git a/src/ui/configuration/ArduPlanePidConfig.h b/src/ui/configuration/ArduPlanePidConfig.h index dcb75eef00..b0f12c4b8d 100644 --- a/src/ui/configuration/ArduPlanePidConfig.h +++ b/src/ui/configuration/ArduPlanePidConfig.h @@ -14,7 +14,10 @@ public: ~ArduPlanePidConfig(); private slots: void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void writeButtonClicked(); + void refreshButtonClicked(); private: + QMap nameToBoxMap; Ui::ArduPlanePidConfig ui; }; diff --git a/src/ui/configuration/ArduPlanePidConfig.ui b/src/ui/configuration/ArduPlanePidConfig.ui index b1cb38fd2f..4ee4c406b1 100644 --- a/src/ui/configuration/ArduPlanePidConfig.ui +++ b/src/ui/configuration/ArduPlanePidConfig.ui @@ -164,9 +164,9 @@ - + - 100.000000000000000 + 10000.000000000000000 @@ -252,7 +252,7 @@ - 100.000000000000000 + 10000.000000000000000 @@ -338,7 +338,7 @@ - 100.000000000000000 + 10000.000000000000000 @@ -424,7 +424,7 @@ - 100.000000000000000 + 10000.000000000000000 @@ -510,7 +510,7 @@ - 100.000000000000000 + 10000.000000000000000 @@ -596,7 +596,7 @@ - 100.000000000000000 + 10000.000000000000000 @@ -815,8 +815,11 @@ 3 + + -10000.000000000000000 + - 100.000000000000000 + 10000.000000000000000 @@ -826,7 +829,10 @@ 3 - 100.000000000000000 + 10000.000000000000000 + + + 0.000000000000000 -- GitLab From 1bf19f54675d20fd779c047c43ff3a3f5fd48e67 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 10 Jul 2013 17:01:10 -0400 Subject: [PATCH 050/460] Implementation of ArduCoptor configuration screen --- src/ui/configuration/ArduCopterPidConfig.cc | 76 ++ src/ui/configuration/ArduCopterPidConfig.h | 6 +- src/ui/configuration/ArduCopterPidConfig.ui | 1033 ++++++++++++++++++- 3 files changed, 1112 insertions(+), 3 deletions(-) diff --git a/src/ui/configuration/ArduCopterPidConfig.cc b/src/ui/configuration/ArduCopterPidConfig.cc index 0a1dfc69a1..e6e0498fbf 100644 --- a/src/ui/configuration/ArduCopterPidConfig.cc +++ b/src/ui/configuration/ArduCopterPidConfig.cc @@ -3,8 +3,84 @@ ArduCopterPidConfig::ArduCopterPidConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); + nameToBoxMap["STB_RLL_P"] = ui.stabilPitchPSpinBox; + nameToBoxMap["STB_PIT_P"] = ui.stabilRollPSpinBox; + nameToBoxMap["STB_YAW_P"] = ui.stabilYawPSpinBox; + nameToBoxMap["HLD_LAT_P"] = ui.loiterPidPSpinBox; + + nameToBoxMap["RATE_RLL_P"] = ui.rateRollPSpinBox; + nameToBoxMap["RATE_RLL_I"] = ui.rateRollISpinBox; + nameToBoxMap["RATE_RLL_D"] = ui.rateRollDSpinBox; + nameToBoxMap["RATE_RLL_IMAX"] = ui.rateRollIMAXSpinBox; + + nameToBoxMap["RATE_PIT_P"] = ui.ratePitchPSpinBox; + nameToBoxMap["RATE_PIT_I"] = ui.ratePitchISpinBox; + nameToBoxMap["RATE_PIT_D"] = ui.ratePitchDSpinBox; + nameToBoxMap["RATE_PIT_IMAX"] = ui.ratePitchIMAXSpinBox; + + nameToBoxMap["RATE_YAW_P"] = ui.rateYawPSpinBox; + nameToBoxMap["RATE_YAW_I"] = ui.rateYawISpinBox; + nameToBoxMap["RATE_YAW_D"] = ui.rateYawDSpinBox; + nameToBoxMap["RATE_YAW_IMAX"] = ui.rateYawIMAXSpinBox; + + nameToBoxMap["LOITER_LAT_P"] = ui.rateLoiterPSpinBox; + nameToBoxMap["LOITER_LAT_I"] = ui.rateLoiterISpinBox; + nameToBoxMap["LOITER_LAT_D"] = ui.rateLoiterDSpinBox; + nameToBoxMap["LOITER_LAT_IMAX"] = ui.rateLoiterIMAXSpinBox; + + nameToBoxMap["THR_ACCEL_P"] = ui.throttleAccelPSpinBox; + nameToBoxMap["THR_ACCEL_I"] = ui.throttleAccelISpinBox; + nameToBoxMap["THR_ACCEL_D"] = ui.throttleAccelDSpinBox; + nameToBoxMap["THR_ACCEL_IMAX"] = ui.throttleAccelIMAXSpinBox; + + nameToBoxMap["THR_RATE_P"] = ui.throttleRatePSpinBox; + nameToBoxMap["THR_RATE_D"] = ui.throttleDateDSpinBox; + + nameToBoxMap["THR_ALT_P"] = ui.altitudeHoldPSpinBox; + + nameToBoxMap["WPNAV_SPEED"] = ui.wpNavLoiterSpeedSpinBox; + nameToBoxMap["WPNAV_RADIUS"] = ui.wpNavRadiusSpinBox; + nameToBoxMap["WPNAV_SPEED_DN"] = ui.wpNavSpeedDownSpinBox; + nameToBoxMap["WPNAV_LOIT_SPEED"] = ui.wpNavSpeedSpinBox; + nameToBoxMap["WPNAV_SPEED_UP"] = ui.wpNavSpeedUpSpinBox; + + nameToBoxMap["TUNE_HIGH"] = ui.ch6MaxSpinBox; + nameToBoxMap["TUNE_LOW"] = ui.ch6MinSpinBox; + + connect(ui.writePushButton,SIGNAL(clicked()),this,SLOT(writeButtonClicked())); + connect(ui.refreshPushButton,SIGNAL(clicked()),this,SLOT(refreshButtonClicked())); } ArduCopterPidConfig::~ArduCopterPidConfig() { } +void ArduCopterPidConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + if (nameToBoxMap.contains(parameterName)) + { + nameToBoxMap[parameterName]->setValue(value.toDouble()); + } +} +void ArduCopterPidConfig::writeButtonClicked() +{ + if (!m_uas) + { + return; + } + for (QMap::const_iterator i=nameToBoxMap.constBegin();i!=nameToBoxMap.constEnd();i++) + { + m_uas->getParamManager()->setParameter(1,i.key(),i.value()->value()); + } +} + +void ArduCopterPidConfig::refreshButtonClicked() +{ + if (!m_uas) + { + return; + } + for (QMap::const_iterator i=nameToBoxMap.constBegin();i!=nameToBoxMap.constEnd();i++) + { + m_uas->getParamManager()->requestParameterUpdate(1,i.key()); + } +} diff --git a/src/ui/configuration/ArduCopterPidConfig.h b/src/ui/configuration/ArduCopterPidConfig.h index 339b8c4725..b7b2b07354 100644 --- a/src/ui/configuration/ArduCopterPidConfig.h +++ b/src/ui/configuration/ArduCopterPidConfig.h @@ -13,8 +13,12 @@ class ArduCopterPidConfig : public AP2ConfigWidget public: explicit ArduCopterPidConfig(QWidget *parent = 0); ~ArduCopterPidConfig(); - +private slots: + void writeButtonClicked(); + void refreshButtonClicked(); + void parameterChanged(int uas, int component, QString parameterName, QVariant value); private: + QMap nameToBoxMap; Ui::ArduCopterPidConfig ui; }; diff --git a/src/ui/configuration/ArduCopterPidConfig.ui b/src/ui/configuration/ArduCopterPidConfig.ui index a472f6a8f7..351ce51ed2 100644 --- a/src/ui/configuration/ArduCopterPidConfig.ui +++ b/src/ui/configuration/ArduCopterPidConfig.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 300 + 750 + 596 @@ -26,6 +26,1035 @@ <h2>ArduCopter Pids</h2> + + + + 120 + 540 + 75 + 23 + + + + Write Params + + + + + + 220 + 540 + 91 + 23 + + + + Refresh Params + + + + + + 10 + 70 + 695 + 401 + + + + + + + Rate Yaw + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + Loiter PID + + + + + + + + + + P + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + Rate Pitch + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + Stabilize Roll + + + + + + + + + + P + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + Stabilize Pitch + + + + + + + + + + P + + + + + + + + + + + 3 + + + 100.000000000000000 + + + + + + + + + + + + + + Rate Roll + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + Altitude Hold + + + + + + + + + + P + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + Stabilize Yaw + + + + + + + + + + P + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + Rate Loiter + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + Lock Pitch and Roll Values + + + + + + + + + + + Ch6 Opt + + + + + + + + + + + + + + Min + + + + + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + Max + + + + + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + Ch7 Opt + + + + + + + + + + + + + + Ch8 Opt + + + + + + + + + + + + + + Throttle Accel + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Throttle Rate + + + + + + + + + + P + + + + + + + D + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + WPNav (cm's) + + + + + + + + + + Speed + + + + + + + Radius + + + + + + + Speed Up + + + + + + + speed Down + + + + + + + Loiter Speed + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + -- GitLab From 9e10b726e9c5095ae279bcd7af34bdb2b0de25d9 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 10 Jul 2013 18:50:03 -0400 Subject: [PATCH 051/460] Implementation of Advanced Parameter List, with descriptions and names from the XML file --- qgroundcontrol.pro | 9 ++-- src/ui/configuration/AdvParameterList.cc | 55 +++++++++++++++++++++++ src/ui/configuration/AdvParameterList.h | 25 +++++++++++ src/ui/configuration/AdvParameterList.ui | 31 +++++++++++++ src/ui/configuration/ApmSoftwareConfig.cc | 7 +++ src/ui/configuration/ApmSoftwareConfig.h | 3 +- 6 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 src/ui/configuration/AdvParameterList.cc create mode 100644 src/ui/configuration/AdvParameterList.h create mode 100644 src/ui/configuration/AdvParameterList.ui diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 9032232290..be5811b24d 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -259,7 +259,8 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/ArduCopterPidConfig.ui \ src/ui/configuration/ApmPlaneLevel.ui \ src/ui/configuration/ParamWidget.ui \ - src/ui/configuration/ArduPlanePidConfig.ui + src/ui/configuration/ArduPlanePidConfig.ui \ + src/ui/configuration/AdvParameterList.ui INCLUDEPATH += src \ src/ui \ src/ui/linechart \ @@ -443,7 +444,8 @@ HEADERS += src/MG.h \ src/ui/configuration/ArduCopterPidConfig.h \ src/ui/configuration/ApmPlaneLevel.h \ src/ui/configuration/ParamWidget.h \ - src/ui/configuration/ArduPlanePidConfig.h + src/ui/configuration/ArduPlanePidConfig.h \ + src/ui/configuration/AdvParameterList.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -645,7 +647,8 @@ SOURCES += src/main.cc \ src/ui/configuration/ArduCopterPidConfig.cc \ src/ui/configuration/ApmPlaneLevel.cc \ src/ui/configuration/ParamWidget.cc \ - src/ui/configuration/ArduPlanePidConfig.cc + src/ui/configuration/ArduPlanePidConfig.cc \ + src/ui/configuration/AdvParameterList.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/configuration/AdvParameterList.cc b/src/ui/configuration/AdvParameterList.cc new file mode 100644 index 0000000000..5dccd07079 --- /dev/null +++ b/src/ui/configuration/AdvParameterList.cc @@ -0,0 +1,55 @@ +#include "AdvParameterList.h" + + +AdvParameterList::AdvParameterList(QWidget *parent) : AP2ConfigWidget(parent) +{ + ui.setupUi(this); + ui.tableWidget->setColumnCount(4); + ui.tableWidget->horizontalHeader()->hide(); + ui.tableWidget->verticalHeader()->hide(); + //ui.tableWidget->setHorizontalHeader(0); + //ui.tableWidget->setVerticalHeader(0); + ui.tableWidget->setColumnWidth(0,200); + ui.tableWidget->setColumnWidth(1,100); + ui.tableWidget->setColumnWidth(2,200); + ui.tableWidget->setColumnWidth(3,800); + +} + +AdvParameterList::~AdvParameterList() +{ +} +void AdvParameterList::setParameterMetaData(QString name,QString humanname,QString description) +{ + paramToNameMap[name] = humanname; + paramToDescriptionMap[name] = description; +} + +void AdvParameterList::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + + if (!paramValueMap.contains(parameterName)) + { + ui.tableWidget->setRowCount(ui.tableWidget->rowCount()+1); + if (paramToNameMap.contains(parameterName)) + { + ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,0,new QTableWidgetItem(paramToNameMap[parameterName])); + } + else + { + ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,0,new QTableWidgetItem("Unknown")); + } + ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,1,new QTableWidgetItem(QString::number(value.toFloat(),'g',2))); + ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,2,new QTableWidgetItem(parameterName)); + if (paramToDescriptionMap.contains(parameterName)) + { + ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,3,new QTableWidgetItem(paramToDescriptionMap[parameterName])); + } + else + { + ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,3,new QTableWidgetItem("Unknown")); + } + paramValueMap[parameterName] = ui.tableWidget->item(ui.tableWidget->rowCount()-1,1); + } + paramValueMap[parameterName]->setText(QString::number(value.toFloat(),'g',2)); +} diff --git a/src/ui/configuration/AdvParameterList.h b/src/ui/configuration/AdvParameterList.h new file mode 100644 index 0000000000..6a530f9f19 --- /dev/null +++ b/src/ui/configuration/AdvParameterList.h @@ -0,0 +1,25 @@ +#ifndef ADVPARAMETERLIST_H +#define ADVPARAMETERLIST_H + +#include +#include "ui_AdvParameterList.h" +#include "AP2ConfigWidget.h" + +class AdvParameterList : public AP2ConfigWidget +{ + Q_OBJECT + +public: + explicit AdvParameterList(QWidget *parent = 0); + void setParameterMetaData(QString name,QString humanname,QString description); + ~AdvParameterList(); +private slots: + void parameterChanged(int uas, int component, QString parameterName, QVariant value); +private: + QMap paramValueMap; + QMap paramToNameMap; + QMap paramToDescriptionMap; + Ui::AdvParameterList ui; +}; + +#endif // ADVPARAMETERLIST_H diff --git a/src/ui/configuration/AdvParameterList.ui b/src/ui/configuration/AdvParameterList.ui new file mode 100644 index 0000000000..9b9d40849b --- /dev/null +++ b/src/ui/configuration/AdvParameterList.ui @@ -0,0 +1,31 @@ + + + AdvParameterList + + + + 0 + 0 + 666 + 497 + + + + Form + + + + + + <h2>Advanced Parameter List</h2> + + + + + + + + + + + diff --git a/src/ui/configuration/ApmSoftwareConfig.cc b/src/ui/configuration/ApmSoftwareConfig.cc index a12719cf74..c8e1261b69 100644 --- a/src/ui/configuration/ApmSoftwareConfig.cc +++ b/src/ui/configuration/ApmSoftwareConfig.cc @@ -47,6 +47,11 @@ ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) buttonToConfigWidgetMap[ui.advancedParamButton] = advancedParamConfig; connect(ui.advancedParamButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + advParameterList = new AdvParameterList(this); + ui.stackedWidget->addWidget(advParameterList); + buttonToConfigWidgetMap[ui.advParamListButton] = advParameterList; + connect(ui.advParamListButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + arduCopterPidConfig = new ArduCopterPidConfig(this); ui.stackedWidget->addWidget(arduCopterPidConfig); buttonToConfigWidgetMap[ui.arduCopterPidButton] = arduCopterPidConfig; @@ -312,6 +317,7 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) { advancedParamConfig->addCombo(humanname,docs,name,valuelist); } + advParameterList->setParameterMetaData(name,humanname,docs); } else if (fieldmap.size() > 0) { @@ -341,6 +347,7 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) { advancedParamConfig->addRange(humanname,docs,name,max,min); } + advParameterList->setParameterMetaData(name,humanname,docs); } } diff --git a/src/ui/configuration/ApmSoftwareConfig.h b/src/ui/configuration/ApmSoftwareConfig.h index d314450e25..700a820673 100644 --- a/src/ui/configuration/ApmSoftwareConfig.h +++ b/src/ui/configuration/ApmSoftwareConfig.h @@ -11,7 +11,7 @@ #include "AdvancedParamConfig.h" #include "ArduCopterPidConfig.h" #include "ArduPlanePidConfig.h" - +#include "AdvParameterList.h" #include "UASInterface.h" #include "UASManager.h" @@ -35,6 +35,7 @@ private: AdvancedParamConfig *advancedParamConfig; ArduCopterPidConfig *arduCopterPidConfig; ArduPlanePidConfig *arduPlanePidConfig; + AdvParameterList *advParameterList; QMap buttonToConfigWidgetMap; }; -- GitLab From 75851a36919671fa710227b9af9b23cf848771f0 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Thu, 11 Jul 2013 09:25:50 -0400 Subject: [PATCH 052/460] Implementation of ArduRover pid configuration screen --- qgroundcontrol.pro | 9 +- src/ui/configuration/ApmSoftwareConfig.cc | 18 +- src/ui/configuration/ApmSoftwareConfig.h | 2 + src/ui/configuration/ApmSoftwareConfig.ui | 13 + src/ui/configuration/ArduRoverPidConfig.cc | 75 +++ src/ui/configuration/ArduRoverPidConfig.h | 23 + src/ui/configuration/ArduRoverPidConfig.ui | 732 +++++++++++++++++++++ 7 files changed, 868 insertions(+), 4 deletions(-) create mode 100644 src/ui/configuration/ArduRoverPidConfig.cc create mode 100644 src/ui/configuration/ArduRoverPidConfig.h create mode 100644 src/ui/configuration/ArduRoverPidConfig.ui diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index be5811b24d..47a864da2f 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -260,7 +260,8 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/ApmPlaneLevel.ui \ src/ui/configuration/ParamWidget.ui \ src/ui/configuration/ArduPlanePidConfig.ui \ - src/ui/configuration/AdvParameterList.ui + src/ui/configuration/AdvParameterList.ui \ + src/ui/configuration/ArduRoverPidConfig.ui INCLUDEPATH += src \ src/ui \ src/ui/linechart \ @@ -445,7 +446,8 @@ HEADERS += src/MG.h \ src/ui/configuration/ApmPlaneLevel.h \ src/ui/configuration/ParamWidget.h \ src/ui/configuration/ArduPlanePidConfig.h \ - src/ui/configuration/AdvParameterList.h + src/ui/configuration/AdvParameterList.h \ + src/ui/configuration/ArduRoverPidConfig.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -648,7 +650,8 @@ SOURCES += src/main.cc \ src/ui/configuration/ApmPlaneLevel.cc \ src/ui/configuration/ParamWidget.cc \ src/ui/configuration/ArduPlanePidConfig.cc \ - src/ui/configuration/AdvParameterList.cc + src/ui/configuration/AdvParameterList.cc \ + src/ui/configuration/ArduRoverPidConfig.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/configuration/ApmSoftwareConfig.cc b/src/ui/configuration/ApmSoftwareConfig.cc index c8e1261b69..fa36a6a1d2 100644 --- a/src/ui/configuration/ApmSoftwareConfig.cc +++ b/src/ui/configuration/ApmSoftwareConfig.cc @@ -16,6 +16,8 @@ ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) ui.advancedParamButton->setVisible(false); ui.advParamListButton->setVisible(false); ui.arduCopterPidButton->setVisible(false); + ui.arduRoverPidButton->setVisible(false); + ui.arduPlanePidButton->setVisible(false); /*basicPidConfig = new BasicPidConfig(this); ui.stackedWidget->addWidget(basicPidConfig); @@ -57,12 +59,18 @@ ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) buttonToConfigWidgetMap[ui.arduCopterPidButton] = arduCopterPidConfig; connect(ui.arduCopterPidButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - arduPlanePidConfig = new ArduPlanePidConfig(this); ui.stackedWidget->addWidget(arduPlanePidConfig); buttonToConfigWidgetMap[ui.arduPlanePidButton] = arduPlanePidConfig; connect(ui.arduPlanePidButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + arduRoverPidConfig = new ArduRoverPidConfig(this); + ui.stackedWidget->addWidget(arduRoverPidConfig); + buttonToConfigWidgetMap[ui.arduRoverPidButton] = arduRoverPidConfig; + connect(ui.arduRoverPidButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); + + + connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); @@ -101,11 +109,19 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) { ui.arduPlanePidButton->setVisible(true); ui.arduCopterPidButton->setVisible(false); + ui.arduRoverPidButton->setVisible(false); } else if (uas->getSystemType() == MAV_TYPE_QUADROTOR) { ui.arduCopterPidButton->setVisible(true); ui.arduPlanePidButton->setVisible(false); + ui.arduRoverPidButton->setVisible(false); + } + else if (uas->getSystemType() == MAV_TYPE_GROUND_ROVER) + { + ui.arduRoverPidButton->setVisible(true); + ui.arduCopterPidButton->setVisible(false); + ui.arduPlanePidButton->setVisible(false); } diff --git a/src/ui/configuration/ApmSoftwareConfig.h b/src/ui/configuration/ApmSoftwareConfig.h index 700a820673..7b0b5138e3 100644 --- a/src/ui/configuration/ApmSoftwareConfig.h +++ b/src/ui/configuration/ApmSoftwareConfig.h @@ -11,6 +11,7 @@ #include "AdvancedParamConfig.h" #include "ArduCopterPidConfig.h" #include "ArduPlanePidConfig.h" +#include "ArduRoverPidConfig.h" #include "AdvParameterList.h" #include "UASInterface.h" #include "UASManager.h" @@ -35,6 +36,7 @@ private: AdvancedParamConfig *advancedParamConfig; ArduCopterPidConfig *arduCopterPidConfig; ArduPlanePidConfig *arduPlanePidConfig; + ArduRoverPidConfig *arduRoverPidConfig; AdvParameterList *advParameterList; QMap buttonToConfigWidgetMap; }; diff --git a/src/ui/configuration/ApmSoftwareConfig.ui b/src/ui/configuration/ApmSoftwareConfig.ui index b25f61577e..aa039930b2 100644 --- a/src/ui/configuration/ApmSoftwareConfig.ui +++ b/src/ui/configuration/ApmSoftwareConfig.ui @@ -200,6 +200,19 @@ + + + + + 0 + 35 + + + + ArduRover Pids + + + diff --git a/src/ui/configuration/ArduRoverPidConfig.cc b/src/ui/configuration/ArduRoverPidConfig.cc new file mode 100644 index 0000000000..725cbb9568 --- /dev/null +++ b/src/ui/configuration/ArduRoverPidConfig.cc @@ -0,0 +1,75 @@ +#include "ArduRoverPidConfig.h" + + +ArduRoverPidConfig::ArduRoverPidConfig(QWidget *parent) : AP2ConfigWidget(parent) +{ + ui.setupUi(this); + nameToBoxMap["STEER2SRV_P"] = ui.steer2ServoPSpinBox; + nameToBoxMap["STEER2SRV_I"] = ui.steer2ServoISpinBox; + nameToBoxMap["STEER2SRV_D"] = ui.steer2ServoDSpinBox; + nameToBoxMap["STEER2SRV_IMAX"] = ui.steer2ServoIMAXSpinBox; + + nameToBoxMap["XTRK_ANGLE_CD"] = ui.xtrackEntryAngleSpinBox; + nameToBoxMap["XTRK_GAIN_SC"] = ui.xtrackGainSpinBox; + + nameToBoxMap["CRUISE_THROTTLE"] = ui.throttleCruiseSpinBox; + nameToBoxMap["THR_MIN"] = ui.throttleMinSpinBox; + nameToBoxMap["THR_MAX"] = ui.throttleMaxSpinBox; + nameToBoxMap["FS_THR_VALUE"] = ui.throttleFSSpinBox; + + nameToBoxMap["HDNG2STEER_P"] = ui.heading2SteerPSpinBox; + nameToBoxMap["HDNG2STEER_I"] = ui.heading2SteerISpinBox; + nameToBoxMap["HDNG2STEER_D"] = ui.heading2SteerDSpinBox; + nameToBoxMap["HDNG2STEER_IMAX"] = ui.heading2SteerIMAXSpinBox; + + nameToBoxMap["SPEED2THR_P"] = ui.speed2ThrottlePSpinBox; + nameToBoxMap["SPEED2THR_I"] = ui.speed2ThrottleISpinBox; + nameToBoxMap["SPEED2THR_D"] = ui.speed2ThrottleDSpinBox; + nameToBoxMap["SPEED2THR_IMAX"] = ui.speed2ThrottleIMAXSpinBox; + + nameToBoxMap["CRUISE_SPEED"] = ui.roverCruiseSpinBox; + nameToBoxMap["SPEED_TURN_GAIN"] = ui.roverTurnSpeedSpinBox; + nameToBoxMap["SPEED_TURN_DIST"] = ui.roverTurnDistSpinBox; + nameToBoxMap["WP_RADIUS"] = ui.roverWPRadiusSpinBox; + + nameToBoxMap["SONAR_TRIGGER_CM"] = ui.sonarTriggerSpinBox; + nameToBoxMap["SONAR_TURN_ANGLE"] = ui.sonarTurnAngleSpinBox; + nameToBoxMap["SONAR_TURN_TIME"] = ui.sonarTurnTimeSpinBox; + nameToBoxMap["SONAR_DEBOUNCE"] = ui.sonaeDebounceSpinBox; + +} + +ArduRoverPidConfig::~ArduRoverPidConfig() +{ +} +void ArduRoverPidConfig::writeButtonClicked() +{ + if (!m_uas) + { + return; + } + for (QMap::const_iterator i=nameToBoxMap.constBegin();i!=nameToBoxMap.constEnd();i++) + { + m_uas->getParamManager()->setParameter(1,i.key(),i.value()->value()); + } +} + +void ArduRoverPidConfig::refreshButtonClicked() +{ + if (!m_uas) + { + return; + } + for (QMap::const_iterator i=nameToBoxMap.constBegin();i!=nameToBoxMap.constEnd();i++) + { + m_uas->getParamManager()->requestParameterUpdate(1,i.key()); + } +} + +void ArduRoverPidConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + if (nameToBoxMap.contains(parameterName)) + { + nameToBoxMap[parameterName]->setValue(value.toFloat()); + } +} diff --git a/src/ui/configuration/ArduRoverPidConfig.h b/src/ui/configuration/ArduRoverPidConfig.h new file mode 100644 index 0000000000..214658bdcc --- /dev/null +++ b/src/ui/configuration/ArduRoverPidConfig.h @@ -0,0 +1,23 @@ +#ifndef ARDUROVERPIDCONFIG_H +#define ARDUROVERPIDCONFIG_H + +#include +#include "ui_ArduRoverPidConfig.h" +#include "AP2ConfigWidget.h" +class ArduRoverPidConfig : public AP2ConfigWidget +{ + Q_OBJECT + +public: + explicit ArduRoverPidConfig(QWidget *parent = 0); + ~ArduRoverPidConfig(); +private slots: + void writeButtonClicked(); + void refreshButtonClicked(); + void parameterChanged(int uas, int component, QString parameterName, QVariant value); +private: + QMap nameToBoxMap; + Ui::ArduRoverPidConfig ui; +}; + +#endif // ARDUROVERPIDCONFIG_H diff --git a/src/ui/configuration/ArduRoverPidConfig.ui b/src/ui/configuration/ArduRoverPidConfig.ui new file mode 100644 index 0000000000..47831616e0 --- /dev/null +++ b/src/ui/configuration/ArduRoverPidConfig.ui @@ -0,0 +1,732 @@ + + + ArduRoverPidConfig + + + + 0 + 0 + 626 + 607 + + + + Form + + + + + 10 + 10 + 151 + 21 + + + + <h2>ArduRover Pids</h2> + + + + + + 60 + 90 + 504 + 419 + + + + + + + Steer 2 Servo + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + Speed 2 Throttle + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + Heading 2 Steer + + + + + + + + + + P + + + + + + + I + + + + + + + D + + + + + + + INT_MAX + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + Throttle 0-100% + + + + + + + + + + Cruise + + + + + + + Min + + + + + + + Max + + + + + + + FS Value + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + Xtrack Pids + + + + + + + + + + Gain (cm) + + + + + + + Entry Angle + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Sonar + + + + + + + + + + Trigger cm + + + + + + + Turn Angle + + + + + + + Turn Time + + + + + + + Debounce + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + Rover + + + + + + + + + + Cruise Speed + + + + + + + Turn Speed + + + + + + + Turn Dist + + + + + + + WP Radius + + + + + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + + + + + + + + + 300 + 540 + 91 + 23 + + + + Refresh Params + + + + + + 200 + 540 + 75 + 23 + + + + Write Params + + + + + + -- GitLab From 0fc7dca5a4af54205b65761434a5e7404c143443 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Thu, 11 Jul 2013 10:09:33 -0400 Subject: [PATCH 053/460] Connected write/refresh buttons to their proper slots --- src/ui/configuration/ArduPlanePidConfig.cc | 3 +++ src/ui/configuration/ArduRoverPidConfig.cc | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/ui/configuration/ArduPlanePidConfig.cc b/src/ui/configuration/ArduPlanePidConfig.cc index ac6d4da28d..f97e6af607 100644 --- a/src/ui/configuration/ArduPlanePidConfig.cc +++ b/src/ui/configuration/ArduPlanePidConfig.cc @@ -56,6 +56,9 @@ ArduPlanePidConfig::ArduPlanePidConfig(QWidget *parent) : AP2ConfigWidget(parent nameToBoxMap["LIM_PITCH_MAX"] = ui.navPitchMaxSpinBox; nameToBoxMap["LIM_PITCH_MIN"] = ui.navPitchMinSpinBox; + connect(ui.writePushButton,SIGNAL(clicked()),this,SLOT(writeButtonClicked())); + connect(ui.refreshPushButton,SIGNAL(clicked()),this,SLOT(refreshButtonClicked())); + } ArduPlanePidConfig::~ArduPlanePidConfig() diff --git a/src/ui/configuration/ArduRoverPidConfig.cc b/src/ui/configuration/ArduRoverPidConfig.cc index 725cbb9568..60f2f28f97 100644 --- a/src/ui/configuration/ArduRoverPidConfig.cc +++ b/src/ui/configuration/ArduRoverPidConfig.cc @@ -37,6 +37,9 @@ ArduRoverPidConfig::ArduRoverPidConfig(QWidget *parent) : AP2ConfigWidget(parent nameToBoxMap["SONAR_TURN_TIME"] = ui.sonarTurnTimeSpinBox; nameToBoxMap["SONAR_DEBOUNCE"] = ui.sonaeDebounceSpinBox; + connect(ui.writePushButton,SIGNAL(clicked()),this,SLOT(writeButtonClicked())); + connect(ui.refreshPushButton,SIGNAL(clicked()),this,SLOT(refreshButtonClicked())); + } ArduRoverPidConfig::~ArduRoverPidConfig() -- GitLab From a01da581483a415c0b2c35fc6e6c71b8cd8629a0 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Thu, 11 Jul 2013 16:20:35 -0700 Subject: [PATCH 054/460] APMToolBar as a docking widget [complete] --- qml/components/TextButton.qml | 70 +++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 qml/components/TextButton.qml diff --git a/qml/components/TextButton.qml b/qml/components/TextButton.qml new file mode 100644 index 0000000000..c7b2b32226 --- /dev/null +++ b/qml/components/TextButton.qml @@ -0,0 +1,70 @@ +import QtQuick 1.1 + +Rectangle { + signal clicked + + property string label: "Text Button label" + property int minWidth: 75 + property int minHeight: 0 + property int margin: 5 + + width: textBox.width + height: 72 + anchors.verticalCenter: parent.verticalCenter + color: "black" + + signal buttonClick() + + onButtonClick: { + console.log(label + " clicked calling signal") + clicked() + } + + // Highlighting and ativation section + property color buttonColor: "black" + property color onHoverbuttonColor: "lightblue" + property color onHoverColor: "darkblue" + property color borderColor: "white" + + Rectangle { + width: textButtonLabel.paintedwidth + anchors.centerIn: parent + + Rectangle{ + id: textBox + anchors.centerIn: parent + width: minWidth > textButtonLabel.paintedWidth + margin ? minWidth : textButtonLabel.paintedWidth + margin + height: minHeight > textButtonLabel.paintedHeight + margin ? minHeight : textButtonLabel.paintedHeight + margin + + Text { + id: textButtonLabel + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: 2 + text: label + color: "white" + font.pointSize: 11 + } + + MouseArea { + id: textButtonMouseArea + anchors.fill: parent + onClicked: buttonClick() + hoverEnabled: true + onEntered: { + parent.border.color = onHoverColor + parent.color = onHoverbuttonColor + } + onExited: { + parent.border.color = borderColor + parent.color = buttonColor + } + onPressed: parent.color = Qt.darker(onHoverbuttonColor, 1.5) + onReleased: parent.color = buttonColor + } + color: buttonColor + border.color: borderColor + border.width: 1 + } + } +} -- GitLab From 359f8bd1d8ed6e53da2fd4060c4ccf4320189bde Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Thu, 11 Jul 2013 16:22:53 -0700 Subject: [PATCH 055/460] APMToolbar as a docking widget [complete] + missing files --- qgroundcontrol.pro | 1 + qml/ApmToolBar.qml | 73 +++++++++++++++++++++---- qml/components/Button.qml | 2 +- src/comm/SerialLink.cc | 31 ++++++----- src/comm/SerialLink.h | 2 +- src/ui/CommConfigurationWindow.cc | 2 +- src/ui/MainWindow.cc | 61 ++++++++++++++++----- src/ui/MainWindow.h | 2 +- src/ui/MainWindow.ui | 6 +- src/ui/apmtoolbar.cpp | 91 ++++++++++++++++++++++++++++--- src/ui/apmtoolbar.h | 11 +++- 11 files changed, 229 insertions(+), 53 deletions(-) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 01475e1127..c968bfd9a0 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -778,6 +778,7 @@ OTHER_FILES += \ OTHER_FILES += \ qml/ApmToolBar.qml \ qml/components/Button.qml \ + qml/components/TextButton.qml \ qml/resources/apmplanner/toolbar/connect.png \ qml/resources/apmplanner/toolbar/flightplanner.png \ qml/resources/apmplanner/toolbar/helpwizard.png \ diff --git a/qml/ApmToolBar.qml b/qml/ApmToolBar.qml index 6748a651af..21cc0fd3d4 100644 --- a/qml/ApmToolBar.qml +++ b/qml/ApmToolBar.qml @@ -4,21 +4,46 @@ import "./components" Rectangle { id: toolbar - width: parent.width + + property alias backgroundColor : toolbar.color + property alias linkNameLabel: linkDevice.label + property alias baudrateLabel: baudrate.label + + width: 1024 < parent.width ? 1024 : parent.width height: 72 color: "black" border.color: "black" + Connections { + target: globalObj + onMAVConnected: { + console.log("Change Connection " + connected) + if (connect){ + console.log("connected") + // connectButton.image = "./resources/apmplanner/toolbar/disconnect.png" + } else { + console.log("disconnected") + // connectButton.image = "./resources/apmplanner/toolbar/connect.png" + } + } + } + Row { anchors.left: parent.left spacing: 2 + Rectangle { + width: 5 + height: parent.height + color: "black" + } + Button { id: flightDataView label: "FLIGHT DATA" image: "./resources/apmplanner/toolbar/flightdata.png" onClicked: { - globalObj.selectFlightView() + globalObj.triggerFlightView() } } @@ -26,7 +51,7 @@ Rectangle { id: flightPlanView label: "FLIGHT PLAN" image: "./resources/apmplanner/toolbar/flightplanner.png" - onClicked: globalObj.selectFlightPlanView() + onClicked: globalObj.triggerFlightPlanView() } Button { @@ -34,7 +59,7 @@ Rectangle { label: "HARDWARE" image: "./resources/apmplanner/toolbar/hardwareconfig.png" margins: 8 - onClicked: globalObj.selectHardwareView() + onClicked: globalObj.triggerHardwareView() } Button { @@ -42,34 +67,62 @@ Rectangle { label: "SOFTWARE" image: "./resources/apmplanner/toolbar/softwareconfig.png" margins: 8 - onClicked: globalObj.selectSoftwareView() + onClicked: globalObj.triggerSoftwareView() } Button { id: simualtionView label: "SIMULATION" image: "./resources/apmplanner/toolbar/simulation.png" - onClicked: globalObj.selectSimulationView() + onClicked: globalObj.triggerSimulationView() } Button { id: terminalView label: "TERMINAL" image: "./resources/apmplanner/toolbar/terminal.png" - onClicked: globalObj.selectTerminalView() + onClicked: globalObj.triggerTerminalView() } } Row { - anchors.left: parent.right + anchors.right: parent.right spacing: 2 + TextButton { + id: linkDevice + label: "none" + minWidth: 100 + + onClicked: globalObj.showConnectionDialog() + } + + TextButton { + id: baudrate + label: "none" + minWidth: 100 + + onClicked: globalObj.showConnectionDialog() + } + + Rectangle { + width: 5 + height: parent.height + color: "black" + } + Button { id: connectButton label: "CONNECT" image: "./resources/apmplanner/toolbar/connect.png" - onClicked: globalObj.connect() + onClicked: globalObj.connectMAV() + } + + Rectangle { + anchors.right: parent.right + width: 5 + height: parent.height + color: "black" } } } - diff --git a/qml/components/Button.qml b/qml/components/Button.qml index 567eca2ee2..ee40e9e5f5 100644 --- a/qml/components/Button.qml +++ b/qml/components/Button.qml @@ -38,7 +38,7 @@ Rectangle { signal buttonClick() onButtonClick: { - console.log(buttonLabel.text + " clicked.") + console.log(buttonLabel.text + " clicked calling signal") clicked() } diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 51ebb0b718..bd456d93b4 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -27,14 +27,18 @@ SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, m_stopp(false), m_reqReset(false) { + qDebug() << "create SerialLink " << portname << baudRate << hardwareFlowControl + << parity << dataBits << stopBits; // Setup settings m_portName = portname.trimmed(); if (m_portName == "" && getCurrentPorts()->size() > 0) { - m_portName = m_ports->first().trimmed(); + m_portName = m_ports->first().trimmed(); } + qDebug() << "m_portName " << m_portName; + // Set unique ID and add link to the list of links m_id = getNextLinkId(); @@ -61,14 +65,15 @@ SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, m_stopBits = stopBits; // Set the port name - if (m_portName == "") - { - m_name = tr("Serial Link ") + QString::number(getId()); - } - else - { - m_name = portname.trimmed(); - } +// if (m_portName == "") +// { +// m_name = tr("Serial Link ") + QString::number(getId()); +// } +// else +// { +// m_name = portname.trimmed(); +// } + loadSettings(); } void SerialLink::requestReset() @@ -187,7 +192,7 @@ void SerialLink::run() m_bitsReceivedTotal += readData.length() * 8; } } else { - qDebug() << "readyReadTime #"<< __LINE__; +// qDebug() << "readyReadTime #"<< __LINE__; } @@ -460,7 +465,7 @@ int SerialLink::getId() QString SerialLink::getName() { - return m_name; + return m_portName; } /** @@ -695,11 +700,11 @@ bool SerialLink::setPortName(QString portName) if ((portName != m_portName) && (portName.trimmed().length() > 0)) { m_portName = portName.trimmed(); - m_name = tr("serial port ") + portName.trimmed(); // [TODO] Do we need this? +// m_name = tr("serial port ") + portName.trimmed(); // [TODO] Do we need this? if(m_port) m_port->setPortName(portName); - emit nameChanged(m_name); // [TODO] maybe we can eliminate this + emit nameChanged(m_portName); // [TODO] maybe we can eliminate this return accepted; } return false; diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index 3ada34e743..9a31cc8ca3 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -148,7 +148,7 @@ protected: int m_stopBits; int m_parity; QString m_portName; - QString m_name; +// QString m_name; int m_timeout; int m_id; diff --git a/src/ui/CommConfigurationWindow.cc b/src/ui/CommConfigurationWindow.cc index 43a3698a1e..de6c8715d5 100644 --- a/src/ui/CommConfigurationWindow.cc +++ b/src/ui/CommConfigurationWindow.cc @@ -55,7 +55,7 @@ This file is part of the QGROUNDCONTROL project #include "LinkManager.h" #include "MainWindow.h" -CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolInterface* protocol, QWidget *parent) : QWidget(NULL) +CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolInterface* protocol, QWidget *parent) : QWidget(parent) { this->link = link; diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 870d805c68..3d1d28fd45 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -181,15 +181,6 @@ MainWindow::MainWindow(QWidget *parent): actions << ui.actionSoftwareConfig; toolBar->setPerspectiveChangeActions(actions); - // We only want one of these. - apmToolBar = new APMToolBar(this); - apmToolBar->setFlightViewAction(ui.actionFlightView); - apmToolBar->setFlightPlanViewAction(ui.actionMissionView); - apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); - apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); - apmToolBar->setSimulationViewAction(ui.actionSimulation_View); - apmToolBar->setTerminalViewAction(ui.actionSimulation_View); - // Add actions for advanced users (displayed in dropdown under "advanced") QList advancedActions; advancedActions << ui.actionSimulation_View; @@ -200,8 +191,6 @@ MainWindow::MainWindow(QWidget *parent): setStatusBar(customStatusBar); statusBar()->setSizeGripEnabled(true); - - emit initStatusChanged("Building common widgets."); buildCommonWidgets(); @@ -616,9 +605,17 @@ void MainWindow::buildCommonWidgets() createDockWidget(pilotView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea,this->width()/1.8); // Add Our new 'toolbar' - qDebug() << "width" << this->width(); + // Create the APM Toolbar + APMToolBar *apmToolBar = new APMToolBar(this); + apmToolBar->setFlightViewAction(ui.actionFlightView); + apmToolBar->setFlightPlanViewAction(ui.actionMissionView); + apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); + apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); + apmToolBar->setSimulationViewAction(ui.actionSimulation_View); + apmToolBar->setTerminalViewAction(ui.actionSimulation_View); createDockWidget(pilotView,apmToolBar,tr("APM Tool Bar"),"APM_TOOLBAR_DOCKWIDGET",VIEW_FLIGHT,Qt::TopDockWidgetArea,this->width(), 70); + QGCTabbedInfoView *infoview = new QGCTabbedInfoView(this); infoview->addSource(mavlinkDecoder); createDockWidget(pilotView,infoview,tr("Info View"),"UAS_INFO_INFOVIEW_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea); @@ -864,7 +861,15 @@ void MainWindow::loadDockWidget(QString name) else if (name == "APM_TOOLBAR_DOCKWIDGET") { // Add Our new 'toolbar' - createDockWidget(centerStack->currentWidget(),apmToolBar,tr("APM Tool Bar"),"APM_TOOLBAR_DOCKWIDGET",VIEW_FLIGHT,Qt::TopDockWidgetArea,this->width(), 70); + // Create the APM Toolbar + APMToolBar *apmToolBar = new APMToolBar(this); + apmToolBar->setFlightViewAction(ui.actionFlightView); + apmToolBar->setFlightPlanViewAction(ui.actionMissionView); + apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); + apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); + apmToolBar->setSimulationViewAction(ui.actionSimulation_View); + apmToolBar->setTerminalViewAction(ui.actionSimulation_View); + createDockWidget(centerStack->currentWidget(),apmToolBar,tr("APM Tool Bar"),"APM_TOOLBAR_DOCKWIDGET",currentView,Qt::TopDockWidgetArea,this->width(), 70); } else { @@ -1651,6 +1656,29 @@ void MainWindow::addLink() } } + +bool MainWindow::configLink(LinkInterface *link) +{ + // Go searching for this link's configuration window + QList actions = ui.menuNetwork->actions(); + + bool found(false); + + const int32_t& linkIndex(LinkManager::instance()->getLinks().indexOf(link)); + const int32_t& linkID(LinkManager::instance()->getLinks()[linkIndex]->getId()); + + foreach (QAction* action, actions) + { + if (action->data().toInt() == linkID) + { // LinkManager::instance()->getLinks().indexOf(link) + found = true; + action->trigger(); // Show the Link Config Dialog + } + } + + return found; +} + void MainWindow::addLink(LinkInterface *link) { // IMPORTANT! KEEP THESE TWO LINES @@ -1680,7 +1708,7 @@ void MainWindow::addLink(LinkInterface *link) if (!found) { // || udp - CommConfigurationWindow* commWidget = new CommConfigurationWindow(link, mavlink, this); + CommConfigurationWindow* commWidget = new CommConfigurationWindow(link, mavlink, NULL); commsWidgetList.append(commWidget); connect(commWidget,SIGNAL(destroyed(QObject*)),this,SLOT(commsWidgetDestroyed(QObject*))); QAction* action = commWidget->getAction(); @@ -1696,6 +1724,11 @@ void MainWindow::addLink(LinkInterface *link) } } } + +//void MainWindow::configLink(LinkInterface *link) +//{ + +//} void MainWindow::commsWidgetDestroyed(QObject *obj) { if (commsWidgetList.contains(obj)) diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 5d765debe2..e66e650cd7 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -151,6 +151,7 @@ public slots: /** @brief Add a communication link */ void addLink(); void addLink(LinkInterface* link); + bool configLink(LinkInterface *link); void configure(); /** @brief Set the currently controlled UAS */ void setActiveUAS(UASInterface* uas); @@ -404,7 +405,6 @@ protected: QPointer toolBar; QPointer customStatusBar; - QPointer apmToolBar; QPointer debugConsole; diff --git a/src/ui/MainWindow.ui b/src/ui/MainWindow.ui index 99a69c43d2..d0ba091980 100644 --- a/src/ui/MainWindow.ui +++ b/src/ui/MainWindow.ui @@ -284,7 +284,7 @@ - :/files/images/status/weather-overcast.svg:/files/images/status/weather-overcast.svg + :/files/images/categories/applications-internet.svg:/files/images/categories/applications-internet.svg Mission @@ -496,6 +496,10 @@ + + + :/files/images/categories/applications-system.svg:/files/images/categories/applications-system.svg + Software diff --git a/src/ui/apmtoolbar.cpp b/src/ui/apmtoolbar.cpp index 71e3e9ab7d..f73032102d 100644 --- a/src/ui/apmtoolbar.cpp +++ b/src/ui/apmtoolbar.cpp @@ -1,67 +1,81 @@ #include #include #include +#include "LinkManager.h" +#include "MainWindow.h" #include "apmtoolbar.h" -APMToolBar::APMToolBar(QWidget *parent) : +APMToolBar::APMToolBar(QWidget *parent): QDeclarativeView(parent) { // Configure our QML object this->rootContext()->setContextProperty("globalObj", this); setSource(QUrl::fromLocalFile("qml/ApmToolBar.qml")); setResizeMode(QDeclarativeView::SizeRootObjectToView); + + QObject *root = rootObject(); + connect(LinkManager::instance(),SIGNAL(newLink(LinkInterface*)), + this, SLOT(updateLinkDisplay(LinkInterface*))); } void APMToolBar::setFlightViewAction(QAction *action) { - connect(this, SIGNAL(selectFlightView()), action, SIGNAL(triggered())); + connect(this, SIGNAL(triggerFlightView()), action, SIGNAL(triggered())); } void APMToolBar::setFlightPlanViewAction(QAction *action) { - connect(this, SIGNAL(selectFlightPlanView()), action, SIGNAL(triggered())); + connect(this, SIGNAL(triggerFlightPlanView()), action, SIGNAL(triggered())); } void APMToolBar::setHardwareViewAction(QAction *action) { - connect(this, SIGNAL(selectHardwareView()), action, SIGNAL(triggered())); + connect(this, SIGNAL(triggerHardwareView()), action, SIGNAL(triggered())); } void APMToolBar::setSoftwareViewAction(QAction *action) { - connect(this, SIGNAL(selectSoftwareView()), action, SIGNAL(triggered())); + connect(this, SIGNAL(triggerSoftwareView()), action, SIGNAL(triggered())); } void APMToolBar::setSimulationViewAction(QAction *action) { - connect(this, SIGNAL(selectSimualtionView()), action, SIGNAL(triggered())); + connect(this, SIGNAL(triggerSimulationView()), action, SIGNAL(triggered())); } void APMToolBar::setTerminalViewAction(QAction *action) { - connect(this, SIGNAL(selectTerminalView()), action, SIGNAL(triggered())); + connect(this, SIGNAL(triggerTerminalView()), action, SIGNAL(triggered())); +} + +void APMToolBar::setConnectMAVAction(QAction *action) +{ + connect(this, SIGNAL(connectMAV()), action, SIGNAL(triggered())); } void APMToolBar::selectFlightView() { qDebug() << "APMToolBar: SelectFlightView"; -// emit triggerFlightView(); + emit triggerFlightView(); } void APMToolBar::selectFlightPlanView() { qDebug() << "APMToolBar: SelectFlightPlanView"; + emit triggerFlightPlanView(); } void APMToolBar::selectHardwareView() { qDebug() << "APMToolBar: selectHardwareView"; + emit triggerHardwareView(); } void APMToolBar::selectSoftwareView() { qDebug() << "APMToolBar: selectSoftwareView"; + emit triggerSoftwareView(); } void APMToolBar::selectSimulationView() @@ -76,6 +90,65 @@ void APMToolBar::selectTerminalView() void APMToolBar::connectMAV() { - qDebug() << "APMToolBar: connect"; + qDebug() << "APMToolBar: connectMAV "; + + bool connected = LinkManager::instance()->getLinks().last()->isConnected(); + bool result; + + if (!connected && LinkManager::instance()->getLinks().count() < 3) + { + // No Link so prompt to connect one + MainWindow::instance()->addLink(); + } else if (!connected) { + // Need to Connect Link + result = LinkManager::instance()->getLinks().last()->connect(); + + } else if (connected && LinkManager::instance()->getLinks().count() > 2) { + // result need to be the opposite of success. + result = !LinkManager::instance()->getLinks().last()->disconnect(); + } + qDebug() << "result = " << result; + emit MAVConnected(result); +} + +APMToolBar::~APMToolBar() +{ + qDebug() << "Destory APM Toolbar"; +} + +void APMToolBar::showConnectionDialog() +{ + // Displays a UI where the user can select a MAV Link. + qDebug() << "APMToolBar: showConnectionDialog link count =" + << LinkManager::instance()->getLinks().count(); + + LinkInterface *link = LinkManager::instance()->getLinks().last(); + bool result; + + if (link && LinkManager::instance()->getLinks().count() >= 3) + { + // Serial Link so prompt to config it + result = MainWindow::instance()->configLink(link); + + if (!result) + qDebug() << "Link Config Failed!"; + } else { + // No Link so prompt to create one + MainWindow::instance()->addLink(); + } + } +void APMToolBar::updateLinkDisplay(LinkInterface* newLink) +{ + qDebug() << "APMToolBar: updateLinkDisplay"; + QObject *object = rootObject(); + + if (newLink){ + qint64 baudrate = newLink->getNominalDataRate(); + object->setProperty("baudrateLabel", QString::number(baudrate)); + + QString linkName = newLink->getName(); + object->setProperty("linkNameLabel", linkName); + } +} diff --git a/src/ui/apmtoolbar.h b/src/ui/apmtoolbar.h index e7d0386991..e6e14446cb 100644 --- a/src/ui/apmtoolbar.h +++ b/src/ui/apmtoolbar.h @@ -4,11 +4,14 @@ #include #include +class LinkInterface; + class APMToolBar : public QDeclarativeView { Q_OBJECT public: explicit APMToolBar(QWidget *parent = 0); + ~APMToolBar(); void setFlightViewAction(QAction *action); void setFlightPlanViewAction(QAction *action); @@ -16,6 +19,7 @@ public: void setSoftwareViewAction(QAction *action); void setSimulationViewAction(QAction *action); void setTerminalViewAction(QAction *action); + void setConnectMAVAction(QAction *action); signals: void triggerFlightView(); @@ -25,8 +29,9 @@ signals: void triggerSimulationView(); void triggerTerminalView(); + void MAVConnected(bool connected); + public slots: -//signals: void selectFlightView(); void selectFlightPlanView(); void selectHardwareView(); @@ -34,8 +39,10 @@ public slots: void selectSimulationView(); void selectTerminalView(); -public slots: void connectMAV(); + void showConnectionDialog(); + + void updateLinkDisplay(LinkInterface *newLink); }; #endif // APMTOOLBAR_H -- GitLab From e24d2ada2d0ad894a95742e6b8958ada1ce1dade Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Thu, 11 Jul 2013 16:35:03 -0700 Subject: [PATCH 056/460] Fixed APM Tool Bar not being populated with link info when switching perspectives --- src/ui/apmtoolbar.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ui/apmtoolbar.cpp b/src/ui/apmtoolbar.cpp index f73032102d..6ed411e7d0 100644 --- a/src/ui/apmtoolbar.cpp +++ b/src/ui/apmtoolbar.cpp @@ -14,9 +14,12 @@ APMToolBar::APMToolBar(QWidget *parent): setSource(QUrl::fromLocalFile("qml/ApmToolBar.qml")); setResizeMode(QDeclarativeView::SizeRootObjectToView); - QObject *root = rootObject(); connect(LinkManager::instance(),SIGNAL(newLink(LinkInterface*)), this, SLOT(updateLinkDisplay(LinkInterface*))); + + if (LinkManager::instance()->getLinks().count()>=3) { + updateLinkDisplay(LinkManager::instance()->getLinks().last()); + } } void APMToolBar::setFlightViewAction(QAction *action) -- GitLab From d7def6d461d0b07a38bf890758e3449aa11fd023 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Thu, 11 Jul 2013 20:11:05 -0400 Subject: [PATCH 057/460] Some comment and general code cleanup tasks --- src/ui/configuration/ApmHardwareConfig.cc | 20 +++----------- src/ui/configuration/ApmSoftwareConfig.cc | 19 +------------- src/ui/configuration/ApmSoftwareConfig.ui | 32 ----------------------- 3 files changed, 5 insertions(+), 66 deletions(-) diff --git a/src/ui/configuration/ApmHardwareConfig.cc b/src/ui/configuration/ApmHardwareConfig.cc index 3b9c5655d7..06f6a2a354 100644 --- a/src/ui/configuration/ApmHardwareConfig.cc +++ b/src/ui/configuration/ApmHardwareConfig.cc @@ -33,7 +33,8 @@ This file is part of the QGROUNDCONTROL project ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) { ui.setupUi(this); - //ui.firmwareButton->setVisible(valse); + + ui.manditoryHardware->setVisible(false); ui.frameTypeButton->setVisible(false); ui.compassButton->setVisible(false); @@ -41,15 +42,12 @@ ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) ui.arduPlaneLevelButton->setVisible(false); ui.radioCalibrateButton->setVisible(false); ui.optionalHardwareButton->setVisible(false); - //ui.radio3DRButton->setVisible(false); ui.batteryMonitorButton->setVisible(false); ui.sonarButton->setVisible(false); ui.airspeedButton->setVisible(false); ui.opticalFlowButton->setVisible(false); ui.osdButton->setVisible(false); ui.cameraGimbalButton->setVisible(false); - //ui.antennaTrackerButton->setVisible(false); - connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.radio3DRButton,SLOT(setShown(bool))); connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.batteryMonitorButton,SLOT(setShown(bool))); @@ -134,8 +132,6 @@ ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) buttonToConfigWidgetMap[ui.antennaTrackerButton] = antennaTrackerConfig; connect(ui.antennaTrackerButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - - connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); if (UASManager::instance()->getActiveUAS()) { @@ -185,15 +181,7 @@ void ApmHardwareConfig::activeUASSet(UASInterface *uas) } ui.firmwareButton->setVisible(true); ui.manditoryHardware->setVisible(true); - ui.manditoryHardware->setChecked(false); + ui.manditoryHardware->setChecked(true); ui.optionalHardwareButton->setVisible(true); - ui.optionalHardwareButton->setChecked(false); - ui.radio3DRButton->setVisible(false); - ui.antennaTrackerButton->setVisible(false); - - - - - - + ui.optionalHardwareButton->setChecked(true); } diff --git a/src/ui/configuration/ApmSoftwareConfig.cc b/src/ui/configuration/ApmSoftwareConfig.cc index fa36a6a1d2..0412287222 100644 --- a/src/ui/configuration/ApmSoftwareConfig.cc +++ b/src/ui/configuration/ApmSoftwareConfig.cc @@ -8,10 +8,8 @@ ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) { ui.setupUi(this); - ui.basicPidsButton->setVisible(false); ui.flightModesButton->setVisible(false); ui.standardParamButton->setVisible(false); - ui.geoFenceButton->setVisible(false); ui.failSafeButton->setVisible(false); ui.advancedParamButton->setVisible(false); ui.advParamListButton->setVisible(false); @@ -19,11 +17,6 @@ ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) ui.arduRoverPidButton->setVisible(false); ui.arduPlanePidButton->setVisible(false); - /*basicPidConfig = new BasicPidConfig(this); - ui.stackedWidget->addWidget(basicPidConfig); - buttonToConfigWidgetMap[ui.basicPidsButton] = basicPidConfig; - connect(ui.basicPidsButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget()));*/ - flightConfig = new FlightModeConfig(this); ui.stackedWidget->addWidget(flightConfig); buttonToConfigWidgetMap[ui.flightModesButton] = flightConfig; @@ -34,11 +27,6 @@ ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) buttonToConfigWidgetMap[ui.standardParamButton] = standardParamConfig; connect(ui.standardParamButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - /*geoFenceConfig = new GeoFenceConfig(this); - ui.stackedWidget->addWidget(geoFenceConfig); - buttonToConfigWidgetMap[ui.geoFenceButton] = geoFenceConfig; - connect(ui.geoFenceButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget()));*/ - failSafeConfig = new FailSafeConfig(this); ui.stackedWidget->addWidget(failSafeConfig); buttonToConfigWidgetMap[ui.failSafeButton] = failSafeConfig; @@ -69,10 +57,6 @@ ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) buttonToConfigWidgetMap[ui.arduRoverPidButton] = arduRoverPidConfig; connect(ui.arduRoverPidButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - - - - connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); if (UASManager::instance()->getActiveUAS()) { @@ -97,10 +81,8 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) return; } - ui.basicPidsButton->setVisible(true); ui.flightModesButton->setVisible(true); ui.standardParamButton->setVisible(true); - ui.geoFenceButton->setVisible(true); ui.failSafeButton->setVisible(true); ui.advancedParamButton->setVisible(true); ui.advParamListButton->setVisible(true); @@ -136,6 +118,7 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) xmlfile.close(); //TODO: Testing to ensure that incorrectly formated XML won't break this. + //Also, move this into the Param Manager, as it should handle all metadata. while (!xml.atEnd()) { if (xml.isStartElement() && xml.name() == "paramfile") diff --git a/src/ui/configuration/ApmSoftwareConfig.ui b/src/ui/configuration/ApmSoftwareConfig.ui index aa039930b2..c29e3b6ff7 100644 --- a/src/ui/configuration/ApmSoftwareConfig.ui +++ b/src/ui/configuration/ApmSoftwareConfig.ui @@ -59,22 +59,6 @@ - - - - - 0 - 35 - - - - Basic Pids - - - false - - - @@ -107,22 +91,6 @@ - - - - - 0 - 35 - - - - GeoFence - - - false - - - -- GitLab From 1bd6a3e6597104d9e9feb7cb5fbbf0314bfe7ff5 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Thu, 11 Jul 2013 20:14:07 -0400 Subject: [PATCH 058/460] Added forgotten ParamWidget --- src/ui/configuration/ParamWidget.cc | 79 +++++++++++++++++++++++++++++ src/ui/configuration/ParamWidget.h | 34 +++++++++++++ src/ui/configuration/ParamWidget.ui | 78 ++++++++++++++++++++++++++++ 3 files changed, 191 insertions(+) create mode 100644 src/ui/configuration/ParamWidget.cc create mode 100644 src/ui/configuration/ParamWidget.h create mode 100644 src/ui/configuration/ParamWidget.ui diff --git a/src/ui/configuration/ParamWidget.cc b/src/ui/configuration/ParamWidget.cc new file mode 100644 index 0000000000..93b3bfd264 --- /dev/null +++ b/src/ui/configuration/ParamWidget.cc @@ -0,0 +1,79 @@ +#include "ParamWidget.h" + + +ParamWidget::ParamWidget(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} + +ParamWidget::~ParamWidget() +{ +} + +void ParamWidget::setupInt(QString title,QString description,int value,int min,int max) +{ + type = INT; + ui.titleLabel->setText("

" + title + "

"); + ui.descriptionLabel->setText(description); + ui.valueComboBox->hide(); + ui.valueSlider->show(); + ui.intSpinBox->show(); + ui.doubleSpinBox->hide(); + m_min = min; + m_max = max; +} + +void ParamWidget::setupDouble(QString title,QString description,double value,double min,double max) +{ + type = DOUBLE; + ui.titleLabel->setText("

" + title + "

"); + ui.descriptionLabel->setText(description); + ui.valueComboBox->hide(); + ui.valueSlider->show(); + ui.intSpinBox->hide(); + ui.doubleSpinBox->show(); + m_min = min; + m_max = max; +} + +void ParamWidget::setupCombo(QString title,QString description,QList > list) +{ + type = COMBO; + ui.titleLabel->setText("

" + title + "

"); + ui.descriptionLabel->setText(description); + ui.valueComboBox->show(); + ui.valueSlider->hide(); + ui.intSpinBox->hide(); + ui.doubleSpinBox->hide(); + m_valueList = list; + ui.valueComboBox->clear(); + for (int i=0;iaddItem(m_valueList[i].second); + } +} + +void ParamWidget::setValue(double value) +{ + if (type == INT) + { + ui.intSpinBox->setValue(value); + ui.valueSlider->setValue(((value + m_min) / (m_max + m_min)) * 100.0); + } + else if (type == DOUBLE) + { + ui.doubleSpinBox->setValue(value); + ui.valueSlider->setValue(((value + m_min) / (m_max + m_min)) * 100.0); + } + else if (type == COMBO) + { + for (int i=0;isetCurrentIndex(i); + return; + } + } + } +} diff --git a/src/ui/configuration/ParamWidget.h b/src/ui/configuration/ParamWidget.h new file mode 100644 index 0000000000..aa375d2967 --- /dev/null +++ b/src/ui/configuration/ParamWidget.h @@ -0,0 +1,34 @@ +#ifndef PARAMWIDGET_H +#define PARAMWIDGET_H + +#include +#include "ui_ParamWidget.h" + +class ParamWidget : public QWidget +{ + Q_OBJECT + +public: + explicit ParamWidget(QWidget *parent = 0); + ~ParamWidget(); + void setupInt(QString title,QString description,int value,int min,int max); + void setupDouble(QString title,QString description,double value,double min,double max); + void setupCombo(QString title,QString description,QList > list); + void setValue(double value); +private: + enum VIEWTYPE + { + INT, + DOUBLE, + COMBO + }; + double m_min; + double m_max; + double m_dvalue; + int m_ivalue; + VIEWTYPE type; + QList > m_valueList; + Ui::ParamWidget ui; +}; + +#endif // PARAMWIDGET_H diff --git a/src/ui/configuration/ParamWidget.ui b/src/ui/configuration/ParamWidget.ui new file mode 100644 index 0000000000..ddf4653b8f --- /dev/null +++ b/src/ui/configuration/ParamWidget.ui @@ -0,0 +1,78 @@ + + + ParamWidget + + + + 0 + 0 + 619 + 207 + + + + Form + + + + + + + + TextLabel + + + + + + + TextLabel + + + true + + + + + + + + + + + + + + + 100 + + + Qt::Horizontal + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + -- GitLab From e3afbf8b7578b7a8f55ac06199e02f7bef1e4857 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 12 Jul 2013 10:10:31 -0400 Subject: [PATCH 059/460] Addition of orientation combo box for compass config --- src/ui/configuration/CompassConfig.cc | 41 +++++++++++++++++++++++++++ src/ui/configuration/CompassConfig.ui | 8 +++--- src/ui/configuration/SonarConfig.ui | 2 +- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/ui/configuration/CompassConfig.cc b/src/ui/configuration/CompassConfig.cc index 5c37b0cbf6..43da906fd8 100644 --- a/src/ui/configuration/CompassConfig.cc +++ b/src/ui/configuration/CompassConfig.cc @@ -16,6 +16,33 @@ CompassConfig::CompassConfig(QWidget *parent) : QWidget(parent) connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); activeUASSet(UASManager::instance()->getActiveUAS()); + ui.orientationComboBox->addItem("ROTATION_NONE"); + ui.orientationComboBox->addItem("ROTATION_YAW_45"); + ui.orientationComboBox->addItem("ROTATION_YAW_90"); + ui.orientationComboBox->addItem("ROTATION_YAW_135"); + ui.orientationComboBox->addItem("ROTATION_YAW_180"); + ui.orientationComboBox->addItem("ROTATION_YAW_225"); + ui.orientationComboBox->addItem("ROTATION_YAW_270"); + ui.orientationComboBox->addItem("ROTATION_YAW_315"); + ui.orientationComboBox->addItem("ROTATION_ROLL_180"); + ui.orientationComboBox->addItem("ROTATION_ROLL_180_YAW_45"); + ui.orientationComboBox->addItem("ROTATION_ROLL_180_YAW_90"); + ui.orientationComboBox->addItem("ROTATION_ROLL_180_YAW_135"); + ui.orientationComboBox->addItem("ROTATION_PITCH_180"); + ui.orientationComboBox->addItem("ROTATION_ROLL_180_YAW_225"); + ui.orientationComboBox->addItem("ROTATION_ROLL_180_YAW_270"); + ui.orientationComboBox->addItem("ROTATION_ROLL_180_YAW_315"); + ui.orientationComboBox->addItem("ROTATION_ROLL_90"); + ui.orientationComboBox->addItem("ROTATION_ROLL_90_YAW_45"); + ui.orientationComboBox->addItem("ROTATION_ROLL_90_YAW_90"); + ui.orientationComboBox->addItem("ROTATION_ROLL_90_YAW_135"); + ui.orientationComboBox->addItem("ROTATION_ROLL_270"); + ui.orientationComboBox->addItem("ROTATION_ROLL_270_YAW_45"); + ui.orientationComboBox->addItem("ROTATION_ROLL_270_YAW_90"); + ui.orientationComboBox->addItem("ROTATION_ROLL_270_YAW_135"); + ui.orientationComboBox->addItem("ROTATION_PITCH_90"); + ui.orientationComboBox->addItem("ROTATION_PITCH_270"); + ui.orientationComboBox->addItem("ROTATION_MAX"); } CompassConfig::~CompassConfig() { @@ -39,12 +66,14 @@ void CompassConfig::parameterChanged(int uas, int component, QString parameterNa ui.enableCheckBox->setChecked(false); ui.autoDecCheckBox->setEnabled(false); ui.declinationLineEdit->setEnabled(false); + ui.orientationComboBox->setEnabled(false); } else { ui.enableCheckBox->setChecked(true); ui.autoDecCheckBox->setEnabled(true); ui.declinationLineEdit->setEnabled(true); + ui.orientationComboBox->setEnabled(true); } ui.enableCheckBox->setEnabled(true); } @@ -63,6 +92,12 @@ void CompassConfig::parameterChanged(int uas, int component, QString parameterNa { ui.declinationLineEdit->setText(QString::number(value.toDouble())); } + else if (parameterName == "COMPASS_ORIENT") + { + disconnect(ui.orientationComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(orientationComboChanged(int))); + ui.orientationComboBox->setCurrentIndex(value.toInt()); + connect(ui.orientationComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(orientationComboChanged(int))); + } } void CompassConfig::enableClicked(bool enabled) @@ -104,5 +139,11 @@ void CompassConfig::autoDecClicked(bool enabled) void CompassConfig::orientationComboChanged(int index) { + //COMPASS_ORIENT + if (!m_uas) + { + return; + } + m_uas->getParamManager()->setParameter(1,"COMPASS_ORIENT",index); } diff --git a/src/ui/configuration/CompassConfig.ui b/src/ui/configuration/CompassConfig.ui index 7ac1ede4fa..95b9362b44 100644 --- a/src/ui/configuration/CompassConfig.ui +++ b/src/ui/configuration/CompassConfig.ui @@ -55,9 +55,9 @@ - 300 + 290 180 - 91 + 101 23 @@ -70,7 +70,7 @@ 390 180 - 91 + 101 23
@@ -118,7 +118,7 @@ 10 70 - 201 + 211 111 diff --git a/src/ui/configuration/SonarConfig.ui b/src/ui/configuration/SonarConfig.ui index 6bce3475ae..7c40d028ce 100644 --- a/src/ui/configuration/SonarConfig.ui +++ b/src/ui/configuration/SonarConfig.ui @@ -58,7 +58,7 @@ - CheckBox + Enable
-- GitLab From 214607c7049c4dae0a7b5dfc201390d42afb395f Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 12 Jul 2013 11:50:40 -0400 Subject: [PATCH 060/460] Change so airspeed config is only displayed when Arduplane firmware is loaded --- src/ui/configuration/ApmHardwareConfig.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/configuration/ApmHardwareConfig.cc b/src/ui/configuration/ApmHardwareConfig.cc index 06f6a2a354..0341ab345b 100644 --- a/src/ui/configuration/ApmHardwareConfig.cc +++ b/src/ui/configuration/ApmHardwareConfig.cc @@ -52,7 +52,6 @@ ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.radio3DRButton,SLOT(setShown(bool))); connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.batteryMonitorButton,SLOT(setShown(bool))); connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.sonarButton,SLOT(setShown(bool))); - connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.airspeedButton,SLOT(setShown(bool))); connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.opticalFlowButton,SLOT(setShown(bool))); connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.osdButton,SLOT(setShown(bool))); connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.cameraGimbalButton,SLOT(setShown(bool))); @@ -161,6 +160,7 @@ void ApmHardwareConfig::activeUASSet(UASInterface *uas) connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.compassButton,SLOT(setShown(bool))); connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.arduPlaneLevelButton,SLOT(setShown(bool))); connect(ui.manditoryHardware,SIGNAL(toggled(bool)),ui.radioCalibrateButton,SLOT(setShown(bool))); + connect(ui.optionalHardwareButton,SIGNAL(toggled(bool)),ui.airspeedButton,SLOT(setShown(bool))); } else if (uas->getSystemType() == MAV_TYPE_QUADROTOR) { -- GitLab From 8b706b019982af11bd80b9ecf28023281a0cc36a Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 12 Jul 2013 14:00:37 -0400 Subject: [PATCH 061/460] Change so battery monitor config screen properly reads battery voltage now --- src/ui/configuration/BatteryMonitorConfig.cc | 18 ++++++++++++++++++ src/ui/configuration/BatteryMonitorConfig.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/src/ui/configuration/BatteryMonitorConfig.cc b/src/ui/configuration/BatteryMonitorConfig.cc index 5e74cedde2..05b6dc2343 100644 --- a/src/ui/configuration/BatteryMonitorConfig.cc +++ b/src/ui/configuration/BatteryMonitorConfig.cc @@ -32,6 +32,16 @@ BatteryMonitorConfig::BatteryMonitorConfig(QWidget *parent) : AP2ConfigWidget(pa } +void BatteryMonitorConfig::activeUASSet(UASInterface *uas) +{ + if (!uas) + { + return; + } + connect(uas,SIGNAL(batteryChanged(UASInterface*,double,double,double,int)),this,SLOT(batteryChanged(UASInterface*,double,double,double,int))); + AP2ConfigWidget::activeUASSet(uas); +} + void BatteryMonitorConfig::calcDividerSet() { if (!m_uas) @@ -222,6 +232,14 @@ void BatteryMonitorConfig::apmVerCurrentIndexChanged(int index) BatteryMonitorConfig::~BatteryMonitorConfig() { } +void BatteryMonitorConfig::batteryChanged(UASInterface* uas, double voltage, double current, double percent, int seconds) +{ + ui.calcVoltsLineEdit->setText(QString::number(voltage,'f',2)); + if (ui.measuredVoltsLineEdit->text() == "") + { + ui.measuredVoltsLineEdit->setText(ui.calcVoltsLineEdit->text()); + } +} void BatteryMonitorConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { diff --git a/src/ui/configuration/BatteryMonitorConfig.h b/src/ui/configuration/BatteryMonitorConfig.h index 183d782d23..2bbdb56f2e 100644 --- a/src/ui/configuration/BatteryMonitorConfig.h +++ b/src/ui/configuration/BatteryMonitorConfig.h @@ -20,6 +20,8 @@ private slots: void calcDividerSet(); void ampsPerVoltSet(); void batteryCapacitySet(); + void activeUASSet(UASInterface *uas); + void batteryChanged(UASInterface* uas, double voltage, double current, double percent, int seconds); private: Ui::BatteryMonitorConfig ui; }; -- GitLab From 069dced802d06e40a2edd089c7481111b99df2a7 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Fri, 12 Jul 2013 14:49:39 -0700 Subject: [PATCH 062/460] Fix to toolbar size, and to remove QGCToolbar (compile time option) --- qml/components/Button.qml | 2 +- src/ui/MainWindow.cc | 60 ++++++++++++++++----------------------- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/qml/components/Button.qml b/qml/components/Button.qml index ee40e9e5f5..798a161076 100644 --- a/qml/components/Button.qml +++ b/qml/components/Button.qml @@ -18,7 +18,7 @@ Rectangle { id: buttonLabel anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter - anchors.margins: 2 + anchors.margins: 5 text: label color: "white" font.pointSize: 10 diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 3d1d28fd45..0d3029181b 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -168,7 +168,9 @@ MainWindow::MainWindow(QWidget *parent): centerStack = new QStackedWidget(this); setCentralWidget(centerStack); + // Load Toolbar +#ifdef QGC_TOOLBAR_ENABLED toolBar = new QGCToolBar(this); this->addToolBar(toolBar); @@ -187,6 +189,28 @@ MainWindow::MainWindow(QWidget *parent): advancedActions << ui.actionEngineersView; toolBar->setPerspectiveChangeAdvancedActions(advancedActions); +#else + // Add the APM 'toolbar' + + APMToolBar *apmToolBar = new APMToolBar(this); + apmToolBar->setFlightViewAction(ui.actionFlightView); + apmToolBar->setFlightPlanViewAction(ui.actionMissionView); + apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); + apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); + apmToolBar->setSimulationViewAction(ui.actionSimulation_View); + apmToolBar->setTerminalViewAction(ui.actionSimulation_View); + + QDockWidget *widget = new QDockWidget(tr("APM Tool Bar"),this); + widget->setWidget(apmToolBar); + widget->setMinimumHeight(72); + widget->setMaximumHeight(72); + widget->setMinimumWidth(1024); + widget->setFeatures(QDockWidget::NoDockWidgetFeatures); + widget->setTitleBarWidget(new QWidget(this)); // Disables the title bar +// /*widget*/->setStyleSheet("QDockWidget { border: 0px solid #FFFFFF; border-radius: 0px; border-bottom: 0px;}"); + this->addDockWidget(Qt::TopDockWidgetArea, widget); +#endif + customStatusBar = new QGCStatusBar(this); setStatusBar(customStatusBar); statusBar()->setSizeGripEnabled(true); @@ -342,15 +366,6 @@ MainWindow::~MainWindow() void MainWindow::resizeEvent(QResizeEvent * event) { - if (width() > 1200) - { - toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - } - else - { - toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly); - } - QMainWindow::resizeEvent(event); } @@ -604,18 +619,6 @@ void MainWindow::buildCommonWidgets() createDockWidget(simView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_SIMULATION,Qt::RightDockWidgetArea,this->width()/1.5); createDockWidget(pilotView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea,this->width()/1.8); - // Add Our new 'toolbar' - // Create the APM Toolbar - APMToolBar *apmToolBar = new APMToolBar(this); - apmToolBar->setFlightViewAction(ui.actionFlightView); - apmToolBar->setFlightPlanViewAction(ui.actionMissionView); - apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); - apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); - apmToolBar->setSimulationViewAction(ui.actionSimulation_View); - apmToolBar->setTerminalViewAction(ui.actionSimulation_View); - createDockWidget(pilotView,apmToolBar,tr("APM Tool Bar"),"APM_TOOLBAR_DOCKWIDGET",VIEW_FLIGHT,Qt::TopDockWidgetArea,this->width(), 70); - - QGCTabbedInfoView *infoview = new QGCTabbedInfoView(this); infoview->addSource(mavlinkDecoder); createDockWidget(pilotView,infoview,tr("Info View"),"UAS_INFO_INFOVIEW_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea); @@ -858,19 +861,6 @@ void MainWindow::loadDockWidget(QString name) { createDockWidget(centerStack->currentWidget(),new UASQuickView(this),tr("Quick View"),"UAS_INFO_QUICKVIEW_DOCKWIDGET",currentView,Qt::LeftDockWidgetArea); } - else if (name == "APM_TOOLBAR_DOCKWIDGET") - { - // Add Our new 'toolbar' - // Create the APM Toolbar - APMToolBar *apmToolBar = new APMToolBar(this); - apmToolBar->setFlightViewAction(ui.actionFlightView); - apmToolBar->setFlightPlanViewAction(ui.actionMissionView); - apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); - apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); - apmToolBar->setSimulationViewAction(ui.actionSimulation_View); - apmToolBar->setTerminalViewAction(ui.actionSimulation_View); - createDockWidget(centerStack->currentWidget(),apmToolBar,tr("APM Tool Bar"),"APM_TOOLBAR_DOCKWIDGET",currentView,Qt::TopDockWidgetArea,this->width(), 70); - } else { if (customWidgetNameToFilenameMap.contains(name)) @@ -965,7 +955,7 @@ void MainWindow::showHILConfigurationWidget(UASInterface* uas) //createDockWidget(centerStack->currentWidget(),tool,"Unnamed Tool " + QString::number(ui.menuTools->actions().size()),"UNNAMED_TOOL_" + QString::number(ui.menuTools->actions().size())+"DOCK",currentView,Qt::BottomDockWidgetArea); QGCHilConfiguration* hconf = new QGCHilConfiguration(mav, this); - QString hilDockName = tr("HIL Config %1").arg(uas->getUASName()); + QString hilDockName = tr("HIL Config %1").arg(uas->getUASName()); QDockWidget* hilDock = createDockWidget(simView, hconf,hilDockName, hilDockName.toUpper().replace(" ", "_"),VIEW_SIMULATION,Qt::LeftDockWidgetArea); hilDocks.insert(mav->getUASID(), hilDock); -- GitLab From db3e3dab31d59d3596dfe7c22916d426ebed55e3 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Fri, 12 Jul 2013 17:36:57 -0700 Subject: [PATCH 063/460] Fixed APM Tool Bar connect button not changing images when connected --- qml/ApmToolBar.qml | 35 +++++++++++++++++++++++------------ src/ui/apmtoolbar.cpp | 13 ++++++++++--- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/qml/ApmToolBar.qml b/qml/ApmToolBar.qml index 21cc0fd3d4..fed71697aa 100644 --- a/qml/ApmToolBar.qml +++ b/qml/ApmToolBar.qml @@ -8,26 +8,37 @@ Rectangle { property alias backgroundColor : toolbar.color property alias linkNameLabel: linkDevice.label property alias baudrateLabel: baudrate.label + property bool connected: false width: 1024 < parent.width ? 1024 : parent.width height: 72 color: "black" border.color: "black" - Connections { - target: globalObj - onMAVConnected: { - console.log("Change Connection " + connected) - if (connect){ - console.log("connected") - // connectButton.image = "./resources/apmplanner/toolbar/disconnect.png" - } else { - console.log("disconnected") - // connectButton.image = "./resources/apmplanner/toolbar/connect.png" - } - } + onConnectedChanged: { + if (connected){ + console.log("APM Tool BAR QML: connected") + connectButton.image = "./resources/apmplanner/toolbar/disconnect.png" + } else { + console.log("APM Tool BAR QML: disconnected") + connectButton.image = "./resources/apmplanner/toolbar/connect.png" + } } +// Connections { +// target: globalObj +// onMAVConnected: { +// console.log("QML Change Connection " + connected) +// if (connected){ +// console.log("connected") +// connectButton.image = "./resources/apmplanner/toolbar/disconnect.png" +// } else { +// console.log("disconnected") +// connectButton.image = "./resources/apmplanner/toolbar/connect.png" +// } +// } +// } + Row { anchors.left: parent.left spacing: 2 diff --git a/src/ui/apmtoolbar.cpp b/src/ui/apmtoolbar.cpp index 6ed411e7d0..ff9a944199 100644 --- a/src/ui/apmtoolbar.cpp +++ b/src/ui/apmtoolbar.cpp @@ -10,16 +10,18 @@ APMToolBar::APMToolBar(QWidget *parent): QDeclarativeView(parent) { // Configure our QML object - this->rootContext()->setContextProperty("globalObj", this); setSource(QUrl::fromLocalFile("qml/ApmToolBar.qml")); setResizeMode(QDeclarativeView::SizeRootObjectToView); - + this->rootContext()->setContextProperty("globalObj", this); connect(LinkManager::instance(),SIGNAL(newLink(LinkInterface*)), this, SLOT(updateLinkDisplay(LinkInterface*))); if (LinkManager::instance()->getLinks().count()>=3) { updateLinkDisplay(LinkManager::instance()->getLinks().last()); } + + QObject *object = rootObject(); + object->setProperty("connected", false); } void APMToolBar::setFlightViewAction(QAction *action) @@ -111,6 +113,11 @@ void APMToolBar::connectMAV() result = !LinkManager::instance()->getLinks().last()->disconnect(); } qDebug() << "result = " << result; + + // Change the image to represent the state + QObject *object = rootObject(); + object->setProperty("connected", result); + emit MAVConnected(result); } @@ -147,7 +154,7 @@ void APMToolBar::updateLinkDisplay(LinkInterface* newLink) qDebug() << "APMToolBar: updateLinkDisplay"; QObject *object = rootObject(); - if (newLink){ + if (newLink && object){ qint64 baudrate = newLink->getNominalDataRate(); object->setProperty("baudrateLabel", QString::number(baudrate)); -- GitLab From c59b4e5936cc853d356a8837123dca43e11b3120 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Mon, 15 Jul 2013 08:37:40 -0400 Subject: [PATCH 064/460] Change for label sizes so text is not clipped --- src/ui/configuration/AccelCalibrationConfig.ui | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/configuration/AccelCalibrationConfig.ui b/src/ui/configuration/AccelCalibrationConfig.ui index a1b99045e6..6555a57258 100644 --- a/src/ui/configuration/AccelCalibrationConfig.ui +++ b/src/ui/configuration/AccelCalibrationConfig.ui @@ -34,8 +34,8 @@ 70 160 - 81 - 31 + 111 + 41 @@ -48,8 +48,8 @@ Accelerometer 20 50 - 211 - 91 + 311 + 101 -- GitLab From 922b5d6e151c8d9743a2edd2aebc03216011f495 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Mon, 15 Jul 2013 08:37:50 -0400 Subject: [PATCH 065/460] Change in Organization Domain of application --- src/QGCCore.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/QGCCore.cc b/src/QGCCore.cc index c4a38bf0e3..d2379d63b5 100644 --- a/src/QGCCore.cc +++ b/src/QGCCore.cc @@ -72,7 +72,7 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv) this->setApplicationName(QGC_APPLICATION_NAME); this->setApplicationVersion(QGC_APPLICATION_VERSION); this->setOrganizationName(QLatin1String("diydrones")); - this->setOrganizationDomain("org.diydrones"); + this->setOrganizationDomain("com.diydrones"); // Set settings format QSettings::setDefaultFormat(QSettings::IniFormat); -- GitLab From a1083c5323ebfb03d0589535498324bd20f34255 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 16 Jul 2013 09:03:55 -0400 Subject: [PATCH 066/460] Changes for AdvParameterList number display, and proper handling of CH6/7/8 options in ArduCopter pids --- src/ui/configuration/AdvParameterList.cc | 4 +- src/ui/configuration/ArduCopterPidConfig.cc | 109 ++++++++++++++++++++ src/ui/configuration/ArduCopterPidConfig.h | 3 + 3 files changed, 114 insertions(+), 2 deletions(-) diff --git a/src/ui/configuration/AdvParameterList.cc b/src/ui/configuration/AdvParameterList.cc index 5dccd07079..e1abae86ec 100644 --- a/src/ui/configuration/AdvParameterList.cc +++ b/src/ui/configuration/AdvParameterList.cc @@ -39,7 +39,7 @@ void AdvParameterList::parameterChanged(int uas, int component, QString paramete { ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,0,new QTableWidgetItem("Unknown")); } - ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,1,new QTableWidgetItem(QString::number(value.toFloat(),'g',2))); + ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,1,new QTableWidgetItem(QString::number(value.toFloat(),'f',2))); ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,2,new QTableWidgetItem(parameterName)); if (paramToDescriptionMap.contains(parameterName)) { @@ -51,5 +51,5 @@ void AdvParameterList::parameterChanged(int uas, int component, QString paramete } paramValueMap[parameterName] = ui.tableWidget->item(ui.tableWidget->rowCount()-1,1); } - paramValueMap[parameterName]->setText(QString::number(value.toFloat(),'g',2)); + paramValueMap[parameterName]->setText(QString::number(value.toFloat(),'f',2)); } diff --git a/src/ui/configuration/ArduCopterPidConfig.cc b/src/ui/configuration/ArduCopterPidConfig.cc index e6e0498fbf..0bdf0a6b19 100644 --- a/src/ui/configuration/ArduCopterPidConfig.cc +++ b/src/ui/configuration/ArduCopterPidConfig.cc @@ -49,6 +49,80 @@ ArduCopterPidConfig::ArduCopterPidConfig(QWidget *parent) : AP2ConfigWidget(pare connect(ui.writePushButton,SIGNAL(clicked()),this,SLOT(writeButtonClicked())); connect(ui.refreshPushButton,SIGNAL(clicked()),this,SLOT(refreshButtonClicked())); + + + + ch6ValueToTextList.append(QPair(0,"CH6_NONE")); + ch6ValueToTextList.append(QPair(1,"CH6_STABILIZE_KP")); + ch6ValueToTextList.append(QPair(2,"CH6_STABILIZE_KI")); + ch6ValueToTextList.append(QPair(3,"CH6_YAW_KP")); + ch6ValueToTextList.append(QPair(24,"CH6_YAW_KI")); + ch6ValueToTextList.append(QPair(4,"CH6_RATE_KP")); + ch6ValueToTextList.append(QPair(5,"CH6_RATE_KI")); + ch6ValueToTextList.append(QPair(6,"CH6_YAW_RATE_KP")); + ch6ValueToTextList.append(QPair(26,"CH6_YAW_RATE_KD")); + ch6ValueToTextList.append(QPair(7,"CH6_THROTTLE_KP")); + ch6ValueToTextList.append(QPair(9,"CH6_RELAY")); + ch6ValueToTextList.append(QPair(10,"CH6_WP_SPEED")); + ch6ValueToTextList.append(QPair(12,"CH6_LOITER_KP")); + ch6ValueToTextList.append(QPair(13,"CH6_HELI_EXTERNAL_GYRO")); + ch6ValueToTextList.append(QPair(14,"CH6_THR_HOLD_KP")); + ch6ValueToTextList.append(QPair(17,"CH6_OPTFLOW_KP")); + ch6ValueToTextList.append(QPair(18,"CH6_OPTFLOW_KI")); + ch6ValueToTextList.append(QPair(19,"CH6_OPTFLOW_KD")); + ch6ValueToTextList.append(QPair(21,"CH6_RATE_KD")); + ch6ValueToTextList.append(QPair(22,"CH6_LOITER_RATE_KP")); + ch6ValueToTextList.append(QPair(23,"CH6_LOITER_RATE_KD")); + ch6ValueToTextList.append(QPair(25,"CH6_ACRO_KP")); + ch6ValueToTextList.append(QPair(27,"CH6_LOITER_KI")); + ch6ValueToTextList.append(QPair(28,"CH6_LOITER_RATE_KI")); + ch6ValueToTextList.append(QPair(29,"CH6_STABILIZE_KD")); + ch6ValueToTextList.append(QPair(30,"CH6_AHRS_YAW_KP")); + ch6ValueToTextList.append(QPair(31,"CH6_AHRS_KP")); + ch6ValueToTextList.append(QPair(32,"CH6_INAV_TC")); + ch6ValueToTextList.append(QPair(33,"CH6_THROTTLE_KI")); + ch6ValueToTextList.append(QPair(34,"CH6_THR_ACCEL_KP")); + ch6ValueToTextList.append(QPair(35,"CH6_THR_ACCEL_KI")); + ch6ValueToTextList.append(QPair(36,"CH6_THR_ACCEL_KD")); + ch6ValueToTextList.append(QPair(38,"CH6_DECLINATION")); + ch6ValueToTextList.append(QPair(39,"CH6_CIRCLE_RATE")); + for (int i=0;iaddItem(ch6ValueToTextList[i].second); + } + + ch7ValueToTextList.append(QPair(0,"Do nothing")); + ch7ValueToTextList.append(QPair(2,"Flip")); + ch7ValueToTextList.append(QPair(3,"Simple mode")); + ch7ValueToTextList.append(QPair(4,"RTL")); + ch7ValueToTextList.append(QPair(5,"Save Trim")); + ch7ValueToTextList.append(QPair(7,"Save WP")); + ch7ValueToTextList.append(QPair(8,"Multi Mode")); + ch7ValueToTextList.append(QPair(9,"Camera Trigger")); + ch7ValueToTextList.append(QPair(10,"Sonar")); + ch7ValueToTextList.append(QPair(11,"Fence")); + ch7ValueToTextList.append(QPair(12,"ResetToArmedYaw")); + for (int i=0;iaddItem(ch7ValueToTextList[i].second); + } + + ch8ValueToTextList.append(QPair(0,"Do nothing")); + ch8ValueToTextList.append(QPair(2,"Flip")); + ch8ValueToTextList.append(QPair(3,"Simple mode")); + ch8ValueToTextList.append(QPair(4,"RTL")); + ch8ValueToTextList.append(QPair(5,"Save Trim")); + ch8ValueToTextList.append(QPair(7,"Save WP")); + ch8ValueToTextList.append(QPair(8,"Multi Mode")); + ch8ValueToTextList.append(QPair(9,"Camera Trigger")); + ch8ValueToTextList.append(QPair(10,"Sonar")); + ch8ValueToTextList.append(QPair(11,"Fence")); + ch8ValueToTextList.append(QPair(12,"ResetToArmedYaw")); + for (int i=0;iaddItem(ch8ValueToTextList[i].second); + } + } ArduCopterPidConfig::~ArduCopterPidConfig() @@ -60,6 +134,35 @@ void ArduCopterPidConfig::parameterChanged(int uas, int component, QString param { nameToBoxMap[parameterName]->setValue(value.toDouble()); } + else if (parameterName == "TUNE") + { + for (int i=0;isetCurrentIndex(i); + } + } + } + else if (parameterName == "CH7_OPT") + { + for (int i=0;isetCurrentIndex(i); + } + } + } + else if (parameterName == "CH8_OPT") + { + for (int i=0;isetCurrentIndex(i); + } + } } void ArduCopterPidConfig::writeButtonClicked() { @@ -71,6 +174,9 @@ void ArduCopterPidConfig::writeButtonClicked() { m_uas->getParamManager()->setParameter(1,i.key(),i.value()->value()); } + m_uas->getParamManager()->setParameter(1,"TUNE",ch8ValueToTextList[ui.ch6OptComboBox->currentIndex()].first); + m_uas->getParamManager()->setParameter(1,"CH7_OPT",ch7ValueToTextList[ui.ch7OptComboBox->currentIndex()].first); + m_uas->getParamManager()->setParameter(1,"CH8_OPT",ch8ValueToTextList[ui.ch8OptComboBox->currentIndex()].first); } void ArduCopterPidConfig::refreshButtonClicked() @@ -83,4 +189,7 @@ void ArduCopterPidConfig::refreshButtonClicked() { m_uas->getParamManager()->requestParameterUpdate(1,i.key()); } + m_uas->getParamManager()->requestParameterUpdate(1,"TUNE"); + m_uas->getParamManager()->requestParameterUpdate(1,"CH7_OPT"); + m_uas->getParamManager()->requestParameterUpdate(1,"CH8_OPT"); } diff --git a/src/ui/configuration/ArduCopterPidConfig.h b/src/ui/configuration/ArduCopterPidConfig.h index b7b2b07354..dff3bb5a55 100644 --- a/src/ui/configuration/ArduCopterPidConfig.h +++ b/src/ui/configuration/ArduCopterPidConfig.h @@ -18,6 +18,9 @@ private slots: void refreshButtonClicked(); void parameterChanged(int uas, int component, QString parameterName, QVariant value); private: + QList > ch6ValueToTextList; + QList > ch7ValueToTextList; + QList > ch8ValueToTextList; QMap nameToBoxMap; Ui::ArduCopterPidConfig ui; }; -- GitLab From 98dc9dfcb1164f7852d0570ee4dac6476c59808e Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 16 Jul 2013 09:07:57 -0400 Subject: [PATCH 067/460] Typo fix, missed a bracket --- src/ui/configuration/ArduCopterPidConfig.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui/configuration/ArduCopterPidConfig.cc b/src/ui/configuration/ArduCopterPidConfig.cc index 0bdf0a6b19..f64dec4c2b 100644 --- a/src/ui/configuration/ArduCopterPidConfig.cc +++ b/src/ui/configuration/ArduCopterPidConfig.cc @@ -161,6 +161,7 @@ void ArduCopterPidConfig::parameterChanged(int uas, int component, QString param if (ch8ValueToTextList[i].first == value.toInt()) { ui.ch8OptComboBox->setCurrentIndex(i); + } } } } -- GitLab From eea4f8fb9c40e345e87e4ebbdcab4ba07967f279 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 16 Jul 2013 11:41:29 -0400 Subject: [PATCH 068/460] Changes for compiling QSerialPort based communications library in windows --- libs/serialport/qserialportglobal.h | 4 ++-- src/ui/XbeeConfigurationWindow.cpp | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libs/serialport/qserialportglobal.h b/libs/serialport/qserialportglobal.h index 03cd6a62b7..34c5ba4ffe 100644 --- a/libs/serialport/qserialportglobal.h +++ b/libs/serialport/qserialportglobal.h @@ -51,12 +51,12 @@ QT_BEGIN_NAMESPACE # if defined(QT_BUILD_SERIALPORT_LIB) # define Q_SERIALPORT_EXPORT Q_DECL_EXPORT # else -# define Q_SERIALPORT_EXPORT Q_DECL_IMPORT +//# define Q_SERIALPORT_EXPORT Q_DECL_IMPORT # endif #else # define Q_SERIALPORT_EXPORT #endif - +# define Q_SERIALPORT_EXPORT // The macro has been available only since Qt 5.0 #ifndef Q_DECL_OVERRIDE #define Q_DECL_OVERRIDE diff --git a/src/ui/XbeeConfigurationWindow.cpp b/src/ui/XbeeConfigurationWindow.cpp index 7be847ac65..6910261889 100644 --- a/src/ui/XbeeConfigurationWindow.cpp +++ b/src/ui/XbeeConfigurationWindow.cpp @@ -8,7 +8,8 @@ #include #ifdef _WIN32 -#include +//#include +#include #endif #if defined (__APPLE__) && defined (__MACH__) @@ -368,11 +369,12 @@ void XbeeConfigurationWindow::setupPortList() #ifdef _WIN32 // Get the ports available on this system - QList ports = QextSerialEnumerator::getPorts(); + QList ports = QSerialPortInfo::availablePorts(); + //QList ports = QextSerialEnumerator::getPorts(); // Add the ports in reverse order, because we prepend them to the list for (int i = ports.size() - 1; i >= 0; i--) { - QString portString = QString(ports.at(i).portName.toLocal8Bit().constData()) + " - " + QString(ports.at(i).friendName.toLocal8Bit().constData()).split("(").first(); + QString portString = QString(ports.at(i).portName.toLocal8Bit().constData()); // Prepend newly found port to the list if (portBox->findText(portString) == -1) { portBox->insertItem(0, portString); -- GitLab From 111300d2da431f7da827ffbd8ba21548f345a4a9 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 16 Jul 2013 11:41:41 -0400 Subject: [PATCH 069/460] Change in how Flight modes are read for APMCopter --- src/ui/configuration/FlightModeConfig.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ui/configuration/FlightModeConfig.cc b/src/ui/configuration/FlightModeConfig.cc index e0a04572ab..933bf07dda 100644 --- a/src/ui/configuration/FlightModeConfig.cc +++ b/src/ui/configuration/FlightModeConfig.cc @@ -152,12 +152,12 @@ void FlightModeConfig::saveButtonClicked() } else if (m_uas->getSystemType() == MAV_TYPE_QUADROTOR) { - m_uas->getParamManager()->setParameter(1,"FLTMODE1",(char)ui.mode1ComboBox->currentIndex()+1); - m_uas->getParamManager()->setParameter(1,"FLTMODE2",(char)ui.mode2ComboBox->currentIndex()+1); - m_uas->getParamManager()->setParameter(1,"FLTMODE3",(char)ui.mode3ComboBox->currentIndex()+1); - m_uas->getParamManager()->setParameter(1,"FLTMODE4",(char)ui.mode4ComboBox->currentIndex()+1); - m_uas->getParamManager()->setParameter(1,"FLTMODE5",(char)ui.mode5ComboBox->currentIndex()+1); - m_uas->getParamManager()->setParameter(1,"FLTMODE6",(char)ui.mode6ComboBox->currentIndex()+1); + m_uas->getParamManager()->setParameter(1,"FLTMODE1",(char)ui.mode1ComboBox->currentIndex()); + m_uas->getParamManager()->setParameter(1,"FLTMODE2",(char)ui.mode2ComboBox->currentIndex()); + m_uas->getParamManager()->setParameter(1,"FLTMODE3",(char)ui.mode3ComboBox->currentIndex()); + m_uas->getParamManager()->setParameter(1,"FLTMODE4",(char)ui.mode4ComboBox->currentIndex()); + m_uas->getParamManager()->setParameter(1,"FLTMODE5",(char)ui.mode5ComboBox->currentIndex()); + m_uas->getParamManager()->setParameter(1,"FLTMODE6",(char)ui.mode6ComboBox->currentIndex()); } } @@ -280,27 +280,27 @@ void FlightModeConfig::parameterChanged(int uas, int component, QString paramete { if (parameterName == "FLTMODE1") { - ui.mode1ComboBox->setCurrentIndex(value.toInt()-1); + ui.mode1ComboBox->setCurrentIndex(value.toInt()); } else if (parameterName == "FLTMODE2") { - ui.mode2ComboBox->setCurrentIndex(value.toInt()-1); + ui.mode2ComboBox->setCurrentIndex(value.toInt()); } else if (parameterName == "FLTMODE3") { - ui.mode3ComboBox->setCurrentIndex(value.toInt()-1); + ui.mode3ComboBox->setCurrentIndex(value.toInt()); } else if (parameterName == "FLTMODE4") { - ui.mode4ComboBox->setCurrentIndex(value.toInt()-1); + ui.mode4ComboBox->setCurrentIndex(value.toInt()); } else if (parameterName == "FLTMODE5") { - ui.mode5ComboBox->setCurrentIndex(value.toInt()-1); + ui.mode5ComboBox->setCurrentIndex(value.toInt()); } else if (parameterName == "FLTMODE6") { - ui.mode6ComboBox->setCurrentIndex(value.toInt()-1); + ui.mode6ComboBox->setCurrentIndex(value.toInt()); } } } -- GitLab From 75def93bc34cf14d08606bccf42078dab45e63ac Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Tue, 16 Jul 2013 09:37:40 -0700 Subject: [PATCH 070/460] APM ToolBar chnages --- qgroundcontrol.pro | 3 ++- qml/ApmToolBar.qml | 43 +++++++++++++++++++++++++++++-- qml/components/DigitalDisplay.qml | 30 +++++++++++++++++++++ src/comm/SerialLink.cc | 1 + src/ui/apmtoolbar.cpp | 3 ++- 5 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 qml/components/DigitalDisplay.qml diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index c968bfd9a0..80d0414c31 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -773,7 +773,8 @@ unix:!macx:!symbian: LIBS += -losg OTHER_FILES += \ dongfang_notes.txt \ - src/ui/dongfang-scrapyard.txt + src/ui/dongfang-scrapyard.txt \ + qml/components/DigitalDisplay.qml OTHER_FILES += \ qml/ApmToolBar.qml \ diff --git a/qml/ApmToolBar.qml b/qml/ApmToolBar.qml index fed71697aa..393e4c3bf9 100644 --- a/qml/ApmToolBar.qml +++ b/qml/ApmToolBar.qml @@ -25,6 +25,7 @@ Rectangle { } } +// [BB] The code below should work, not sure why. replaced with code above // Connections { // target: globalObj // onMAVConnected: { @@ -43,7 +44,7 @@ Rectangle { anchors.left: parent.left spacing: 2 - Rectangle { + Rectangle { // Spacer width: 5 height: parent.height color: "black" @@ -94,6 +95,44 @@ Rectangle { image: "./resources/apmplanner/toolbar/terminal.png" onClicked: globalObj.triggerTerminalView() } + + Rectangle { // Spacer + width: 5 + height: parent.height + color: "black" + } + +// DigitalDisplay { // Information Pane +// title:"Mode" +// textValue: "Stabilize" +// color: "black" +// } +// DigitalDisplay { // Information Pane +// title: "Speed" +// textValue: "11.0m/s" +// color: "black" +// } +// DigitalDisplay { // Information Pane +// title: "Alt" +// textValue: "20.0m" +// color: "black" +// } +// DigitalDisplay { // Information Pane +// title: "Volts" +// textValue: "14.8V" +// color: "black" +// } +// DigitalDisplay { // Information Pane +// title: "Current" +// textValue: "12.0A" +// color: "black" +// } +// DigitalDisplay { // Information Pane +// title: "Level" +// textValue: "77%" +// color: "black" +// } + } Row { @@ -129,7 +168,7 @@ Rectangle { onClicked: globalObj.connectMAV() } - Rectangle { + Rectangle { // Spacer anchors.right: parent.right width: 5 height: parent.height diff --git a/qml/components/DigitalDisplay.qml b/qml/components/DigitalDisplay.qml new file mode 100644 index 0000000000..be69b6712b --- /dev/null +++ b/qml/components/DigitalDisplay.qml @@ -0,0 +1,30 @@ +import QtQuick 1.1 + +Rectangle { + + property alias title: displayTitle.text + property string textValue: "none" + + width: 100 + height: parent.height/3 + anchors.verticalCenter: parent.verticalCenter + border.color: "white" + + Text { + id:displayTitle + anchors.left: parent.left + anchors.leftMargin: 3 + anchors.verticalCenter: parent.verticalCenter + text: "blank" + color: "white" + } + + Text { + id:displayValue + anchors.right: parent.right + anchors.rightMargin: 3 + anchors.verticalCenter: parent.verticalCenter + text: textValue + color: "white" + } +} diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index bd456d93b4..0091e434af 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -96,6 +96,7 @@ QVector* SerialLink::getCurrentPorts() Q_ASSERT_X(m_ports != NULL, "getCurrentPorts", "m_ports is NULL"); m_ports->clear(); // Example use QSerialPortInfo + // [TODO] make this thread safe foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { // qDebug() << "PortName : " << info.portName() diff --git a/src/ui/apmtoolbar.cpp b/src/ui/apmtoolbar.cpp index ff9a944199..f3253160bf 100644 --- a/src/ui/apmtoolbar.cpp +++ b/src/ui/apmtoolbar.cpp @@ -21,7 +21,8 @@ APMToolBar::APMToolBar(QWidget *parent): } QObject *object = rootObject(); - object->setProperty("connected", false); + if (object) + object->setProperty("connected", false); } void APMToolBar::setFlightViewAction(QAction *action) -- GitLab From eb8d8faa37be98a8f647e60fa6acc259bf120a36 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Tue, 16 Jul 2013 10:21:13 -0700 Subject: [PATCH 071/460] Fixed two warnings. --- src/comm/MAVLinkProtocol.cc | 2 +- src/uas/UASManager.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/comm/MAVLinkProtocol.cc b/src/comm/MAVLinkProtocol.cc index 180670b813..227e1f0958 100644 --- a/src/comm/MAVLinkProtocol.cc +++ b/src/comm/MAVLinkProtocol.cc @@ -187,7 +187,7 @@ void MAVLinkProtocol::linkStatusChanged(bool connected) link->writeBytes(init, sizeof(init)); // Stop any running mavlink instance - char* cmd = "mavlink stop\n"; + const char* cmd = "mavlink stop\n"; link->writeBytes(cmd, strlen(cmd)); link->writeBytes(init, 2); cmd = "uorb start"; diff --git a/src/uas/UASManager.cc b/src/uas/UASManager.cc index 00bb81ba26..21a6a4d9ab 100644 --- a/src/uas/UASManager.cc +++ b/src/uas/UASManager.cc @@ -232,11 +232,11 @@ void UASManager::uavChangedHomePosition(int uav, double lat, double lon, double **/ UASManager::UASManager() : activeUAS(NULL), + offlineUASWaypointManager(NULL), homeLat(47.3769), homeLon(8.549444), homeAlt(470.0), - homeFrame(MAV_FRAME_GLOBAL), - offlineUASWaypointManager(NULL) + homeFrame(MAV_FRAME_GLOBAL) { loadSettings(); setLocalNEDSafetyBorders(1, -1, 0, -1, 1, -1); -- GitLab From d3e93a35317f1619884cb1a20c8c8bb6b7841dff Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Tue, 16 Jul 2013 11:13:08 -0700 Subject: [PATCH 072/460] APM Tool Bar: connected coonect(bool) signal to connect button. --- src/QGCCore.cc | 33 ++---------------------------- src/ui/MainWindow.cc | 46 ++++++++++++++++++++++++------------------ src/ui/QGCStatusBar.cc | 13 +----------- src/ui/QGCToolBar.cc | 2 ++ src/ui/apmtoolbar.cpp | 19 ++++++++++++----- src/ui/apmtoolbar.h | 1 + 6 files changed, 46 insertions(+), 68 deletions(-) diff --git a/src/QGCCore.cc b/src/QGCCore.cc index d2379d63b5..ee0e4ef818 100644 --- a/src/QGCCore.cc +++ b/src/QGCCore.cc @@ -168,38 +168,9 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv) // Remove splash screen splashScreen->finish(mainWindow); - if (upgraded) mainWindow->showInfoMessage(tr("Default Settings Loaded"), tr("APM Planner has been upgraded from version %1 to version %2. Some of your user preferences have been reset to defaults for safety reasons. Please adjust them where needed.").arg(lastApplicationVersion).arg(QGC_APPLICATION_VERSION)); + if (upgraded) mainWindow->showInfoMessage(tr("Default Settings Loaded"), + tr("APM Planner has been upgraded from version %1 to version %2. Some of your user preferences have been reset to defaults for safety reasons. Please adjust them where needed.").arg(lastApplicationVersion).arg(QGC_APPLICATION_VERSION)); - // Check if link could be connected - if (!udpLink->connect()) - { - QMessageBox msgBox; - msgBox.setIcon(QMessageBox::Critical); - msgBox.setText("Could not connect UDP port. Is an instance of " + qAppName() + "already running?"); - msgBox.setInformativeText("You will not be able to receive data via UDP. Please check that you're running the right executable and then re-start " + qAppName() + ". Do you want to close the application?"); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::No); - int ret = msgBox.exec(); - - // Close the message box shortly after the click to prevent accidental clicks - QTimer::singleShot(15000, &msgBox, SLOT(reject())); - - // Exit application - if (ret == QMessageBox::Yes) - { - //mainWindow->close(); - QTimer::singleShot(200, mainWindow, SLOT(close())); - } - } - -// forever -// { -// QGC::SLEEP::msleep(5000); -// } - -// mainWindow->close(); -// mainWindow->deleteLater(); -// QGC::SLEEP::msleep(200); } /** diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 0d3029181b..eab45af760 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -189,26 +189,6 @@ MainWindow::MainWindow(QWidget *parent): advancedActions << ui.actionEngineersView; toolBar->setPerspectiveChangeAdvancedActions(advancedActions); -#else - // Add the APM 'toolbar' - - APMToolBar *apmToolBar = new APMToolBar(this); - apmToolBar->setFlightViewAction(ui.actionFlightView); - apmToolBar->setFlightPlanViewAction(ui.actionMissionView); - apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); - apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); - apmToolBar->setSimulationViewAction(ui.actionSimulation_View); - apmToolBar->setTerminalViewAction(ui.actionSimulation_View); - - QDockWidget *widget = new QDockWidget(tr("APM Tool Bar"),this); - widget->setWidget(apmToolBar); - widget->setMinimumHeight(72); - widget->setMaximumHeight(72); - widget->setMinimumWidth(1024); - widget->setFeatures(QDockWidget::NoDockWidgetFeatures); - widget->setTitleBarWidget(new QWidget(this)); // Disables the title bar -// /*widget*/->setStyleSheet("QDockWidget { border: 0px solid #FFFFFF; border-radius: 0px; border-bottom: 0px;}"); - this->addDockWidget(Qt::TopDockWidgetArea, widget); #endif customStatusBar = new QGCStatusBar(this); @@ -235,6 +215,28 @@ MainWindow::MainWindow(QWidget *parent): connect(LinkManager::instance(), SIGNAL(newLink(LinkInterface*)), this, SLOT(addLink(LinkInterface*))); +#ifndef QGC_TOOLBAR_ENABLED + // Add the APM 'toolbar' + + APMToolBar *apmToolBar = new APMToolBar(this); + apmToolBar->setFlightViewAction(ui.actionFlightView); + apmToolBar->setFlightPlanViewAction(ui.actionMissionView); + apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); + apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); + apmToolBar->setSimulationViewAction(ui.actionSimulation_View); + apmToolBar->setTerminalViewAction(ui.actionSimulation_View); + + QDockWidget *widget = new QDockWidget(tr("APM Tool Bar"),this); + widget->setWidget(apmToolBar); + widget->setMinimumHeight(72); + widget->setMaximumHeight(72); + widget->setMinimumWidth(1024); + widget->setFeatures(QDockWidget::NoDockWidgetFeatures); + widget->setTitleBarWidget(new QWidget(this)); // Disables the title bar +// /*widget*/->setStyleSheet("QDockWidget { border: 0px solid #FFFFFF; border-radius: 0px; border-bottom: 0px;}"); + this->addDockWidget(Qt::TopDockWidgetArea, widget); +#endif + // Connect user interface devices emit initStatusChanged("Initializing joystick interface."); joystickWidget = 0; @@ -918,6 +920,8 @@ void MainWindow::showTool(bool show) }*/ void MainWindow::addCentralWidget(QWidget* widget, const QString& title) { + Q_UNUSED(title); + // Check if this widget already has been added if (centerStack->indexOf(widget) == -1) { @@ -1729,6 +1733,7 @@ void MainWindow::commsWidgetDestroyed(QObject *obj) void MainWindow::setActiveUAS(UASInterface* uas) { + Q_UNUSED(uas); // Enable and rename menu // ui.menuUnmanned_System->setTitle(uas->getUASName()); // if (!ui.menuUnmanned_System->isEnabled()) ui.menuUnmanned_System->setEnabled(true); @@ -1950,6 +1955,7 @@ void MainWindow::UASCreated(UASInterface* uas) void MainWindow::UASDeleted(UASInterface* uas) { + Q_UNUSED(uas); if (UASManager::instance()->getUASList().count() == 0) { // Last system deleted diff --git a/src/ui/QGCStatusBar.cc b/src/ui/QGCStatusBar.cc index 04f77de2f4..2870e20f97 100644 --- a/src/ui/QGCStatusBar.cc +++ b/src/ui/QGCStatusBar.cc @@ -49,16 +49,11 @@ QGCStatusBar::QGCStatusBar(QWidget *parent) : void QGCStatusBar::paintEvent(QPaintEvent * event) { + Q_UNUSED(event); QPainter p(this); QStyleOption opt; opt.initFrom(this); style()->drawPrimitive(QStyle::PE_PanelStatusBar, &opt, &p, this); - //QStatusBar::paintEvent(event); -// if (currentMessage().length() == 0) { -// QStatusBar::paintEvent(event); -// } else { - -// } } void QGCStatusBar::setLogPlayer(QGCMAVLinkLogPlayer* player) @@ -66,12 +61,6 @@ void QGCStatusBar::setLogPlayer(QGCMAVLinkLogPlayer* player) this->player = player; addPermanentWidget(player); connect(toggleLoggingButton, SIGNAL(clicked(bool)), this, SLOT(logging(bool))); - //connect(MainWindow::instance()->getMAVLink(), SIGNAL(loggingChanged(bool)), toggleLoggingButton, SLOT(setChecked(bool))); - - // XXX Mutex issue if called like this -// toggleLoggingButton->blockSignals(true); -// toggleLoggingButton->setChecked(MainWindow::instance()->getMAVLink()->loggingEnabled()); -// toggleLoggingButton->blockSignals(false); } void QGCStatusBar::logging(bool checked) diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 1a7414bd87..30d89f5d81 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -423,6 +423,8 @@ void QGCToolBar::updateBatteryRemaining(UASInterface* uas, double voltage, doubl { Q_UNUSED(uas); Q_UNUSED(seconds); + Q_UNUSED(current); + if (batteryPercent != percent || batteryVoltage != voltage) changed = true; batteryPercent = percent; batteryVoltage = voltage; diff --git a/src/ui/apmtoolbar.cpp b/src/ui/apmtoolbar.cpp index f3253160bf..56fd991a0a 100644 --- a/src/ui/apmtoolbar.cpp +++ b/src/ui/apmtoolbar.cpp @@ -20,9 +20,7 @@ APMToolBar::APMToolBar(QWidget *parent): updateLinkDisplay(LinkManager::instance()->getLinks().last()); } - QObject *object = rootObject(); - if (object) - object->setProperty("connected", false); + setConnection(false); } void APMToolBar::setFlightViewAction(QAction *action) @@ -116,12 +114,18 @@ void APMToolBar::connectMAV() qDebug() << "result = " << result; // Change the image to represent the state - QObject *object = rootObject(); - object->setProperty("connected", result); + setConnection(result); emit MAVConnected(result); } +void APMToolBar::setConnection(bool connection) +{ + // Change the image to represent the state + QObject *object = rootObject(); + object->setProperty("connected", connection); +} + APMToolBar::~APMToolBar() { qDebug() << "Destory APM Toolbar"; @@ -161,5 +165,10 @@ void APMToolBar::updateLinkDisplay(LinkInterface* newLink) QString linkName = newLink->getName(); object->setProperty("linkNameLabel", linkName); + + connect(newLink, SIGNAL(connected(bool)), + this, SLOT(setConnection(bool))); + + setConnection(newLink->isConnected()); } } diff --git a/src/ui/apmtoolbar.h b/src/ui/apmtoolbar.h index e6e14446cb..d4e48212e5 100644 --- a/src/ui/apmtoolbar.h +++ b/src/ui/apmtoolbar.h @@ -41,6 +41,7 @@ public slots: void connectMAV(); void showConnectionDialog(); + void setConnection(bool connection); void updateLinkDisplay(LinkInterface *newLink); }; -- GitLab From 45bad6d10a93f80f329d6c7ceba610528cd88389 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Tue, 16 Jul 2013 11:13:08 -0700 Subject: [PATCH 073/460] APM Tool Bar: connected connect(bool) signal to connect button. --- src/QGCCore.cc | 33 ++---------------------------- src/ui/MainWindow.cc | 46 ++++++++++++++++++++++++------------------ src/ui/QGCStatusBar.cc | 13 +----------- src/ui/QGCToolBar.cc | 2 ++ src/ui/apmtoolbar.cpp | 19 ++++++++++++----- src/ui/apmtoolbar.h | 1 + 6 files changed, 46 insertions(+), 68 deletions(-) diff --git a/src/QGCCore.cc b/src/QGCCore.cc index d2379d63b5..ee0e4ef818 100644 --- a/src/QGCCore.cc +++ b/src/QGCCore.cc @@ -168,38 +168,9 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv) // Remove splash screen splashScreen->finish(mainWindow); - if (upgraded) mainWindow->showInfoMessage(tr("Default Settings Loaded"), tr("APM Planner has been upgraded from version %1 to version %2. Some of your user preferences have been reset to defaults for safety reasons. Please adjust them where needed.").arg(lastApplicationVersion).arg(QGC_APPLICATION_VERSION)); + if (upgraded) mainWindow->showInfoMessage(tr("Default Settings Loaded"), + tr("APM Planner has been upgraded from version %1 to version %2. Some of your user preferences have been reset to defaults for safety reasons. Please adjust them where needed.").arg(lastApplicationVersion).arg(QGC_APPLICATION_VERSION)); - // Check if link could be connected - if (!udpLink->connect()) - { - QMessageBox msgBox; - msgBox.setIcon(QMessageBox::Critical); - msgBox.setText("Could not connect UDP port. Is an instance of " + qAppName() + "already running?"); - msgBox.setInformativeText("You will not be able to receive data via UDP. Please check that you're running the right executable and then re-start " + qAppName() + ". Do you want to close the application?"); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::No); - int ret = msgBox.exec(); - - // Close the message box shortly after the click to prevent accidental clicks - QTimer::singleShot(15000, &msgBox, SLOT(reject())); - - // Exit application - if (ret == QMessageBox::Yes) - { - //mainWindow->close(); - QTimer::singleShot(200, mainWindow, SLOT(close())); - } - } - -// forever -// { -// QGC::SLEEP::msleep(5000); -// } - -// mainWindow->close(); -// mainWindow->deleteLater(); -// QGC::SLEEP::msleep(200); } /** diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 0d3029181b..eab45af760 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -189,26 +189,6 @@ MainWindow::MainWindow(QWidget *parent): advancedActions << ui.actionEngineersView; toolBar->setPerspectiveChangeAdvancedActions(advancedActions); -#else - // Add the APM 'toolbar' - - APMToolBar *apmToolBar = new APMToolBar(this); - apmToolBar->setFlightViewAction(ui.actionFlightView); - apmToolBar->setFlightPlanViewAction(ui.actionMissionView); - apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); - apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); - apmToolBar->setSimulationViewAction(ui.actionSimulation_View); - apmToolBar->setTerminalViewAction(ui.actionSimulation_View); - - QDockWidget *widget = new QDockWidget(tr("APM Tool Bar"),this); - widget->setWidget(apmToolBar); - widget->setMinimumHeight(72); - widget->setMaximumHeight(72); - widget->setMinimumWidth(1024); - widget->setFeatures(QDockWidget::NoDockWidgetFeatures); - widget->setTitleBarWidget(new QWidget(this)); // Disables the title bar -// /*widget*/->setStyleSheet("QDockWidget { border: 0px solid #FFFFFF; border-radius: 0px; border-bottom: 0px;}"); - this->addDockWidget(Qt::TopDockWidgetArea, widget); #endif customStatusBar = new QGCStatusBar(this); @@ -235,6 +215,28 @@ MainWindow::MainWindow(QWidget *parent): connect(LinkManager::instance(), SIGNAL(newLink(LinkInterface*)), this, SLOT(addLink(LinkInterface*))); +#ifndef QGC_TOOLBAR_ENABLED + // Add the APM 'toolbar' + + APMToolBar *apmToolBar = new APMToolBar(this); + apmToolBar->setFlightViewAction(ui.actionFlightView); + apmToolBar->setFlightPlanViewAction(ui.actionMissionView); + apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); + apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); + apmToolBar->setSimulationViewAction(ui.actionSimulation_View); + apmToolBar->setTerminalViewAction(ui.actionSimulation_View); + + QDockWidget *widget = new QDockWidget(tr("APM Tool Bar"),this); + widget->setWidget(apmToolBar); + widget->setMinimumHeight(72); + widget->setMaximumHeight(72); + widget->setMinimumWidth(1024); + widget->setFeatures(QDockWidget::NoDockWidgetFeatures); + widget->setTitleBarWidget(new QWidget(this)); // Disables the title bar +// /*widget*/->setStyleSheet("QDockWidget { border: 0px solid #FFFFFF; border-radius: 0px; border-bottom: 0px;}"); + this->addDockWidget(Qt::TopDockWidgetArea, widget); +#endif + // Connect user interface devices emit initStatusChanged("Initializing joystick interface."); joystickWidget = 0; @@ -918,6 +920,8 @@ void MainWindow::showTool(bool show) }*/ void MainWindow::addCentralWidget(QWidget* widget, const QString& title) { + Q_UNUSED(title); + // Check if this widget already has been added if (centerStack->indexOf(widget) == -1) { @@ -1729,6 +1733,7 @@ void MainWindow::commsWidgetDestroyed(QObject *obj) void MainWindow::setActiveUAS(UASInterface* uas) { + Q_UNUSED(uas); // Enable and rename menu // ui.menuUnmanned_System->setTitle(uas->getUASName()); // if (!ui.menuUnmanned_System->isEnabled()) ui.menuUnmanned_System->setEnabled(true); @@ -1950,6 +1955,7 @@ void MainWindow::UASCreated(UASInterface* uas) void MainWindow::UASDeleted(UASInterface* uas) { + Q_UNUSED(uas); if (UASManager::instance()->getUASList().count() == 0) { // Last system deleted diff --git a/src/ui/QGCStatusBar.cc b/src/ui/QGCStatusBar.cc index 04f77de2f4..2870e20f97 100644 --- a/src/ui/QGCStatusBar.cc +++ b/src/ui/QGCStatusBar.cc @@ -49,16 +49,11 @@ QGCStatusBar::QGCStatusBar(QWidget *parent) : void QGCStatusBar::paintEvent(QPaintEvent * event) { + Q_UNUSED(event); QPainter p(this); QStyleOption opt; opt.initFrom(this); style()->drawPrimitive(QStyle::PE_PanelStatusBar, &opt, &p, this); - //QStatusBar::paintEvent(event); -// if (currentMessage().length() == 0) { -// QStatusBar::paintEvent(event); -// } else { - -// } } void QGCStatusBar::setLogPlayer(QGCMAVLinkLogPlayer* player) @@ -66,12 +61,6 @@ void QGCStatusBar::setLogPlayer(QGCMAVLinkLogPlayer* player) this->player = player; addPermanentWidget(player); connect(toggleLoggingButton, SIGNAL(clicked(bool)), this, SLOT(logging(bool))); - //connect(MainWindow::instance()->getMAVLink(), SIGNAL(loggingChanged(bool)), toggleLoggingButton, SLOT(setChecked(bool))); - - // XXX Mutex issue if called like this -// toggleLoggingButton->blockSignals(true); -// toggleLoggingButton->setChecked(MainWindow::instance()->getMAVLink()->loggingEnabled()); -// toggleLoggingButton->blockSignals(false); } void QGCStatusBar::logging(bool checked) diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 1a7414bd87..30d89f5d81 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -423,6 +423,8 @@ void QGCToolBar::updateBatteryRemaining(UASInterface* uas, double voltage, doubl { Q_UNUSED(uas); Q_UNUSED(seconds); + Q_UNUSED(current); + if (batteryPercent != percent || batteryVoltage != voltage) changed = true; batteryPercent = percent; batteryVoltage = voltage; diff --git a/src/ui/apmtoolbar.cpp b/src/ui/apmtoolbar.cpp index f3253160bf..56fd991a0a 100644 --- a/src/ui/apmtoolbar.cpp +++ b/src/ui/apmtoolbar.cpp @@ -20,9 +20,7 @@ APMToolBar::APMToolBar(QWidget *parent): updateLinkDisplay(LinkManager::instance()->getLinks().last()); } - QObject *object = rootObject(); - if (object) - object->setProperty("connected", false); + setConnection(false); } void APMToolBar::setFlightViewAction(QAction *action) @@ -116,12 +114,18 @@ void APMToolBar::connectMAV() qDebug() << "result = " << result; // Change the image to represent the state - QObject *object = rootObject(); - object->setProperty("connected", result); + setConnection(result); emit MAVConnected(result); } +void APMToolBar::setConnection(bool connection) +{ + // Change the image to represent the state + QObject *object = rootObject(); + object->setProperty("connected", connection); +} + APMToolBar::~APMToolBar() { qDebug() << "Destory APM Toolbar"; @@ -161,5 +165,10 @@ void APMToolBar::updateLinkDisplay(LinkInterface* newLink) QString linkName = newLink->getName(); object->setProperty("linkNameLabel", linkName); + + connect(newLink, SIGNAL(connected(bool)), + this, SLOT(setConnection(bool))); + + setConnection(newLink->isConnected()); } } diff --git a/src/ui/apmtoolbar.h b/src/ui/apmtoolbar.h index e6e14446cb..d4e48212e5 100644 --- a/src/ui/apmtoolbar.h +++ b/src/ui/apmtoolbar.h @@ -41,6 +41,7 @@ public slots: void connectMAV(); void showConnectionDialog(); + void setConnection(bool connection); void updateLinkDisplay(LinkInterface *newLink); }; -- GitLab From 8cfd4f8f1bf8cb382e963dfcbd897e51834fd88a Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 17 Jul 2013 18:09:46 -0400 Subject: [PATCH 074/460] Fix for compile error on windows --- src/ui/XbeeConfigurationWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/XbeeConfigurationWindow.cpp b/src/ui/XbeeConfigurationWindow.cpp index 6910261889..72104bffd9 100644 --- a/src/ui/XbeeConfigurationWindow.cpp +++ b/src/ui/XbeeConfigurationWindow.cpp @@ -374,7 +374,7 @@ void XbeeConfigurationWindow::setupPortList() // Add the ports in reverse order, because we prepend them to the list for (int i = ports.size() - 1; i >= 0; i--) { - QString portString = QString(ports.at(i).portName.toLocal8Bit().constData()); + QString portString = QString(ports.at(i).portName().toLocal8Bit().constData()); // Prepend newly found port to the list if (portBox->findText(portString) == -1) { portBox->insertItem(0, portString); -- GitLab From a87fdb8f8f91fe6040cba28c65d145f719f4db04 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 17 Jul 2013 20:24:46 -0400 Subject: [PATCH 075/460] Removed DESTDIR from .pro file to allow for OS to decide where to place binaries --- qgroundcontrol.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 9663d2260b..5fe780edb3 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -49,7 +49,7 @@ linux-g++|linux-g++-64{ BUILDDIR = $${OUT_PWD}/build } -DESTDIR = $${TARGETDIR} + LANGUAGE = C++ OBJECTS_DIR = $${BUILDDIR}/obj -- GitLab From bc2ce1ab47fb7fcc2fb751d674d327618bbc3ab6 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Wed, 17 Jul 2013 20:17:11 -0700 Subject: [PATCH 076/460] Fix to make Baud and PortName update when changed --- qml/ApmToolBar.qml | 9 ++++++--- src/comm/SerialLink.cc | 22 ++++++++++++++++++++-- src/comm/SerialLink.h | 3 +++ src/ui/apmtoolbar.cpp | 2 ++ 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/qml/ApmToolBar.qml b/qml/ApmToolBar.qml index 393e4c3bf9..75fa879257 100644 --- a/qml/ApmToolBar.qml +++ b/qml/ApmToolBar.qml @@ -10,7 +10,7 @@ Rectangle { property alias baudrateLabel: baudrate.label property bool connected: false - width: 1024 < parent.width ? 1024 : parent.width + width: toolbar.width height: 72 color: "black" border.color: "black" @@ -19,9 +19,11 @@ Rectangle { if (connected){ console.log("APM Tool BAR QML: connected") connectButton.image = "./resources/apmplanner/toolbar/disconnect.png" + connectButton.label = "CONNECT" } else { console.log("APM Tool BAR QML: disconnected") connectButton.image = "./resources/apmplanner/toolbar/connect.png" + connectButton.label = "DISCONNECT" } } @@ -83,7 +85,7 @@ Rectangle { } Button { - id: simualtionView + id: simulationView label: "SIMULATION" image: "./resources/apmplanner/toolbar/simulation.png" onClicked: globalObj.triggerSimulationView() @@ -102,6 +104,8 @@ Rectangle { color: "black" } +// [BB] Commented out ToolBar Status info work. +// WIP: To be fixed later // DigitalDisplay { // Information Pane // title:"Mode" // textValue: "Stabilize" @@ -169,7 +173,6 @@ Rectangle { } Rectangle { // Spacer - anchors.right: parent.right width: 5 height: parent.height color: "black" diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 0091e434af..0f50e912f5 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -97,7 +97,14 @@ QVector* SerialLink::getCurrentPorts() m_ports->clear(); // Example use QSerialPortInfo // [TODO] make this thread safe - foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) + + QList portList = QSerialPortInfo::availablePorts(); + + if( portList.count() == 0){ + qDebug() << "No Ports Found" << m_ports; + } + + foreach (const QSerialPortInfo &info, portList) { // qDebug() << "PortName : " << info.portName() // << "Description : " << info.description(); @@ -706,6 +713,7 @@ bool SerialLink::setPortName(QString portName) m_port->setPortName(portName); emit nameChanged(m_portName); // [TODO] maybe we can eliminate this + emit updateLink(this); return accepted; } return false; @@ -716,12 +724,15 @@ bool SerialLink::setBaudRateType(int rateIndex) { Q_ASSERT_X(m_port != NULL, "setBaudRateType", "m_port is NULL"); // These minimum and maximum baud rates were based on those enumerated in qserialport.h + bool result; const int minBaud = (int)QSerialPort::Baud1200; const int maxBaud = (int)QSerialPort::Baud115200; if (m_port && (rateIndex >= minBaud && rateIndex <= maxBaud)) { - return m_port->setBaudRate(static_cast(rateIndex)); + result = m_port->setBaudRate(static_cast(rateIndex)); + emit updateLink(this); + return result; } return false; @@ -743,6 +754,7 @@ bool SerialLink::setBaudRate(int rate) accepted = true; if (m_port) accepted = m_port->setBaudRate(rate); + emit updateLink(this); } return accepted; } @@ -755,6 +767,7 @@ bool SerialLink::setFlowType(int flow) accepted = true; if (m_port) accepted = m_port->setFlowControl(static_cast(flow)); + emit updateLink(this); } return accepted; } @@ -784,6 +797,7 @@ bool SerialLink::setParityType(int parity) accepted = false; break; } + emit updateLink(this); } } return accepted; @@ -798,6 +812,7 @@ bool SerialLink::setDataBits(int dataBits) accepted = true; if (m_port) accepted = m_port->setDataBits(static_cast(dataBits)); + emit updateLink(this); } return accepted; } @@ -811,6 +826,7 @@ bool SerialLink::setStopBits(int stopBits) accepted = true; if (m_port) accepted = m_port->setStopBits(static_cast(stopBits)); + emit updateLink(this); } return accepted; } @@ -823,6 +839,7 @@ bool SerialLink::setDataBitsType(int dataBits) accepted = true; if (m_port) accepted = m_port->setDataBits(static_cast(dataBits)); + emit updateLink(this); } return accepted; } @@ -835,6 +852,7 @@ bool SerialLink::setStopBitsType(int stopBits) accepted = true; if (m_port) accepted = m_port->setStopBits(static_cast(stopBits)); + emit updateLink(this); } return accepted; } diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index 9a31cc8ca3..cab1e91d7a 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -112,6 +112,9 @@ public: bool isFullDuplex(); int getId(); +signals: //[TODO] Refactor to Linkinterface + void updateLink(LinkInterface*); + public slots: bool setPortName(QString portName); bool setBaudRate(int rate); diff --git a/src/ui/apmtoolbar.cpp b/src/ui/apmtoolbar.cpp index 56fd991a0a..42e85ddc91 100644 --- a/src/ui/apmtoolbar.cpp +++ b/src/ui/apmtoolbar.cpp @@ -143,6 +143,8 @@ void APMToolBar::showConnectionDialog() if (link && LinkManager::instance()->getLinks().count() >= 3) { // Serial Link so prompt to config it + connect(link, SIGNAL(updateLink(LinkInterface*)), + this, SLOT(updateLinkDisplay(LinkInterface*))); result = MainWindow::instance()->configLink(link); if (!result) -- GitLab From 31a118ce917da58c8cec72c6b994eed2bf78b3c9 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 17 Jul 2013 20:36:04 -0400 Subject: [PATCH 077/460] First round of fixes per Bill's git commit comments --- src/ui/MainWindow.cc | 1 - src/ui/MainWindow.h | 1 - src/ui/configuration/AP2ConfigWidget.cc | 8 +- src/ui/configuration/AP2ConfigWidget.h | 1 + .../configuration/AccelCalibrationConfig.cc | 54 ++-- src/ui/configuration/AccelCalibrationConfig.h | 6 +- src/ui/configuration/AdvParameterList.cc | 20 +- src/ui/configuration/AdvParameterList.h | 6 +- src/ui/configuration/AdvancedParamConfig.cc | 8 +- src/ui/configuration/AdvancedParamConfig.h | 2 +- src/ui/configuration/AirspeedConfig.cc | 4 +- src/ui/configuration/ApmHardwareConfig.cc | 84 +++---- src/ui/configuration/ApmHardwareConfig.h | 28 +-- src/ui/configuration/ApmPlaneLevel.cc | 20 +- src/ui/configuration/ApmSoftwareConfig.cc | 174 +++---------- src/ui/configuration/ApmSoftwareConfig.h | 22 +- src/ui/configuration/ArduCopterPidConfig.cc | 230 ++++++++---------- src/ui/configuration/ArduCopterPidConfig.h | 7 +- src/ui/configuration/ArduPlanePidConfig.cc | 110 +++++---- src/ui/configuration/ArduPlanePidConfig.h | 2 +- src/ui/configuration/ArduRoverPidConfig.cc | 2 + src/ui/configuration/BatteryMonitorConfig.cc | 76 +++--- src/ui/configuration/BatteryMonitorConfig.h | 2 + src/ui/configuration/BatteryMonitorConfig.ui | 2 +- src/ui/configuration/CameraGimbalConfig.cc | 108 ++++---- src/ui/configuration/CameraGimbalConfig.h | 8 +- src/ui/configuration/CompassConfig.cc | 15 +- src/ui/configuration/CompassConfig.h | 4 +- src/ui/configuration/FailSafeConfig.cc | 28 ++- src/ui/configuration/FlightModeConfig.cc | 12 +- src/ui/configuration/FlightModeConfig.h | 5 +- src/ui/configuration/FrameTypeConfig.cc | 15 +- src/ui/configuration/FrameTypeConfig.h | 4 +- src/ui/configuration/OsdConfig.cc | 2 +- .../configuration/RadioCalibrationConfig.cc | 19 +- src/ui/configuration/RadioCalibrationConfig.h | 5 +- src/ui/configuration/StandardParamConfig.cc | 7 - src/ui/configuration/StandardParamConfig.h | 1 - 38 files changed, 490 insertions(+), 613 deletions(-) diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index eab45af760..cf1a72ca3d 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -1527,7 +1527,6 @@ void MainWindow::connectCommonActions() connect(ui.actionEngineersView, SIGNAL(triggered()), this, SLOT(loadEngineerView())); connect(ui.actionMissionView, SIGNAL(triggered()), this, SLOT(loadOperatorView())); connect(ui.actionUnconnectedView, SIGNAL(triggered()), this, SLOT(loadUnconnectedView())); - //connect(ui.actionConfiguration_2,SIGNAL(triggered()),this,SLOT(loadConfigurationView())); connect(ui.actionHardwareConfig,SIGNAL(triggered()),this,SLOT(loadHardwareConfigView())); connect(ui.actionSoftwareConfig,SIGNAL(triggered()),this,SLOT(loadSoftwareConfigView())); diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index e66e650cd7..b51dba6b20 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -30,7 +30,6 @@ This file is part of the QGROUNDCONTROL project #ifndef _MAINWINDOW_H_ #define _MAINWINDOW_H_ - #include #include #include diff --git a/src/ui/configuration/AP2ConfigWidget.cc b/src/ui/configuration/AP2ConfigWidget.cc index 21c5895069..08eb44f215 100644 --- a/src/ui/configuration/AP2ConfigWidget.cc +++ b/src/ui/configuration/AP2ConfigWidget.cc @@ -1,3 +1,4 @@ +#include #include "AP2ConfigWidget.h" AP2ConfigWidget::AP2ConfigWidget(QWidget *parent) : QWidget(parent) @@ -8,11 +9,12 @@ AP2ConfigWidget::AP2ConfigWidget(QWidget *parent) : QWidget(parent) } void AP2ConfigWidget::activeUASSet(UASInterface *uas) { - if (!uas) return; if (m_uas) { disconnect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); + m_uas = 0; } + if (!uas) return; m_uas = uas; connect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); } @@ -21,3 +23,7 @@ void AP2ConfigWidget::parameterChanged(int uas, int component, QString parameter { } +void AP2ConfigWidget::showNullMAVErrorMessageBox() +{ + QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); +} diff --git a/src/ui/configuration/AP2ConfigWidget.h b/src/ui/configuration/AP2ConfigWidget.h index 2f27e35abf..69e9f6f7fb 100644 --- a/src/ui/configuration/AP2ConfigWidget.h +++ b/src/ui/configuration/AP2ConfigWidget.h @@ -11,6 +11,7 @@ public: explicit AP2ConfigWidget(QWidget *parent = 0); protected: UASInterface *m_uas; + void showNullMAVErrorMessageBox(); signals: public slots: diff --git a/src/ui/configuration/AccelCalibrationConfig.cc b/src/ui/configuration/AccelCalibrationConfig.cc index eedd35e963..e5d2b7a173 100644 --- a/src/ui/configuration/AccelCalibrationConfig.cc +++ b/src/ui/configuration/AccelCalibrationConfig.cc @@ -1,7 +1,7 @@ #include "AccelCalibrationConfig.h" -AccelCalibrationConfig::AccelCalibrationConfig(QWidget *parent) : QWidget(parent) +AccelCalibrationConfig::AccelCalibrationConfig(QWidget *parent) : AP2ConfigWidget(parent) { m_uas=0; ui.setupUi(this); @@ -9,7 +9,7 @@ AccelCalibrationConfig::AccelCalibrationConfig(QWidget *parent) : QWidget(parent connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); activeUASSet(UASManager::instance()->getActiveUAS()); - accelAckCount=0; + m_accelAckCount=0; } AccelCalibrationConfig::~AccelCalibrationConfig() @@ -17,42 +17,48 @@ AccelCalibrationConfig::~AccelCalibrationConfig() } void AccelCalibrationConfig::activeUASSet(UASInterface *uas) { - if (!uas) + if (m_uas) { - return; + disconnect(m_uas,SIGNAL(textMessageReceived(int,int,int,QString)),this,SLOT(uasTextMessageReceived(int,int,int,QString))); } - if (m_uas) + AP2ConfigWidget::activeUASSet(uas); + if (!uas) { + return; } - m_uas = uas; connect(m_uas,SIGNAL(textMessageReceived(int,int,int,QString)),this,SLOT(uasTextMessageReceived(int,int,int,QString))); + } void AccelCalibrationConfig::calibrateButtonClicked() { - if (accelAckCount == 0) + if (!m_uas) + { + showNullMAVErrorMessageBox(); + return; + } + if (m_accelAckCount == 0) { MAV_CMD command = MAV_CMD_PREFLIGHT_CALIBRATION; int confirm = 0; - float param1 = 0; - float param2 = 0; - float param3 = 0; - float param4 = 0; - float param5 = 1; - float param6 = 0; - float param7 = 0; + float param1 = 0.0; + float param2 = 0.0; + float param3 = 0.0; + float param4 = 0.0; + float param5 = 1.0; + float param6 = 0.0; + float param7 = 0.0; int component = 1; m_uas->executeCommand(command, confirm, param1, param2, param3, param4, param5, param6, param7, component); } - else if (accelAckCount <= 5) + else if (m_accelAckCount <= 5) { - m_uas->executeCommandAck(accelAckCount++,true); + m_uas->executeCommandAck(m_accelAckCount++,true); } else { - m_uas->executeCommandAck(accelAckCount++,true); + m_uas->executeCommandAck(m_accelAckCount++,true); ui.calibrateAccelButton->setText("Calibrate\nAccelerometer"); - //accelAckCount = 0; } } @@ -63,24 +69,24 @@ void AccelCalibrationConfig::uasTextMessageReceived(int uasid, int componentid, if (severity == 5) { //This is a calibration instruction - if (accelAckCount == 0) + if (m_accelAckCount == 0) { //Calibration Sucessful\r" ui.calibrateAccelButton->setText("Any\nKey"); - accelAckCount++; + m_accelAckCount++; } - if (accelAckCount == 7) + if (m_accelAckCount == 7) { //All finished //ui.outputLabel->setText(ui.outputLabel->text() + "\n" + text); ui.outputLabel->setText(text); - accelAckCount++; + m_accelAckCount++; } - if (accelAckCount == 8) + if (m_accelAckCount == 8) { if (text.contains("Calibration") && text.contains("successful")) { - accelAckCount = 0; + m_accelAckCount = 0; } ui.outputLabel->setText(ui.outputLabel->text() + "\n" + text); } diff --git a/src/ui/configuration/AccelCalibrationConfig.h b/src/ui/configuration/AccelCalibrationConfig.h index a9e5f20534..69dc2c414f 100644 --- a/src/ui/configuration/AccelCalibrationConfig.h +++ b/src/ui/configuration/AccelCalibrationConfig.h @@ -5,7 +5,9 @@ #include "ui_AccelCalibrationConfig.h" #include "UASManager.h" #include "UASInterface.h" -class AccelCalibrationConfig : public QWidget +#include "AP2ConfigWidget.h" + +class AccelCalibrationConfig : public AP2ConfigWidget { Q_OBJECT @@ -17,7 +19,7 @@ private slots: void calibrateButtonClicked(); void uasTextMessageReceived(int uasid, int componentid, int severity, QString text); private: - int accelAckCount; + int m_accelAckCount; Ui::AccelCalibrationConfig ui; UASInterface *m_uas; }; diff --git a/src/ui/configuration/AdvParameterList.cc b/src/ui/configuration/AdvParameterList.cc index e1abae86ec..971f290e61 100644 --- a/src/ui/configuration/AdvParameterList.cc +++ b/src/ui/configuration/AdvParameterList.cc @@ -7,8 +7,6 @@ AdvParameterList::AdvParameterList(QWidget *parent) : AP2ConfigWidget(parent) ui.tableWidget->setColumnCount(4); ui.tableWidget->horizontalHeader()->hide(); ui.tableWidget->verticalHeader()->hide(); - //ui.tableWidget->setHorizontalHeader(0); - //ui.tableWidget->setVerticalHeader(0); ui.tableWidget->setColumnWidth(0,200); ui.tableWidget->setColumnWidth(1,100); ui.tableWidget->setColumnWidth(2,200); @@ -21,19 +19,19 @@ AdvParameterList::~AdvParameterList() } void AdvParameterList::setParameterMetaData(QString name,QString humanname,QString description) { - paramToNameMap[name] = humanname; - paramToDescriptionMap[name] = description; + m_paramToNameMap[name] = humanname; + m_paramToDescriptionMap[name] = description; } void AdvParameterList::parameterChanged(int uas, int component, QString parameterName, QVariant value) { - if (!paramValueMap.contains(parameterName)) + if (!m_paramValueMap.contains(parameterName)) { ui.tableWidget->setRowCount(ui.tableWidget->rowCount()+1); - if (paramToNameMap.contains(parameterName)) + if (m_paramToNameMap.contains(parameterName)) { - ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,0,new QTableWidgetItem(paramToNameMap[parameterName])); + ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,0,new QTableWidgetItem(m_paramToNameMap[parameterName])); } else { @@ -41,15 +39,15 @@ void AdvParameterList::parameterChanged(int uas, int component, QString paramete } ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,1,new QTableWidgetItem(QString::number(value.toFloat(),'f',2))); ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,2,new QTableWidgetItem(parameterName)); - if (paramToDescriptionMap.contains(parameterName)) + if (m_paramToDescriptionMap.contains(parameterName)) { - ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,3,new QTableWidgetItem(paramToDescriptionMap[parameterName])); + ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,3,new QTableWidgetItem(m_paramToDescriptionMap[parameterName])); } else { ui.tableWidget->setItem(ui.tableWidget->rowCount()-1,3,new QTableWidgetItem("Unknown")); } - paramValueMap[parameterName] = ui.tableWidget->item(ui.tableWidget->rowCount()-1,1); + m_paramValueMap[parameterName] = ui.tableWidget->item(ui.tableWidget->rowCount()-1,1); } - paramValueMap[parameterName]->setText(QString::number(value.toFloat(),'f',2)); + m_paramValueMap[parameterName]->setText(QString::number(value.toFloat(),'f',2)); } diff --git a/src/ui/configuration/AdvParameterList.h b/src/ui/configuration/AdvParameterList.h index 6a530f9f19..6ff55a22ff 100644 --- a/src/ui/configuration/AdvParameterList.h +++ b/src/ui/configuration/AdvParameterList.h @@ -16,9 +16,9 @@ public: private slots: void parameterChanged(int uas, int component, QString parameterName, QVariant value); private: - QMap paramValueMap; - QMap paramToNameMap; - QMap paramToDescriptionMap; + QMap m_paramValueMap; + QMap m_paramToNameMap; + QMap m_paramToDescriptionMap; Ui::AdvParameterList ui; }; diff --git a/src/ui/configuration/AdvancedParamConfig.cc b/src/ui/configuration/AdvancedParamConfig.cc index 5f4102c242..8410b6a002 100644 --- a/src/ui/configuration/AdvancedParamConfig.cc +++ b/src/ui/configuration/AdvancedParamConfig.cc @@ -12,7 +12,7 @@ AdvancedParamConfig::~AdvancedParamConfig() void AdvancedParamConfig::addRange(QString title,QString description,QString param,double min,double max) { ParamWidget *widget = new ParamWidget(ui.scrollAreaWidgetContents); - paramToWidgetMap[param] = widget; + m_paramToWidgetMap[param] = widget; widget->setupDouble(title + "(" + param + ")",description,0,min,max); ui.verticalLayout->addWidget(widget); widget->show(); @@ -21,15 +21,15 @@ void AdvancedParamConfig::addRange(QString title,QString description,QString par void AdvancedParamConfig::addCombo(QString title,QString description,QString param,QList > valuelist) { ParamWidget *widget = new ParamWidget(ui.scrollAreaWidgetContents); - paramToWidgetMap[param] = widget; + m_paramToWidgetMap[param] = widget; widget->setupCombo(title + "(" + param + ")",description,valuelist); ui.verticalLayout->addWidget(widget); widget->show(); } void AdvancedParamConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { - if (paramToWidgetMap.contains(parameterName)) + if (m_paramToWidgetMap.contains(parameterName)) { - paramToWidgetMap[parameterName]->setValue(value.toDouble()); + m_paramToWidgetMap[parameterName]->setValue(value.toDouble()); } } diff --git a/src/ui/configuration/AdvancedParamConfig.h b/src/ui/configuration/AdvancedParamConfig.h index 9c69156d89..6d52ede4cd 100644 --- a/src/ui/configuration/AdvancedParamConfig.h +++ b/src/ui/configuration/AdvancedParamConfig.h @@ -17,7 +17,7 @@ public: private slots: void parameterChanged(int uas, int component, QString parameterName, QVariant value); private: - QMap paramToWidgetMap; + QMap m_paramToWidgetMap; Ui::AdvancedParamConfig ui; }; diff --git a/src/ui/configuration/AirspeedConfig.cc b/src/ui/configuration/AirspeedConfig.cc index dfdc1e08d8..b5c91f33b7 100644 --- a/src/ui/configuration/AirspeedConfig.cc +++ b/src/ui/configuration/AirspeedConfig.cc @@ -51,7 +51,7 @@ void AirspeedConfig::useCheckBoxClicked(bool checked) { if (!m_uas) { - QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + showNullMAVErrorMessageBox(); return; } if (checked) @@ -68,7 +68,7 @@ void AirspeedConfig::enableCheckBoxClicked(bool checked) { if (!m_uas) { - QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + showNullMAVErrorMessageBox(); return; } if (checked) diff --git a/src/ui/configuration/ApmHardwareConfig.cc b/src/ui/configuration/ApmHardwareConfig.cc index 0341ab345b..225f6a1f2b 100644 --- a/src/ui/configuration/ApmHardwareConfig.cc +++ b/src/ui/configuration/ApmHardwareConfig.cc @@ -62,73 +62,73 @@ ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) QWidget *widget = new QWidget(this); ui.stackedWidget->addWidget(widget); //Firmware placeholder. - buttonToConfigWidgetMap[ui.firmwareButton] = widget; + m_buttonToConfigWidgetMap[ui.firmwareButton] = widget; connect(ui.firmwareButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - frameConfig = new FrameTypeConfig(this); - ui.stackedWidget->addWidget(frameConfig); - buttonToConfigWidgetMap[ui.frameTypeButton] = frameConfig; + m_frameConfig = new FrameTypeConfig(this); + ui.stackedWidget->addWidget(m_frameConfig); + m_buttonToConfigWidgetMap[ui.frameTypeButton] = m_frameConfig; connect(ui.frameTypeButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - compassConfig = new CompassConfig(this); - ui.stackedWidget->addWidget(compassConfig); - buttonToConfigWidgetMap[ui.compassButton] = compassConfig; + m_compassConfig = new CompassConfig(this); + ui.stackedWidget->addWidget(m_compassConfig); + m_buttonToConfigWidgetMap[ui.compassButton] = m_compassConfig; connect(ui.compassButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - accelConfig = new AccelCalibrationConfig(this); - ui.stackedWidget->addWidget(accelConfig); - buttonToConfigWidgetMap[ui.accelCalibrateButton] = accelConfig; + m_accelConfig = new AccelCalibrationConfig(this); + ui.stackedWidget->addWidget(m_accelConfig); + m_buttonToConfigWidgetMap[ui.accelCalibrateButton] = m_accelConfig; connect(ui.accelCalibrateButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - planeLevel = new ApmPlaneLevel(this); - ui.stackedWidget->addWidget(planeLevel); - buttonToConfigWidgetMap[ui.arduPlaneLevelButton] = planeLevel; + m_planeLevel = new ApmPlaneLevel(this); + ui.stackedWidget->addWidget(m_planeLevel); + m_buttonToConfigWidgetMap[ui.arduPlaneLevelButton] = m_planeLevel; connect(ui.arduPlaneLevelButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - radioConfig = new RadioCalibrationConfig(this); - ui.stackedWidget->addWidget(radioConfig); - buttonToConfigWidgetMap[ui.radioCalibrateButton] = radioConfig; + m_radioConfig = new RadioCalibrationConfig(this); + ui.stackedWidget->addWidget(m_radioConfig); + m_buttonToConfigWidgetMap[ui.radioCalibrateButton] = m_radioConfig; connect(ui.radioCalibrateButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - radio3drConfig = new Radio3DRConfig(this); - ui.stackedWidget->addWidget(radio3drConfig); - buttonToConfigWidgetMap[ui.radio3DRButton] = radio3drConfig; + m_radio3drConfig = new Radio3DRConfig(this); + ui.stackedWidget->addWidget(m_radio3drConfig); + m_buttonToConfigWidgetMap[ui.radio3DRButton] = m_radio3drConfig; connect(ui.radio3DRButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - batteryConfig = new BatteryMonitorConfig(this); - ui.stackedWidget->addWidget(batteryConfig); - buttonToConfigWidgetMap[ui.batteryMonitorButton] = batteryConfig; + m_batteryConfig = new BatteryMonitorConfig(this); + ui.stackedWidget->addWidget(m_batteryConfig); + m_buttonToConfigWidgetMap[ui.batteryMonitorButton] = m_batteryConfig; connect(ui.batteryMonitorButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - sonarConfig = new SonarConfig(this); - ui.stackedWidget->addWidget(sonarConfig); - buttonToConfigWidgetMap[ui.sonarButton] = sonarConfig; + m_sonarConfig = new SonarConfig(this); + ui.stackedWidget->addWidget(m_sonarConfig); + m_buttonToConfigWidgetMap[ui.sonarButton] = m_sonarConfig; connect(ui.sonarButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - airspeedConfig = new AirspeedConfig(this); - ui.stackedWidget->addWidget(airspeedConfig); - buttonToConfigWidgetMap[ui.airspeedButton] = airspeedConfig; + m_airspeedConfig = new AirspeedConfig(this); + ui.stackedWidget->addWidget(m_airspeedConfig); + m_buttonToConfigWidgetMap[ui.airspeedButton] = m_airspeedConfig; connect(ui.airspeedButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - opticalFlowConfig = new OpticalFlowConfig(this); - ui.stackedWidget->addWidget(opticalFlowConfig); - buttonToConfigWidgetMap[ui.opticalFlowButton] = opticalFlowConfig; + m_opticalFlowConfig = new OpticalFlowConfig(this); + ui.stackedWidget->addWidget(m_opticalFlowConfig); + m_buttonToConfigWidgetMap[ui.opticalFlowButton] = m_opticalFlowConfig; connect(ui.opticalFlowButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - osdConfig = new OsdConfig(this); - ui.stackedWidget->addWidget(osdConfig); - buttonToConfigWidgetMap[ui.osdButton] = osdConfig; + m_osdConfig = new OsdConfig(this); + ui.stackedWidget->addWidget(m_osdConfig); + m_buttonToConfigWidgetMap[ui.osdButton] = m_osdConfig; connect(ui.osdButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - cameraGimbalConfig = new CameraGimbalConfig(this); - ui.stackedWidget->addWidget(cameraGimbalConfig); - buttonToConfigWidgetMap[ui.cameraGimbalButton] = cameraGimbalConfig; + m_cameraGimbalConfig = new CameraGimbalConfig(this); + ui.stackedWidget->addWidget(m_cameraGimbalConfig); + m_buttonToConfigWidgetMap[ui.cameraGimbalButton] = m_cameraGimbalConfig; connect(ui.cameraGimbalButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - antennaTrackerConfig = new AntennaTrackerConfig(this); - ui.stackedWidget->addWidget(antennaTrackerConfig); - buttonToConfigWidgetMap[ui.antennaTrackerButton] = antennaTrackerConfig; + m_antennaTrackerConfig = new AntennaTrackerConfig(this); + ui.stackedWidget->addWidget(m_antennaTrackerConfig); + m_buttonToConfigWidgetMap[ui.antennaTrackerButton] = m_antennaTrackerConfig; connect(ui.antennaTrackerButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); @@ -139,9 +139,9 @@ ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) } void ApmHardwareConfig::activateStackedWidget() { - if (buttonToConfigWidgetMap.contains(sender())) + if (m_buttonToConfigWidgetMap.contains(sender())) { - ui.stackedWidget->setCurrentWidget(buttonToConfigWidgetMap[sender()]); + ui.stackedWidget->setCurrentWidget(m_buttonToConfigWidgetMap[sender()]); } } diff --git a/src/ui/configuration/ApmHardwareConfig.h b/src/ui/configuration/ApmHardwareConfig.h index 6d48bf9547..aea82cde73 100644 --- a/src/ui/configuration/ApmHardwareConfig.h +++ b/src/ui/configuration/ApmHardwareConfig.h @@ -58,20 +58,20 @@ public: explicit ApmHardwareConfig(QWidget *parent = 0); ~ApmHardwareConfig(); private: - FrameTypeConfig *frameConfig; - CompassConfig *compassConfig; - AccelCalibrationConfig *accelConfig; - RadioCalibrationConfig *radioConfig; + FrameTypeConfig *m_frameConfig; + CompassConfig *m_compassConfig; + AccelCalibrationConfig *m_accelConfig; + RadioCalibrationConfig *m_radioConfig; - Radio3DRConfig *radio3drConfig; - BatteryMonitorConfig *batteryConfig; - SonarConfig *sonarConfig; - AirspeedConfig *airspeedConfig; - OpticalFlowConfig *opticalFlowConfig; - OsdConfig *osdConfig; - CameraGimbalConfig *cameraGimbalConfig; - AntennaTrackerConfig *antennaTrackerConfig; - ApmPlaneLevel *planeLevel; + Radio3DRConfig *m_radio3drConfig; + BatteryMonitorConfig *m_batteryConfig; + SonarConfig *m_sonarConfig; + AirspeedConfig *m_airspeedConfig; + OpticalFlowConfig *m_opticalFlowConfig; + OsdConfig *m_osdConfig; + CameraGimbalConfig *m_cameraGimbalConfig; + AntennaTrackerConfig *m_antennaTrackerConfig; + ApmPlaneLevel *m_planeLevel; private slots: void activeUASSet(UASInterface *uas); void activateStackedWidget(); @@ -79,7 +79,7 @@ private: Ui::ApmHardwareConfig ui; //This is a map between the buttons, and the widgets they should be displying - QMap buttonToConfigWidgetMap; + QMap m_buttonToConfigWidgetMap; }; #endif // APMHARDWARECONFIG_H diff --git a/src/ui/configuration/ApmPlaneLevel.cc b/src/ui/configuration/ApmPlaneLevel.cc index 7b00374834..c93193055f 100644 --- a/src/ui/configuration/ApmPlaneLevel.cc +++ b/src/ui/configuration/ApmPlaneLevel.cc @@ -13,16 +13,21 @@ ApmPlaneLevel::~ApmPlaneLevel() } void ApmPlaneLevel::levelClicked() { + if (!m_uas) + { + showNullMAVErrorMessageBox(); + return; + } QMessageBox::information(0,"Warning","Be sure the plane is completly level, then click ok"); MAV_CMD command = MAV_CMD_PREFLIGHT_CALIBRATION; int confirm = 0; - float param1 = 1; - float param2 = 0; - float param3 = 1; - float param4 = 0; - float param5 = 0; - float param6 = 0; - float param7 = 0; + float param1 = 1.0; + float param2 = 0.0; + float param3 = 1.0; + float param4 = 0.0; + float param5 = 0.0; + float param6 = 0.0; + float param7 = 0.0; int component = 1; m_uas->executeCommand(command, confirm, param1, param2, param3, param4, param5, param6, param7, component); QMessageBox::information(0,"Warning","Leveling completed"); @@ -32,6 +37,7 @@ void ApmPlaneLevel::manualCheckBoxToggled(bool checked) { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } if (checked) diff --git a/src/ui/configuration/ApmSoftwareConfig.cc b/src/ui/configuration/ApmSoftwareConfig.cc index 0412287222..fabc49139b 100644 --- a/src/ui/configuration/ApmSoftwareConfig.cc +++ b/src/ui/configuration/ApmSoftwareConfig.cc @@ -1,8 +1,9 @@ -#include "ApmSoftwareConfig.h" #include #include #include +#include "ApmSoftwareConfig.h" + ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) { @@ -17,51 +18,48 @@ ApmSoftwareConfig::ApmSoftwareConfig(QWidget *parent) : QWidget(parent) ui.arduRoverPidButton->setVisible(false); ui.arduPlanePidButton->setVisible(false); - flightConfig = new FlightModeConfig(this); - ui.stackedWidget->addWidget(flightConfig); - buttonToConfigWidgetMap[ui.flightModesButton] = flightConfig; + m_flightConfig = new FlightModeConfig(this); + ui.stackedWidget->addWidget(m_flightConfig); + m_buttonToConfigWidgetMap[ui.flightModesButton] = m_flightConfig; connect(ui.flightModesButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - standardParamConfig = new StandardParamConfig(this); - ui.stackedWidget->addWidget(standardParamConfig); - buttonToConfigWidgetMap[ui.standardParamButton] = standardParamConfig; + m_standardParamConfig = new StandardParamConfig(this); + ui.stackedWidget->addWidget(m_standardParamConfig); + m_buttonToConfigWidgetMap[ui.standardParamButton] = m_standardParamConfig; connect(ui.standardParamButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - failSafeConfig = new FailSafeConfig(this); - ui.stackedWidget->addWidget(failSafeConfig); - buttonToConfigWidgetMap[ui.failSafeButton] = failSafeConfig; + m_failSafeConfig = new FailSafeConfig(this); + ui.stackedWidget->addWidget(m_failSafeConfig); + m_buttonToConfigWidgetMap[ui.failSafeButton] = m_failSafeConfig; connect(ui.failSafeButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - advancedParamConfig = new AdvancedParamConfig(this); - ui.stackedWidget->addWidget(advancedParamConfig); - buttonToConfigWidgetMap[ui.advancedParamButton] = advancedParamConfig; + m_advancedParamConfig = new AdvancedParamConfig(this); + ui.stackedWidget->addWidget(m_advancedParamConfig); + m_buttonToConfigWidgetMap[ui.advancedParamButton] = m_advancedParamConfig; connect(ui.advancedParamButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - advParameterList = new AdvParameterList(this); - ui.stackedWidget->addWidget(advParameterList); - buttonToConfigWidgetMap[ui.advParamListButton] = advParameterList; + m_advParameterList = new AdvParameterList(this); + ui.stackedWidget->addWidget(m_advParameterList); + m_buttonToConfigWidgetMap[ui.advParamListButton] = m_advParameterList; connect(ui.advParamListButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - arduCopterPidConfig = new ArduCopterPidConfig(this); - ui.stackedWidget->addWidget(arduCopterPidConfig); - buttonToConfigWidgetMap[ui.arduCopterPidButton] = arduCopterPidConfig; + m_arduCopterPidConfig = new ArduCopterPidConfig(this); + ui.stackedWidget->addWidget(m_arduCopterPidConfig); + m_buttonToConfigWidgetMap[ui.arduCopterPidButton] = m_arduCopterPidConfig; connect(ui.arduCopterPidButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - arduPlanePidConfig = new ArduPlanePidConfig(this); - ui.stackedWidget->addWidget(arduPlanePidConfig); - buttonToConfigWidgetMap[ui.arduPlanePidButton] = arduPlanePidConfig; + m_arduPlanePidConfig = new ArduPlanePidConfig(this); + ui.stackedWidget->addWidget(m_arduPlanePidConfig); + m_buttonToConfigWidgetMap[ui.arduPlanePidButton] = m_arduPlanePidConfig; connect(ui.arduPlanePidButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - arduRoverPidConfig = new ArduRoverPidConfig(this); - ui.stackedWidget->addWidget(arduRoverPidConfig); - buttonToConfigWidgetMap[ui.arduRoverPidButton] = arduRoverPidConfig; + m_arduRoverPidConfig = new ArduRoverPidConfig(this); + ui.stackedWidget->addWidget(m_arduRoverPidConfig); + m_buttonToConfigWidgetMap[ui.arduRoverPidButton] = m_arduRoverPidConfig; connect(ui.arduRoverPidButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); - if (UASManager::instance()->getActiveUAS()) - { - activeUASSet(UASManager::instance()->getActiveUAS()); - } + activeUASSet(UASManager::instance()->getActiveUAS()); } ApmSoftwareConfig::~ApmSoftwareConfig() @@ -69,9 +67,9 @@ ApmSoftwareConfig::~ApmSoftwareConfig() } void ApmSoftwareConfig::activateStackedWidget() { - if (buttonToConfigWidgetMap.contains(sender())) + if (m_buttonToConfigWidgetMap.contains(sender())) { - ui.stackedWidget->setCurrentWidget(buttonToConfigWidgetMap[sender()]); + ui.stackedWidget->setCurrentWidget(m_buttonToConfigWidgetMap[sender()]); } } void ApmSoftwareConfig::activeUASSet(UASInterface *uas) @@ -296,11 +294,6 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) genset["count"] = genarraycount; } //Right here we have a single param in memory - name; - docs; - valuemap; - fieldmap; - //standardParamConfig if (valuemap.size() > 0) { QList > valuelist; @@ -310,13 +303,13 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) } if (tab == "Standard") { - standardParamConfig->addCombo(humanname,docs,name,valuelist); + m_standardParamConfig->addCombo(humanname,docs,name,valuelist); } else if (tab == "Advanced") { - advancedParamConfig->addCombo(humanname,docs,name,valuelist); + m_advancedParamConfig->addCombo(humanname,docs,name,valuelist); } - advParameterList->setParameterMetaData(name,humanname,docs); + m_advParameterList->setParameterMetaData(name,humanname,docs); } else if (fieldmap.size() > 0) { @@ -340,120 +333,23 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) } if (tab == "Standard") { - standardParamConfig->addRange(humanname,docs,name,min,max); + m_standardParamConfig->addRange(humanname,docs,name,min,max); } else if (tab == "Advanced") { - advancedParamConfig->addRange(humanname,docs,name,max,min); + m_advancedParamConfig->addRange(humanname,docs,name,max,min); } - advParameterList->setParameterMetaData(name,humanname,docs); + m_advParameterList->setParameterMetaData(name,humanname,docs); } } xml.readNext(); } - if (genarraycount > 0) - { - /* - tool = new QGCToolWidget("", this); - tool->addUAS(mav); - tool->setTitle(parametersname); - tool->setObjectName(parametersname); - tool->setSettings(genset); - QList paramlist = tool->getParamList(); - for (int i=0;iinsert(paramlist[i],tool); - } - else if (parametersname == "ArduCopter") //MAV_TYPE_QUADROTOR "QUADROTOR - { - systemTypeToParamMap["QUADROTOR"]->insert(paramlist[i],tool); - } - else if (parametersname == "APMrover2") //MAV_TYPE_GROUND_ROVER GROUND_ROVER - { - systemTypeToParamMap["GROUND_ROVER"]->insert(paramlist[i],tool); - } - else - { - libParamToWidgetMap->insert(paramlist[i],tool); - } - } - - toolWidgets.append(tool); - QGroupBox *box = new QGroupBox(this); - box->setTitle(tool->objectName()); - box->setLayout(new QVBoxLayout()); - box->layout()->addWidget(tool); - if (valuetype == "vehicles") - { - ui->leftGeneralLayout->addWidget(box); - } - else if (valuetype == "libraries") - { - ui->rightGeneralLayout->addWidget(box); - } - box->hide(); - toolToBoxMap[tool] = box;*/ - } - if (advarraycount > 0) - { - /* - tool = new QGCToolWidget("", this); - tool->addUAS(mav); - tool->setTitle(parametersname); - tool->setObjectName(parametersname); - tool->setSettings(advset); - QList paramlist = tool->getParamList(); - for (int i=0;iinsert(paramlist[i],tool); - } - else if (parametersname == "ArduCopter") //MAV_TYPE_QUADROTOR "QUADROTOR - { - systemTypeToParamMap["QUADROTOR"]->insert(paramlist[i],tool); - } - else if (parametersname == "APMrover2") //MAV_TYPE_GROUND_ROVER GROUND_ROVER - { - systemTypeToParamMap["GROUND_ROVER"]->insert(paramlist[i],tool); - } - else - { - libParamToWidgetMap->insert(paramlist[i],tool); - } - } - - toolWidgets.append(tool); - QGroupBox *box = new QGroupBox(this); - box->setTitle(tool->objectName()); - box->setLayout(new QVBoxLayout()); - box->layout()->addWidget(tool); - if (valuetype == "vehicles") - { - ui->leftAdvancedLayout->addWidget(box); - } - else if (valuetype == "libraries") - { - ui->rightAdvancedLayout->addWidget(box); - } - box->hide(); - toolToBoxMap[tool] = box;*/ - } - - - - } xml.readNext(); } } - xml.readNext(); } } diff --git a/src/ui/configuration/ApmSoftwareConfig.h b/src/ui/configuration/ApmSoftwareConfig.h index 7b0b5138e3..c4eabf414e 100644 --- a/src/ui/configuration/ApmSoftwareConfig.h +++ b/src/ui/configuration/ApmSoftwareConfig.h @@ -28,17 +28,17 @@ private slots: void activeUASSet(UASInterface *uas); private: Ui::ApmSoftwareConfig ui; - BasicPidConfig *basicPidConfig; - FlightModeConfig *flightConfig; - StandardParamConfig *standardParamConfig; - GeoFenceConfig *geoFenceConfig; - FailSafeConfig *failSafeConfig; - AdvancedParamConfig *advancedParamConfig; - ArduCopterPidConfig *arduCopterPidConfig; - ArduPlanePidConfig *arduPlanePidConfig; - ArduRoverPidConfig *arduRoverPidConfig; - AdvParameterList *advParameterList; - QMap buttonToConfigWidgetMap; + BasicPidConfig *m_basicPidConfig; + FlightModeConfig *m_flightConfig; + StandardParamConfig *m_standardParamConfig; + GeoFenceConfig *m_geoFenceConfig; + FailSafeConfig *m_failSafeConfig; + AdvancedParamConfig *m_advancedParamConfig; + ArduCopterPidConfig *m_arduCopterPidConfig; + ArduPlanePidConfig *m_arduPlanePidConfig; + ArduRoverPidConfig *m_arduRoverPidConfig; + AdvParameterList *m_advParameterList; + QMap m_buttonToConfigWidgetMap; }; #endif // APMSOFTWARECONFIG_H diff --git a/src/ui/configuration/ArduCopterPidConfig.cc b/src/ui/configuration/ArduCopterPidConfig.cc index f64dec4c2b..bd0924323b 100644 --- a/src/ui/configuration/ArduCopterPidConfig.cc +++ b/src/ui/configuration/ArduCopterPidConfig.cc @@ -3,126 +3,110 @@ ArduCopterPidConfig::ArduCopterPidConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); - nameToBoxMap["STB_RLL_P"] = ui.stabilPitchPSpinBox; - nameToBoxMap["STB_PIT_P"] = ui.stabilRollPSpinBox; - nameToBoxMap["STB_YAW_P"] = ui.stabilYawPSpinBox; - nameToBoxMap["HLD_LAT_P"] = ui.loiterPidPSpinBox; - - nameToBoxMap["RATE_RLL_P"] = ui.rateRollPSpinBox; - nameToBoxMap["RATE_RLL_I"] = ui.rateRollISpinBox; - nameToBoxMap["RATE_RLL_D"] = ui.rateRollDSpinBox; - nameToBoxMap["RATE_RLL_IMAX"] = ui.rateRollIMAXSpinBox; - - nameToBoxMap["RATE_PIT_P"] = ui.ratePitchPSpinBox; - nameToBoxMap["RATE_PIT_I"] = ui.ratePitchISpinBox; - nameToBoxMap["RATE_PIT_D"] = ui.ratePitchDSpinBox; - nameToBoxMap["RATE_PIT_IMAX"] = ui.ratePitchIMAXSpinBox; - - nameToBoxMap["RATE_YAW_P"] = ui.rateYawPSpinBox; - nameToBoxMap["RATE_YAW_I"] = ui.rateYawISpinBox; - nameToBoxMap["RATE_YAW_D"] = ui.rateYawDSpinBox; - nameToBoxMap["RATE_YAW_IMAX"] = ui.rateYawIMAXSpinBox; - - nameToBoxMap["LOITER_LAT_P"] = ui.rateLoiterPSpinBox; - nameToBoxMap["LOITER_LAT_I"] = ui.rateLoiterISpinBox; - nameToBoxMap["LOITER_LAT_D"] = ui.rateLoiterDSpinBox; - nameToBoxMap["LOITER_LAT_IMAX"] = ui.rateLoiterIMAXSpinBox; - - nameToBoxMap["THR_ACCEL_P"] = ui.throttleAccelPSpinBox; - nameToBoxMap["THR_ACCEL_I"] = ui.throttleAccelISpinBox; - nameToBoxMap["THR_ACCEL_D"] = ui.throttleAccelDSpinBox; - nameToBoxMap["THR_ACCEL_IMAX"] = ui.throttleAccelIMAXSpinBox; - - nameToBoxMap["THR_RATE_P"] = ui.throttleRatePSpinBox; - nameToBoxMap["THR_RATE_D"] = ui.throttleDateDSpinBox; - - nameToBoxMap["THR_ALT_P"] = ui.altitudeHoldPSpinBox; - - nameToBoxMap["WPNAV_SPEED"] = ui.wpNavLoiterSpeedSpinBox; - nameToBoxMap["WPNAV_RADIUS"] = ui.wpNavRadiusSpinBox; - nameToBoxMap["WPNAV_SPEED_DN"] = ui.wpNavSpeedDownSpinBox; - nameToBoxMap["WPNAV_LOIT_SPEED"] = ui.wpNavSpeedSpinBox; - nameToBoxMap["WPNAV_SPEED_UP"] = ui.wpNavSpeedUpSpinBox; - - nameToBoxMap["TUNE_HIGH"] = ui.ch6MaxSpinBox; - nameToBoxMap["TUNE_LOW"] = ui.ch6MinSpinBox; + m_nameToBoxMap["STB_RLL_P"] = ui.stabilPitchPSpinBox; + m_nameToBoxMap["STB_PIT_P"] = ui.stabilRollPSpinBox; + m_nameToBoxMap["STB_YAW_P"] = ui.stabilYawPSpinBox; + m_nameToBoxMap["HLD_LAT_P"] = ui.loiterPidPSpinBox; + + m_nameToBoxMap["RATE_RLL_P"] = ui.rateRollPSpinBox; + m_nameToBoxMap["RATE_RLL_I"] = ui.rateRollISpinBox; + m_nameToBoxMap["RATE_RLL_D"] = ui.rateRollDSpinBox; + m_nameToBoxMap["RATE_RLL_IMAX"] = ui.rateRollIMAXSpinBox; + + m_nameToBoxMap["RATE_PIT_P"] = ui.ratePitchPSpinBox; + m_nameToBoxMap["RATE_PIT_I"] = ui.ratePitchISpinBox; + m_nameToBoxMap["RATE_PIT_D"] = ui.ratePitchDSpinBox; + m_nameToBoxMap["RATE_PIT_IMAX"] = ui.ratePitchIMAXSpinBox; + + m_nameToBoxMap["RATE_YAW_P"] = ui.rateYawPSpinBox; + m_nameToBoxMap["RATE_YAW_I"] = ui.rateYawISpinBox; + m_nameToBoxMap["RATE_YAW_D"] = ui.rateYawDSpinBox; + m_nameToBoxMap["RATE_YAW_IMAX"] = ui.rateYawIMAXSpinBox; + + m_nameToBoxMap["LOITER_LAT_P"] = ui.rateLoiterPSpinBox; + m_nameToBoxMap["LOITER_LAT_I"] = ui.rateLoiterISpinBox; + m_nameToBoxMap["LOITER_LAT_D"] = ui.rateLoiterDSpinBox; + m_nameToBoxMap["LOITER_LAT_IMAX"] = ui.rateLoiterIMAXSpinBox; + + m_nameToBoxMap["THR_ACCEL_P"] = ui.throttleAccelPSpinBox; + m_nameToBoxMap["THR_ACCEL_I"] = ui.throttleAccelISpinBox; + m_nameToBoxMap["THR_ACCEL_D"] = ui.throttleAccelDSpinBox; + m_nameToBoxMap["THR_ACCEL_IMAX"] = ui.throttleAccelIMAXSpinBox; + + m_nameToBoxMap["THR_RATE_P"] = ui.throttleRatePSpinBox; + m_nameToBoxMap["THR_RATE_D"] = ui.throttleDateDSpinBox; + + m_nameToBoxMap["THR_ALT_P"] = ui.altitudeHoldPSpinBox; + + m_nameToBoxMap["WPNAV_SPEED"] = ui.wpNavLoiterSpeedSpinBox; + m_nameToBoxMap["WPNAV_RADIUS"] = ui.wpNavRadiusSpinBox; + m_nameToBoxMap["WPNAV_SPEED_DN"] = ui.wpNavSpeedDownSpinBox; + m_nameToBoxMap["WPNAV_LOIT_SPEED"] = ui.wpNavSpeedSpinBox; + m_nameToBoxMap["WPNAV_SPEED_UP"] = ui.wpNavSpeedUpSpinBox; + + m_nameToBoxMap["TUNE_HIGH"] = ui.ch6MaxSpinBox; + m_nameToBoxMap["TUNE_LOW"] = ui.ch6MinSpinBox; connect(ui.writePushButton,SIGNAL(clicked()),this,SLOT(writeButtonClicked())); connect(ui.refreshPushButton,SIGNAL(clicked()),this,SLOT(refreshButtonClicked())); - ch6ValueToTextList.append(QPair(0,"CH6_NONE")); - ch6ValueToTextList.append(QPair(1,"CH6_STABILIZE_KP")); - ch6ValueToTextList.append(QPair(2,"CH6_STABILIZE_KI")); - ch6ValueToTextList.append(QPair(3,"CH6_YAW_KP")); - ch6ValueToTextList.append(QPair(24,"CH6_YAW_KI")); - ch6ValueToTextList.append(QPair(4,"CH6_RATE_KP")); - ch6ValueToTextList.append(QPair(5,"CH6_RATE_KI")); - ch6ValueToTextList.append(QPair(6,"CH6_YAW_RATE_KP")); - ch6ValueToTextList.append(QPair(26,"CH6_YAW_RATE_KD")); - ch6ValueToTextList.append(QPair(7,"CH6_THROTTLE_KP")); - ch6ValueToTextList.append(QPair(9,"CH6_RELAY")); - ch6ValueToTextList.append(QPair(10,"CH6_WP_SPEED")); - ch6ValueToTextList.append(QPair(12,"CH6_LOITER_KP")); - ch6ValueToTextList.append(QPair(13,"CH6_HELI_EXTERNAL_GYRO")); - ch6ValueToTextList.append(QPair(14,"CH6_THR_HOLD_KP")); - ch6ValueToTextList.append(QPair(17,"CH6_OPTFLOW_KP")); - ch6ValueToTextList.append(QPair(18,"CH6_OPTFLOW_KI")); - ch6ValueToTextList.append(QPair(19,"CH6_OPTFLOW_KD")); - ch6ValueToTextList.append(QPair(21,"CH6_RATE_KD")); - ch6ValueToTextList.append(QPair(22,"CH6_LOITER_RATE_KP")); - ch6ValueToTextList.append(QPair(23,"CH6_LOITER_RATE_KD")); - ch6ValueToTextList.append(QPair(25,"CH6_ACRO_KP")); - ch6ValueToTextList.append(QPair(27,"CH6_LOITER_KI")); - ch6ValueToTextList.append(QPair(28,"CH6_LOITER_RATE_KI")); - ch6ValueToTextList.append(QPair(29,"CH6_STABILIZE_KD")); - ch6ValueToTextList.append(QPair(30,"CH6_AHRS_YAW_KP")); - ch6ValueToTextList.append(QPair(31,"CH6_AHRS_KP")); - ch6ValueToTextList.append(QPair(32,"CH6_INAV_TC")); - ch6ValueToTextList.append(QPair(33,"CH6_THROTTLE_KI")); - ch6ValueToTextList.append(QPair(34,"CH6_THR_ACCEL_KP")); - ch6ValueToTextList.append(QPair(35,"CH6_THR_ACCEL_KI")); - ch6ValueToTextList.append(QPair(36,"CH6_THR_ACCEL_KD")); - ch6ValueToTextList.append(QPair(38,"CH6_DECLINATION")); - ch6ValueToTextList.append(QPair(39,"CH6_CIRCLE_RATE")); - for (int i=0;i(0,"CH6_NONE")); + m_ch6ValueToTextList.append(QPair(1,"CH6_STABILIZE_KP")); + m_ch6ValueToTextList.append(QPair(2,"CH6_STABILIZE_KI")); + m_ch6ValueToTextList.append(QPair(3,"CH6_YAW_KP")); + m_ch6ValueToTextList.append(QPair(24,"CH6_YAW_KI")); + m_ch6ValueToTextList.append(QPair(4,"CH6_RATE_KP")); + m_ch6ValueToTextList.append(QPair(5,"CH6_RATE_KI")); + m_ch6ValueToTextList.append(QPair(6,"CH6_YAW_RATE_KP")); + m_ch6ValueToTextList.append(QPair(26,"CH6_YAW_RATE_KD")); + m_ch6ValueToTextList.append(QPair(7,"CH6_THROTTLE_KP")); + m_ch6ValueToTextList.append(QPair(9,"CH6_RELAY")); + m_ch6ValueToTextList.append(QPair(10,"CH6_WP_SPEED")); + m_ch6ValueToTextList.append(QPair(12,"CH6_LOITER_KP")); + m_ch6ValueToTextList.append(QPair(13,"CH6_HELI_EXTERNAL_GYRO")); + m_ch6ValueToTextList.append(QPair(14,"CH6_THR_HOLD_KP")); + m_ch6ValueToTextList.append(QPair(17,"CH6_OPTFLOW_KP")); + m_ch6ValueToTextList.append(QPair(18,"CH6_OPTFLOW_KI")); + m_ch6ValueToTextList.append(QPair(19,"CH6_OPTFLOW_KD")); + m_ch6ValueToTextList.append(QPair(21,"CH6_RATE_KD")); + m_ch6ValueToTextList.append(QPair(22,"CH6_LOITER_RATE_KP")); + m_ch6ValueToTextList.append(QPair(23,"CH6_LOITER_RATE_KD")); + m_ch6ValueToTextList.append(QPair(25,"CH6_ACRO_KP")); + m_ch6ValueToTextList.append(QPair(27,"CH6_LOITER_KI")); + m_ch6ValueToTextList.append(QPair(28,"CH6_LOITER_RATE_KI")); + m_ch6ValueToTextList.append(QPair(29,"CH6_STABILIZE_KD")); + m_ch6ValueToTextList.append(QPair(30,"CH6_AHRS_YAW_KP")); + m_ch6ValueToTextList.append(QPair(31,"CH6_AHRS_KP")); + m_ch6ValueToTextList.append(QPair(32,"CH6_INAV_TC")); + m_ch6ValueToTextList.append(QPair(33,"CH6_THROTTLE_KI")); + m_ch6ValueToTextList.append(QPair(34,"CH6_THR_ACCEL_KP")); + m_ch6ValueToTextList.append(QPair(35,"CH6_THR_ACCEL_KI")); + m_ch6ValueToTextList.append(QPair(36,"CH6_THR_ACCEL_KD")); + m_ch6ValueToTextList.append(QPair(38,"CH6_DECLINATION")); + m_ch6ValueToTextList.append(QPair(39,"CH6_CIRCLE_RATE")); + for (int i=0;iaddItem(ch6ValueToTextList[i].second); + ui.ch6OptComboBox->addItem(m_ch6ValueToTextList[i].second); } - ch7ValueToTextList.append(QPair(0,"Do nothing")); - ch7ValueToTextList.append(QPair(2,"Flip")); - ch7ValueToTextList.append(QPair(3,"Simple mode")); - ch7ValueToTextList.append(QPair(4,"RTL")); - ch7ValueToTextList.append(QPair(5,"Save Trim")); - ch7ValueToTextList.append(QPair(7,"Save WP")); - ch7ValueToTextList.append(QPair(8,"Multi Mode")); - ch7ValueToTextList.append(QPair(9,"Camera Trigger")); - ch7ValueToTextList.append(QPair(10,"Sonar")); - ch7ValueToTextList.append(QPair(11,"Fence")); - ch7ValueToTextList.append(QPair(12,"ResetToArmedYaw")); - for (int i=0;i(0,"Do nothing")); + m_ch78ValueToTextList.append(QPair(2,"Flip")); + m_ch78ValueToTextList.append(QPair(3,"Simple mode")); + m_ch78ValueToTextList.append(QPair(4,"RTL")); + m_ch78ValueToTextList.append(QPair(5,"Save Trim")); + m_ch78ValueToTextList.append(QPair(7,"Save WP")); + m_ch78ValueToTextList.append(QPair(8,"Multi Mode")); + m_ch78ValueToTextList.append(QPair(9,"Camera Trigger")); + m_ch78ValueToTextList.append(QPair(10,"Sonar")); + m_ch78ValueToTextList.append(QPair(11,"Fence")); + m_ch78ValueToTextList.append(QPair(12,"ResetToArmedYaw")); + for (int i=0;iaddItem(ch7ValueToTextList[i].second); + ui.ch7OptComboBox->addItem(m_ch78ValueToTextList[i].second); + ui.ch8OptComboBox->addItem(m_ch78ValueToTextList[i].second); } - - ch8ValueToTextList.append(QPair(0,"Do nothing")); - ch8ValueToTextList.append(QPair(2,"Flip")); - ch8ValueToTextList.append(QPair(3,"Simple mode")); - ch8ValueToTextList.append(QPair(4,"RTL")); - ch8ValueToTextList.append(QPair(5,"Save Trim")); - ch8ValueToTextList.append(QPair(7,"Save WP")); - ch8ValueToTextList.append(QPair(8,"Multi Mode")); - ch8ValueToTextList.append(QPair(9,"Camera Trigger")); - ch8ValueToTextList.append(QPair(10,"Sonar")); - ch8ValueToTextList.append(QPair(11,"Fence")); - ch8ValueToTextList.append(QPair(12,"ResetToArmedYaw")); - for (int i=0;iaddItem(ch8ValueToTextList[i].second); - } - } ArduCopterPidConfig::~ArduCopterPidConfig() @@ -130,15 +114,15 @@ ArduCopterPidConfig::~ArduCopterPidConfig() } void ArduCopterPidConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { - if (nameToBoxMap.contains(parameterName)) + if (m_nameToBoxMap.contains(parameterName)) { - nameToBoxMap[parameterName]->setValue(value.toDouble()); + m_nameToBoxMap[parameterName]->setValue(value.toDouble()); } else if (parameterName == "TUNE") { - for (int i=0;isetCurrentIndex(i); } @@ -146,9 +130,9 @@ void ArduCopterPidConfig::parameterChanged(int uas, int component, QString param } else if (parameterName == "CH7_OPT") { - for (int i=0;isetCurrentIndex(i); } @@ -156,9 +140,9 @@ void ArduCopterPidConfig::parameterChanged(int uas, int component, QString param } else if (parameterName == "CH8_OPT") { - for (int i=0;isetCurrentIndex(i); } @@ -169,24 +153,26 @@ void ArduCopterPidConfig::writeButtonClicked() { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } - for (QMap::const_iterator i=nameToBoxMap.constBegin();i!=nameToBoxMap.constEnd();i++) + for (QMap::const_iterator i=m_nameToBoxMap.constBegin();i!=m_nameToBoxMap.constEnd();i++) { m_uas->getParamManager()->setParameter(1,i.key(),i.value()->value()); } - m_uas->getParamManager()->setParameter(1,"TUNE",ch8ValueToTextList[ui.ch6OptComboBox->currentIndex()].first); - m_uas->getParamManager()->setParameter(1,"CH7_OPT",ch7ValueToTextList[ui.ch7OptComboBox->currentIndex()].first); - m_uas->getParamManager()->setParameter(1,"CH8_OPT",ch8ValueToTextList[ui.ch8OptComboBox->currentIndex()].first); + m_uas->getParamManager()->setParameter(1,"TUNE",m_ch78ValueToTextList[ui.ch6OptComboBox->currentIndex()].first); + m_uas->getParamManager()->setParameter(1,"CH7_OPT",m_ch78ValueToTextList[ui.ch7OptComboBox->currentIndex()].first); + m_uas->getParamManager()->setParameter(1,"CH8_OPT",m_ch78ValueToTextList[ui.ch8OptComboBox->currentIndex()].first); } void ArduCopterPidConfig::refreshButtonClicked() { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } - for (QMap::const_iterator i=nameToBoxMap.constBegin();i!=nameToBoxMap.constEnd();i++) + for (QMap::const_iterator i=m_nameToBoxMap.constBegin();i!=m_nameToBoxMap.constEnd();i++) { m_uas->getParamManager()->requestParameterUpdate(1,i.key()); } diff --git a/src/ui/configuration/ArduCopterPidConfig.h b/src/ui/configuration/ArduCopterPidConfig.h index dff3bb5a55..bc3ac3a693 100644 --- a/src/ui/configuration/ArduCopterPidConfig.h +++ b/src/ui/configuration/ArduCopterPidConfig.h @@ -18,10 +18,9 @@ private slots: void refreshButtonClicked(); void parameterChanged(int uas, int component, QString parameterName, QVariant value); private: - QList > ch6ValueToTextList; - QList > ch7ValueToTextList; - QList > ch8ValueToTextList; - QMap nameToBoxMap; + QList > m_ch6ValueToTextList; + QList > m_ch78ValueToTextList; + QMap m_nameToBoxMap; Ui::ArduCopterPidConfig ui; }; diff --git a/src/ui/configuration/ArduPlanePidConfig.cc b/src/ui/configuration/ArduPlanePidConfig.cc index f97e6af607..4cfa5efa6e 100644 --- a/src/ui/configuration/ArduPlanePidConfig.cc +++ b/src/ui/configuration/ArduPlanePidConfig.cc @@ -5,56 +5,56 @@ ArduPlanePidConfig::ArduPlanePidConfig(QWidget *parent) : AP2ConfigWidget(parent { ui.setupUi(this); - nameToBoxMap["RLL2SRV_P"] = ui.servoRollPSpinBox; - nameToBoxMap["RLL2SRV_I"] = ui.servoRollISpinBox; - nameToBoxMap["RLL2SRV_D"] = ui.servoRollDSpinBox; - nameToBoxMap["RLL2SRV_IMAX"] = ui.servoRollIMAXSpinBox; - - nameToBoxMap["PTCH2SRV_P"] = ui.servoPitchPSpinBox; - nameToBoxMap["PTCH2SRV_I"] = ui.servoPitchISpinBox; - nameToBoxMap["PTCH2SRV_D"] = ui.servoPitchDSpinBox; - nameToBoxMap["PTCH2SRV_IMAX"] = ui.servoPitchIMAXSpinBox; - - nameToBoxMap["YW2SRV_P"] = ui.servoYawPSpinBox; - nameToBoxMap["YW2SRV_I"] = ui.servoYawISpinBox; - nameToBoxMap["YW2SRV_D"] = ui.servoYawDSpinBox; - nameToBoxMap["YW2SRV_IMAX"] = ui.servoYawIMAXSpinBox; - - nameToBoxMap["ALT2PTCH_P"] = ui.navAltPSpinBox; - nameToBoxMap["ALT2PTCH_I"] = ui.navAltISpinBox; - nameToBoxMap["ALT2PTCH_D"] = ui.navAltDSpinBox; - nameToBoxMap["ALT2PTCH_IMAX"] = ui.navAltIMAXSpinBox; - - nameToBoxMap["ARSP2PTCH_P"] = ui.navASPSpinBox; - nameToBoxMap["ARSP2PTCH_I"] = ui.navASISpinBox; - nameToBoxMap["ARSP2PTCH_D"] = ui.navASDSpinBox; - nameToBoxMap["ARSP2PTCH_IMAX"] = ui.navASIMAXSpinBox; - - nameToBoxMap["ENRGY2THR_P"] = ui.energyPSpinBox; - nameToBoxMap["ENRGY2THR_I"] = ui.energyISpinBox; - nameToBoxMap["ENRGY2THR_D"] = ui.energyDSpinBox; - nameToBoxMap["ENRGY2THR_IMAX"] = ui.energyIMAXSpinBox; - - nameToBoxMap["KFF_PTCH2THR"] = ui.otherPitchCompSpinBox; - nameToBoxMap["KFF_PTCHCOMP"] = ui.otherPtTSpinBox; - nameToBoxMap["KFF_RDDRMIX"] = ui.otherRudderMixSpinBox; - - nameToBoxMap["TRIM_THROTTLE"] = ui.throttleCruiseSpinBox; - nameToBoxMap["THR_FS_VALUE"] = ui.throttleFSSpinBox; - nameToBoxMap["THR_MAX"] = ui.throttleMaxSpinBox; - nameToBoxMap["THR_MIN"] = ui.throttleMinSpinBox; - - nameToBoxMap["TRIM_ARSPD_CM"] = ui.airspeedCruiseSpinBox; - nameToBoxMap["ARSPD_FBW_MAX"] = ui.airspeedFBWMaxSpinBox; - nameToBoxMap["ARSPD_FBW_MIN"] = ui.airspeedFBWMinSpinBox; - nameToBoxMap["ARSPD_RATIO"] = ui.airspeedRatioSpinBox; - - nameToBoxMap["NAVL1_DAMPING"] = ui.l1DampingSpinBox; - nameToBoxMap["NAVL1_PERIOD"] = ui.l1PeriodSpinBox; - - nameToBoxMap["LIM_ROLL_CD"] = ui.navBankMaxSpinBox; - nameToBoxMap["LIM_PITCH_MAX"] = ui.navPitchMaxSpinBox; - nameToBoxMap["LIM_PITCH_MIN"] = ui.navPitchMinSpinBox; + m_nameToBoxMap["RLL2SRV_P"] = ui.servoRollPSpinBox; + m_nameToBoxMap["RLL2SRV_I"] = ui.servoRollISpinBox; + m_nameToBoxMap["RLL2SRV_D"] = ui.servoRollDSpinBox; + m_nameToBoxMap["RLL2SRV_IMAX"] = ui.servoRollIMAXSpinBox; + + m_nameToBoxMap["PTCH2SRV_P"] = ui.servoPitchPSpinBox; + m_nameToBoxMap["PTCH2SRV_I"] = ui.servoPitchISpinBox; + m_nameToBoxMap["PTCH2SRV_D"] = ui.servoPitchDSpinBox; + m_nameToBoxMap["PTCH2SRV_IMAX"] = ui.servoPitchIMAXSpinBox; + + m_nameToBoxMap["YW2SRV_P"] = ui.servoYawPSpinBox; + m_nameToBoxMap["YW2SRV_I"] = ui.servoYawISpinBox; + m_nameToBoxMap["YW2SRV_D"] = ui.servoYawDSpinBox; + m_nameToBoxMap["YW2SRV_IMAX"] = ui.servoYawIMAXSpinBox; + + m_nameToBoxMap["ALT2PTCH_P"] = ui.navAltPSpinBox; + m_nameToBoxMap["ALT2PTCH_I"] = ui.navAltISpinBox; + m_nameToBoxMap["ALT2PTCH_D"] = ui.navAltDSpinBox; + m_nameToBoxMap["ALT2PTCH_IMAX"] = ui.navAltIMAXSpinBox; + + m_nameToBoxMap["ARSP2PTCH_P"] = ui.navASPSpinBox; + m_nameToBoxMap["ARSP2PTCH_I"] = ui.navASISpinBox; + m_nameToBoxMap["ARSP2PTCH_D"] = ui.navASDSpinBox; + m_nameToBoxMap["ARSP2PTCH_IMAX"] = ui.navASIMAXSpinBox; + + m_nameToBoxMap["ENRGY2THR_P"] = ui.energyPSpinBox; + m_nameToBoxMap["ENRGY2THR_I"] = ui.energyISpinBox; + m_nameToBoxMap["ENRGY2THR_D"] = ui.energyDSpinBox; + m_nameToBoxMap["ENRGY2THR_IMAX"] = ui.energyIMAXSpinBox; + + m_nameToBoxMap["KFF_PTCH2THR"] = ui.otherPitchCompSpinBox; + m_nameToBoxMap["KFF_PTCHCOMP"] = ui.otherPtTSpinBox; + m_nameToBoxMap["KFF_RDDRMIX"] = ui.otherRudderMixSpinBox; + + m_nameToBoxMap["TRIM_THROTTLE"] = ui.throttleCruiseSpinBox; + m_nameToBoxMap["THR_FS_VALUE"] = ui.throttleFSSpinBox; + m_nameToBoxMap["THR_MAX"] = ui.throttleMaxSpinBox; + m_nameToBoxMap["THR_MIN"] = ui.throttleMinSpinBox; + + m_nameToBoxMap["TRIM_ARSPD_CM"] = ui.airspeedCruiseSpinBox; + m_nameToBoxMap["ARSPD_FBW_MAX"] = ui.airspeedFBWMaxSpinBox; + m_nameToBoxMap["ARSPD_FBW_MIN"] = ui.airspeedFBWMinSpinBox; + m_nameToBoxMap["ARSPD_RATIO"] = ui.airspeedRatioSpinBox; + + m_nameToBoxMap["NAVL1_DAMPING"] = ui.l1DampingSpinBox; + m_nameToBoxMap["NAVL1_PERIOD"] = ui.l1PeriodSpinBox; + + m_nameToBoxMap["LIM_ROLL_CD"] = ui.navBankMaxSpinBox; + m_nameToBoxMap["LIM_PITCH_MAX"] = ui.navPitchMaxSpinBox; + m_nameToBoxMap["LIM_PITCH_MIN"] = ui.navPitchMinSpinBox; connect(ui.writePushButton,SIGNAL(clicked()),this,SLOT(writeButtonClicked())); connect(ui.refreshPushButton,SIGNAL(clicked()),this,SLOT(refreshButtonClicked())); @@ -66,18 +66,19 @@ ArduPlanePidConfig::~ArduPlanePidConfig() } void ArduPlanePidConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { - if (nameToBoxMap.contains(parameterName)) + if (m_nameToBoxMap.contains(parameterName)) { - nameToBoxMap[parameterName]->setValue(value.toDouble()); + m_nameToBoxMap[parameterName]->setValue(value.toDouble()); } } void ArduPlanePidConfig::writeButtonClicked() { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } - for (QMap::const_iterator i=nameToBoxMap.constBegin();i!=nameToBoxMap.constEnd();i++) + for (QMap::const_iterator i=m_nameToBoxMap.constBegin();i!=m_nameToBoxMap.constEnd();i++) { m_uas->getParamManager()->setParameter(1,i.key(),i.value()->value()); } @@ -87,9 +88,10 @@ void ArduPlanePidConfig::refreshButtonClicked() { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } - for (QMap::const_iterator i=nameToBoxMap.constBegin();i!=nameToBoxMap.constEnd();i++) + for (QMap::const_iterator i=m_nameToBoxMap.constBegin();i!=m_nameToBoxMap.constEnd();i++) { m_uas->getParamManager()->requestParameterUpdate(1,i.key()); } diff --git a/src/ui/configuration/ArduPlanePidConfig.h b/src/ui/configuration/ArduPlanePidConfig.h index b0f12c4b8d..3a254cb371 100644 --- a/src/ui/configuration/ArduPlanePidConfig.h +++ b/src/ui/configuration/ArduPlanePidConfig.h @@ -17,7 +17,7 @@ private slots: void writeButtonClicked(); void refreshButtonClicked(); private: - QMap nameToBoxMap; + QMap m_nameToBoxMap; Ui::ArduPlanePidConfig ui; }; diff --git a/src/ui/configuration/ArduRoverPidConfig.cc b/src/ui/configuration/ArduRoverPidConfig.cc index 60f2f28f97..f9d9034e67 100644 --- a/src/ui/configuration/ArduRoverPidConfig.cc +++ b/src/ui/configuration/ArduRoverPidConfig.cc @@ -49,6 +49,7 @@ void ArduRoverPidConfig::writeButtonClicked() { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } for (QMap::const_iterator i=nameToBoxMap.constBegin();i!=nameToBoxMap.constEnd();i++) @@ -61,6 +62,7 @@ void ArduRoverPidConfig::refreshButtonClicked() { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } for (QMap::const_iterator i=nameToBoxMap.constBegin();i!=nameToBoxMap.constEnd();i++) diff --git a/src/ui/configuration/BatteryMonitorConfig.cc b/src/ui/configuration/BatteryMonitorConfig.cc index 05b6dc2343..e94ce6da3b 100644 --- a/src/ui/configuration/BatteryMonitorConfig.cc +++ b/src/ui/configuration/BatteryMonitorConfig.cc @@ -4,11 +4,11 @@ BatteryMonitorConfig::BatteryMonitorConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); - ui.monitorComboBox->addItem("0: Disabled"); - ui.monitorComboBox->addItem("3: Battery Volts"); - ui.monitorComboBox->addItem("4: Voltage and Current"); + ui.monitorComboBox->addItem(tr("0: Disabled")); + ui.monitorComboBox->addItem(tr("3: Battery Volts")); + ui.monitorComboBox->addItem(tr("4: Voltage and Current")); - ui.sensorComboBox->addItem("0: Other"); + ui.sensorComboBox->addItem(tr("0: Other")); ui.sensorComboBox->addItem("1: AttoPilot 45A"); ui.sensorComboBox->addItem("2: AttoPilot 90A"); ui.sensorComboBox->addItem("3: AttoPilot 180A"); @@ -34,19 +34,24 @@ BatteryMonitorConfig::BatteryMonitorConfig(QWidget *parent) : AP2ConfigWidget(pa } void BatteryMonitorConfig::activeUASSet(UASInterface *uas) { + if (m_uas) + { + disconnect(m_uas,SIGNAL(batteryChanged(UASInterface*,double,double,double,int)),this,SLOT(batteryChanged(UASInterface*,double,double,double,int))); + } + AP2ConfigWidget::activeUASSet(uas); if (!uas) { return; } connect(uas,SIGNAL(batteryChanged(UASInterface*,double,double,double,int)),this,SLOT(batteryChanged(UASInterface*,double,double,double,int))); - AP2ConfigWidget::activeUASSet(uas); + } void BatteryMonitorConfig::calcDividerSet() { if (!m_uas) { - QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + showNullMAVErrorMessageBox(); return; } bool ok = false; @@ -63,7 +68,7 @@ void BatteryMonitorConfig::ampsPerVoltSet() { if (!m_uas) { - QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + showNullMAVErrorMessageBox(); return; } bool ok = false; @@ -80,7 +85,7 @@ void BatteryMonitorConfig::batteryCapacitySet() { if (!m_uas) { - QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + showNullMAVErrorMessageBox(); return; } bool ok = false; @@ -98,10 +103,10 @@ void BatteryMonitorConfig::monitorCurrentIndexChanged(int index) { if (!m_uas) { - QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + showNullMAVErrorMessageBox(); return; } - if (index == 0) + if (index == 0) //Battery Monitor Disabled { m_uas->getParamManager()->setParameter(1,"BATT_VOLT_PIN",-1); m_uas->getParamManager()->setParameter(1,"BATT_CURR_PIN",-1); @@ -114,7 +119,7 @@ void BatteryMonitorConfig::monitorCurrentIndexChanged(int index) ui.calcVoltsLineEdit->setEnabled(false); ui.ampsPerVoltsLineEdit->setEnabled(false); } - else if (index == 1) + else if (index == 1) //Monitor voltage only { m_uas->getParamManager()->setParameter(1,"BATT_MONITOR",3); ui.sensorComboBox->setEnabled(false); @@ -124,7 +129,7 @@ void BatteryMonitorConfig::monitorCurrentIndexChanged(int index) ui.calcVoltsLineEdit->setEnabled(false); ui.ampsPerVoltsLineEdit->setEnabled(false); } - else if (index == 2) + else if (index == 2) //Monitor voltage and current { m_uas->getParamManager()->setParameter(1,"BATT_MONITOR",4); ui.sensorComboBox->setEnabled(true); @@ -139,45 +144,39 @@ void BatteryMonitorConfig::monitorCurrentIndexChanged(int index) } void BatteryMonitorConfig::sensorCurrentIndexChanged(int index) { - float maxvolt = 0; - float maxamps = 0; - float mvpervolt = 0; - float mvperamp = 0; - float topvolt = 0; - float topamps = 0; + float maxvolt = 0.0; + float maxamps = 0.0; + float mvpervolt = 0.0; + float mvperamp = 0.0; + float topvolt = 0.0; + float topamps = 0.0; if (index == 1) { - //atto 45 + //atto 45 see https://www.sparkfun.com/products/10643 maxvolt = 13.6; maxamps = 44.7; - mvpervolt = 242.3; - mvperamp = 73.20; } else if (index == 2) { - //atto 90 - maxvolt = 50; + //atto 90 see https://www.sparkfun.com/products/9028 + maxvolt = 51.8; maxamps = 89.4; - mvpervolt = 63.69; - mvperamp = 36.60; } else if (index == 3) { - //atto 180 - maxvolt = 50; + //atto 180 see https://www.sparkfun.com/products/10644 + maxvolt = 51.8; maxamps = 178.8; - mvpervolt = 63.69; - mvperamp = 18.30; } else if (index == 4) { //3dr - maxvolt = 50; - maxamps = 90; - mvpervolt = 100; - mvperamp = 55.55; + maxvolt = 50.0; + maxamps = 90.0; } + mvpervolt = calculatemVPerVolt(3.3,maxvolt); + mvperamp = calculatemVPerAmp(3.3,maxamps); if (index == 0) { //Other @@ -197,12 +196,21 @@ void BatteryMonitorConfig::sensorCurrentIndexChanged(int index) ui.measuredVoltsLineEdit->setEnabled(false); } } +float BatteryMonitorConfig::calculatemVPerAmp(float maxvoltsout,float maxamps) +{ + return (1000.0 * (maxvoltsout/maxamps)); +} + +float BatteryMonitorConfig::calculatemVPerVolt(float maxvoltsout,float maxvolts) +{ + return (1000.0 * (maxvoltsout/maxvolts)); +} void BatteryMonitorConfig::apmVerCurrentIndexChanged(int index) { if (!m_uas) { - QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + showNullMAVErrorMessageBox(); return; } if (index == 0) //APM1 diff --git a/src/ui/configuration/BatteryMonitorConfig.h b/src/ui/configuration/BatteryMonitorConfig.h index 2bbdb56f2e..a7349766ea 100644 --- a/src/ui/configuration/BatteryMonitorConfig.h +++ b/src/ui/configuration/BatteryMonitorConfig.h @@ -24,6 +24,8 @@ private slots: void batteryChanged(UASInterface* uas, double voltage, double current, double percent, int seconds); private: Ui::BatteryMonitorConfig ui; + inline float calculatemVPerAmp(float maxvoltsout,float maxamps); + inline float calculatemVPerVolt(float maxvoltsout,float maxvolts); }; #endif // BATTERYMONITORCONFIG_H diff --git a/src/ui/configuration/BatteryMonitorConfig.ui b/src/ui/configuration/BatteryMonitorConfig.ui index 0c008dc1a8..6d6974a81e 100644 --- a/src/ui/configuration/BatteryMonitorConfig.ui +++ b/src/ui/configuration/BatteryMonitorConfig.ui @@ -150,7 +150,7 @@ 160 70 281 - 80 + 91 diff --git a/src/ui/configuration/CameraGimbalConfig.cc b/src/ui/configuration/CameraGimbalConfig.cc index 7aef99903a..9c0b0e4c98 100644 --- a/src/ui/configuration/CameraGimbalConfig.cc +++ b/src/ui/configuration/CameraGimbalConfig.cc @@ -1,10 +1,12 @@ -#include "CameraGimbalConfig.h" #include #include + +#include "CameraGimbalConfig.h" + CameraGimbalConfig::CameraGimbalConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); - ui.tiltChannelComboBox->addItem("Disable"); + ui.tiltChannelComboBox->addItem(tr("Disable")); ui.tiltChannelComboBox->addItem("RC5"); ui.tiltChannelComboBox->addItem("RC6"); ui.tiltChannelComboBox->addItem("RC7"); @@ -12,13 +14,13 @@ CameraGimbalConfig::CameraGimbalConfig(QWidget *parent) : AP2ConfigWidget(parent ui.tiltChannelComboBox->addItem("RC10"); ui.tiltChannelComboBox->addItem("RC11"); - ui.tiltInputChannelComboBox->addItem("Disable"); + ui.tiltInputChannelComboBox->addItem(tr("Disable")); ui.tiltInputChannelComboBox->addItem("RC5"); ui.tiltInputChannelComboBox->addItem("RC6"); ui.tiltInputChannelComboBox->addItem("RC7"); ui.tiltInputChannelComboBox->addItem("RC8"); - ui.rollChannelComboBox->addItem("Disable"); + ui.rollChannelComboBox->addItem(tr("Disable")); ui.rollChannelComboBox->addItem("RC5"); ui.rollChannelComboBox->addItem("RC6"); ui.rollChannelComboBox->addItem("RC7"); @@ -26,14 +28,14 @@ CameraGimbalConfig::CameraGimbalConfig(QWidget *parent) : AP2ConfigWidget(parent ui.rollChannelComboBox->addItem("RC10"); ui.rollChannelComboBox->addItem("RC11"); - ui.rollInputChannelComboBox->addItem("Disable"); + ui.rollInputChannelComboBox->addItem(tr("Disable")); ui.rollInputChannelComboBox->addItem("RC5"); ui.rollInputChannelComboBox->addItem("RC6"); ui.rollInputChannelComboBox->addItem("RC7"); ui.rollInputChannelComboBox->addItem("RC8"); - ui.panChannelComboBox->addItem("Disable"); + ui.panChannelComboBox->addItem(tr("Disable")); ui.panChannelComboBox->addItem("RC5"); ui.panChannelComboBox->addItem("RC6"); ui.panChannelComboBox->addItem("RC7"); @@ -41,16 +43,16 @@ CameraGimbalConfig::CameraGimbalConfig(QWidget *parent) : AP2ConfigWidget(parent ui.panChannelComboBox->addItem("RC10"); ui.panChannelComboBox->addItem("RC11"); - ui.panInputChannelComboBox->addItem("Disable"); + ui.panInputChannelComboBox->addItem(tr("Disable")); ui.panInputChannelComboBox->addItem("RC5"); ui.panInputChannelComboBox->addItem("RC6"); ui.panInputChannelComboBox->addItem("RC7"); ui.panInputChannelComboBox->addItem("RC8"); - ui.shutterChannelComboBox->addItem("Disable"); - ui.shutterChannelComboBox->addItem("Relay"); - ui.shutterChannelComboBox->addItem("Transistor"); + ui.shutterChannelComboBox->addItem(tr("Disable")); + ui.shutterChannelComboBox->addItem(tr("Relay")); + ui.shutterChannelComboBox->addItem(tr("Transistor")); ui.shutterChannelComboBox->addItem("RC5"); ui.shutterChannelComboBox->addItem("RC6"); ui.shutterChannelComboBox->addItem("RC7"); @@ -100,13 +102,13 @@ void CameraGimbalConfig::updateTilt() { if (!m_uas) { - QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + showNullMAVErrorMessageBox(); return; } - if (!tiltPrefix.isEmpty()) + if (!m_tiltPrefix.isEmpty()) { //We need to set this to 0 for disabled. - m_uas->getParamManager()->setParameter(1,tiltPrefix + "FUNCTION",0); + m_uas->getParamManager()->setParameter(1,m_tiltPrefix + "FUNCTION",0); } if (ui.tiltChannelComboBox->currentIndex() == 0) { @@ -134,7 +136,7 @@ void CameraGimbalConfig::updateRoll() { if (!m_uas) { - QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + showNullMAVErrorMessageBox(); return; } m_uas->getParamManager()->setParameter(1,ui.rollChannelComboBox->currentText() + "_FUNCTION",8); @@ -157,7 +159,7 @@ void CameraGimbalConfig::updatePan() { if (!m_uas) { - QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + showNullMAVErrorMessageBox(); return; } m_uas->getParamManager()->setParameter(1,ui.panChannelComboBox->currentText() + "_FUNCTION",6); @@ -180,7 +182,7 @@ void CameraGimbalConfig::updateShutter() { if (!m_uas) { - QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + showNullMAVErrorMessageBox(); return; } if (ui.shutterChannelComboBox->currentIndex() == 0) //Disabled @@ -216,24 +218,6 @@ CameraGimbalConfig::~CameraGimbalConfig() void CameraGimbalConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { - connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - connect(ui.tiltInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - disconnect(ui.tiltInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - - connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); - disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); - connect(ui.panInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); - disconnect(ui.panInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); - - connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); - disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); - connect(ui.rollInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); - disconnect(ui.rollInputChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); - - connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); - disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); - if (parameterName == "MNT_ANGMIN_TIL") //TILT { ui.tiltAngleMinSpinBox->setValue(value.toInt() / 100.0); @@ -327,7 +311,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame } connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); } - if (parameterName.startsWith(shutterPrefix) && !shutterPrefix.isEmpty()) + if (parameterName.startsWith(m_shutterPrefix) && !m_shutterPrefix.isEmpty()) { if (parameterName.endsWith("MIN")) { @@ -338,7 +322,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame ui.shutterServoMaxSpinBox->setValue(value.toInt()); } } - else if (parameterName.startsWith(tiltPrefix) && !tiltPrefix.isEmpty()) + else if (parameterName.startsWith(m_tiltPrefix) && !m_tiltPrefix.isEmpty()) { if (parameterName.endsWith("MIN")) { @@ -360,7 +344,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame } } } - else if (parameterName.startsWith(rollPrefix) && !rollPrefix.isEmpty()) + else if (parameterName.startsWith(m_rollPrefix) && !m_rollPrefix.isEmpty()) { if (parameterName.endsWith("MIN")) { @@ -382,7 +366,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame } } } - else if (parameterName.startsWith(panPrefix) && !panPrefix.isEmpty()) + else if (parameterName.startsWith(m_panPrefix) && !m_panPrefix.isEmpty()) { if (parameterName.endsWith("MIN")) { @@ -412,7 +396,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); ui.shutterChannelComboBox->setCurrentIndex(3); connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); - shutterPrefix = "RC5_"; + m_shutterPrefix = "RC5_"; } else if (value.toInt() == 8) { @@ -420,7 +404,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); ui.rollChannelComboBox->setCurrentIndex(1); connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); - rollPrefix = "RC5_"; + m_rollPrefix = "RC5_"; } else if (value.toInt() == 7) { @@ -428,7 +412,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); ui.tiltChannelComboBox->setCurrentIndex(1); connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - tiltPrefix = "RC5_"; + m_tiltPrefix = "RC5_"; } else if (value.toInt() == 6) { @@ -436,7 +420,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); ui.panChannelComboBox->setCurrentIndex(1); connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); - panPrefix = "RC5_"; + m_panPrefix = "RC5_"; } m_uas->getParamManager()->requestParameterUpdate(1,"RC5_MIN"); m_uas->getParamManager()->requestParameterUpdate(1,"RC5_MAX"); @@ -450,7 +434,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); ui.shutterChannelComboBox->setCurrentIndex(4); connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); - shutterPrefix = "RC6_"; + m_shutterPrefix = "RC6_"; } else if (value.toInt() == 8) { @@ -458,7 +442,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); ui.rollChannelComboBox->setCurrentIndex(2); connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); - rollPrefix = "RC6_"; + m_rollPrefix = "RC6_"; } else if (value.toInt() == 7) { @@ -466,7 +450,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); ui.tiltChannelComboBox->setCurrentIndex(2); connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - tiltPrefix = "RC6_"; + m_tiltPrefix = "RC6_"; } else if (value.toInt() == 6) { @@ -474,7 +458,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); ui.panChannelComboBox->setCurrentIndex(2); connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); - panPrefix = "RC6_"; + m_panPrefix = "RC6_"; } m_uas->getParamManager()->requestParameterUpdate(1,"RC6_MIN"); m_uas->getParamManager()->requestParameterUpdate(1,"RC6_MAX"); @@ -488,7 +472,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); ui.shutterChannelComboBox->setCurrentIndex(5); connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); - shutterPrefix = "RC7_"; + m_shutterPrefix = "RC7_"; } else if (value.toInt() == 8) { @@ -496,7 +480,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); ui.rollChannelComboBox->setCurrentIndex(3); connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); - rollPrefix = "RC7_"; + m_rollPrefix = "RC7_"; } else if (value.toInt() == 7) { @@ -504,7 +488,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); ui.tiltChannelComboBox->setCurrentIndex(3); connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - tiltPrefix = "RC7_"; + m_tiltPrefix = "RC7_"; } else if (value.toInt() == 6) { @@ -512,7 +496,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); ui.panChannelComboBox->setCurrentIndex(3); connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); - panPrefix = "RC7_"; + m_panPrefix = "RC7_"; } m_uas->getParamManager()->requestParameterUpdate(1,"RC7_MIN"); m_uas->getParamManager()->requestParameterUpdate(1,"RC7_MAX"); @@ -526,7 +510,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); ui.shutterChannelComboBox->setCurrentIndex(6); connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); - shutterPrefix = "RC8_"; + m_shutterPrefix = "RC8_"; } else if (value.toInt() == 8) { @@ -534,7 +518,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); ui.rollChannelComboBox->setCurrentIndex(4); connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); - rollPrefix = "RC8_"; + m_rollPrefix = "RC8_"; } else if (value.toInt() == 7) { @@ -542,7 +526,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); ui.tiltChannelComboBox->setCurrentIndex(4); connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - tiltPrefix = "RC8_"; + m_tiltPrefix = "RC8_"; } else if (value.toInt() == 6) { @@ -550,7 +534,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); ui.panChannelComboBox->setCurrentIndex(4); connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); - panPrefix = "RC8_"; + m_panPrefix = "RC8_"; } m_uas->getParamManager()->requestParameterUpdate(1,"RC8_MIN"); m_uas->getParamManager()->requestParameterUpdate(1,"RC8_MAX"); @@ -564,7 +548,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); ui.shutterChannelComboBox->setCurrentIndex(7); connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); - shutterPrefix = "RC10_"; + m_shutterPrefix = "RC10_"; } else if (value.toInt() == 8) { @@ -572,7 +556,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); ui.rollChannelComboBox->setCurrentIndex(5); connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); - rollPrefix = "RC10_"; + m_rollPrefix = "RC10_"; } else if (value.toInt() == 7) { @@ -580,7 +564,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); ui.tiltChannelComboBox->setCurrentIndex(5); connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - tiltPrefix = "RC10_"; + m_tiltPrefix = "RC10_"; } else if (value.toInt() == 6) { @@ -588,7 +572,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); ui.panChannelComboBox->setCurrentIndex(5); connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); - panPrefix = "RC10_"; + m_panPrefix = "RC10_"; } m_uas->getParamManager()->requestParameterUpdate(1,"RC10_MIN"); m_uas->getParamManager()->requestParameterUpdate(1,"RC10_MAX"); @@ -602,7 +586,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); ui.shutterChannelComboBox->setCurrentIndex(8); connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); - shutterPrefix = "RC11_"; + m_shutterPrefix = "RC11_"; } else if (value.toInt() == 8) { @@ -610,7 +594,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); ui.rollChannelComboBox->setCurrentIndex(6); connect(ui.rollChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateRoll())); - rollPrefix = "RC11_"; + m_rollPrefix = "RC11_"; } else if (value.toInt() == 7) { @@ -618,7 +602,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); ui.tiltChannelComboBox->setCurrentIndex(6); connect(ui.tiltChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateTilt())); - tiltPrefix = "RC11_"; + m_tiltPrefix = "RC11_"; } else if (value.toInt() == 6) { @@ -626,7 +610,7 @@ void CameraGimbalConfig::parameterChanged(int uas, int component, QString parame disconnect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); ui.panChannelComboBox->setCurrentIndex(6); connect(ui.panChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePan())); - panPrefix = "RC11_"; + m_panPrefix = "RC11_"; } m_uas->getParamManager()->requestParameterUpdate(1,"RC11_MIN"); m_uas->getParamManager()->requestParameterUpdate(1,"RC11_MAX"); diff --git a/src/ui/configuration/CameraGimbalConfig.h b/src/ui/configuration/CameraGimbalConfig.h index 2608752b17..f5d737f193 100644 --- a/src/ui/configuration/CameraGimbalConfig.h +++ b/src/ui/configuration/CameraGimbalConfig.h @@ -21,10 +21,10 @@ private slots: private: Ui::CameraGimbalConfig ui; - QString shutterPrefix; - QString rollPrefix; - QString tiltPrefix; - QString panPrefix; + QString m_shutterPrefix; + QString m_rollPrefix; + QString m_tiltPrefix; + QString m_panPrefix; }; #endif // CAMERAGIMBALCONFIG_H diff --git a/src/ui/configuration/CompassConfig.cc b/src/ui/configuration/CompassConfig.cc index 43da906fd8..394ffe9842 100644 --- a/src/ui/configuration/CompassConfig.cc +++ b/src/ui/configuration/CompassConfig.cc @@ -1,7 +1,7 @@ #include "CompassConfig.h" -CompassConfig::CompassConfig(QWidget *parent) : QWidget(parent) +CompassConfig::CompassConfig(QWidget *parent) : AP2ConfigWidget(parent) { m_uas=0; ui.setupUi(this); @@ -13,9 +13,6 @@ CompassConfig::CompassConfig(QWidget *parent) : QWidget(parent) connect(ui.autoDecCheckBox,SIGNAL(clicked(bool)),this,SLOT(autoDecClicked(bool))); connect(ui.orientationComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(orientationComboChanged(int))); - connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); - activeUASSet(UASManager::instance()->getActiveUAS()); - ui.orientationComboBox->addItem("ROTATION_NONE"); ui.orientationComboBox->addItem("ROTATION_YAW_45"); ui.orientationComboBox->addItem("ROTATION_YAW_90"); @@ -47,16 +44,6 @@ CompassConfig::CompassConfig(QWidget *parent) : QWidget(parent) CompassConfig::~CompassConfig() { } -void CompassConfig::activeUASSet(UASInterface *uas) -{ - if (!uas) return; - if (!m_uas) - { - disconnect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); - } - m_uas = uas; - connect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); -} void CompassConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { if (parameterName == "MAG_ENABLE") diff --git a/src/ui/configuration/CompassConfig.h b/src/ui/configuration/CompassConfig.h index 31a7fe3e1f..fde4bf05e0 100644 --- a/src/ui/configuration/CompassConfig.h +++ b/src/ui/configuration/CompassConfig.h @@ -5,7 +5,8 @@ #include "ui_CompassConfig.h" #include "UASManager.h" #include "UASInterface.h" -class CompassConfig : public QWidget +#include "AP2ConfigWidget.h" +class CompassConfig : public AP2ConfigWidget { Q_OBJECT @@ -13,7 +14,6 @@ public: explicit CompassConfig(QWidget *parent = 0); ~CompassConfig(); private slots: - void activeUASSet(UASInterface *uas); void parameterChanged(int uas, int component, QString parameterName, QVariant value); void enableClicked(bool enabled); void autoDecClicked(bool enabled); diff --git a/src/ui/configuration/FailSafeConfig.cc b/src/ui/configuration/FailSafeConfig.cc index 2517a322ca..0e0d45e3dd 100644 --- a/src/ui/configuration/FailSafeConfig.cc +++ b/src/ui/configuration/FailSafeConfig.cc @@ -87,6 +87,7 @@ void FailSafeConfig::gcsChecked(bool checked) { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } if (checked) @@ -103,6 +104,7 @@ void FailSafeConfig::throttleActionChecked(bool checked) { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } if (checked) @@ -119,6 +121,7 @@ void FailSafeConfig::throttleChecked(bool checked) { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } if (checked) @@ -135,6 +138,7 @@ void FailSafeConfig::throttlePwmChanged() { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } m_uas->setParameter(1,"THR_FS_VALUE",ui.throttlePwmSpinBox->value()); @@ -144,6 +148,7 @@ void FailSafeConfig::throttleFailSafeChanged(int index) { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } m_uas->setParameter(1,"FS_THR_ENABLE",index); @@ -153,6 +158,7 @@ void FailSafeConfig::fsLongClicked(bool checked) { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } if (checked) @@ -169,6 +175,7 @@ void FailSafeConfig::fsShortClicked(bool checked) { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } if (checked) @@ -185,6 +192,7 @@ void FailSafeConfig::batteryFailChecked(bool checked) { if (!m_uas) { + showNullMAVErrorMessageBox(); return; } if (checked) @@ -202,11 +210,21 @@ FailSafeConfig::~FailSafeConfig() } void FailSafeConfig::activeUASSet(UASInterface *uas) { + if (m_uas) + { + disconnect(m_uas,SIGNAL(remoteControlChannelRawChanged(int,float)),this,SLOT(remoteControlChannelRawChanges(int,float))); + disconnect(m_uas,SIGNAL(hilActuatorsChanged(uint64_t,float,float,float,float,float,float,float,float)),this,SLOT(hilActuatorsChanged(uint64_t,float,float,float,float,float,float,float,float))); + disconnect(m_uas,SIGNAL(armingChanged(bool)),this,SLOT(armingChanged(bool))); + } AP2ConfigWidget::activeUASSet(uas); - connect(uas,SIGNAL(remoteControlChannelRawChanged(int,float)),this,SLOT(remoteControlChannelRawChanges(int,float))); - connect(uas,SIGNAL(hilActuatorsChanged(uint64_t,float,float,float,float,float,float,float,float)),this,SLOT(hilActuatorsChanged(uint64_t,float,float,float,float,float,float,float,float))); - connect(uas,SIGNAL(armingChanged(bool)),this,SLOT(armingChanged(bool))); - if (uas->getSystemType() == MAV_TYPE_FIXED_WING) + if (!uas) + { + return; + } + connect(m_uas,SIGNAL(remoteControlChannelRawChanged(int,float)),this,SLOT(remoteControlChannelRawChanges(int,float))); + connect(m_uas,SIGNAL(hilActuatorsChanged(uint64_t,float,float,float,float,float,float,float,float)),this,SLOT(hilActuatorsChanged(uint64_t,float,float,float,float,float,float,float,float))); + connect(m_uas,SIGNAL(armingChanged(bool)),this,SLOT(armingChanged(bool))); + if (m_uas->getSystemType() == MAV_TYPE_FIXED_WING) { ui.batteryFailCheckBox->setVisible(false); ui.throttleFailSafeComboBox->setVisible(false); @@ -221,7 +239,7 @@ void FailSafeConfig::activeUASSet(UASInterface *uas) ui.fsLongCheckBox->setVisible(true); ui.fsShortCheckBox->setVisible(true); } - else if (uas->getSystemType() == MAV_TYPE_QUADROTOR) + else if (m_uas->getSystemType() == MAV_TYPE_QUADROTOR) { ui.batteryFailCheckBox->setVisible(true); ui.throttleFailSafeComboBox->setVisible(true); diff --git a/src/ui/configuration/FlightModeConfig.cc b/src/ui/configuration/FlightModeConfig.cc index 933bf07dda..d5acd58176 100644 --- a/src/ui/configuration/FlightModeConfig.cc +++ b/src/ui/configuration/FlightModeConfig.cc @@ -1,25 +1,25 @@ #include "FlightModeConfig.h" -FlightModeConfig::FlightModeConfig(QWidget *parent) : QWidget(parent) +FlightModeConfig::FlightModeConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); connect(ui.savePushButton,SIGNAL(clicked()),this,SLOT(saveButtonClicked())); - connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(setActiveUAS(UASInterface*))); } FlightModeConfig::~FlightModeConfig() { } -void FlightModeConfig::setActiveUAS(UASInterface *uas) +void FlightModeConfig::activeUASSet(UASInterface *uas) { - if (!uas) return; if (m_uas) { + disconnect(m_uas,SIGNAL(modeChanged(int,QString,QString)),this,SLOT(modeChanged(int,QString,QString))); + disconnect(m_uas,SIGNAL(remoteControlChannelRawChanged(int,float)),this,SLOT(remoteControlChannelRawChanged(int,float))); } - m_uas = uas; + AP2ConfigWidget::activeUASSet(uas); + if (!uas) return; connect(m_uas,SIGNAL(modeChanged(int,QString,QString)),this,SLOT(modeChanged(int,QString,QString))); - connect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); connect(m_uas,SIGNAL(remoteControlChannelRawChanged(int,float)),this,SLOT(remoteControlChannelRawChanged(int,float))); QStringList itemlist; if (m_uas->getSystemType() == MAV_TYPE_FIXED_WING) diff --git a/src/ui/configuration/FlightModeConfig.h b/src/ui/configuration/FlightModeConfig.h index fa3ded3338..8506a51281 100644 --- a/src/ui/configuration/FlightModeConfig.h +++ b/src/ui/configuration/FlightModeConfig.h @@ -5,8 +5,9 @@ #include "ui_FlightModeConfig.h" #include "UASInterface.h" #include "UASManager.h" +#include "AP2ConfigWidget.h" -class FlightModeConfig : public QWidget +class FlightModeConfig : public AP2ConfigWidget { Q_OBJECT @@ -14,7 +15,7 @@ public: explicit FlightModeConfig(QWidget *parent = 0); ~FlightModeConfig(); private slots: - void setActiveUAS(UASInterface *uas); + void activeUASSet(UASInterface *uas); void saveButtonClicked(); void modeChanged(int sysId, QString status, QString description); void remoteControlChannelRawChanged(int chan,float val); diff --git a/src/ui/configuration/FrameTypeConfig.cc b/src/ui/configuration/FrameTypeConfig.cc index 1e4fc5f79e..430bb35e04 100644 --- a/src/ui/configuration/FrameTypeConfig.cc +++ b/src/ui/configuration/FrameTypeConfig.cc @@ -32,9 +32,8 @@ This file is part of the QGROUNDCONTROL project #include "FrameTypeConfig.h" -FrameTypeConfig::FrameTypeConfig(QWidget *parent) : QWidget(parent) +FrameTypeConfig::FrameTypeConfig(QWidget *parent) : AP2ConfigWidget(parent) { - m_uas=0; ui.setupUi(this); //Disable until we get a FRAME parameter. @@ -45,23 +44,11 @@ FrameTypeConfig::FrameTypeConfig(QWidget *parent) : QWidget(parent) connect(ui.plusRadioButton,SIGNAL(clicked()),this,SLOT(plusFrameSelected())); connect(ui.xRadioButton,SIGNAL(clicked()),this,SLOT(xFrameSelected())); connect(ui.vRadioButton,SIGNAL(clicked()),this,SLOT(vFrameSelected())); - connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); - activeUASSet(UASManager::instance()->getActiveUAS()); } FrameTypeConfig::~FrameTypeConfig() { } -void FrameTypeConfig::activeUASSet(UASInterface *uas) -{ - if (!uas) return; - if (!m_uas) - { - disconnect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); - } - m_uas = uas; - connect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); -} void FrameTypeConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { if (parameterName == "FRAME") diff --git a/src/ui/configuration/FrameTypeConfig.h b/src/ui/configuration/FrameTypeConfig.h index d28c914391..fbee2d1301 100644 --- a/src/ui/configuration/FrameTypeConfig.h +++ b/src/ui/configuration/FrameTypeConfig.h @@ -37,7 +37,8 @@ This file is part of the QGROUNDCONTROL project #include "UASInterface.h" #include "UASManager.h" #include "QGCUASParamManager.h" -class FrameTypeConfig : public QWidget +#include "AP2ConfigWidget.h" +class FrameTypeConfig : public AP2ConfigWidget { Q_OBJECT @@ -45,7 +46,6 @@ public: explicit FrameTypeConfig(QWidget *parent = 0); ~FrameTypeConfig(); private slots: - void activeUASSet(UASInterface *uas); void parameterChanged(int uas, int component, QString parameterName, QVariant value); void xFrameSelected(); void plusFrameSelected(); diff --git a/src/ui/configuration/OsdConfig.cc b/src/ui/configuration/OsdConfig.cc index 8fd0d9f367..766c9b0edb 100644 --- a/src/ui/configuration/OsdConfig.cc +++ b/src/ui/configuration/OsdConfig.cc @@ -14,7 +14,7 @@ void OsdConfig::enableButtonClicked() { if (!m_uas) { - QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + showNullMAVErrorMessageBox(); return; } m_uas->getParamManager()->setParameter(1,"SR0_EXT_STAT",2); diff --git a/src/ui/configuration/RadioCalibrationConfig.cc b/src/ui/configuration/RadioCalibrationConfig.cc index 0de51073a2..067a56fc14 100644 --- a/src/ui/configuration/RadioCalibrationConfig.cc +++ b/src/ui/configuration/RadioCalibrationConfig.cc @@ -32,15 +32,12 @@ This file is part of the QGROUNDCONTROL project #include "RadioCalibrationConfig.h" #include -RadioCalibrationConfig::RadioCalibrationConfig(QWidget *parent) : QWidget(parent) +RadioCalibrationConfig::RadioCalibrationConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); connect(ui.calibrateButton,SIGNAL(clicked()),this,SLOT(calibrateButtonClicked())); - m_uas = 0; m_calibrationEnabled = false; - connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); - setActiveUAS(UASManager::instance()->getActiveUAS()); ui.rollWidget->setMin(800); ui.rollWidget->setMax(2200); ui.pitchWidget->setMin(800); @@ -79,20 +76,18 @@ RadioCalibrationConfig::RadioCalibrationConfig(QWidget *parent) : QWidget(parent RadioCalibrationConfig::~RadioCalibrationConfig() { } -void RadioCalibrationConfig::setActiveUAS(UASInterface *uas) +void RadioCalibrationConfig::activeUASSet(UASInterface *uas) { - if (uas==NULL) return; - if (m_uas) { - // Disconnect old system disconnect(m_uas, SIGNAL(remoteControlChannelRawChanged(int,float)), this,SLOT(remoteControlChannelRawChanged(int,float))); - disconnect(m_uas, SIGNAL(parameterChanged(int,int,QString,QVariant)), this,SLOT(parameterChanged(int,int,QString,QVariant))); } - m_uas = uas; + AP2ConfigWidget::activeUASSet(uas); + if (!uas) + { + return; + } connect(m_uas,SIGNAL(remoteControlChannelRawChanged(int,float)),this,SLOT(remoteControlChannelRawChanged(int,float))); - connect(m_uas,SIGNAL(parameterChanged(int,int,QString,QVariant)),this,SLOT(parameterChanged(int,int,QString,QVariant))); - } void RadioCalibrationConfig::remoteControlChannelRawChanged(int chan,float val) { diff --git a/src/ui/configuration/RadioCalibrationConfig.h b/src/ui/configuration/RadioCalibrationConfig.h index e51501dd65..8e9eb30070 100644 --- a/src/ui/configuration/RadioCalibrationConfig.h +++ b/src/ui/configuration/RadioCalibrationConfig.h @@ -39,7 +39,8 @@ This file is part of the QGROUNDCONTROL project #include "ui_RadioCalibrationConfig.h" #include "UASManager.h" #include "UASInterface.h" -class RadioCalibrationConfig : public QWidget +#include "AP2ConfigWidget.h" +class RadioCalibrationConfig : public AP2ConfigWidget { Q_OBJECT @@ -50,7 +51,7 @@ protected: void showEvent(QShowEvent *event); void hideEvent(QHideEvent *event); private slots: - void setActiveUAS(UASInterface *uas); + void activeUASSet(UASInterface *uas); void remoteControlChannelRawChanged(int chan,float val); void parameterChanged(int uas, int component, QString parameterName, QVariant value); void guiUpdateTimerTick(); diff --git a/src/ui/configuration/StandardParamConfig.cc b/src/ui/configuration/StandardParamConfig.cc index 0be1d02f22..c9ebb4acf9 100644 --- a/src/ui/configuration/StandardParamConfig.cc +++ b/src/ui/configuration/StandardParamConfig.cc @@ -7,13 +7,6 @@ StandardParamConfig::StandardParamConfig(QWidget *parent) : AP2ConfigWidget(pare StandardParamConfig::~StandardParamConfig() { } - - -void StandardParamConfig::activeUASSet(UASInterface *uas) -{ - - AP2ConfigWidget::activeUASSet(uas); -} void StandardParamConfig::addRange(QString title,QString description,QString param,double min,double max) { ParamWidget *widget = new ParamWidget(ui.scrollAreaWidgetContents); diff --git a/src/ui/configuration/StandardParamConfig.h b/src/ui/configuration/StandardParamConfig.h index d337b9b4f2..b2fbc04f48 100644 --- a/src/ui/configuration/StandardParamConfig.h +++ b/src/ui/configuration/StandardParamConfig.h @@ -18,7 +18,6 @@ private slots: void parameterChanged(int uas, int component, QString parameterName, QVariant value); private: QMap paramToWidgetMap; - void activeUASSet(UASInterface *uas); Ui::StandardParamConfig ui; }; -- GitLab From 50d01b95fade069a1f987bbc8686385599263a44 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Thu, 18 Jul 2013 10:58:52 -0400 Subject: [PATCH 078/460] Fix for crash involving improperly setting m_uas to 0 in some Config Widgets --- src/ui/configuration/AccelCalibrationConfig.cc | 1 - src/ui/configuration/AccelCalibrationConfig.h | 1 - src/ui/configuration/CompassConfig.cc | 1 - src/ui/configuration/CompassConfig.h | 1 - src/ui/configuration/FlightModeConfig.h | 1 - src/ui/configuration/FrameTypeConfig.h | 1 - src/ui/configuration/RadioCalibrationConfig.h | 1 - 7 files changed, 7 deletions(-) diff --git a/src/ui/configuration/AccelCalibrationConfig.cc b/src/ui/configuration/AccelCalibrationConfig.cc index e5d2b7a173..945ba5e2e0 100644 --- a/src/ui/configuration/AccelCalibrationConfig.cc +++ b/src/ui/configuration/AccelCalibrationConfig.cc @@ -3,7 +3,6 @@ AccelCalibrationConfig::AccelCalibrationConfig(QWidget *parent) : AP2ConfigWidget(parent) { - m_uas=0; ui.setupUi(this); connect(ui.calibrateAccelButton,SIGNAL(clicked()),this,SLOT(calibrateButtonClicked())); diff --git a/src/ui/configuration/AccelCalibrationConfig.h b/src/ui/configuration/AccelCalibrationConfig.h index 69dc2c414f..ef6f6e1a17 100644 --- a/src/ui/configuration/AccelCalibrationConfig.h +++ b/src/ui/configuration/AccelCalibrationConfig.h @@ -21,7 +21,6 @@ private slots: private: int m_accelAckCount; Ui::AccelCalibrationConfig ui; - UASInterface *m_uas; }; #endif // ACCELCALIBRATIONCONFIG_H diff --git a/src/ui/configuration/CompassConfig.cc b/src/ui/configuration/CompassConfig.cc index 394ffe9842..d0cbcc7ada 100644 --- a/src/ui/configuration/CompassConfig.cc +++ b/src/ui/configuration/CompassConfig.cc @@ -3,7 +3,6 @@ CompassConfig::CompassConfig(QWidget *parent) : AP2ConfigWidget(parent) { - m_uas=0; ui.setupUi(this); ui.autoDecCheckBox->setEnabled(false); ui.enableCheckBox->setEnabled(false); diff --git a/src/ui/configuration/CompassConfig.h b/src/ui/configuration/CompassConfig.h index fde4bf05e0..d650c1bebb 100644 --- a/src/ui/configuration/CompassConfig.h +++ b/src/ui/configuration/CompassConfig.h @@ -20,7 +20,6 @@ private slots: void orientationComboChanged(int index); private: Ui::CompassConfig ui; - UASInterface *m_uas; }; #endif // COMPASSCONFIG_H diff --git a/src/ui/configuration/FlightModeConfig.h b/src/ui/configuration/FlightModeConfig.h index 8506a51281..373de8560e 100644 --- a/src/ui/configuration/FlightModeConfig.h +++ b/src/ui/configuration/FlightModeConfig.h @@ -26,7 +26,6 @@ private: QMap roverModeUiIndexToIndex; QMap planeModeUiIndexToIndex; Ui::FlightModeConfig ui; - UASInterface *m_uas; }; #endif // FLIGHTMODECONFIG_H diff --git a/src/ui/configuration/FrameTypeConfig.h b/src/ui/configuration/FrameTypeConfig.h index fbee2d1301..92d04b95c5 100644 --- a/src/ui/configuration/FrameTypeConfig.h +++ b/src/ui/configuration/FrameTypeConfig.h @@ -52,7 +52,6 @@ private slots: void vFrameSelected(); private: Ui::FrameTypeConfig ui; - UASInterface *m_uas; }; #endif // FRAMETYPECONFIG_H diff --git a/src/ui/configuration/RadioCalibrationConfig.h b/src/ui/configuration/RadioCalibrationConfig.h index 8e9eb30070..fb2519863c 100644 --- a/src/ui/configuration/RadioCalibrationConfig.h +++ b/src/ui/configuration/RadioCalibrationConfig.h @@ -63,7 +63,6 @@ private: double rcValue[8]; QTimer *guiUpdateTimer; bool m_calibrationEnabled; - UASInterface *m_uas; Ui::RadioCalibrationConfig ui; }; -- GitLab From 07a9ab08f0514800161723c710171451c9f7b0e7 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 19 Jul 2013 06:51:16 -0400 Subject: [PATCH 079/460] Addition of Retract/Neutral/Control angles to CameraGimbal config screen --- src/ui/configuration/CameraGimbalConfig.cc | 47 ++++ src/ui/configuration/CameraGimbalConfig.h | 4 +- src/ui/configuration/CameraGimbalConfig.ui | 239 ++++++++++++++++++++- 3 files changed, 280 insertions(+), 10 deletions(-) diff --git a/src/ui/configuration/CameraGimbalConfig.cc b/src/ui/configuration/CameraGimbalConfig.cc index 9c0b0e4c98..724dd4bc1d 100644 --- a/src/ui/configuration/CameraGimbalConfig.cc +++ b/src/ui/configuration/CameraGimbalConfig.cc @@ -95,7 +95,54 @@ CameraGimbalConfig::CameraGimbalConfig(QWidget *parent) : AP2ConfigWidget(parent connect(ui.shutterDurationSpinBox,SIGNAL(editingFinished()),this,SLOT(updateShutter())); connect(ui.shutterChannelComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(updateShutter())); + connect(ui.retractXSpinBox,SIGNAL(editingFinished()),this,SLOT(updateRetractAngles())); + connect(ui.retractYSpinBox,SIGNAL(editingFinished()),this,SLOT(updateRetractAngles())); + connect(ui.retractZSpinBox,SIGNAL(editingFinished()),this,SLOT(updateRetractAngles())); + connect(ui.controlXSpinBox,SIGNAL(editingFinished()),this,SLOT(updateControlAngles())); + connect(ui.controlYSpinBox,SIGNAL(editingFinished()),this,SLOT(updateControlAngles())); + connect(ui.controlZSpinBox,SIGNAL(editingFinished()),this,SLOT(updateControlAngles())); + + connect(ui.neutralXSpinBox,SIGNAL(editingFinished()),this,SLOT(updateNeutralAngles())); + connect(ui.neutralYSpinBox,SIGNAL(editingFinished()),this,SLOT(updateNeutralAngles())); + connect(ui.neutralZSpinBox,SIGNAL(editingFinished()),this,SLOT(updateNeutralAngles())); + + +} +void CameraGimbalConfig::updateRetractAngles() +{ + if (!m_uas) + { + showNullMAVErrorMessageBox(); + return; + } + m_uas->getParamManager()->setParameter(1,"MNT_RETRACT_X",ui.retractXSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_RETRACT_Y",ui.retractYSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_RETRACT_Z",ui.retractZSpinBox->value()); +} + +void CameraGimbalConfig::updateNeutralAngles() +{ + if (!m_uas) + { + showNullMAVErrorMessageBox(); + return; + } + m_uas->getParamManager()->setParameter(1,"MNT_NEUTRAL_X",ui.neutralXSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_NEUTRAL_Y",ui.neutralYSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_NEUTRAL_Z",ui.neutralZSpinBox->value()); +} + +void CameraGimbalConfig::updateControlAngles() +{ + if (!m_uas) + { + showNullMAVErrorMessageBox(); + return; + } + m_uas->getParamManager()->setParameter(1,"MNT_CONTROL_X",ui.controlXSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_CONTROL_Y",ui.controlYSpinBox->value()); + m_uas->getParamManager()->setParameter(1,"MNT_CONTROL_Z",ui.controlZSpinBox->value()); } void CameraGimbalConfig::updateTilt() diff --git a/src/ui/configuration/CameraGimbalConfig.h b/src/ui/configuration/CameraGimbalConfig.h index f5d737f193..9f686243f7 100644 --- a/src/ui/configuration/CameraGimbalConfig.h +++ b/src/ui/configuration/CameraGimbalConfig.h @@ -18,7 +18,9 @@ private slots: void updateRoll(); void updatePan(); void updateShutter(); - + void updateRetractAngles(); + void updateNeutralAngles(); + void updateControlAngles(); private: Ui::CameraGimbalConfig ui; QString m_shutterPrefix; diff --git a/src/ui/configuration/CameraGimbalConfig.ui b/src/ui/configuration/CameraGimbalConfig.ui index 75dec1117b..1775b5945e 100644 --- a/src/ui/configuration/CameraGimbalConfig.ui +++ b/src/ui/configuration/CameraGimbalConfig.ui @@ -123,7 +123,7 @@ - CheckBox + Stabilize Tilt @@ -191,7 +191,7 @@ 100 - -100 + 0
@@ -297,7 +297,7 @@ - CheckBox + Stabilize Roll @@ -471,7 +471,7 @@ - CheckBox + Stabilize Pan @@ -726,15 +726,236 @@ - 720 - 70 - 120 - 80 + 590 + 60 + 171 + 131 + + + + Retract Angles + + + + + + + + + + X + + + + + + + Y + + + + + + + Z + + + + + + + + + + + -180 + + + 180 + + + + + + + -180 + + + 180 + + + + + + + -180 + + + 180 + + + + + + + + + + + + + 590 + 210 + 171 + 131 - GroupBox + Neutral Angles + + + + + + + + + X + + + + + + + Y + + + + + + + Z + + + + + + + + + + + -180 + + + 180 + + + + + + + -180 + + + 180 + + + + + + + -180 + + + 180 + + + + + + + + + + + + + 590 + 360 + 171 + 131 + + + + Control Angles + + + + + + + + + + X + + + + + + + Y + + + + + + + Z + + + + + + + + + + + -180 + + + 180 + + + + + + + -180 + + + 180 + + + + + + + -180 + + + 180 + + + + + + + + -- GitLab From fb6efcee77b0c2fd487ce4abe8ebbbe5c86f1e6b Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 19 Jul 2013 07:06:42 -0400 Subject: [PATCH 080/460] More changes based on code comments by Bill. --- src/ui/configuration/BatteryMonitorConfig.cc | 6 +++++- src/ui/configuration/BatteryMonitorConfig.h | 1 + src/ui/configuration/BatteryMonitorConfig.ui | 4 ++-- src/ui/configuration/FrameTypeConfig.cc | 18 ++++++++++++------ src/ui/configuration/OpticalFlowConfig.cc | 2 +- src/ui/configuration/RadioCalibrationConfig.h | 12 ++++++++---- 6 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/ui/configuration/BatteryMonitorConfig.cc b/src/ui/configuration/BatteryMonitorConfig.cc index e94ce6da3b..6e56877884 100644 --- a/src/ui/configuration/BatteryMonitorConfig.cc +++ b/src/ui/configuration/BatteryMonitorConfig.cc @@ -18,7 +18,8 @@ BatteryMonitorConfig::BatteryMonitorConfig(QWidget *parent) : AP2ConfigWidget(pa ui.apmVerComboBox->addItem("1: APM2 - 2.5 non 3DR"); ui.apmVerComboBox->addItem("2: APM2.5 - 3DR Power Module"); ui.apmVerComboBox->addItem("3: PX4"); - ui.alertOnLowCheckBox->setVisible(false); + + ui.alertOnLowCheckBox->setVisible(false); //Unimpelemented, but TODO. connect(ui.monitorComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(monitorCurrentIndexChanged(int))); @@ -46,6 +47,9 @@ void BatteryMonitorConfig::activeUASSet(UASInterface *uas) connect(uas,SIGNAL(batteryChanged(UASInterface*,double,double,double,int)),this,SLOT(batteryChanged(UASInterface*,double,double,double,int))); } +void BatteryMonitorConfig::alertOnLowClicked(bool checked) +{ +} void BatteryMonitorConfig::calcDividerSet() { diff --git a/src/ui/configuration/BatteryMonitorConfig.h b/src/ui/configuration/BatteryMonitorConfig.h index a7349766ea..417e6922a9 100644 --- a/src/ui/configuration/BatteryMonitorConfig.h +++ b/src/ui/configuration/BatteryMonitorConfig.h @@ -20,6 +20,7 @@ private slots: void calcDividerSet(); void ampsPerVoltSet(); void batteryCapacitySet(); + void alertOnLowClicked(bool checked); void activeUASSet(UASInterface *uas); void batteryChanged(UASInterface* uas, double voltage, double current, double percent, int seconds); private: diff --git a/src/ui/configuration/BatteryMonitorConfig.ui b/src/ui/configuration/BatteryMonitorConfig.ui index 6d6974a81e..5d11f960ad 100644 --- a/src/ui/configuration/BatteryMonitorConfig.ui +++ b/src/ui/configuration/BatteryMonitorConfig.ui @@ -53,12 +53,12 @@ 480 120 - 70 + 91 17 - CheckBox + Alert On Low diff --git a/src/ui/configuration/FrameTypeConfig.cc b/src/ui/configuration/FrameTypeConfig.cc index 430bb35e04..7ee5abad3d 100644 --- a/src/ui/configuration/FrameTypeConfig.cc +++ b/src/ui/configuration/FrameTypeConfig.cc @@ -73,24 +73,30 @@ void FrameTypeConfig::parameterChanged(int uas, int component, QString parameter void FrameTypeConfig::xFrameSelected() { - if (m_uas) + if (!m_uas) { - m_uas->getParamManager()->setParameter(1,"FRAME",QVariant(1)); + showNullMAVErrorMessageBox(); + return; } + m_uas->getParamManager()->setParameter(1,"FRAME",QVariant(1)); } void FrameTypeConfig::plusFrameSelected() { - if (m_uas) + if (!m_uas) { - m_uas->getParamManager()->setParameter(1,"FRAME",QVariant(0)); + showNullMAVErrorMessageBox(); + return; } + m_uas->getParamManager()->setParameter(1,"FRAME",QVariant(0)); } void FrameTypeConfig::vFrameSelected() { - if (m_uas) + if (!m_uas) { - m_uas->getParamManager()->setParameter(1,"FRAME",QVariant(2)); + showNullMAVErrorMessageBox(); + return; } + m_uas->getParamManager()->setParameter(1,"FRAME",QVariant(2)); } diff --git a/src/ui/configuration/OpticalFlowConfig.cc b/src/ui/configuration/OpticalFlowConfig.cc index 085a83f3f1..cc0404a06d 100644 --- a/src/ui/configuration/OpticalFlowConfig.cc +++ b/src/ui/configuration/OpticalFlowConfig.cc @@ -29,7 +29,7 @@ void OpticalFlowConfig::enableCheckBoxClicked(bool checked) { if (!m_uas) { - QMessageBox::information(0,tr("Error"),tr("Please connect to a MAV before attempting to set configuration")); + showNullMAVErrorMessageBox(); return; } m_uas->getParamManager()->setParameter(1,"FLOW_ENABLE",checked ? 1 : 0); diff --git a/src/ui/configuration/RadioCalibrationConfig.h b/src/ui/configuration/RadioCalibrationConfig.h index fb2519863c..00b90f8e20 100644 --- a/src/ui/configuration/RadioCalibrationConfig.h +++ b/src/ui/configuration/RadioCalibrationConfig.h @@ -57,10 +57,14 @@ private slots: void guiUpdateTimerTick(); void calibrateButtonClicked(); private: - double rcMin[8]; - double rcMax[8]; - double rcTrim[8]; - double rcValue[8]; + QList rcMin; + QList rcMax; + QList rcTrim; + QList rcValue; + //double rcMin[8]; + //double rcMax[8]; + //double rcTrim[8]; + //double rcValue[8]; QTimer *guiUpdateTimer; bool m_calibrationEnabled; Ui::RadioCalibrationConfig ui; -- GitLab From 9b5c656fc1c73ec1dd58f93de2845b32a1fe3b59 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Fri, 19 Jul 2013 10:06:30 -0700 Subject: [PATCH 081/460] Fix to improve QSerialPort integration & stability. --- src/comm/SerialLink.cc | 54 ++++++++++++++++------------- src/comm/SerialLink.h | 6 ++-- src/comm/SerialLinkInterface.h | 2 +- src/ui/QGCToolBar.cc | 6 ++-- src/ui/SerialConfigurationWindow.cc | 12 +++---- 5 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 0f50e912f5..c91ef70d5d 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -23,7 +23,6 @@ SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, int dataBits, int stopBits) : m_bytesRead(0), m_port(NULL), - m_ports(new QVector()), m_stopp(false), m_reqReset(false) { @@ -32,9 +31,9 @@ SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, // Setup settings m_portName = portname.trimmed(); - if (m_portName == "" && getCurrentPorts()->size() > 0) + if (m_portName == "" && getCurrentPorts().size() > 0) { - m_portName = m_ports->first().trimmed(); + m_portName = m_ports.first().trimmed(); } qDebug() << "m_portName " << m_portName; @@ -87,14 +86,11 @@ SerialLink::~SerialLink() disconnect(); if(m_port) delete m_port; m_port = NULL; - if (m_ports) delete m_ports; - m_ports = NULL; } -QVector* SerialLink::getCurrentPorts() +QList SerialLink::getCurrentPorts() { - Q_ASSERT_X(m_ports != NULL, "getCurrentPorts", "m_ports is NULL"); - m_ports->clear(); + m_ports.clear(); // Example use QSerialPortInfo // [TODO] make this thread safe @@ -110,7 +106,7 @@ QVector* SerialLink::getCurrentPorts() // << "Description : " << info.description(); // qDebug() << "Manufacturer: " << info.manufacturer(); - m_ports->append(info.portName()); + m_ports.append(info.portName()); } return m_ports; } @@ -186,6 +182,18 @@ void SerialLink::run() m_port->setDataTerminalReady(false); } } + + if (m_transmitBuffer.size() > 0) { + // send the data + QMutexLocker lockWrite(&m_writeMutex); + int num_written = m_port->write(m_transmitBuffer.constData()); + if (num_written > 0){ + m_transmitBuffer = m_transmitBuffer.remove(0,num_written); + } + + } + + bool error = m_port->waitForReadyRead(500); if(error) { // Waits for 1/2 second [TODO][BB] lower to SerialLink::poll_interval? @@ -203,7 +211,6 @@ void SerialLink::run() // qDebug() << "readyReadTime #"<< __LINE__; } - if (bytes != m_bytesRead) // i.e things are good and data is being read. { bytes = m_bytesRead; @@ -265,26 +272,25 @@ void SerialLink::writeBytes(const char* data, qint64 size) { if(m_port && m_port->isOpen()) { // qDebug() << "writeBytes" << m_portName << "attempting to tx " << size << "bytes."; - int b = m_port->write(data, size); - if (b > 0) { - Q_ASSERT_X(b = size, "writeBytes", "failed to write all bytes"); + QByteArray byteArray(data,size); + { + QMutexLocker writeLocker(&m_writeMutex); + m_transmitBuffer.append(byteArray); + } -// qDebug() << "writeBytes " << m_portName << "tx'd" << b << "bytes:"; +// qDebug() << "writeBytes " << m_portName << "tx'd" << b << "bytes:"; - // Increase write counter - m_bitsSentTotal += size * 8; + // Increase write counter + m_bitsSentTotal += size * 8; - // Extra debug logging -// QByteArray* byteArray = new QByteArray(data,size); + // Extra debug logging // qDebug() << byteArray->toHex(); // delete byteArray; - - } else { - disconnect(); - // Error occured - emit communicationError(getName(), tr("Could not send data - link %1 is disconnected!").arg(getName())); - } + } else { + disconnect(); + // Error occured + emit communicationError(getName(), tr("Could not send data - link %1 is disconnected!").arg(getName())); } } diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index cab1e91d7a..963a14a258 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -65,7 +65,7 @@ public: static const int poll_interval = SERIAL_POLL_INTERVAL; ///< Polling interval, defined in configuration.h /** @brief Get a list of the currently available ports */ - QVector* getCurrentPorts(); + QList getCurrentPorts(); void requestReset(); @@ -166,12 +166,14 @@ protected: quint64 m_connectionStartTime; QMutex m_statisticsMutex; QMutex m_dataMutex; - QVector* m_ports; + QList m_ports; private: volatile bool m_stopp; volatile bool m_reqReset; QMutex m_stoppMutex; + QMutex m_writeMutex; + QByteArray m_transmitBuffer; bool hardwareConnect(); diff --git a/src/comm/SerialLinkInterface.h b/src/comm/SerialLinkInterface.h index 59ff90132e..767d3011c9 100644 --- a/src/comm/SerialLinkInterface.h +++ b/src/comm/SerialLinkInterface.h @@ -42,7 +42,7 @@ class SerialLinkInterface : public LinkInterface Q_OBJECT public: - virtual QVector* getCurrentPorts() = 0; + virtual QList getCurrentPorts() = 0; virtual QString getPortName() = 0; virtual int getBaudRate() = 0; virtual int getDataBits() = 0; diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 30d89f5d81..40a80d616b 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -577,12 +577,12 @@ void QGCToolBar::updateComboBox() if (slink) { //It's a serial link - QVector *portlist = slink->getCurrentPorts(); + QList portlist = slink->getCurrentPorts(); //if (!slink->isConnected()) //{ - for (int j=0;jsize();j++) + for (int j=0;jaddItem("Serial port:" + QString::number(i) + ":" + portlist->at(j)); + portComboBox->addItem("Serial port:" + QString::number(i) + ":" + portlist[j]); } //} //We only really want to display from unconnected sources. diff --git a/src/ui/SerialConfigurationWindow.cc b/src/ui/SerialConfigurationWindow.cc index 3354deb6cd..72974c7c14 100644 --- a/src/ui/SerialConfigurationWindow.cc +++ b/src/ui/SerialConfigurationWindow.cc @@ -216,23 +216,23 @@ void SerialConfigurationWindow::setupPortList() if (!link) return; // Get the ports available on this system - QVector* ports = link->getCurrentPorts(); + QList ports = link->getCurrentPorts(); QString storedName = this->link->getPortName(); bool storedFound = false; // Add the ports in reverse order, because we prepend them to the list - for (int i = ports->size() - 1; i >= 0; --i) + for (int i = ports.count() - 1; i >= 0; --i) { // Prepend newly found port to the list - if (ui.portName->findText(ports->at(i)) == -1) + if (ui.portName->findText(ports[i]) == -1) { - ui.portName->insertItem(0, ports->at(i)); - if (!userConfigured) ui.portName->setEditText(ports->at(i)); + ui.portName->insertItem(0, ports[i]); + if (!userConfigured) ui.portName->setEditText(ports[i]); } // Check if the stored link name is still present - if (ports->at(i).contains(storedName) || storedName.contains(ports->at(i))) + if (ports[i].contains(storedName) || storedName.contains(ports[i])) storedFound = true; } -- GitLab From 34eaf1fb422146f5df3b01fad4d756343b3127c9 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Fri, 19 Jul 2013 12:13:10 -0700 Subject: [PATCH 082/460] Fixed: APM Tool Bar showing Connect/Disconnect labels in reverse --- qml/ApmToolBar.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qml/ApmToolBar.qml b/qml/ApmToolBar.qml index 75fa879257..234e421952 100644 --- a/qml/ApmToolBar.qml +++ b/qml/ApmToolBar.qml @@ -19,11 +19,11 @@ Rectangle { if (connected){ console.log("APM Tool BAR QML: connected") connectButton.image = "./resources/apmplanner/toolbar/disconnect.png" - connectButton.label = "CONNECT" + connectButton.label = "DISCONNECT" } else { console.log("APM Tool BAR QML: disconnected") connectButton.image = "./resources/apmplanner/toolbar/connect.png" - connectButton.label = "DISCONNECT" + connectButton.label = "CONNECT" } } -- GitLab From 179cb2863b86b3b382cce43e7b8df2feb821b0d8 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 21 Jul 2013 21:57:54 +0200 Subject: [PATCH 083/460] Some minor execution time fixes --- src/ui/MainWindow.cc | 2 +- src/ui/UASRawStatusView.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 2b78425fec..dbf4b24190 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -203,8 +203,8 @@ void MainWindow::init() QList actions; actions << ui.actionFlightView; actions << ui.actionMissionView; - //actions << ui.actionConfiguration_2; actions << ui.actionHardwareConfig; + actions << ui.actionSoftwareConfig; toolBar->setPerspectiveChangeActions(actions); // Add actions for advanced users (displayed in dropdown under "advanced") diff --git a/src/ui/UASRawStatusView.cpp b/src/ui/UASRawStatusView.cpp index ca0ac37003..5824ec65d9 100644 --- a/src/ui/UASRawStatusView.cpp +++ b/src/ui/UASRawStatusView.cpp @@ -16,7 +16,7 @@ UASRawStatusView::UASRawStatusView(QWidget *parent) : QWidget(parent) // FIXME reinstate once fixed. - timer->start(2000); + //timer->start(2000); } void UASRawStatusView::addSource(MAVLinkDecoder *decoder) { -- GitLab From 342634ca928f2fae67552daf7026dae88a58ce25 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 23 Jul 2013 10:42:16 -0400 Subject: [PATCH 084/460] Change so OsdConfig only sends requests to start telemetry on a single serial port --- src/ui/configuration/OsdConfig.cc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/ui/configuration/OsdConfig.cc b/src/ui/configuration/OsdConfig.cc index 766c9b0edb..25f5cd376d 100644 --- a/src/ui/configuration/OsdConfig.cc +++ b/src/ui/configuration/OsdConfig.cc @@ -25,13 +25,4 @@ void OsdConfig::enableButtonClicked() m_uas->getParamManager()->setParameter(1,"SR0_RAW_CTRL",2); m_uas->getParamManager()->setParameter(1,"SR0_RAW_SENS",2); m_uas->getParamManager()->setParameter(1,"SR0_RC_CHAN",2); - - m_uas->getParamManager()->setParameter(1,"SR3_EXT_STAT",2); - m_uas->getParamManager()->setParameter(1,"SR3_EXTRA1",10); - m_uas->getParamManager()->setParameter(1,"SR3_EXTRA2",10); - m_uas->getParamManager()->setParameter(1,"SR3_EXTRA3",2); - m_uas->getParamManager()->setParameter(1,"SR3_POSITION",3); - m_uas->getParamManager()->setParameter(1,"SR3_RAW_CTRL",2); - m_uas->getParamManager()->setParameter(1,"SR3_RAW_SENS",2); - m_uas->getParamManager()->setParameter(1,"SR3_RC_CHAN",2); } -- GitLab From 84af735ef20ac90daae8f71bb38f1aee66636596 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 23 Jul 2013 10:42:54 -0400 Subject: [PATCH 085/460] Change for user configurable column count in UASQuickView --- src/ui/uas/UASQuickView.cc | 105 ++++++++++++++++++++++++++++++++++--- src/ui/uas/UASQuickView.h | 13 +++++ src/ui/uas/UASQuickView.ui | 8 +-- 3 files changed, 112 insertions(+), 14 deletions(-) diff --git a/src/ui/uas/UASQuickView.cc b/src/ui/uas/UASQuickView.cc index 9bb52255d4..23e3fcc2d4 100644 --- a/src/ui/uas/UASQuickView.cc +++ b/src/ui/uas/UASQuickView.cc @@ -4,10 +4,17 @@ #include "UASQuickViewItemSelect.h" #include "UASQuickViewTextItem.h" #include +#include UASQuickView::UASQuickView(QWidget *parent) : QWidget(parent) { quickViewSelectDialog=0; + m_columnCount=2; + m_currentColumn=0; ui.setupUi(this); + + m_verticalLayoutList.append(new QVBoxLayout()); + ui.horizontalLayout->addItem(m_verticalLayoutList[0]); + connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(setActiveUAS(UASInterface*))); connect(UASManager::instance(),SIGNAL(UASCreated(UASInterface*)),this,SLOT(addUAS(UASInterface*))); if (UASManager::instance()->getActiveUAS()) @@ -23,7 +30,7 @@ UASQuickView::UASQuickView(QWidget *parent) : QWidget(parent) { valueEnabled("altitude"); valueEnabled("groundSpeed"); - valueEnabled("distToWaypoint"); + valueEnabled("distToWP"); valueEnabled("yaw"); valueEnabled("roll"); } @@ -33,9 +40,15 @@ UASQuickView::UASQuickView(QWidget *parent) : QWidget(parent) connect(action,SIGNAL(triggered()),this,SLOT(actionTriggered())); this->addAction(action); + QAction *columnaction = new QAction("Set Column Count",this); + columnaction->setCheckable(false); + connect(columnaction,SIGNAL(triggered()),this,SLOT(columnActionTriggered())); + this->addAction(columnaction); + updateTimer = new QTimer(this); connect(updateTimer,SIGNAL(timeout()),this,SLOT(updateTimerTick())); updateTimer->start(1000); + } UASQuickView::~UASQuickView() { @@ -44,6 +57,18 @@ UASQuickView::~UASQuickView() delete quickViewSelectDialog; } } +void UASQuickView::columnActionTriggered() +{ + bool ok = false; + int newcolumns = QInputDialog::getInt(this,"Columns","Enter number of columns",1,0,100,1,&ok); + if (!ok) + { + return; + } + m_columnCount = newcolumns; + sortItems(newcolumns); + saveSettings(); +} void UASQuickView::actionTriggered() { @@ -75,6 +100,7 @@ void UASQuickView::saveSettings() settings.setValue("type","text"); } settings.endArray(); + settings.setValue("UAS_QUICK_VIEW_COLUMNS",m_columnCount); settings.sync(); } void UASQuickView::loadSettings() @@ -91,15 +117,27 @@ void UASQuickView::loadSettings() valueEnabled(nameval); } } + settings.endArray(); + m_columnCount = settings.value("UAS_QUICK_VIEW_COLUMNS",1).toInt(); + sortItems(m_columnCount); } void UASQuickView::valueEnabled(QString value) { UASQuickViewItem *item = new UASQuickViewTextItem(this); item->setTitle(value); - ui.verticalLayout->addWidget(item); + //ui.verticalLayout->addWidget(item); + //m_currentColumn + m_verticalLayoutList[m_currentColumn]->addWidget(item); + m_PropertyToLayoutIndexMap[value] = m_currentColumn; + m_currentColumn++; + if (m_currentColumn >= m_columnCount-1) + { + m_currentColumn = 0; + } uasPropertyToLabelMap[value] = item; uasEnabledPropertyList.append(value); + if (!uasPropertyValueMap.contains(value)) { uasPropertyValueMap[value] = 0; @@ -107,6 +145,44 @@ void UASQuickView::valueEnabled(QString value) saveSettings(); } +void UASQuickView::sortItems(int columncount) +{ + QList itemlist; + for (QMap::const_iterator i = uasPropertyToLabelMap.constBegin();i!=uasPropertyToLabelMap.constEnd();i++) + { + m_verticalLayoutList[m_PropertyToLayoutIndexMap[i.key()]]->removeWidget(i.value()); + m_PropertyToLayoutIndexMap.remove(i.key()); + itemlist.append(i.value()); + } + //Item list has all the widgets availble, now re-add them to the layouts. + for (int i=0;iremoveItem(m_verticalLayoutList[i]); + m_verticalLayoutList[i]->deleteLater(); //removeItem de-parents the item. + } + m_verticalLayoutList.clear(); + + //Create a vertical layout for every intended column + for (int i=0;iaddItem(layout); + m_verticalLayoutList.append(layout); + } + + //Cycle through all items and add them to the layout + int currcol = 0; + for (int i=0;iaddWidget(itemlist[i]); + currcol++; + if (currcol >= columncount) + { + currcol = 0; + } + } + m_currentColumn = currcol; +} void UASQuickView::valueDisabled(QString value) { @@ -115,7 +191,10 @@ void UASQuickView::valueDisabled(QString value) UASQuickViewItem *item = uasPropertyToLabelMap[value]; uasPropertyToLabelMap.remove(value); item->hide(); - ui.verticalLayout->removeWidget(item); + //ui.verticalLayout->removeWidget(item); + //layout->removeWidget(item); + m_verticalLayoutList[m_PropertyToLayoutIndexMap[value]]->removeWidget(item); + sortItems(m_columnCount); item->deleteLater(); uasEnabledPropertyList.removeOne(value); saveSettings(); @@ -282,16 +361,26 @@ void UASQuickView::actionTriggered(bool checked) } if (checked) { - UASQuickViewItem *item = new UASQuickViewTextItem(this); + valueEnabled(senderlabel->text()); + /*UASQuickViewItem *item = new UASQuickViewTextItem(this); item->setTitle(senderlabel->text()); - ui.verticalLayout->addWidget(item); - uasPropertyToLabelMap[senderlabel->text()] = item; + layout->addWidget(item); + //ui.verticalLayout->addWidget(item); + m_currentColumn++; + if (m_currentColumn >= m_verticalLayoutList.size()) + { + m_currentColumn = 0; + } + uasPropertyToLabelMap[senderlabel->text()] = item;*/ + + } else { - ui.verticalLayout->removeWidget(uasPropertyToLabelMap[senderlabel->text()]); + valueDisabled(senderlabel->text()); + /*layout->removeWidget(uasPropertyToLabelMap[senderlabel->text()]); uasPropertyToLabelMap[senderlabel->text()]->deleteLater(); - uasPropertyToLabelMap.remove(senderlabel->text()); + uasPropertyToLabelMap.remove(senderlabel->text());*/ } } diff --git a/src/ui/uas/UASQuickView.h b/src/ui/uas/UASQuickView.h index 4a0dc9b7b2..16109e4a1a 100644 --- a/src/ui/uas/UASQuickView.h +++ b/src/ui/uas/UASQuickView.h @@ -10,6 +10,7 @@ #include "UASQuickViewItem.h" #include "MAVLinkDecoder.h" #include "UASQuickViewItemSelect.h" +#include "FlowLayout.h" class UASQuickView : public QWidget { Q_OBJECT @@ -40,6 +41,17 @@ private: /** Loads gauge layout from settings file */ void loadSettings(); + + /** Column Count */ + int m_columnCount; + + QList m_verticalLayoutList; + void sortItems(int columncount); + QList m_verticalLayoutItemCount; + int m_currentColumn; + QMap m_PropertyToLayoutIndexMap; + + //FlowLayout *layout; protected: Ui::Form ui; signals: @@ -65,6 +77,7 @@ public slots: void selectDialogClosed(); void valueEnabled(QString value); void valueDisabled(QString value); + void columnActionTriggered(); }; #endif // UASQUICKVIEW_H diff --git a/src/ui/uas/UASQuickView.ui b/src/ui/uas/UASQuickView.ui index 067c3afc6f..f11c734b7c 100644 --- a/src/ui/uas/UASQuickView.ui +++ b/src/ui/uas/UASQuickView.ui @@ -19,13 +19,9 @@ Form - + - - - 0 - - + -- GitLab From 51fa42c92afde53a573b4e0d9969eea2cfdd13da Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 24 Jul 2013 06:23:44 -0400 Subject: [PATCH 086/460] Fix for compile error from missing header --- src/ui/uas/UASQuickView.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ui/uas/UASQuickView.h b/src/ui/uas/UASQuickView.h index 16109e4a1a..977b5c21d0 100644 --- a/src/ui/uas/UASQuickView.h +++ b/src/ui/uas/UASQuickView.h @@ -10,7 +10,6 @@ #include "UASQuickViewItem.h" #include "MAVLinkDecoder.h" #include "UASQuickViewItemSelect.h" -#include "FlowLayout.h" class UASQuickView : public QWidget { Q_OBJECT -- GitLab From f60e7231d572fde63499d6a250c7ea8e31e19e29 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Wed, 24 Jul 2013 09:11:25 -0700 Subject: [PATCH 087/460] FIX: Added the use of waitForBytesWritten to enable sending data --- src/comm/SerialLink.cc | 49 ++++++++++++++++++------------------------ src/comm/SerialLink.h | 4 +++- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index c91ef70d5d..8f80b759d8 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -63,16 +63,6 @@ SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, m_dataBits = dataBits; m_stopBits = stopBits; - // Set the port name -// if (m_portName == "") -// { -// m_name = tr("Serial Link ") + QString::number(getId()); -// } -// else -// { -// m_name = portname.trimmed(); -// } - loadSettings(); } void SerialLink::requestReset() @@ -91,8 +81,6 @@ SerialLink::~SerialLink() QList SerialLink::getCurrentPorts() { m_ports.clear(); - // Example use QSerialPortInfo - // [TODO] make this thread safe QList portList = QSerialPortInfo::availablePorts(); @@ -152,6 +140,7 @@ void SerialLink::run() { //Need to error out here. emit communicationError(getName(),"Error connecting: " + m_port->errorString()); + disconnect(); // This tidies up and sends the necessary signals return; } @@ -183,18 +172,18 @@ void SerialLink::run() } } - if (m_transmitBuffer.size() > 0) { - // send the data - QMutexLocker lockWrite(&m_writeMutex); - int num_written = m_port->write(m_transmitBuffer.constData()); - if (num_written > 0){ - m_transmitBuffer = m_transmitBuffer.remove(0,num_written); - } - + if (m_transmitBuffer.length() > 0) { + QMutexLocker writeLocker(&m_writeMutex); + int numWritten = m_port->write(m_transmitBuffer); + bool txError = m_port->waitForBytesWritten(-1); +// if ((txError) || (numWritten == -1)) +// qDebug() << "TX Error!"; + m_transmitBuffer = m_transmitBuffer.remove(0, numWritten); + } else { +// qDebug() << "Wait write response timeout %1" << QTime::currentTime().toString(); } - - bool error = m_port->waitForReadyRead(500); + bool error = m_port->waitForReadyRead(10); if(error) { // Waits for 1/2 second [TODO][BB] lower to SerialLink::poll_interval? QByteArray readData = m_port->readAll(); @@ -208,9 +197,9 @@ void SerialLink::run() m_bitsReceivedTotal += readData.length() * 8; } } else { -// qDebug() << "readyReadTime #"<< __LINE__; - +// qDebug() << "Wait write response timeout %1" << QTime::currentTime().toString(); } + if (bytes != m_bytesRead) // i.e things are good and data is being read. { bytes = m_bytesRead; @@ -273,20 +262,17 @@ void SerialLink::writeBytes(const char* data, qint64 size) if(m_port && m_port->isOpen()) { // qDebug() << "writeBytes" << m_portName << "attempting to tx " << size << "bytes."; - QByteArray byteArray(data,size); + QByteArray byteArray(data, size); { QMutexLocker writeLocker(&m_writeMutex); m_transmitBuffer.append(byteArray); } -// qDebug() << "writeBytes " << m_portName << "tx'd" << b << "bytes:"; - // Increase write counter m_bitsSentTotal += size * 8; // Extra debug logging // qDebug() << byteArray->toHex(); -// delete byteArray; } else { disconnect(); // Error occured @@ -420,6 +406,8 @@ bool SerialLink::hardwareConnect() } QObject::connect(m_port,SIGNAL(aboutToClose()),this,SIGNAL(disconnected())); + QObject::connect(m_port, SIGNAL(error(QSerialPort::SerialPortError)), + this, SLOT(linkError(QSerialPort::SerialPortError))); // port->setCommTimeouts(QSerialPort::CtScheme_NonBlockingRead); m_connectionStartTime = MG::TIME::getGroundTimeNow(); @@ -451,6 +439,11 @@ bool SerialLink::hardwareConnect() return true; // successful connection } +void SerialLink::linkError(QSerialPort::SerialPortError error) +{ + qDebug() << error; +} + /** * @brief Check if connection is active. diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index 963a14a258..a7e8e148a2 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -142,6 +142,8 @@ public slots: bool connect(); bool disconnect(); + void linkError(QSerialPort::SerialPortError error); + protected: quint64 m_bytesRead; QSerialPort* m_port; @@ -166,13 +168,13 @@ protected: quint64 m_connectionStartTime; QMutex m_statisticsMutex; QMutex m_dataMutex; + QMutex m_writeMutex; QList m_ports; private: volatile bool m_stopp; volatile bool m_reqReset; QMutex m_stoppMutex; - QMutex m_writeMutex; QByteArray m_transmitBuffer; bool hardwareConnect(); -- GitLab From 250624fc241fd66474d5c2f9e016a2ad03079bd3 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Wed, 24 Jul 2013 09:15:24 -0700 Subject: [PATCH 088/460] Fixes #22 add init to lists to fix out-of-bounds issue --- src/ui/configuration/RadioCalibrationConfig.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ui/configuration/RadioCalibrationConfig.cc b/src/ui/configuration/RadioCalibrationConfig.cc index 067a56fc14..a3ce3b6121 100644 --- a/src/ui/configuration/RadioCalibrationConfig.cc +++ b/src/ui/configuration/RadioCalibrationConfig.cc @@ -71,6 +71,11 @@ RadioCalibrationConfig::RadioCalibrationConfig(QWidget *parent) : AP2ConfigWidge guiUpdateTimer = new QTimer(this); connect(guiUpdateTimer,SIGNAL(timeout()),this,SLOT(guiUpdateTimerTick())); + + rcMin << 1100.0 << 1100.0 << 1100.0 << 1100.0 << 1100.0 << 1100.0 << 1100.0 << 1100.0; + rcMax << 1900.0 << 1900.0 << 1900.0 << 1900.0 << 1900.0 << 1900.0 << 1900.0 << 1900.0; + rcTrim << 1500.0 << 1500.0 << 1500.0 << 1500.0 << 1500.0 << 1500.0 << 1500.0 << 1500.0; + rcValue << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0; } RadioCalibrationConfig::~RadioCalibrationConfig() -- GitLab From 123707a91812459270dfe22309dbf44618e698a1 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Fri, 26 Jul 2013 23:26:52 +0200 Subject: [PATCH 089/460] Allowed flexible config initialization --- qgroundcontrol.pro | 12 +- src/ui/MainWindow.cc | 52 +- src/ui/QGCConfigView.cc | 57 ++ src/ui/QGCConfigView.h | 28 + src/ui/QGCConfigView.ui | 28 + src/ui/QGCPX4VehicleConfig.cc | 1581 +++++++++++++++++++++++++++++++++ src/ui/QGCPX4VehicleConfig.h | 202 +++++ src/ui/QGCPX4VehicleConfig.ui | 1302 +++++++++++++++++++++++++++ 8 files changed, 3241 insertions(+), 21 deletions(-) create mode 100644 src/ui/QGCConfigView.cc create mode 100644 src/ui/QGCConfigView.h create mode 100644 src/ui/QGCConfigView.ui create mode 100644 src/ui/QGCPX4VehicleConfig.cc create mode 100644 src/ui/QGCPX4VehicleConfig.h create mode 100644 src/ui/QGCPX4VehicleConfig.ui diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 9814de6fe2..df6f4f3d6b 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -222,6 +222,7 @@ FORMS += src/ui/MainWindow.ui \ src/ui/mission/QGCMissionDoStartSearch.ui \ src/ui/mission/QGCMissionDoFinishSearch.ui \ src/ui/QGCVehicleConfig.ui \ + src/ui/QGCPX4VehicleConfig.ui \ src/ui/QGCHilConfiguration.ui \ src/ui/QGCHilFlightGearConfiguration.ui \ src/ui/QGCHilJSBSimConfiguration.ui \ @@ -261,7 +262,8 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/ParamWidget.ui \ src/ui/configuration/ArduPlanePidConfig.ui \ src/ui/configuration/AdvParameterList.ui \ - src/ui/configuration/ArduRoverPidConfig.ui + src/ui/configuration/ArduRoverPidConfig.ui \ + src/ui/QGCConfigView.ui INCLUDEPATH += src \ src/ui \ @@ -401,6 +403,7 @@ HEADERS += src/MG.h \ src/ui/mission/QGCMissionDoStartSearch.h \ src/ui/mission/QGCMissionDoFinishSearch.h \ src/ui/QGCVehicleConfig.h \ + src/ui/QGCPX4VehicleConfig.h \ src/comm/QGCHilLink.h \ src/ui/QGCHilConfiguration.h \ src/ui/QGCHilFlightGearConfiguration.h \ @@ -451,7 +454,8 @@ HEADERS += src/MG.h \ src/ui/configuration/ParamWidget.h \ src/ui/configuration/ArduPlanePidConfig.h \ src/ui/configuration/AdvParameterList.h \ - src/ui/configuration/ArduRoverPidConfig.h + src/ui/configuration/ArduRoverPidConfig.h \ + src/ui/QGCConfigView.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -608,6 +612,7 @@ SOURCES += src/main.cc \ src/ui/mission/QGCMissionDoStartSearch.cc \ src/ui/mission/QGCMissionDoFinishSearch.cc \ src/ui/QGCVehicleConfig.cc \ + src/ui/QGCPX4VehicleConfig.cc \ src/ui/QGCHilConfiguration.cc \ src/ui/QGCHilFlightGearConfiguration.cc \ src/ui/QGCHilJSBSimConfiguration.cc \ @@ -657,7 +662,8 @@ SOURCES += src/main.cc \ src/ui/configuration/ParamWidget.cc \ src/ui/configuration/ArduPlanePidConfig.cc \ src/ui/configuration/AdvParameterList.cc \ - src/ui/configuration/ArduRoverPidConfig.cc + src/ui/configuration/ArduRoverPidConfig.cc \ + src/ui/QGCConfigView.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index dbf4b24190..39a20cd506 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -69,6 +69,7 @@ This file is part of the QGROUNDCONTROL project #include #include #include +#include #ifdef QGC_OSG_ENABLED #include "Q3DWidgetFactory.h" @@ -199,12 +200,13 @@ void MainWindow::init() toolBar = new QGCToolBar(this); this->addToolBar(toolBar); + ui.actionHardwareConfig->setText(tr("Config")); + // Add actions for average users (displayed next to each other) QList actions; actions << ui.actionFlightView; actions << ui.actionMissionView; actions << ui.actionHardwareConfig; - actions << ui.actionSoftwareConfig; toolBar->setPerspectiveChangeActions(actions); // Add actions for advanced users (displayed in dropdown under "advanced") @@ -512,22 +514,33 @@ void MainWindow::buildCommonWidgets() pilotView->setCentralWidget(new QGCMapTool(this)); addCentralWidget(pilotView, "Pilot"); } - if (!configView) - { - configView = new SubMainWindow(this); - configView->setObjectName("VIEW_HARDWARE_CONFIG"); - configView->setCentralWidget(new ApmHardwareConfig(this)); - addCentralWidget(configView,"Hardware"); - centralWidgetToDockWidgetsMap[VIEW_HARDWARE_CONFIG] = QMap(); + if (apmToolBarEnabled) { + if (!configView) + { + configView = new SubMainWindow(this); + configView->setObjectName("VIEW_HARDWARE_CONFIG"); + configView->setCentralWidget(new ApmHardwareConfig(this)); + addCentralWidget(configView,"Hardware"); + centralWidgetToDockWidgetsMap[VIEW_HARDWARE_CONFIG] = QMap(); - } - if (!softwareConfigView) - { - softwareConfigView = new SubMainWindow(this); - softwareConfigView->setObjectName("VIEW_SOFTWARE_CONFIG"); - softwareConfigView->setCentralWidget(new ApmSoftwareConfig(this)); - addCentralWidget(softwareConfigView,"Software"); - centralWidgetToDockWidgetsMap[VIEW_SOFTWARE_CONFIG] = QMap(); + } + if (!softwareConfigView) + { + softwareConfigView = new SubMainWindow(this); + softwareConfigView->setObjectName("VIEW_SOFTWARE_CONFIG"); + softwareConfigView->setCentralWidget(new ApmSoftwareConfig(this)); + addCentralWidget(softwareConfigView,"Software"); + centralWidgetToDockWidgetsMap[VIEW_SOFTWARE_CONFIG] = QMap(); + } + } else { + if (!configView) + { + configView = new SubMainWindow(this); + configView->setObjectName("VIEW_HARDWARE_CONFIG"); + configView->setCentralWidget(new QGCConfigView(this)); + addCentralWidget(configView,"Config"); + centralWidgetToDockWidgetsMap[VIEW_HARDWARE_CONFIG] = QMap(); + } } if (!engineeringView) { @@ -1477,7 +1490,9 @@ void MainWindow::connectCommonActions() connect(ui.actionMissionView, SIGNAL(triggered()), this, SLOT(loadOperatorView())); connect(ui.actionUnconnectedView, SIGNAL(triggered()), this, SLOT(loadUnconnectedView())); connect(ui.actionHardwareConfig,SIGNAL(triggered()),this,SLOT(loadHardwareConfigView())); - connect(ui.actionSoftwareConfig,SIGNAL(triggered()),this,SLOT(loadSoftwareConfigView())); + if (apmToolBarEnabled) { + connect(ui.actionSoftwareConfig,SIGNAL(triggered()),this,SLOT(loadSoftwareConfigView())); + } connect(ui.actionFirmwareUpdateView, SIGNAL(triggered()), this, SLOT(loadFirmwareUpdateView())); connect(ui.actionMavlinkView, SIGNAL(triggered()), this, SLOT(loadMAVLinkView())); @@ -1973,7 +1988,8 @@ void MainWindow::loadViewState() centerStack->setCurrentWidget(configView); break; case VIEW_SOFTWARE_CONFIG: - centerStack->setCurrentWidget(softwareConfigView); + if (softwareConfigView) + centerStack->setCurrentWidget(softwareConfigView); break; case VIEW_ENGINEER: centerStack->setCurrentWidget(engineeringView); diff --git a/src/ui/QGCConfigView.cc b/src/ui/QGCConfigView.cc new file mode 100644 index 0000000000..b33e6e664b --- /dev/null +++ b/src/ui/QGCConfigView.cc @@ -0,0 +1,57 @@ +#include "QGCConfigView.h" +#include "ui_QGCConfigView.h" +#include "UASManager.h" +#include "QGCPX4VehicleConfig.h" +#include "QGCVehicleConfig.h" +#include "QGCPX4VehicleConfig.h" + +QGCConfigView::QGCConfigView(QWidget *parent) : + QWidget(parent), + ui(new Ui::QGCConfigView), + currUAS(NULL) +{ + ui->setupUi(this); + + connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(activeUASChanged(UASInterface*))); + + if (ui->waitingLabel) { + ui->gridLayout->removeWidget(ui->waitingLabel); + delete ui->waitingLabel; + ui->waitingLabel = NULL; + } + ui->gridLayout->addWidget(new QGCPX4VehicleConfig()); +} + +QGCConfigView::~QGCConfigView() +{ + delete ui; +} + +void QGCConfigView::activeUASChanged(UASInterface* uas) +{ + if (currUAS == uas) + return; + + if (ui->waitingLabel) { + ui->gridLayout->removeWidget(ui->waitingLabel); + delete ui->waitingLabel; + ui->waitingLabel = NULL; + } + + if (currUAS && currUAS->getAutopilotType() != uas->getAutopilotType()) { + foreach (QObject* obj, ui->gridLayout->children()) { + QWidget* w = dynamic_cast(obj); + if (w) { + ui->gridLayout->removeWidget(w); + delete obj; + } + } + } + + switch (uas->getAutopilotType()) { + case MAV_AUTOPILOT_PX4: + ui->gridLayout->addWidget(new QGCPX4VehicleConfig()); + default: + ui->gridLayout->addWidget(new QGCVehicleConfig()); + } +} diff --git a/src/ui/QGCConfigView.h b/src/ui/QGCConfigView.h new file mode 100644 index 0000000000..182d50c3b7 --- /dev/null +++ b/src/ui/QGCConfigView.h @@ -0,0 +1,28 @@ +#ifndef QGCCONFIGVIEW_H +#define QGCCONFIGVIEW_H + +#include +#include + +namespace Ui { +class QGCConfigView; +} + +class QGCConfigView : public QWidget +{ + Q_OBJECT + +public: + explicit QGCConfigView(QWidget *parent = 0); + ~QGCConfigView(); + +public slots: + void activeUASChanged(UASInterface* uas); + +private: + Ui::QGCConfigView *ui; + UASInterface* currUAS; + +}; + +#endif // QGCCONFIGVIEW_H diff --git a/src/ui/QGCConfigView.ui b/src/ui/QGCConfigView.ui new file mode 100644 index 0000000000..cd4b9c98fe --- /dev/null +++ b/src/ui/QGCConfigView.ui @@ -0,0 +1,28 @@ + + + QGCConfigView + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + Waiting for connection... + + + + + + + + diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc new file mode 100644 index 0000000000..a0c01d0f5e --- /dev/null +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -0,0 +1,1581 @@ +// On Windows (for VS2010) stdint.h contains the limits normally contained in limits.h +// It also needs the __STDC_LIMIT_MACROS macro defined in order to include them (done +// in qgroundcontrol.pri). +#ifdef WIN32 +#include +#else +#include +#endif + +#include +#include +#include +#include + +#include "QGCPX4VehicleConfig.h" +#include "UASManager.h" +#include "QGC.h" +#include "QGCToolWidget.h" +#include "ui_QGCPX4VehicleConfig.h" + +QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : + QWidget(parent), + mav(NULL), + chanCount(0), + rcRoll(0.0f), + rcPitch(0.0f), + rcYaw(0.0f), + rcThrottle(0.0f), + rcMode(0.0f), + rcAux1(0.0f), + rcAux2(0.0f), + rcAux3(0.0f), + changed(true), + rc_mode(RC_MODE_NONE), + calibrationEnabled(false), + ui(new Ui::QGCPX4VehicleConfig) +{ + doneLoadingConfig = false; + + setObjectName("QGC_VEHICLECONFIG"); + ui->setupUi(this); + + ui->rollWidget->setOrientation(Qt::Horizontal); + ui->rollWidget->setName("Roll"); + ui->yawWidget->setOrientation(Qt::Horizontal); + ui->yawWidget->setName("Yaw"); + ui->pitchWidget->setName("Pitch"); + ui->throttleWidget->setName("Throttle"); + ui->radio5Widget->setOrientation(Qt::Horizontal); + ui->radio5Widget->setName("Radio 5"); + ui->radio6Widget->setOrientation(Qt::Horizontal); + ui->radio6Widget->setName("Radio 6"); + ui->radio7Widget->setOrientation(Qt::Horizontal); + ui->radio7Widget->setName("Radio 7"); + ui->radio8Widget->setOrientation(Qt::Horizontal); + ui->radio8Widget->setName("Radio 8"); + + connect(ui->rcMenuButton,SIGNAL(clicked()),this,SLOT(rcMenuButtonClicked())); + connect(ui->sensorMenuButton,SIGNAL(clicked()),this,SLOT(sensorMenuButtonClicked())); + connect(ui->generalMenuButton,SIGNAL(clicked()),this,SLOT(generalMenuButtonClicked())); + connect(ui->advancedMenuButton,SIGNAL(clicked()),this,SLOT(advancedMenuButtonClicked())); + + ui->rcModeComboBox->setCurrentIndex((int)rc_mode - 1); + + ui->rcCalibrationButton->setCheckable(true); + connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool))); + connect(ui->setButton, SIGNAL(clicked()), this, SLOT(writeParameters())); + connect(ui->rcModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setRCModeIndex(int))); + //connect(ui->setTrimButton, SIGNAL(clicked()), this, SLOT(setTrimPositions())); + + /* Connect RC mapping assignments */ + connect(ui->rollSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setRollChan(int))); + connect(ui->pitchSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setPitchChan(int))); + connect(ui->yawSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setYawChan(int))); + connect(ui->throttleSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setThrottleChan(int))); + connect(ui->modeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setModeChan(int))); + connect(ui->aux1SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux1Chan(int))); + connect(ui->aux2SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux2Chan(int))); + connect(ui->aux3SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux3Chan(int))); + + // Connect RC reverse assignments + connect(ui->invertCheckBox, SIGNAL(clicked(bool)), this, SLOT(setRollInverted(bool))); + connect(ui->invertCheckBox_2, SIGNAL(clicked(bool)), this, SLOT(setPitchInverted(bool))); + connect(ui->invertCheckBox_3, SIGNAL(clicked(bool)), this, SLOT(setYawInverted(bool))); + connect(ui->invertCheckBox_4, SIGNAL(clicked(bool)), this, SLOT(setThrottleInverted(bool))); + connect(ui->invertCheckBox_5, SIGNAL(clicked(bool)), this, SLOT(setModeInverted(bool))); + connect(ui->invertCheckBox_6, SIGNAL(clicked(bool)), this, SLOT(setAux1Inverted(bool))); + connect(ui->invertCheckBox_7, SIGNAL(clicked(bool)), this, SLOT(setAux2Inverted(bool))); + connect(ui->invertCheckBox_8, SIGNAL(clicked(bool)), this, SLOT(setAux3Inverted(bool))); + + connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); + + setActiveUAS(UASManager::instance()->getActiveUAS()); + + for (unsigned int i = 0; i < chanMax; i++) + { + rcValue[i] = UINT16_MAX; + rcMapping[i] = i; + } + + updateTimer.setInterval(150); + connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateView())); + updateTimer.start(); + + ui->advancedGroupBox->hide(); + connect(ui->advancedCheckBox,SIGNAL(toggled(bool)),ui->advancedGroupBox,SLOT(setShown(bool))); +} +void QGCPX4VehicleConfig::rcMenuButtonClicked() +{ + ui->stackedWidget->setCurrentIndex(0); +} + +void QGCPX4VehicleConfig::sensorMenuButtonClicked() +{ + ui->stackedWidget->setCurrentIndex(1); +} + +void QGCPX4VehicleConfig::generalMenuButtonClicked() +{ + ui->stackedWidget->setCurrentIndex(ui->stackedWidget->count()-2); +} + +void QGCPX4VehicleConfig::advancedMenuButtonClicked() +{ + ui->stackedWidget->setCurrentIndex(ui->stackedWidget->count()-1); +} + +QGCPX4VehicleConfig::~QGCPX4VehicleConfig() +{ + delete ui; +} + +void QGCPX4VehicleConfig::setRCModeIndex(int newRcMode) +{ + if (newRcMode > 0 && newRcMode < 6) + { + //rc_mode = (enum RC_MODE) (newRcMode+1); + changed = true; + } +} + +void QGCPX4VehicleConfig::toggleCalibrationRC(bool enabled) +{ + if (enabled) + { + startCalibrationRC(); + } + else + { + stopCalibrationRC(); + } +} + +void QGCPX4VehicleConfig::setTrimPositions() +{ + // Set trim to min if stick is close to min + if (abs(rcValue[rcMapping[3]] - rcMin[rcMapping[3]]) < 100) + { + rcTrim[rcMapping[3]] = rcMin[rcMapping[3]]; // throttle + } + // Set trim to max if stick is close to max + else if (abs(rcValue[rcMapping[3]] - rcMax[rcMapping[3]]) < 100) + { + rcTrim[rcMapping[3]] = rcMax[rcMapping[3]]; // throttle + } + else + { + + // Reject + QMessageBox msgBox; + msgBox.setText(tr("Throttle Stick Trim Position Invalid")); + msgBox.setInformativeText(tr("The throttle stick is not in the min position. Please set it to the minimum value")); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + (void)msgBox.exec(); + } + + // Set trim for roll, pitch, yaw, throttle + rcTrim[rcMapping[0]] = rcValue[rcMapping[0]]; // roll + rcTrim[rcMapping[1]] = rcValue[rcMapping[1]]; // pitch + rcTrim[rcMapping[2]] = rcValue[rcMapping[2]]; // yaw + + rcTrim[rcMapping[4]] = ((rcMax[rcMapping[4]] - rcMin[rcMapping[4]]) / 2.0f) + rcMin[rcMapping[4]]; // mode sw + rcTrim[rcMapping[5]] = ((rcMax[rcMapping[5]] - rcMin[rcMapping[5]]) / 2.0f) + rcMin[rcMapping[5]]; // aux 1 + rcTrim[rcMapping[6]] = ((rcMax[rcMapping[6]] - rcMin[rcMapping[6]]) / 2.0f) + rcMin[rcMapping[6]]; // aux 2 + rcTrim[rcMapping[7]] = ((rcMax[rcMapping[7]] - rcMin[rcMapping[7]]) / 2.0f) + rcMin[rcMapping[7]]; // aux 3 +} + +void QGCPX4VehicleConfig::detectChannelInversion() +{ + +} + +void QGCPX4VehicleConfig::startCalibrationRC() +{ + QMessageBox::information(0,"Warning!","You are about to start radio calibration.\nPlease ensure all motor power is disconnected AND all props are removed from the vehicle.\nAlso ensure transmitter and reciever are powered and connected\n\nClick OK to confirm"); + QMessageBox::information(0,"Information","Click OK, then move all sticks to their extreme positions, watching the min/max values to ensure you get the most range from your controller. This includes all switches"); + ui->rcTypeComboBox->setEnabled(false); + ui->rcCalibrationButton->setText(tr("Stop RC Calibration")); + resetCalibrationRC(); + calibrationEnabled = true; + ui->rollWidget->showMinMax(); + ui->pitchWidget->showMinMax(); + ui->yawWidget->showMinMax(); + ui->throttleWidget->showMinMax(); + ui->radio5Widget->showMinMax(); + ui->radio6Widget->showMinMax(); + ui->radio7Widget->showMinMax(); + ui->radio8Widget->showMinMax(); +} + +void QGCPX4VehicleConfig::stopCalibrationRC() +{ + QMessageBox::information(0,"Trims","Ensure all sticks are centeres and throttle is in the downmost position, click OK to continue"); + calibrationEnabled = false; + ui->rcTypeComboBox->setEnabled(true); + ui->rcCalibrationButton->setText(tr("Start RC Calibration")); + ui->rollWidget->hideMinMax(); + ui->pitchWidget->hideMinMax(); + ui->yawWidget->hideMinMax(); + ui->throttleWidget->hideMinMax(); + ui->radio5Widget->hideMinMax(); + ui->radio6Widget->hideMinMax(); + ui->radio7Widget->hideMinMax(); + ui->radio8Widget->hideMinMax(); + QString statusstr; + statusstr = "Below you will find the detected radio calibration information that will be sent to the autopilot\n"; + statusstr += "Normal values are around 1100 to 1900, with disconnected channels reading very close to 1500\n\n"; + statusstr += "Channel\tMin\tCenter\tMax\n"; + statusstr += "--------------------\n"; + for (int i=0;i<8;i++) + { + statusstr += QString::number(i) + "\t" + QString::number(rcMin[i]) + "\t" + QString::number(rcValue[i]) + "\t" + QString::number(rcMax[i]) + "\n"; + } + QMessageBox::information(0,"Status",statusstr); +} + +void QGCPX4VehicleConfig::loadQgcConfig(bool primary) +{ + Q_UNUSED(primary); + QDir autopilotdir(qApp->applicationDirPath() + "/files/" + mav->getAutopilotTypeName().toLower()); + QDir generaldir = QDir(autopilotdir.absolutePath() + "/general/widgets"); + QDir vehicledir = QDir(autopilotdir.absolutePath() + "/" + mav->getSystemTypeName().toLower() + "/widgets"); + if (!autopilotdir.exists("general")) + { + //TODO: Throw some kind of error here. There is no general configuration directory + qWarning() << "Invalid general dir. no general configuration will be loaded."; + } + if (!autopilotdir.exists(mav->getAutopilotTypeName().toLower())) + { + //TODO: Throw an error here too, no autopilot specific configuration + qWarning() << "Invalid vehicle dir, no vehicle specific configuration will be loaded."; + } + + // Generate widgets for the General tab. + QGCToolWidget *tool; + bool left = true; + foreach (QString file,generaldir.entryList(QDir::Files | QDir::NoDotAndDotDot)) + { + if (file.toLower().endsWith(".qgw")) { + QWidget* parent = left?ui->generalLeftContents:ui->generalRightContents; + tool = new QGCToolWidget("", parent); + if (tool->loadSettings(generaldir.absoluteFilePath(file), false)) + { + toolWidgets.append(tool); + QGroupBox *box = new QGroupBox(parent); + box->setTitle(tool->objectName()); + box->setLayout(new QVBoxLayout(box)); + box->layout()->addWidget(tool); + if (left) + { + left = false; + ui->generalLeftLayout->addWidget(box); + } + else + { + left = true; + ui->generalRightLayout->addWidget(box); + } + } else { + delete tool; + } + } + } + + // Generate widgets for the Advanced tab. + left = true; + foreach (QString file,vehicledir.entryList(QDir::Files | QDir::NoDotAndDotDot)) + { + if (file.toLower().endsWith(".qgw")) { + QWidget* parent = left?ui->advancedLeftContents:ui->advancedRightContents; + tool = new QGCToolWidget("", parent); + if (tool->loadSettings(vehicledir.absoluteFilePath(file), false)) + { + toolWidgets.append(tool); + QGroupBox *box = new QGroupBox(parent); + box->setTitle(tool->objectName()); + box->setLayout(new QVBoxLayout(box)); + box->layout()->addWidget(tool); + if (left) + { + left = false; + ui->advancedLeftLayout->addWidget(box); + } + else + { + left = true; + ui->advancedRightLayout->addWidget(box); + } + } else { + delete tool; + } + } + } + + // Load tabs for general configuration + foreach (QString dir,generaldir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) + { + QPushButton *button = new QPushButton(ui->scrollAreaWidgetContents_3); + connect(button,SIGNAL(clicked()),this,SLOT(menuButtonClicked())); + ui->navBarLayout->insertWidget(2,button); + button->setMinimumHeight(75); + button->setMinimumWidth(100); + button->show(); + button->setText(dir); + QWidget *tab = new QWidget(ui->stackedWidget); + ui->stackedWidget->insertWidget(2,tab); + buttonToWidgetMap[button] = tab; + tab->setLayout(new QVBoxLayout()); + tab->show(); + QScrollArea *area = new QScrollArea(tab); + tab->layout()->addWidget(area); + QWidget *scrollArea = new QWidget(tab); + scrollArea->setLayout(new QVBoxLayout(tab)); + area->setWidget(scrollArea); + area->setWidgetResizable(true); + area->show(); + scrollArea->show(); + QDir newdir = QDir(generaldir.absoluteFilePath(dir)); + foreach (QString file,newdir.entryList(QDir::Files| QDir::NoDotAndDotDot)) + { + if (file.toLower().endsWith(".qgw")) { + tool = new QGCToolWidget("", tab); + if (tool->loadSettings(newdir.absoluteFilePath(file), false)) + { + toolWidgets.append(tool); + //ui->sensorLayout->addWidget(tool); + QGroupBox *box = new QGroupBox(tab); + box->setTitle(tool->objectName()); + box->setLayout(new QVBoxLayout(tab)); + box->layout()->addWidget(tool); + scrollArea->layout()->addWidget(box); + } else { + delete tool; + } + } + } + } + + // Load additional tabs for vehicle specific configuration + foreach (QString dir,vehicledir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) + { + QPushButton *button = new QPushButton(ui->scrollAreaWidgetContents_3); + connect(button,SIGNAL(clicked()),this,SLOT(menuButtonClicked())); + ui->navBarLayout->insertWidget(2,button); + + QWidget *tab = new QWidget(ui->stackedWidget); + ui->stackedWidget->insertWidget(2,tab); + buttonToWidgetMap[button] = tab; + + button->setMinimumHeight(75); + button->setMinimumWidth(100); + button->show(); + button->setText(dir); + tab->setLayout(new QVBoxLayout()); + tab->show(); + QScrollArea *area = new QScrollArea(tab); + tab->layout()->addWidget(area); + QWidget *scrollArea = new QWidget(tab); + scrollArea->setLayout(new QVBoxLayout(tab)); + area->setWidget(scrollArea); + area->setWidgetResizable(true); + area->show(); + scrollArea->show(); + + QDir newdir = QDir(vehicledir.absoluteFilePath(dir)); + foreach (QString file,newdir.entryList(QDir::Files| QDir::NoDotAndDotDot)) + { + if (file.toLower().endsWith(".qgw")) { + tool = new QGCToolWidget("", tab); + tool->addUAS(mav); + if (tool->loadSettings(newdir.absoluteFilePath(file), false)) + { + toolWidgets.append(tool); + //ui->sensorLayout->addWidget(tool); + QGroupBox *box = new QGroupBox(tab); + box->setTitle(tool->objectName()); + box->setLayout(new QVBoxLayout(box)); + box->layout()->addWidget(tool); + scrollArea->layout()->addWidget(box); + box->show(); + //gbox->layout()->addWidget(box); + } else { + delete tool; + } + } + } + } + + // Load general calibration for autopilot + //TODO: Handle this more gracefully, maybe have it scan the directory for multiple calibration entries? + tool = new QGCToolWidget("", ui->sensorContents); + tool->addUAS(mav); + if (tool->loadSettings(autopilotdir.absolutePath() + "/general/calibration/calibration.qgw", false)) + { + toolWidgets.append(tool); + QGroupBox *box = new QGroupBox(ui->sensorContents); + box->setTitle(tool->objectName()); + box->setLayout(new QVBoxLayout(box)); + box->layout()->addWidget(tool); + ui->sensorLayout->addWidget(box); + } else { + delete tool; + } + + // Load vehicle-specific autopilot configuration + tool = new QGCToolWidget("", ui->sensorContents); + tool->addUAS(mav); + if (tool->loadSettings(autopilotdir.absolutePath() + "/" + mav->getSystemTypeName().toLower() + "/calibration/calibration.qgw", false)) + { + toolWidgets.append(tool); + QGroupBox *box = new QGroupBox(ui->sensorContents); + box->setTitle(tool->objectName()); + box->setLayout(new QVBoxLayout(box)); + box->layout()->addWidget(tool); + ui->sensorLayout->addWidget(box); + } else { + delete tool; + } + + //description.txt + QFile sensortipsfile(autopilotdir.absolutePath() + "/general/calibration/description.txt"); + sensortipsfile.open(QIODevice::ReadOnly); + ui->sensorTips->setHtml(sensortipsfile.readAll()); + sensortipsfile.close(); +} +void QGCPX4VehicleConfig::menuButtonClicked() +{ + QPushButton *button = qobject_cast(sender()); + if (!button) + { + return; + } + if (buttonToWidgetMap.contains(button)) + { + ui->stackedWidget->setCurrentWidget(buttonToWidgetMap[button]); + } + +} + +void QGCPX4VehicleConfig::loadConfig() +{ + QGCToolWidget* tool; + + QDir autopilotdir(qApp->applicationDirPath() + "/files/" + mav->getAutopilotTypeName().toLower()); + QDir generaldir = QDir(autopilotdir.absolutePath() + "/general/widgets"); + QDir vehicledir = QDir(autopilotdir.absolutePath() + "/" + mav->getSystemTypeName().toLower() + "/widgets"); + if (!autopilotdir.exists("general")) + { + //TODO: Throw some kind of error here. There is no general configuration directory + qWarning() << "Invalid general dir. no general configuration will be loaded."; + } + if (!autopilotdir.exists(mav->getAutopilotTypeName().toLower())) + { + //TODO: Throw an error here too, no autopilot specific configuration + qWarning() << "Invalid vehicle dir, no vehicle specific configuration will be loaded."; + } + qDebug() << autopilotdir.absolutePath(); + qDebug() << generaldir.absolutePath(); + qDebug() << vehicledir.absolutePath(); + QFile xmlfile(autopilotdir.absolutePath() + "/arduplane.pdef.xml"); + if (xmlfile.exists() && !xmlfile.open(QIODevice::ReadOnly)) + { + loadQgcConfig(false); + doneLoadingConfig = true; + return; + } + loadQgcConfig(true); + + QXmlStreamReader xml(xmlfile.readAll()); + xmlfile.close(); + + //TODO: Testing to ensure that incorrectly formatted XML won't break this. + while (!xml.atEnd()) + { + if (xml.isStartElement() && xml.name() == "paramfile") + { + xml.readNext(); + while ((xml.name() != "paramfile") && !xml.atEnd()) + { + QString valuetype = ""; + if (xml.isStartElement() && (xml.name() == "vehicles" || xml.name() == "libraries")) //Enter into the vehicles loop + { + valuetype = xml.name().toString(); + xml.readNext(); + while ((xml.name() != valuetype) && !xml.atEnd()) + { + if (xml.isStartElement() && xml.name() == "parameters") //This is a parameter block + { + QString parametersname = ""; + if (xml.attributes().hasAttribute("name")) + { + parametersname = xml.attributes().value("name").toString(); + } + QVariantMap genset; + QVariantMap advset; + + QString setname = parametersname; + xml.readNext(); + int genarraycount = 0; + int advarraycount = 0; + while ((xml.name() != "parameters") && !xml.atEnd()) + { + if (xml.isStartElement() && xml.name() == "param") + { + QString humanname = xml.attributes().value("humanName").toString(); + QString name = xml.attributes().value("name").toString(); + QString tab= xml.attributes().value("user").toString(); + if (tab == "Advanced") + { + advset["title"] = parametersname; + } + else + { + genset["title"] = parametersname; + } + if (name.contains(":")) + { + name = name.split(":")[1]; + } + QString docs = xml.attributes().value("documentation").toString(); + paramTooltips[name] = name + " - " + docs; + + int type = -1; //Type of item + QMap fieldmap; + xml.readNext(); + while ((xml.name() != "param") && !xml.atEnd()) + { + if (xml.isStartElement() && xml.name() == "values") + { + type = 1; //1 is a combobox + if (tab == "Advanced") + { + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "TYPE"] = "COMBO"; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_COMBOBOX_DESCRIPTION"] = humanname; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_COMBOBOX_PARAMID"] = name; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_COMBOBOX_COMPONENTID"] = 1; + } + else + { + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "TYPE"] = "COMBO"; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_COMBOBOX_DESCRIPTION"] = humanname; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_COMBOBOX_PARAMID"] = name; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_COMBOBOX_COMPONENTID"] = 1; + } + int paramcount = 0; + xml.readNext(); + while ((xml.name() != "values") && !xml.atEnd()) + { + if (xml.isStartElement() && xml.name() == "value") + { + + QString code = xml.attributes().value("code").toString(); + QString arg = xml.readElementText(); + if (tab == "Advanced") + { + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(paramcount) + "_TEXT"] = arg; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(paramcount) + "_VAL"] = code.toInt(); + } + else + { + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(paramcount) + "_TEXT"] = arg; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(paramcount) + "_VAL"] = code.toInt(); + } + paramcount++; + } + xml.readNext(); + } + if (tab == "Advanced") + { + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_COMBOBOX_COUNT"] = paramcount; + } + else + { + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_COMBOBOX_COUNT"] = paramcount; + } + } + if (xml.isStartElement() && xml.name() == "field") + { + type = 2; //2 is a slider + QString fieldtype = xml.attributes().value("name").toString(); + QString text = xml.readElementText(); + fieldmap[fieldtype] = text; + } + xml.readNext(); + } + if (type == -1) + { + //Nothing inside! Assume it's a value, give it a default range. + type = 2; + QString fieldtype = "Range"; + QString text = "0 100"; //TODO: Determine a better way of figuring out default ranges. + fieldmap[fieldtype] = text; + } + if (type == 2) + { + if (tab == "Advanced") + { + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "TYPE"] = "SLIDER"; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_SLIDER_DESCRIPTION"] = humanname; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_SLIDER_PARAMID"] = name; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_SLIDER_COMPONENTID"] = 1; + } + else + { + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "TYPE"] = "SLIDER"; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_SLIDER_DESCRIPTION"] = humanname; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_SLIDER_PARAMID"] = name; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_SLIDER_COMPONENTID"] = 1; + } + if (fieldmap.contains("Range")) + { + float min = 0; + float max = 0; + //Some range fields list "0-10" and some list "0 10". Handle both. + if (fieldmap["Range"].split(" ").size() > 1) + { + min = fieldmap["Range"].split(" ")[0].trimmed().toFloat(); + max = fieldmap["Range"].split(" ")[1].trimmed().toFloat(); + } + else if (fieldmap["Range"].split("-").size() > 1) + { + min = fieldmap["Range"].split("-")[0].trimmed().toFloat(); + max = fieldmap["Range"].split("-")[1].trimmed().toFloat(); + } + if (tab == "Advanced") + { + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_SLIDER_MIN"] = min; + advset[setname + "\\" + QString::number(advarraycount) + "\\" + "QGC_PARAM_SLIDER_MAX"] = max; + } + else + { + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_SLIDER_MIN"] = min; + genset[setname + "\\" + QString::number(genarraycount) + "\\" + "QGC_PARAM_SLIDER_MAX"] = max; + } + } + } + if (tab == "Advanced") + { + advarraycount++; + advset["count"] = advarraycount; + } + else + { + genarraycount++; + genset["count"] = genarraycount; + } + } + xml.readNext(); + } + if (genarraycount > 0) + { + QWidget* parent = this; + if (valuetype == "vehicles") + { + parent = ui->generalLeftContents; + } + else if (valuetype == "libraries") + { + parent = ui->generalRightContents; + } + tool = new QGCToolWidget("", parent); + tool->addUAS(mav); + tool->setTitle(parametersname); + tool->setObjectName(parametersname); + tool->setSettings(genset); + QList paramlist = tool->getParamList(); + for (int i=0;isetTitle(tool->objectName()); + box->setLayout(new QVBoxLayout(box)); + box->layout()->addWidget(tool); + if (valuetype == "vehicles") + { + ui->generalLeftLayout->addWidget(box); + } + else if (valuetype == "libraries") + { + ui->generalRightLayout->addWidget(box); + } + box->hide(); + toolToBoxMap[tool] = box; + } + if (advarraycount > 0) + { + QWidget* parent = this; + if (valuetype == "vehicles") + { + parent = ui->generalLeftContents; + } + else if (valuetype == "libraries") + { + parent = ui->generalRightContents; + } + tool = new QGCToolWidget("", parent); + tool->addUAS(mav); + tool->setTitle(parametersname); + tool->setObjectName(parametersname); + tool->setSettings(advset); + QList paramlist = tool->getParamList(); + for (int i=0;isetTitle(tool->objectName()); + box->setLayout(new QVBoxLayout(box)); + box->layout()->addWidget(tool); + if (valuetype == "vehicles") + { + ui->generalLeftLayout->addWidget(box); + } + else if (valuetype == "libraries") + { + ui->generalRightLayout->addWidget(box); + } + box->hide(); + toolToBoxMap[tool] = box; + } + } + xml.readNext(); + } + } + xml.readNext(); + } + } + xml.readNext(); + } + + mav->getParamManager()->setParamInfo(paramTooltips); + doneLoadingConfig = true; + mav->requestParameters(); //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. +} + +void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) +{ + // Hide items if NULL and abort + if (!active) { + ui->setButton->setEnabled(false); + ui->refreshButton->setEnabled(false); + ui->readButton->show(); + ui->readButton->setEnabled(false); + ui->writeButton->show(); + ui->writeButton->setEnabled(false); + ui->loadFileButton->setEnabled(false); + ui->saveFileButton->setEnabled(false); + + return; + } + + + // Do nothing if system is the same + if (mav == active) return; + + if (mav) + { + // Disconnect old system + disconnect(mav, SIGNAL(remoteControlChannelRawChanged(int,float)), this, + SLOT(remoteControlChannelRawChanged(int,float))); + disconnect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, + SLOT(parameterChanged(int,int,QString,QVariant))); + disconnect(ui->refreshButton,SIGNAL(clicked()),mav,SLOT(requestParameters())); + + // Delete all children from all fixed tabs. + foreach(QWidget* child, ui->generalLeftContents->findChildren()) + { + child->deleteLater(); + } + foreach(QWidget* child, ui->generalRightContents->findChildren()) + { + child->deleteLater(); + } + foreach(QWidget* child, ui->advancedLeftContents->findChildren()) + { + child->deleteLater(); + } + foreach(QWidget* child, ui->advancedRightContents->findChildren()) + { + child->deleteLater(); + } + foreach(QWidget* child, ui->sensorContents->findChildren()) + { + child->deleteLater(); + } + + // And then delete any custom tabs + foreach(QWidget* child, additionalTabs) + { + child->deleteLater(); + } + additionalTabs.clear(); + + toolWidgets.clear(); + paramToWidgetMap.clear(); + libParamToWidgetMap.clear(); + systemTypeToParamMap.clear(); + toolToBoxMap.clear(); + paramTooltips.clear(); + } + + // Connect new system + mav = active; + + // Reset current state + resetCalibrationRC(); + + requestCalibrationRC(); + mav->requestParameter(0, "RC_TYPE"); + + chanCount = 0; + + // Connect new system + connect(active, SIGNAL(remoteControlChannelRawChanged(int,float)), this, + SLOT(remoteControlChannelRawChanged(int,float))); + connect(active, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, + SLOT(parameterChanged(int,int,QString,QVariant))); + connect(ui->refreshButton, SIGNAL(clicked()), active, SLOT(requestParameters())); + + if (systemTypeToParamMap.contains(mav->getSystemTypeName())) + { + paramToWidgetMap = systemTypeToParamMap[mav->getSystemTypeName()]; + } + else + { + //Indication that we have no meta data for this system type. + qDebug() << "No parameters defined for system type:" << mav->getSystemTypeName(); + paramToWidgetMap = systemTypeToParamMap[mav->getSystemTypeName()]; + } + + if (!paramTooltips.isEmpty()) + { + mav->getParamManager()->setParamInfo(paramTooltips); + } + + qDebug() << "CALIBRATION!! System Type Name:" << mav->getSystemTypeName(); + + //Load configuration after 1ms. This allows it to go into the event loop, and prevents application hangups due to the + //amount of time it actually takes to load the configuration windows. + QTimer::singleShot(1,this,SLOT(loadConfig())); + + updateStatus(QString("Reading from system %1").arg(mav->getUASName())); + + // Since a system is now connected, enable the VehicleConfig UI. + ui->setButton->setEnabled(true); + ui->refreshButton->setEnabled(true); + ui->readButton->setEnabled(true); + ui->writeButton->setEnabled(true); + ui->loadFileButton->setEnabled(true); + ui->saveFileButton->setEnabled(true); + if (mav->getAutopilotTypeName() == "ARDUPILOTMEGA") + { + ui->readButton->hide(); + ui->writeButton->hide(); + } +} + +void QGCPX4VehicleConfig::resetCalibrationRC() +{ + for (unsigned int i = 0; i < chanMax; ++i) + { + rcMin[i] = 1500; + rcMax[i] = 1500; + } +} + +/** + * Sends the RC calibration to the vehicle and stores it in EEPROM + */ +void QGCPX4VehicleConfig::writeCalibrationRC() +{ + if (!mav) return; + + QString minTpl("RC%1_MIN"); + QString maxTpl("RC%1_MAX"); + QString trimTpl("RC%1_TRIM"); + QString revTpl("RC%1_REV"); + + // Do not write the RC type, as these values depend on this + // active onboard parameter + + for (unsigned int i = 0; i < chanCount; ++i) + { + //qDebug() << "SENDING" << minTpl.arg(i+1) << rcMin[i]; + mav->setParameter(0, minTpl.arg(i+1), rcMin[i]); + QGC::SLEEP::usleep(50000); + mav->setParameter(0, trimTpl.arg(i+1), rcTrim[i]); + QGC::SLEEP::usleep(50000); + mav->setParameter(0, maxTpl.arg(i+1), rcMax[i]); + QGC::SLEEP::usleep(50000); + mav->setParameter(0, revTpl.arg(i+1), (rcRev[i]) ? -1.0f : 1.0f); + QGC::SLEEP::usleep(50000); + } + + // Write mappings + mav->setParameter(0, "RC_MAP_ROLL", (int32_t)(rcMapping[0]+1)); + QGC::SLEEP::usleep(50000); + mav->setParameter(0, "RC_MAP_PITCH", (int32_t)(rcMapping[1]+1)); + QGC::SLEEP::usleep(50000); + mav->setParameter(0, "RC_MAP_YAW", (int32_t)(rcMapping[2]+1)); + QGC::SLEEP::usleep(50000); + mav->setParameter(0, "RC_MAP_THROTTLE", (int32_t)(rcMapping[3]+1)); + QGC::SLEEP::usleep(50000); + mav->setParameter(0, "RC_MAP_MODE_SW", (int32_t)(rcMapping[4]+1)); + QGC::SLEEP::usleep(50000); + mav->setParameter(0, "RC_MAP_AUX1", (int32_t)(rcMapping[5]+1)); + QGC::SLEEP::usleep(50000); + mav->setParameter(0, "RC_MAP_AUX2", (int32_t)(rcMapping[6]+1)); + QGC::SLEEP::usleep(50000); + mav->setParameter(0, "RC_MAP_AUX3", (int32_t)(rcMapping[7]+1)); + QGC::SLEEP::usleep(50000); +} + +void QGCPX4VehicleConfig::requestCalibrationRC() +{ + if (!mav) return; + + QString minTpl("RC%1_MIN"); + QString maxTpl("RC%1_MAX"); + QString trimTpl("RC%1_TRIM"); + QString revTpl("RC%1_REV"); + + // Do not request the RC type, as these values depend on this + // active onboard parameter + + for (unsigned int i = 0; i < chanMax; ++i) + { + mav->requestParameter(0, minTpl.arg(i+1)); + QGC::SLEEP::usleep(5000); + mav->requestParameter(0, trimTpl.arg(i+1)); + QGC::SLEEP::usleep(5000); + mav->requestParameter(0, maxTpl.arg(i+1)); + QGC::SLEEP::usleep(5000); + mav->requestParameter(0, revTpl.arg(i+1)); + QGC::SLEEP::usleep(5000); + } +} + +void QGCPX4VehicleConfig::writeParameters() +{ + updateStatus(tr("Writing all onboard parameters.")); + writeCalibrationRC(); + mav->writeParametersToStorage(); +} + +void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) +{ + // Check if index and values are sane + if (chan < 0 || static_cast(chan) >= chanMax || val < 500 || val > 2500) + return; + + if (chan + 1 > (int)chanCount) { + chanCount = chan+1; + } + + // Update calibration data + if (calibrationEnabled) { + if (val < rcMin[chan]) + { + rcMin[chan] = val; + } + + if (val > rcMax[chan]) + { + rcMax[chan] = val; + } + } + + // Raw value + rcValue[chan] = val; + + // Normalized value + float normalized; + + if (val >= rcTrim[chan]) + { + normalized = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]); + } + else + { + normalized = -(rcTrim[chan] - val)/(rcTrim[chan] - rcMin[chan]); + } + + // Bound + normalized = qBound(-1.0f, normalized, 1.0f); + // Invert + normalized = (rcRev[chan]) ? -1.0f*normalized : normalized; + + if (chan == rcMapping[0]) + { + // ROLL + rcRoll = normalized; + } + if (chan == rcMapping[1]) + { + // PITCH + rcPitch = normalized; + } + if (chan == rcMapping[2]) + { + rcYaw = normalized; + } + if (chan == rcMapping[3]) + { + // THROTTLE + if (rcRev[chan]) { + rcThrottle = 1.0f + normalized; + } else { + rcThrottle = normalized; + } + + rcThrottle = qBound(0.0f, rcThrottle, 1.0f); + } + if (chan == rcMapping[4]) + { + // MODE SWITCH + rcMode = normalized; + } + if (chan == rcMapping[5]) + { + // AUX1 + rcAux1 = normalized; + } + if (chan == rcMapping[6]) + { + // AUX2 + rcAux2 = normalized; + } + if (chan == rcMapping[7]) + { + // AUX3 + rcAux3 = normalized; + } + + changed = true; + + //qDebug() << "RC CHAN:" << chan << "PPM:" << val << "NORMALIZED:" << normalized; +} + +void QGCPX4VehicleConfig::updateInvertedCheckboxes(int index) +{ + unsigned int mapindex = rcMapping[index]; + + switch (mapindex) + { + case 0: + ui->invertCheckBox->setChecked(rcRev[index]); + break; + case 1: + ui->invertCheckBox_2->setChecked(rcRev[index]); + break; + case 2: + ui->invertCheckBox_3->setChecked(rcRev[index]); + break; + case 3: + ui->invertCheckBox_4->setChecked(rcRev[index]); + break; + case 4: + ui->invertCheckBox_5->setChecked(rcRev[index]); + break; + case 5: + ui->invertCheckBox_6->setChecked(rcRev[index]); + break; + case 6: + ui->invertCheckBox_7->setChecked(rcRev[index]); + break; + case 7: + ui->invertCheckBox_8->setChecked(rcRev[index]); + break; + } +} + +void QGCPX4VehicleConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + Q_UNUSED(uas); + Q_UNUSED(component); + if (!doneLoadingConfig) + { + //We do not want to attempt to generate any UI elements until loading of the config file is complete. + //We should re-request params later if needed, that is not implemented yet. + return; + } + + if (paramToWidgetMap.contains(parameterName)) + { + //Main group of parameters of the selected airframe + paramToWidgetMap.value(parameterName)->setParameterValue(uas,component,parameterName,value); + if (toolToBoxMap.contains(paramToWidgetMap.value(parameterName))) + { + toolToBoxMap[paramToWidgetMap.value(parameterName)]->show(); + } + else + { + qCritical() << "Widget with no box, possible memory corruption for param:" << parameterName; + } + } + else if (libParamToWidgetMap.contains(parameterName)) + { + //All the library parameters + libParamToWidgetMap.value(parameterName)->setParameterValue(uas,component,parameterName,value); + if (toolToBoxMap.contains(libParamToWidgetMap.value(parameterName))) + { + toolToBoxMap[libParamToWidgetMap.value(parameterName)]->show(); + } + else + { + qCritical() << "Widget with no box, possible memory corruption for param:" << parameterName; + } + } + else + { + //Param recieved that we have no metadata for. Search to see if it belongs in a + //group with some other params + bool found = false; + for (int i=0;iobjectName())) + { + //It should be grouped with this one, add it. + toolWidgets[i]->addParam(uas,component,parameterName,value); + libParamToWidgetMap.insert(parameterName,toolWidgets[i]); + found = true; + break; + } + } + if (!found) + { + //New param type, create a QGroupBox for it. + QWidget* parent; + if (ui->advancedLeftLayout->count() > ui->advancedRightLayout->count()) + { + parent = ui->advancedRightContents; + } + else + { + parent = ui->advancedLeftContents; + } + + // Create the tool, attaching it to the QGroupBox + QGCToolWidget *tool = new QGCToolWidget("", parent); + QString tooltitle = parameterName; + if (parameterName.split("_").size() > 1) + { + tooltitle = parameterName.split("_")[0] + "_"; + } + tool->setTitle(tooltitle); + tool->setObjectName(tooltitle); + //tool->setSettings(set); + libParamToWidgetMap.insert(parameterName,tool); + toolWidgets.append(tool); + tool->addParam(uas, component, parameterName, value); + QGroupBox *box = new QGroupBox(parent); + box->setTitle(tool->objectName()); + box->setLayout(new QVBoxLayout(box)); + box->layout()->addWidget(tool); + + libParamToWidgetMap.insert(parameterName,tool); + toolWidgets.append(tool); + + // Make sure we have similar number of widgets on each side. + if (ui->advancedLeftLayout->count() > ui->advancedRightLayout->count()) + { + ui->advancedRightLayout->addWidget(box); + } + else + { + ui->advancedLeftLayout->addWidget(box); + } + toolToBoxMap[tool] = box; + } + } + + // Channel calibration values + QRegExp minTpl("RC?_MIN"); + minTpl.setPatternSyntax(QRegExp::Wildcard); + QRegExp maxTpl("RC?_MAX"); + maxTpl.setPatternSyntax(QRegExp::Wildcard); + QRegExp trimTpl("RC?_TRIM"); + trimTpl.setPatternSyntax(QRegExp::Wildcard); + QRegExp revTpl("RC?_REV"); + revTpl.setPatternSyntax(QRegExp::Wildcard); + + // Do not write the RC type, as these values depend on this + // active onboard parameter + + if (minTpl.exactMatch(parameterName)) { + bool ok; + unsigned int index = parameterName.mid(2, 1).toInt(&ok) - 1; + //qDebug() << "PARAM:" << parameterName << "index:" << index; + if (ok && index < chanMax) + { + rcMin[index] = value.toInt(); + updateMinMax(); + } + } + + if (maxTpl.exactMatch(parameterName)) { + bool ok; + unsigned int index = parameterName.mid(2, 1).toInt(&ok) - 1; + if (ok && index < chanMax) + { + rcMax[index] = value.toInt(); + updateMinMax(); + } + } + + if (trimTpl.exactMatch(parameterName)) { + bool ok; + unsigned int index = parameterName.mid(2, 1).toInt(&ok) - 1; + if (ok && index < chanMax) + { + rcTrim[index] = value.toInt(); + } + } + + if (revTpl.exactMatch(parameterName)) { + bool ok; + unsigned int index = parameterName.mid(2, 1).toInt(&ok) - 1; + if (ok && index < chanMax) + { + rcRev[index] = (value.toInt() == -1) ? true : false; + updateInvertedCheckboxes(index); + } + } + +// mav->setParameter(0, trimTpl.arg(i), rcTrim[i]); +// mav->setParameter(0, maxTpl.arg(i), rcMax[i]); +// mav->setParameter(0, revTpl.arg(i), (rcRev[i]) ? -1 : 1); +// } + + if (rcTypeUpdateRequested > 0 && parameterName == QString("RC_TYPE")) + { + rcTypeUpdateRequested = 0; + updateStatus(tr("Received RC type update, setting parameters based on model.")); + rcType = value.toInt(); + // Request all other parameters as well + requestCalibrationRC(); + } + + // Order is: roll, pitch, yaw, throttle, mode sw, aux 1-3 + + if (parameterName.contains("RC_MAP_ROLL")) { + rcMapping[0] = value.toInt() - 1; + ui->rollSpinBox->setValue(rcMapping[0]+1); + ui->rollSpinBox->setEnabled(true); + } + + if (parameterName.contains("RC_MAP_PITCH")) { + rcMapping[1] = value.toInt() - 1; + ui->pitchSpinBox->setValue(rcMapping[1]+1); + ui->pitchSpinBox->setEnabled(true); + } + + if (parameterName.contains("RC_MAP_YAW")) { + rcMapping[2] = value.toInt() - 1; + ui->yawSpinBox->setValue(rcMapping[2]+1); + ui->yawSpinBox->setEnabled(true); + } + + if (parameterName.contains("RC_MAP_THROTTLE")) { + rcMapping[3] = value.toInt() - 1; + ui->throttleSpinBox->setValue(rcMapping[3]+1); + ui->throttleSpinBox->setEnabled(true); + } + + if (parameterName.contains("RC_MAP_MODE_SW")) { + rcMapping[4] = value.toInt() - 1; + ui->modeSpinBox->setValue(rcMapping[4]+1); + ui->modeSpinBox->setEnabled(true); + } + + if (parameterName.contains("RC_MAP_AUX1")) { + rcMapping[5] = value.toInt() - 1; + ui->aux1SpinBox->setValue(rcMapping[5]+1); + ui->aux1SpinBox->setEnabled(true); + } + + if (parameterName.contains("RC_MAP_AUX2")) { + rcMapping[6] = value.toInt() - 1; + ui->aux2SpinBox->setValue(rcMapping[6]+1); + ui->aux2SpinBox->setEnabled(true); + } + + if (parameterName.contains("RC_MAP_AUX3")) { + rcMapping[7] = value.toInt() - 1; + ui->aux3SpinBox->setValue(rcMapping[7]+1); + ui->aux3SpinBox->setEnabled(true); + } + + // Scaling + + if (parameterName.contains("RC_SCALE_ROLL")) { + rcScaling[0] = value.toFloat(); + } + + if (parameterName.contains("RC_SCALE_PITCH")) { + rcScaling[1] = value.toFloat(); + } + + if (parameterName.contains("RC_SCALE_YAW")) { + rcScaling[2] = value.toFloat(); + } + + if (parameterName.contains("RC_SCALE_THROTTLE")) { + rcScaling[3] = value.toFloat(); + } + + if (parameterName.contains("RC_SCALE_MODE_SW")) { + rcScaling[4] = value.toFloat(); + } + + if (parameterName.contains("RC_SCALE_AUX1")) { + rcScaling[5] = value.toFloat(); + } + + if (parameterName.contains("RC_SCALE_AUX2")) { + rcScaling[6] = value.toFloat(); + } + + if (parameterName.contains("RC_SCALE_AUX3")) { + rcScaling[7] = value.toFloat(); + } +} + +void QGCPX4VehicleConfig::updateStatus(const QString& str) +{ + ui->statusLabel->setText(str); + ui->statusLabel->setStyleSheet(""); +} + +void QGCPX4VehicleConfig::updateError(const QString& str) +{ + ui->statusLabel->setText(str); + ui->statusLabel->setStyleSheet(QString("QLabel { margin: 0px 2px; font: 14px; color: %1; background-color: %2; }").arg(QGC::colorDarkWhite.name()).arg(QGC::colorMagenta.name())); +} +void QGCPX4VehicleConfig::updateMinMax() +{ + // Order is: roll, pitch, yaw, throttle, mode sw, aux 1-3 + /*ui->rollWidget->setMin(rcMin[0]); + ui->rollWidget->setMax(rcMax[0]); + ui->pitchWidget->setMin(rcMin[1]); + ui->pitchWidget->setMax(rcMax[1]); + ui->yawWidget->setMin(rcMin[2]); + ui->yawWidget->setMax(rcMax[2]); + ui->throttleWidget->setMin(rcMin[3]); + ui->throttleWidget->setMax(rcMax[3]); + ui->radio5Widget->setMin(rcMin[4]); + ui->radio5Widget->setMax(rcMax[4]); + ui->radio6Widget->setMin(rcMin[5]); + ui->radio6Widget->setMax(rcMax[5]); + ui->radio7Widget->setMin(rcMin[6]); + ui->radio7Widget->setMax(rcMax[6]); + ui->radio8Widget->setMin(rcMin[7]); + ui->radio8Widget->setMax(rcMax[7]);*/ +} + +void QGCPX4VehicleConfig::setRCType(int type) +{ + if (!mav) return; + + // XXX TODO Add handling of RC_TYPE vs non-RC_TYPE here + + mav->setParameter(0, "RC_TYPE", type); + rcTypeUpdateRequested = QGC::groundTimeMilliseconds(); + QTimer::singleShot(rcTypeTimeout+100, this, SLOT(checktimeOuts())); +} + +void QGCPX4VehicleConfig::checktimeOuts() +{ + if (rcTypeUpdateRequested > 0) + { + if (QGC::groundTimeMilliseconds() - rcTypeUpdateRequested > rcTypeTimeout) + { + updateError(tr("Setting remote control timed out - is the system connected?")); + } + } +} + +void QGCPX4VehicleConfig::updateView() +{ + if (changed) + { + if (rc_mode == RC_MODE_1) + { + //ui->rollSlider->setValue(rcRoll * 50 + 50); + //ui->pitchSlider->setValue(rcThrottle * 100); + //ui->yawSlider->setValue(rcYaw * 50 + 50); + //ui->throttleSlider->setValue(rcPitch * 50 + 50); + ui->rollWidget->setValue(rcValue[0]); + ui->throttleWidget->setValue(rcValue[1]); + ui->yawWidget->setValue(rcValue[2]); + ui->pitchWidget->setValue(rcValue[3]); + + ui->rollWidget->setMin(rcMin[0]); + ui->rollWidget->setMax(rcMax[0]); + ui->throttleWidget->setMin(rcMin[1]); + ui->throttleWidget->setMax(rcMax[1]); + ui->yawWidget->setMin(rcMin[2]); + ui->yawWidget->setMax(rcMax[2]); + ui->pitchWidget->setMin(rcMin[3]); + ui->pitchWidget->setMax(rcMax[3]); + } + else if (rc_mode == RC_MODE_2) + { + //ui->rollSlider->setValue(rcRoll * 50 + 50); + //ui->pitchSlider->setValue(rcPitch * 50 + 50); + //ui->yawSlider->setValue(rcYaw * 50 + 50); + //ui->throttleSlider->setValue(rcThrottle * 100); + ui->rollWidget->setValue(rcValue[0]); + ui->pitchWidget->setValue(rcValue[1]); + ui->yawWidget->setValue(rcValue[2]); + ui->throttleWidget->setValue(rcValue[3]); + + ui->rollWidget->setMin(rcMin[0]); + ui->rollWidget->setMax(rcMax[0]); + ui->pitchWidget->setMin(rcMin[1]); + ui->pitchWidget->setMax(rcMax[1]); + ui->yawWidget->setMin(rcMin[2]); + ui->yawWidget->setMax(rcMax[2]); + ui->throttleWidget->setMin(rcMin[3]); + ui->throttleWidget->setMax(rcMax[3]); + } + else if (rc_mode == RC_MODE_3) + { + //ui->rollSlider->setValue(rcYaw * 50 + 50); + //ui->pitchSlider->setValue(rcThrottle * 100); + //ui->yawSlider->setValue(rcRoll * 50 + 50); + //ui->throttleSlider->setValue(rcPitch * 50 + 50); + ui->yawWidget->setValue(rcValue[0]); + ui->throttleWidget->setValue(rcValue[1]); + ui->rollWidget->setValue(rcValue[2]); + ui->pitchWidget->setValue(rcValue[3]); + + ui->yawWidget->setMin(rcMin[0]); + ui->yawWidget->setMax(rcMax[0]); + ui->throttleWidget->setMin(rcMin[1]); + ui->throttleWidget->setMax(rcMax[1]); + ui->rollWidget->setMin(rcMin[2]); + ui->rollWidget->setMax(rcMax[2]); + ui->pitchWidget->setMin(rcMin[3]); + ui->pitchWidget->setMax(rcMax[3]); + } + else if (rc_mode == RC_MODE_4) + { + //ui->rollSlider->setValue(rcYaw * 50 + 50); + //ui->pitchSlider->setValue(rcPitch * 50 + 50); + //ui->yawSlider->setValue(rcRoll * 50 + 50); + //ui->throttleSlider->setValue(rcThrottle * 100); + ui->yawWidget->setValue(rcValue[0]); + ui->pitchWidget->setValue(rcValue[1]); + ui->rollWidget->setValue(rcValue[2]); + ui->throttleWidget->setValue(rcValue[3]); + + ui->yawWidget->setMin(rcMin[0]); + ui->yawWidget->setMax(rcMax[0]); + ui->pitchWidget->setMin(rcMin[1]); + ui->pitchWidget->setMax(rcMax[1]); + ui->rollWidget->setMin(rcMin[2]); + ui->rollWidget->setMax(rcMax[2]); + ui->throttleWidget->setMin(rcMin[3]); + ui->throttleWidget->setMax(rcMax[3]); + } + else if (rc_mode == RC_MODE_NONE) + { + ui->rollWidget->setValue(rcValue[0]); + ui->pitchWidget->setValue(rcValue[1]); + ui->throttleWidget->setValue(rcValue[2]); + ui->yawWidget->setValue(rcValue[3]); + + ui->rollWidget->setMin(800); + ui->rollWidget->setMax(2200); + ui->pitchWidget->setMin(800); + ui->pitchWidget->setMax(2200); + ui->throttleWidget->setMin(800); + ui->throttleWidget->setMax(2200); + ui->yawWidget->setMin(800); + ui->yawWidget->setMax(2200); + } + + ui->chanLabel->setText(QString("%1/%2").arg(rcValue[rcMapping[0]]).arg(rcRoll, 5, 'f', 2, QChar(' '))); + ui->chanLabel_2->setText(QString("%1/%2").arg(rcValue[rcMapping[1]]).arg(rcPitch, 5, 'f', 2, QChar(' '))); + ui->chanLabel_3->setText(QString("%1/%2").arg(rcValue[rcMapping[2]]).arg(rcYaw, 5, 'f', 2, QChar(' '))); + ui->chanLabel_4->setText(QString("%1/%2").arg(rcValue[rcMapping[3]]).arg(rcThrottle, 5, 'f', 2, QChar(' '))); + + + + //ui->modeSwitchSlider->setValue(rcMode * 50 + 50); + ui->chanLabel_5->setText(QString("%1/%2").arg(rcValue[rcMapping[4]]).arg(rcMode, 5, 'f', 2, QChar(' '))); + + if (rcValue[rcMapping[4] != UINT16_MAX]) { + ui->radio5Widget->setValue(rcValue[4]); + ui->chanLabel_5->setText(QString("%1/%2").arg(rcValue[rcMapping[5]]).arg(rcAux1, 5, 'f', 2, QChar(' '))); + } else { + ui->chanLabel_5->setText(tr("---")); + } + + if (rcValue[rcMapping[5]] != UINT16_MAX) { + //ui->aux1Slider->setValue(rcAux1 * 50 + 50); + ui->radio6Widget->setValue(rcValue[5]); + ui->chanLabel_6->setText(QString("%1/%2").arg(rcValue[rcMapping[5]]).arg(rcAux1, 5, 'f', 2, QChar(' '))); + } else { + ui->chanLabel_6->setText(tr("---")); + } + + if (rcValue[rcMapping[6]] != UINT16_MAX) { + //ui->aux2Slider->setValue(rcAux2 * 50 + 50); + ui->radio7Widget->setValue(rcValue[6]); + ui->chanLabel_7->setText(QString("%1/%2").arg(rcValue[rcMapping[6]]).arg(rcAux2, 5, 'f', 2, QChar(' '))); + } else { + ui->chanLabel_7->setText(tr("---")); + } + + if (rcValue[rcMapping[7]] != UINT16_MAX) { + //ui->aux3Slider->setValue(rcAux3 * 50 + 50); + ui->radio8Widget->setValue(rcValue[7]); + ui->chanLabel_8->setText(QString("%1/%2").arg(rcValue[rcMapping[7]]).arg(rcAux3, 5, 'f', 2, QChar(' '))); + } else { + ui->chanLabel_8->setText(tr("---")); + } + + changed = false; + } +} diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h new file mode 100644 index 0000000000..4ed7e00698 --- /dev/null +++ b/src/ui/QGCPX4VehicleConfig.h @@ -0,0 +1,202 @@ +#ifndef QGCPX4VehicleConfig_H +#define QGCPX4VehicleConfig_H + +#include +#include +#include +#include +#include + +#include "QGCToolWidget.h" +#include "UASInterface.h" + +namespace Ui { +class QGCPX4VehicleConfig; +} + +class QGCPX4VehicleConfig : public QWidget +{ + Q_OBJECT + +public: + explicit QGCPX4VehicleConfig(QWidget *parent = 0); + ~QGCPX4VehicleConfig(); + + enum RC_MODE { + RC_MODE_1 = 1, + RC_MODE_2 = 2, + RC_MODE_3 = 3, + RC_MODE_4 = 4, + RC_MODE_NONE = 5 + }; + +public slots: + void rcMenuButtonClicked(); + void sensorMenuButtonClicked(); + void generalMenuButtonClicked(); + void advancedMenuButtonClicked(); + + /** Set the MAV currently being calibrated */ + void setActiveUAS(UASInterface* active); + /** Fallback function, automatically called by loadConfig() upon failure to find and xml file*/ + void loadQgcConfig(bool primary); + /** Load configuration from xml file */ + void loadConfig(); + /** Start the RC calibration routine */ + void startCalibrationRC(); + /** Stop the RC calibration routine */ + void stopCalibrationRC(); + /** Start/stop the RC calibration routine */ + void toggleCalibrationRC(bool enabled); + /** Set trim positions */ + void setTrimPositions(); + /** Detect which channels need to be inverted */ + void detectChannelInversion(); + /** Change the mode setting of the control inputs */ + void setRCModeIndex(int newRcMode); + /** Render the data updated */ + void updateView(); + + void updateMinMax(); + + /** Set the RC channel */ + void setRollChan(int channel) { + rcMapping[0] = channel - 1; + updateInvertedCheckboxes(channel - 1); + } + /** Set the RC channel */ + void setPitchChan(int channel) { + rcMapping[1] = channel - 1; + updateInvertedCheckboxes(channel - 1); + } + /** Set the RC channel */ + void setYawChan(int channel) { + rcMapping[2] = channel - 1; + updateInvertedCheckboxes(channel - 1); + } + /** Set the RC channel */ + void setThrottleChan(int channel) { + rcMapping[3] = channel - 1; + updateInvertedCheckboxes(channel - 1); + } + /** Set the RC channel */ + void setModeChan(int channel) { + rcMapping[4] = channel - 1; + updateInvertedCheckboxes(channel - 1); + } + /** Set the RC channel */ + void setAux1Chan(int channel) { + rcMapping[5] = channel - 1; + updateInvertedCheckboxes(channel - 1); + } + /** Set the RC channel */ + void setAux2Chan(int channel) { + rcMapping[6] = channel - 1; + updateInvertedCheckboxes(channel - 1); + } + /** Set the RC channel */ + void setAux3Chan(int channel) { + rcMapping[7] = channel - 1; + updateInvertedCheckboxes(channel - 1); + } + + /** Set channel inversion status */ + void setRollInverted(bool inverted) { + rcRev[rcMapping[0]] = inverted; + } + /** Set channel inversion status */ + void setPitchInverted(bool inverted) { + rcRev[rcMapping[1]] = inverted; + } + /** Set channel inversion status */ + void setYawInverted(bool inverted) { + rcRev[rcMapping[2]] = inverted; + } + /** Set channel inversion status */ + void setThrottleInverted(bool inverted) { + rcRev[rcMapping[3]] = inverted; + } + /** Set channel inversion status */ + void setModeInverted(bool inverted) { + rcRev[rcMapping[4]] = inverted; + } + /** Set channel inversion status */ + void setAux1Inverted(bool inverted) { + rcRev[rcMapping[5]] = inverted; + } + /** Set channel inversion status */ + void setAux2Inverted(bool inverted) { + rcRev[rcMapping[6]] = inverted; + } + /** Set channel inversion status */ + void setAux3Inverted(bool inverted) { + rcRev[rcMapping[7]] = inverted; + } + +protected slots: + void menuButtonClicked(); + /** Reset the RC calibration */ + void resetCalibrationRC(); + /** Write the RC calibration */ + void writeCalibrationRC(); + /** Request the RC calibration */ + void requestCalibrationRC(); + /** Store all parameters in onboard EEPROM */ + void writeParameters(); + /** Receive remote control updates from MAV */ + void remoteControlChannelRawChanged(int chan, float val); + /** Parameter changed onboard */ + void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void updateStatus(const QString& str); + void updateError(const QString& str); + void setRCType(int type); + /** Check timeouts */ + void checktimeOuts(); + /** Update checkbox status */ + void updateInvertedCheckboxes(int index); + +protected: + bool doneLoadingConfig; + UASInterface* mav; ///< The current MAV + static const unsigned int chanMax = 8; ///< Maximum number of channels + unsigned int chanCount; ///< Actual channels + int rcType; ///< Type of the remote control + quint64 rcTypeUpdateRequested; ///< Zero if not requested, non-zero if requested + static const unsigned int rcTypeTimeout = 5000; ///< 5 seconds timeout, in milliseconds + float rcMin[chanMax]; ///< Minimum values + float rcMax[chanMax]; ///< Maximum values + float rcTrim[chanMax]; ///< Zero-position (center for roll/pitch/yaw, 0 throttle for throttle) + int rcMapping[chanMax]; ///< PWM to function mappings + float rcScaling[chanMax]; ///< Scaling of channel input to control commands + bool rcRev[chanMax]; ///< Channel reverse + int rcValue[chanMax]; ///< Last values + float rcRoll; ///< PPM input channel used as roll control input + float rcPitch; ///< PPM input channel used as pitch control input + float rcYaw; ///< PPM input channel used as yaw control input + float rcThrottle; ///< PPM input channel used as throttle control input + float rcMode; ///< PPM input channel used as mode switch control input + float rcAux1; ///< PPM input channel used as aux 1 input + float rcAux2; ///< PPM input channel used as aux 1 input + float rcAux3; ///< PPM input channel used as aux 1 input + bool rcCalChanged; ///< Set if the calibration changes (and needs to be written) + bool changed; ///< Set if any of the input data changed + QTimer updateTimer; ///< Controls update intervals + enum RC_MODE rc_mode; ///< Mode of the remote control, according to usual convention + QList toolWidgets; ///< Configurable widgets + bool calibrationEnabled; ///< calibration mode on / off + + QMap paramToWidgetMap; ///< Holds the current active MAV's parameter widgets. + QList additionalTabs; ///< Stores additional tabs loaded for this vehicle/autopilot configuration. Used for cleaning up. + QMap libParamToWidgetMap; ///< Holds the library parameter widgets + QMap > systemTypeToParamMap; ///< Holds all loaded MAV specific parameter widgets, for every MAV. + QMap toolToBoxMap; ///< Easy method of figuring out which QGroupBox is tied to which ToolWidget. + QMap paramTooltips; ///< Tooltips for the ? button next to a parameter. + +private: + Ui::QGCPX4VehicleConfig *ui; + QMap buttonToWidgetMap; +signals: + void visibilityChanged(bool visible); +}; + +#endif // QGCPX4VehicleConfig_H diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui new file mode 100644 index 0000000000..883dfd72ff --- /dev/null +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -0,0 +1,1302 @@ + + + QGCPX4VehicleConfig + + + + 0 + 0 + 1256 + 711 + + + + + 0 + 0 + + + + Form + + + + + + + 135 + 0 + + + + + 135 + 16777215 + + + + true + + + + + 0 + 0 + 133 + 691 + + + + + + + QLayout::SetMinAndMaxSize + + + + + + 100 + 75 + + + + + 16777215 + 16777215 + + + + RC +Calibration + + + + + + + + 100 + 75 + + + + Sensor +Calibration + + + + + + + + 100 + 75 + + + + General +Config + + + + + + + + 100 + 75 + + + + Advanced +Config + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + 3 + + + + + + + RC Calibration + + + + + + + + + Advanced + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Advanced + + + + + + + + false + + + false + + + + Select transmitter model + + + + + + + + true + + + + Mode 1 + + + + + Mode 2 + + + + + Mode 3 + + + + + Mode 4 + + + + + + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Invert + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Yaw / Rudder + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Invert + + + + + + + Invert + + + + + + + false + + + 1 + + + 8 + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Pitch / Elevator + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Aux 2 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Invert + + + + + + + false + + + 1 + + + 8 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Throttle + + + + + + + Invert + + + + + + + false + + + 1 + + + 8 + + + + + + + false + + + 1 + + + 8 + + + + + + + Mode Switch + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + false + + + 1 + + + 8 + + + + + + + false + + + 1 + + + 8 + + + + + + + Aux 1 + + + + + + + false + + + 1 + + + 8 + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Aux 3 + + + + + + + Invert + + + + + + + false + + + 1 + + + 8 + + + + + + + Invert + + + + + + + Invert + + + + + + + Roll / Ailerons + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + QLayout::SetMinAndMaxSize + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 50 + 200 + + + + + 50 + 200 + + + + + + + + Qt::Horizontal + + + + 250 + 20 + + + + + + + + + 50 + 200 + + + + + 50 + 200 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 40 + 20 + + + + + + + + + + + + Start Calibration + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Sensor Calibration + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p></body></html> + + + + + + + + + true + + + + + 0 + 0 + 530 + 574 + + + + + + + + + + + + + + + + + + + + + + General Config + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Load Platform Defaults + + + + + + + + + + + Configuration + + + + 0 + + + + + true + + + + + 0 + 0 + 525 + 523 + + + + + 0 + + + + + + + + + + + + + + + Configuration + + + + 0 + + + + + true + + + + + 0 + 0 + 524 + 523 + + + + + 0 + + + + + + + + + + + + + + + + + + + + + Advanced Config + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Load Platform Defaults + + + + + + + + + + + Configuration + + + + 0 + + + + + true + + + + + 0 + 0 + 525 + 523 + + + + + 0 + + + + + + + + + + + + + + + Configuration + + + + 0 + + + + + true + + + + + 0 + 0 + 524 + 523 + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + No pending changes + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + false + + + Copy current parameters in non-permanent memory of the aircraft to permanent memory. Transmit your parameters first to write these. + + + + + + Write (ROM) + + + + + + + false + + + Set current parameters in non-permanent onboard memory. + + + + + + Set (UAS) + + + + + + + false + + + Copy parameters from permanent memory to non-permanent current memory of aircraft. DOES NOT update the parameters in this view, click refresh after copying them to get them. + + + + + + + + + Read (ROM) + + + + + + + false + + + Load parameters currently in non-permanent memory of aircraft. + + + + + + Get (UAS) + + + + + + + false + + + Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them. + + + + + + Load (File) + + + + + + + false + + + Save parameters in this view to a file on this computer. + + + + + + Save (File) + + + + + + + + + + + + + + QGCRadioChannelDisplay + QWidget +
ui/designer/QGCRadioChannelDisplay.h
+ 1 +
+
+ + +
-- GitLab From 0eaf806f6074ba8efdfb5b431f2c3f39e1a9b947 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Fri, 26 Jul 2013 23:27:10 +0200 Subject: [PATCH 090/460] Removed files that should not have been comitted in the first place --- dongfang_qgroundcontrol_notes.txt | 90 ---------------------------- dongfang_qgroundcontrol_wishlist.txt | 23 ------- 2 files changed, 113 deletions(-) delete mode 100644 dongfang_qgroundcontrol_notes.txt delete mode 100644 dongfang_qgroundcontrol_wishlist.txt diff --git a/dongfang_qgroundcontrol_notes.txt b/dongfang_qgroundcontrol_notes.txt deleted file mode 100644 index 40fcc46d07..0000000000 --- a/dongfang_qgroundcontrol_notes.txt +++ /dev/null @@ -1,90 +0,0 @@ -From where is the 3D mouse used? - - -Comm folder: -============ - -LinkInterface is a QThread. Appears to describe an interface on the host system (TCP port, serial port, ....). - Does it suppport multiple connections? -SerialLinkInterface: Extension of above -SerialLink: Implementation - -XBeeLinkInterface: Extension of LinkInterface (but without other serial stuff than baudrate, is the rest assumed?) -XBeeLink: Implementation (with address resetting probably it's Series 1) - -UDPLink: UDP implementation. Port is defaulted. - -MAVLinkSimulationLink: Simulation/dummy implementation of LinkInterface. Does some file IO. -MAVLinkSimulationUAV: Simulation/dummy basic (remote) UAV state (minus mission state) for MAVLinkSimulationLink. -MAVLinkSimulationWaypointPlanner: imulation/dummy basic (remote) UAV mission state for MAVLinkSimulationLink. - - -ProtocolInterface describes a protocol. Major method: - virtual void receiveBytes(LinkInterface *link, QByteArray b) = 0; - -MavlinkProtocol: MAVLink implementation of ProtocolInterface - - -Parameter: Identity of a parameter (the value types are not handled here. Oddly there is no type metainfo either) -ParameterList: Is pretty much what the name impiles. -QGCParamID: Wrapper if parameter text IDs, conversion to byte* and back - -QGCHilLink: Link to a HIL external system - QCGFlightGearLink, QGCJSBSimLink, QGCXPlaneLink : Implementations of QGCHilLink - - -QGCMAVLink: Nothing more than in include to raw mavlink.h - - -input folder: -============= -Some exotic input devices - - - -uas folder: -=========== -UAS.h: Local UAV model. Claims to support some sort of RPC. Uses some properties with notifications. Assumes MAVLink. -Some methods: - int getUASID() const; // the systemId - QList* getLinks(); // it knows its links - - virtual void receiveMessage(LinkInterface* link, mavlink_message_t message); - - float receiveDropRate; ///< Percentage of packets that were dropped on the MAV's receiving link (from GCS and other MAVs) - float sendDropRate; ///< Percentage of packets that were not received from the MAV by the GCS - -Some fields: - bool positionLock; ///< Status if position information is available or not - double localX; // (what is this?) - double localY; - double localZ; - double latitude; ///< Global latitude as estimated by position estimator - double longitude; ///< Global longitude as estimated by position estimator - double altitude; ///< Global altitude as estimated by position estimator - double satelliteCount; ///< Number of satellites visible to raw GPS - bool globalEstimatorActive; ///< Global position estimator present, do not fall back to GPS raw for position - double latitude_gps; ///< Global latitude as estimated by raw GPS - double longitude_gps; ///< Global longitude as estimated by raw GPS - double altitude_gps; ///< Global altitude as estimated by raw GPS - - and lots ans lots more... - - -*MAV.h: Implementations of UAS - - -QGCUASParamManager.h: A mixture of a widget and a parameter up/download state machine. Has a reference to its associated UAV. - -UASWaypointManager: API to waypoint / mission control. Not a widget. Has a reference to its associated UAV. - -UASManager.h: Singleton interface to all UASs on all interfaces. Maintains a single selected/active UAS. - -Ideas to do -TCPLink -XBee Series2 implementation -Less stress on uplink -Get rid of hardcoded SystemId of 255 -Quick View should print all altitudes (GPS, mix, ground and/or home), letting user see errors. -Console debugging is hopefully removed? - diff --git a/dongfang_qgroundcontrol_wishlist.txt b/dongfang_qgroundcontrol_wishlist.txt deleted file mode 100644 index f55ba1dc24..0000000000 --- a/dongfang_qgroundcontrol_wishlist.txt +++ /dev/null @@ -1,23 +0,0 @@ -Major -1) Absolute altitude should absolutely work. Also in face of bad GPS init. - How does the mission planning part work with that, how is alt. stored in waypoints? - When is home altitude stored in the UAV? - -2) Some people have worse datalinks than average - eg. slow or noisy telemetry. GPRS data also easily gets - flooded. All data rates should be configurable and uplinks eased off a little. - -3) Some streams should be sent always even if not in use. For example using RC override and then stopping - using it: If the UAV does not received the final RC override message with zero values for all channels, - it will not get out of RC override. A solution is to make the message non final, repeating it every - now and then. - -Minor -1) I would like to see initial dummy values for eg. battery voltage go away and be replaced by "unknown". - Dummy values confuse, you won't know if your sensors and link are working or not. - -2) Suggestion if the DO_JUMP behavior of APM today (where DO_JUMP requires a waypoint command after it): - Modify APM code so DO_JUMP is regarded a navigation command. Make non navigation commands appear in - planning as sub commands of navigation commands (indent them). Easier to understand. - -3) Old style audio with signals/bells/beeps / Morse may be prefered by some. Maybe add slots'n'signals for - all audio and different implementation types (speech, beep, ...). Or a generic operator messaging thing. -- GitLab From 36b7d7952f9db9a24846c0411250a2ee43ec778e Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Fri, 19 Jul 2013 12:21:14 -0700 Subject: [PATCH 091/460] First commit of Terminal Console View --- qgroundcontrol.pro | 18 +- src/ui/MainWindow.cc | 97 ++++--- src/ui/MainWindow.h | 14 +- src/ui/MainWindow.ui | 23 ++ src/ui/configuration/ApmHighlighter.cc | 53 ++++ src/ui/configuration/ApmHighlighter.h | 51 ++++ src/ui/configuration/SerialSettingsDialog.cc | 189 +++++++++++++ src/ui/configuration/SerialSettingsDialog.h | 91 +++++++ src/ui/configuration/SerialSettingsDialog.ui | 151 +++++++++++ src/ui/configuration/TerminalConsole.cc | 14 + src/ui/configuration/console.cpp | 101 +++++++ src/ui/configuration/console.h | 69 +++++ src/ui/configuration/terminalconsole.cpp | 264 +++++++++++++++++++ src/ui/configuration/terminalconsole.h | 92 +++++++ src/ui/configuration/terminalconsole.ui | 187 +++++++++++++ 15 files changed, 1373 insertions(+), 41 deletions(-) create mode 100644 src/ui/configuration/ApmHighlighter.cc create mode 100644 src/ui/configuration/ApmHighlighter.h create mode 100644 src/ui/configuration/SerialSettingsDialog.cc create mode 100644 src/ui/configuration/SerialSettingsDialog.h create mode 100644 src/ui/configuration/SerialSettingsDialog.ui create mode 100644 src/ui/configuration/TerminalConsole.cc create mode 100644 src/ui/configuration/console.cpp create mode 100644 src/ui/configuration/console.h create mode 100644 src/ui/configuration/terminalconsole.cpp create mode 100644 src/ui/configuration/terminalconsole.h create mode 100644 src/ui/configuration/terminalconsole.ui diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 5fe780edb3..43423d7a50 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -260,7 +260,10 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/ParamWidget.ui \ src/ui/configuration/ArduPlanePidConfig.ui \ src/ui/configuration/AdvParameterList.ui \ - src/ui/configuration/ArduRoverPidConfig.ui + src/ui/configuration/ArduRoverPidConfig.ui \ + src/ui/configuration/terminalconsole.ui \ + src/ui/configuration/SerialSettingsDialog.ui + INCLUDEPATH += src \ src/ui \ src/ui/linechart \ @@ -371,7 +374,6 @@ HEADERS += src/MG.h \ src/ui/map/Waypoint2DIcon.h \ src/ui/map/QGCMapTool.h \ src/ui/map/QGCMapToolBar.h \ -# libs/qextserialport/qextserialenumerator.h \ src/QGCGeo.h \ src/ui/QGCToolBar.h \ src/ui/QGCStatusBar.h \ @@ -447,7 +449,11 @@ HEADERS += src/MG.h \ src/ui/configuration/ParamWidget.h \ src/ui/configuration/ArduPlanePidConfig.h \ src/ui/configuration/AdvParameterList.h \ - src/ui/configuration/ArduRoverPidConfig.h + src/ui/configuration/ArduRoverPidConfig.h \ + src/ui/configuration/console.h \ + src/ui/configuration/SerialSettingsDialog.h \ + src/ui/configuration/terminalconsole.h \ + src/ui/configuration/ApmHighlighter.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -652,7 +658,11 @@ SOURCES += src/main.cc \ src/ui/configuration/ParamWidget.cc \ src/ui/configuration/ArduPlanePidConfig.cc \ src/ui/configuration/AdvParameterList.cc \ - src/ui/configuration/ArduRoverPidConfig.cc + src/ui/configuration/ArduRoverPidConfig.cc \ + src/ui/configuration/terminalconsole.cpp \ + src/ui/configuration/console.cpp \ + src/ui/configuration/SerialSettingsDialog.cc \ + src/ui/configuration/ApmHighlighter.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index cf1a72ca3d..1d4c2aa6ac 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -65,6 +65,8 @@ This file is part of the QGROUNDCONTROL project #include "UASRawStatusView.h" #include "PrimaryFlightDisplay.h" #include "apmtoolbar.h" +#include "SerialSettingsDialog.h" +#include "terminalconsole.h" #ifdef QGC_OSG_ENABLED #include "Q3DWidgetFactory.h" @@ -224,7 +226,7 @@ MainWindow::MainWindow(QWidget *parent): apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); apmToolBar->setSimulationViewAction(ui.actionSimulation_View); - apmToolBar->setTerminalViewAction(ui.actionSimulation_View); + apmToolBar->setTerminalViewAction(ui.actionTerminalView); QDockWidget *widget = new QDockWidget(tr("APM Tool Bar"),this); widget->setWidget(apmToolBar); @@ -475,56 +477,67 @@ void MainWindow::buildCommonWidgets() if (!plannerView) { plannerView = new SubMainWindow(this); + plannerView->setObjectName("VIEW_MISSION"); plannerView->setCentralWidget(new QGCMapTool(this)); - //mapWidget = new QGCMapTool(this); - addCentralWidget(plannerView, "Maps"); + addToCentralStackedWidget(plannerView, VIEW_MISSION, "Maps"); } - //pilotView + //pilotView (aka Flight or Mission View) if (!pilotView) { pilotView = new SubMainWindow(this); pilotView->setObjectName("VIEW_FLIGHT"); pilotView->setCentralWidget(new QGCMapTool(this)); - addCentralWidget(pilotView, "Pilot"); + addToCentralStackedWidget(pilotView, VIEW_FLIGHT, "Pilot"); } + if (!configView) { configView = new SubMainWindow(this); configView->setObjectName("VIEW_HARDWARE_CONFIG"); configView->setCentralWidget(new ApmHardwareConfig(this)); - addCentralWidget(configView,"Hardware"); - centralWidgetToDockWidgetsMap[VIEW_HARDWARE_CONFIG] = QMap(); - + addToCentralStackedWidget(configView,VIEW_HARDWARE_CONFIG, tr("Hardware")); } + if (!softwareConfigView) { softwareConfigView = new SubMainWindow(this); softwareConfigView->setObjectName("VIEW_SOFTWARE_CONFIG"); softwareConfigView->setCentralWidget(new ApmSoftwareConfig(this)); - addCentralWidget(softwareConfigView,"Software"); - centralWidgetToDockWidgetsMap[VIEW_SOFTWARE_CONFIG] = QMap(); + addToCentralStackedWidget(softwareConfigView, VIEW_SOFTWARE_CONFIG, tr("Software")); } + if (!engineeringView) { engineeringView = new SubMainWindow(this); engineeringView->setObjectName("VIEW_ENGINEER"); engineeringView->setCentralWidget(new QGCDataPlot2D(this)); - addCentralWidget(engineeringView,tr("Logfile Plot")); + addToCentralStackedWidget(engineeringView, VIEW_ENGINEER, tr("Logfile Plot")); } + if (!mavlinkView) { mavlinkView = new SubMainWindow(this); mavlinkView->setObjectName("VIEW_MAVLINK"); mavlinkView->setCentralWidget(new XMLCommProtocolWidget(this)); - addCentralWidget(mavlinkView,tr("Mavlink Generator")); + addToCentralStackedWidget(mavlinkView, VIEW_MAVLINK, tr("Mavlink Generator")); } + if (!simView) { simView = new SubMainWindow(this); simView->setObjectName("VIEW_SIMULATOR"); simView->setCentralWidget(new QGCMapTool(this)); - addCentralWidget(simView,tr("Simulation View")); + addToCentralStackedWidget(simView, VIEW_SIMULATION, tr("Simulation View")); + } + + if (!terminalView) + { + terminalView = new SubMainWindow(this); + terminalView->setObjectName("VIEW_TERMINAL"); + TerminalConsole *terminalConsole = new TerminalConsole(this); + terminalView->setCentralWidget(terminalConsole); + addToCentralStackedWidget(terminalView, VIEW_TERMINAL, tr("Terminal View")); } // Dock widgets @@ -682,18 +695,20 @@ void MainWindow::buildCommonWidgets() }*/ #ifdef QGC_OSG_ENABLED - if (!_3DWidget) + if (q3DWidget) { - _3DWidget = Q3DWidgetFactory::get("PIXHAWK", this); - addCentralWidget(_3DWidget, tr("Local 3D")); + q3DWidget = Q3DWidgetFactory::get("PIXHAWK", this); + q3DWidget->setObjectName("VIEW_3DWIDGET"); + + addToCentralStackedWidget(q3DWidget, VIEW_3DWIDGET, tr("Local 3D")); } #endif -#if (defined _MSC_VER) | (defined Q_OS_MAC) - if (!gEarthWidget) +#if (defined _MSC_VER) /*| (defined Q_OS_MAC_OFF)*/ + if (!earthWidget) { - gEarthWidget = new QGCGoogleEarthView(this); - addCentralWidget(gEarthWidget, tr("Google Earth")); + earthWidget = new QGCGoogleEarthView(this); + addToCentralStackedWidget(earthWidget,VIEW_GOOGLEEARTH, tr("Google Earth")); } #endif } @@ -918,25 +933,16 @@ void MainWindow::showTool(bool show) addTool(parent,VIEW_SIMULATION,widget,tr("Control"),area); } }*/ -void MainWindow::addCentralWidget(QWidget* widget, const QString& title) +void MainWindow::addToCentralStackedWidget(QWidget* widget, VIEW_SECTIONS viewSection, const QString& title) { Q_UNUSED(title); + Q_ASSERT(widget->objectName().length() != 0); // Check if this widget already has been added if (centerStack->indexOf(widget) == -1) { centerStack->addWidget(widget); - - // QAction* tempAction = ui.menuMain->addAction(title); - - // tempAction->setCheckable(true); - // QVariant var; - // var.setValue((QWidget*)widget); - // tempAction->setData(var); - // centerStackActionGroup->addAction(tempAction); - // connect(tempAction,SIGNAL(triggered()),this, SLOT(showCentralWidget())); - //connect(widget, SIGNAL(visibilityChanged(bool)), tempAction, SLOT(setChecked(bool))); - // tempAction->setChecked(widget->isVisible()); + centralWidgetToDockWidgetsMap[viewSection] = QMap(); } } @@ -1448,6 +1454,7 @@ void MainWindow::connectCommonActions() perspectives->addAction(ui.actionHardwareConfig); perspectives->addAction(ui.actionSoftwareConfig); perspectives->addAction(ui.actionFirmwareUpdateView); + perspectives->addAction(ui.actionTerminalView); perspectives->addAction(ui.actionUnconnectedView); perspectives->setExclusive(true); @@ -1492,6 +1499,11 @@ void MainWindow::connectCommonActions() ui.actionFirmwareUpdateView->setChecked(true); ui.actionFirmwareUpdateView->activate(QAction::Trigger); } + if (currentView == VIEW_TERMINAL) + { + ui.actionTerminalView->setChecked(true); + ui.actionTerminalView->activate(QAction::Trigger); + } if (currentView == VIEW_UNCONNECTED) { ui.actionUnconnectedView->setChecked(true); @@ -1529,6 +1541,7 @@ void MainWindow::connectCommonActions() connect(ui.actionUnconnectedView, SIGNAL(triggered()), this, SLOT(loadUnconnectedView())); connect(ui.actionHardwareConfig,SIGNAL(triggered()),this,SLOT(loadHardwareConfigView())); connect(ui.actionSoftwareConfig,SIGNAL(triggered()),this,SLOT(loadSoftwareConfigView())); + connect(ui.actionTerminalView,SIGNAL(triggered()),this,SLOT(loadTerminalView())); connect(ui.actionFirmwareUpdateView, SIGNAL(triggered()), this, SLOT(loadFirmwareUpdateView())); connect(ui.actionMavlinkView, SIGNAL(triggered()), this, SLOT(loadMAVLinkView())); @@ -1625,7 +1638,7 @@ void MainWindow::showSettings() settings->show(); } -void MainWindow::addLink() +LinkInterface* MainWindow::addLink() { SerialLink* link = new SerialLink(); // TODO This should be only done in the dialog itself @@ -1647,6 +1660,8 @@ void MainWindow::addLink() break; } } + + return link; } @@ -2050,6 +2065,10 @@ void MainWindow::loadViewState() centerStack->setCurrentWidget(simView); break; + case VIEW_TERMINAL: + centerStack->setCurrentWidget(terminalView); + break; + case VIEW_UNCONNECTED: case VIEW_FULL: default: @@ -2161,6 +2180,18 @@ void MainWindow::loadSoftwareConfigView() } } +void MainWindow::loadTerminalView() +{ + if (currentView != VIEW_TERMINAL) + { + storeViewState(); + currentView = VIEW_TERMINAL; + ui.actionTerminalView->setChecked(true); + loadViewState(); + } +} + + void MainWindow::loadUnconnectedView() { if (currentView != VIEW_UNCONNECTED) diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index b51dba6b20..5fe4de6269 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -148,7 +148,7 @@ public slots: /** @brief Show the application settings */ void showSettings(); /** @brief Add a communication link */ - void addLink(); + LinkInterface* addLink(); void addLink(LinkInterface* link); bool configLink(LinkInterface *link); void configure(); @@ -184,6 +184,8 @@ public slots: void loadMAVLinkView(); /** @brief Load firmware update view */ void loadFirmwareUpdateView(); + /** @brief Load Terminal Console views */ + void loadTerminalView(); /** @brief Show the online help for users */ void showHelp(); @@ -288,6 +290,9 @@ protected: VIEW_FIRMWAREUPDATE, VIEW_HARDWARE_CONFIG, VIEW_SOFTWARE_CONFIG, + VIEW_TERMINAL, + VIEW_3DWIDGET, + VIEW_GOOGLEEARTH, VIEW_UNCONNECTED, ///< View in unconnected mode, when no UAS is available VIEW_FULL ///< All widgets shown at once } VIEW_SECTIONS; @@ -317,7 +322,7 @@ protected: * @param widget The QWidget being added * @param title The entry that will appear in the Menu */ - void addCentralWidget(QWidget* widget, const QString& title); + void addToCentralStackedWidget(QWidget* widget, VIEW_SECTIONS viewSection, const QString& title); /** @brief Catch window resize events */ void resizeEvent(QResizeEvent * event); @@ -358,6 +363,7 @@ protected: QPointer mavlinkView; QPointer engineeringView; QPointer simView; + QPointer terminalView; // Center widgets QPointer linechartWidget; @@ -367,10 +373,10 @@ protected: //QPointer protocolWidget; //QPointer dataplotWidget; #ifdef QGC_OSG_ENABLED - QPointer _3DWidget; + QPointer q3DWidget; #endif #if (defined _MSC_VER) || (defined Q_OS_MAC) - QPointer gEarthWidget; + QPointer earthWidget; #endif QPointer firmwareUpdateWidget; diff --git a/src/ui/MainWindow.ui b/src/ui/MainWindow.ui index d0ba091980..ff45d55834 100644 --- a/src/ui/MainWindow.ui +++ b/src/ui/MainWindow.ui @@ -107,6 +107,7 @@ + @@ -491,11 +492,21 @@ + + true + + + + :/files/images/apps/accessories-calculator.svg:/files/images/apps/accessories-calculator.svg + Simulation + + true + :/files/images/categories/applications-system.svg:/files/images/categories/applications-system.svg @@ -504,6 +515,18 @@ Software + + + true + + + + :/files/images/apps/utilities-terminal.svg:/files/images/apps/utilities-terminal.svg + + + Terminal + + diff --git a/src/ui/configuration/ApmHighlighter.cc b/src/ui/configuration/ApmHighlighter.cc new file mode 100644 index 0000000000..8e09ac6f0e --- /dev/null +++ b/src/ui/configuration/ApmHighlighter.cc @@ -0,0 +1,53 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief APM Highligther for ArduPilot Console. + * + * @author Bill Bonney + * + */ + +#include "ApmHighlighter.h" + +APMHighlighter::APMHighlighter(QObject *parent) : + QSyntaxHighlighter(parent) +{ +} + +void APMHighlighter::highlightBlock(const QString &text) + { + QTextCharFormat myClassFormat; + myClassFormat.setFontWeight(QFont::Bold); + myClassFormat.setForeground(Qt::darkMagenta); + QString pattern = "^\\Ardu[A-Za-z]+\\b"; + + QRegExp expression(pattern); + int index = text.indexOf(expression); + while (index >= 0) { + int length = expression.matchedLength(); + setFormat(index, length, myClassFormat); + index = text.indexOf(expression, index + length); + } + } diff --git a/src/ui/configuration/ApmHighlighter.h b/src/ui/configuration/ApmHighlighter.h new file mode 100644 index 0000000000..e4f9b645f1 --- /dev/null +++ b/src/ui/configuration/ApmHighlighter.h @@ -0,0 +1,51 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief APM Highligther for ArduPilot Console. + * + * @author Bill Bonney + * + */ + +#ifndef APMHIGHLIGHTER_H +#define APMHIGHLIGHTER_H + +#include "ApmHighlighter.h" +#include + +class APMHighlighter : public QSyntaxHighlighter +{ + Q_OBJECT +public: + explicit APMHighlighter(QObject *parent = 0); + void highlightBlock(const QString &text); + +signals: + +public slots: + +}; + +#endif // APMHIGHLIGHTER_H diff --git a/src/ui/configuration/SerialSettingsDialog.cc b/src/ui/configuration/SerialSettingsDialog.cc new file mode 100644 index 0000000000..40c317068d --- /dev/null +++ b/src/ui/configuration/SerialSettingsDialog.cc @@ -0,0 +1,189 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Serial Settings View. + * + * @author Bill Bonney + * + * Influenced from Qt examples by :- + * Copyright (C) 2012 Denis Shienkov + * Copyright (C) 2012 Laszlo Papp + * + */ + +#include "SerialSettingsDialog.h" +#include "terminalconsole.h" +#include "ui_settingsdialog.h" + +#include +#include +#include +#include + +QT_USE_NAMESPACE + +SettingsDialog::SettingsDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::SettingsDialog) +{ + ui->setupUi(this); + + m_intValidator = new QIntValidator(0, 4000000, this); + + ui->baudRateBox->setInsertPolicy(QComboBox::NoInsert); + + connect(ui->applyButton, SIGNAL(clicked()), + this, SLOT(apply())); + connect(ui->serialPortInfoListBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(showPortInfo(int))); + connect(ui->baudRateBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(checkCustomBaudRatePolicy(int))); + + fillPortsParameters(); + fillPortsInfo(); + + updateSettings(); +} + +SettingsDialog::~SettingsDialog() +{ + delete ui; +} + +const SerialSettings& SettingsDialog::settings() const +{ + return m_currentSettings; +} + +void SettingsDialog::showPortInfo(int idx) +{ + if (idx != -1) { + QStringList list = ui->serialPortInfoListBox->itemData(idx).toStringList(); + ui->descriptionLabel->setText(tr("Description: %1").arg(list.at(1))); + ui->manufacturerLabel->setText(tr("Manufacturer: %1").arg(list.at(2))); + ui->locationLabel->setText(tr("Location: %1").arg(list.at(3))); + ui->vidLabel->setText(tr("Vendor Identifier: %1").arg(list.at(4))); + ui->pidLabel->setText(tr("Product Identifier: %1").arg(list.at(5))); + } +} + +void SettingsDialog::apply() +{ + updateSettings(); + hide(); +} + +void SettingsDialog::checkCustomBaudRatePolicy(int idx) +{ + bool isCustomBaudRate = !ui->baudRateBox->itemData(idx).isValid(); + ui->baudRateBox->setEditable(isCustomBaudRate); + if (isCustomBaudRate) { + ui->baudRateBox->clearEditText(); + QLineEdit *edit = ui->baudRateBox->lineEdit(); + edit->setValidator(m_intValidator); + } +} + +void SettingsDialog::fillPortsParameters() +{ + // fill baud rate (is not the entire list of available values, + // desired values??, add your independently) + ui->baudRateBox->addItem(QLatin1String("115200"), QSerialPort::Baud115200); + ui->baudRateBox->addItem(QLatin1String("57600"), QSerialPort::Baud57600); + ui->baudRateBox->addItem(QLatin1String("38400"), QSerialPort::Baud38400); + ui->baudRateBox->addItem(QLatin1String("19200"), QSerialPort::Baud19200); + ui->baudRateBox->addItem(QLatin1String("19200"), QSerialPort::Baud19200); + ui->baudRateBox->addItem(QLatin1String("9600"), QSerialPort::Baud9600); + ui->baudRateBox->addItem(QLatin1String("Custom")); + + // fill data bits + ui->dataBitsBox->addItem(QLatin1String("5"), QSerialPort::Data5); + ui->dataBitsBox->addItem(QLatin1String("6"), QSerialPort::Data6); + ui->dataBitsBox->addItem(QLatin1String("7"), QSerialPort::Data7); + ui->dataBitsBox->addItem(QLatin1String("8"), QSerialPort::Data8); + ui->dataBitsBox->setCurrentIndex(3); + + // fill parity + ui->parityBox->addItem(QLatin1String("None"), QSerialPort::NoParity); + ui->parityBox->addItem(QLatin1String("Even"), QSerialPort::EvenParity); + ui->parityBox->addItem(QLatin1String("Odd"), QSerialPort::OddParity); + ui->parityBox->addItem(QLatin1String("Mark"), QSerialPort::MarkParity); + ui->parityBox->addItem(QLatin1String("Space"), QSerialPort::SpaceParity); + + // fill stop bits + ui->stopBitsBox->addItem(QLatin1String("1"), QSerialPort::OneStop); +#ifdef Q_OS_WIN + ui->stopBitsBox->addItem(QLatin1String("1.5"), QSerialPort::OneAndHalfStop); +#endif + ui->stopBitsBox->addItem(QLatin1String("2"), QSerialPort::TwoStop); + + // fill flow control + ui->flowControlBox->addItem(QLatin1String("None"), QSerialPort::NoFlowControl); + ui->flowControlBox->addItem(QLatin1String("RTS/CTS"), QSerialPort::HardwareControl); + ui->flowControlBox->addItem(QLatin1String("XON/XOFF"), QSerialPort::SoftwareControl); +} + +void SettingsDialog::fillPortsInfo() +{ + ui->serialPortInfoListBox->clear(); + foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { + QStringList list; + list << info.portName() + << info.description() + << info.manufacturer() + << info.systemLocation() + << (info.vendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : QString()) + << (info.productIdentifier() ? QString::number(info.productIdentifier(), 16) : QString()); + + ui->serialPortInfoListBox->insertItem(0, list.first(), list); + } +} + +void SettingsDialog::updateSettings() +{ + m_currentSettings.name = ui->serialPortInfoListBox->currentText(); + + // Baud Rate + if (ui->baudRateBox->currentIndex() == 4) { + // custom baud rate + m_currentSettings.baudRate = ui->baudRateBox->currentText().toInt(); + } else { + // standard baud rate + m_currentSettings.baudRate = static_cast( + ui->baudRateBox->itemData(ui->baudRateBox->currentIndex()).toInt()); + } + // Data bits + m_currentSettings.dataBits = static_cast( + ui->dataBitsBox->itemData(ui->dataBitsBox->currentIndex()).toInt()); + // Parity + m_currentSettings.parity = static_cast( + ui->parityBox->itemData(ui->parityBox->currentIndex()).toInt()); + // Stop bits + m_currentSettings.stopBits = static_cast( + ui->stopBitsBox->itemData(ui->stopBitsBox->currentIndex()).toInt()); + // Flow control + m_currentSettings.flowControl = static_cast( + ui->flowControlBox->itemData(ui->flowControlBox->currentIndex()).toInt()); +} diff --git a/src/ui/configuration/SerialSettingsDialog.h b/src/ui/configuration/SerialSettingsDialog.h new file mode 100644 index 0000000000..5b1586fdf2 --- /dev/null +++ b/src/ui/configuration/SerialSettingsDialog.h @@ -0,0 +1,91 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Serial Settings View. + * + * @author Bill Bonney + * + * Influenced from Qt examples by :- + * Copyright (C) 2012 Denis Shienkov + * Copyright (C) 2012 Laszlo Papp + * + */ + +#ifndef SETTINGSDIALOG_H +#define SETTINGSDIALOG_H + +#include +#include + +namespace Ui { +class SettingsDialog; +} + +class QIntValidator; + +class SerialSettings { +public: + SerialSettings() : name(""), + baudRate(115200), + dataBits(QSerialPort::Data8), + parity(QSerialPort::NoParity), + stopBits(QSerialPort::OneStop), + flowControl(QSerialPort::NoFlowControl){} +public: + QString name; + qint32 baudRate; + QSerialPort::DataBits dataBits; + QSerialPort::Parity parity; + QSerialPort::StopBits stopBits; + QSerialPort::FlowControl flowControl; +}; + +class SettingsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SettingsDialog(QWidget *parent = 0); + ~SettingsDialog(); + + const SerialSettings &settings() const; + +private slots: + void showPortInfo(int idx); + void apply(); + void checkCustomBaudRatePolicy(int idx); + +private: + void fillPortsParameters(); + void fillPortsInfo(); + void updateSettings(); + +private: + Ui::SettingsDialog *ui; + SerialSettings m_currentSettings; + QIntValidator *m_intValidator; +}; + +#endif // SETTINGSDIALOG_H diff --git a/src/ui/configuration/SerialSettingsDialog.ui b/src/ui/configuration/SerialSettingsDialog.ui new file mode 100644 index 0000000000..5f2706fa28 --- /dev/null +++ b/src/ui/configuration/SerialSettingsDialog.ui @@ -0,0 +1,151 @@ + + + SettingsDialog + + + + 0 + 0 + 401 + 250 + + + + Settings + + + + + + Select Serial Port + + + + + + + + + Description: + + + + + + + Manufacturer: + + + + + + + Location: + + + + + + + Vendor ID: + + + + + + + Product ID: + + + + + + + + + + + + Qt::Horizontal + + + + 96 + 20 + + + + + + + + Apply + + + + + + + + + Select Parameters + + + + + + BaudRate: + + + + + + + + + + Data bits: + + + + + + + + + + Parity: + + + + + + + + + + Stop bits: + + + + + + + + + + Flow control: + + + + + + + + + + + + + + diff --git a/src/ui/configuration/TerminalConsole.cc b/src/ui/configuration/TerminalConsole.cc new file mode 100644 index 0000000000..1c5233e630 --- /dev/null +++ b/src/ui/configuration/TerminalConsole.cc @@ -0,0 +1,14 @@ +#include "terminalconsole.h" +#include "ui_terminalconsole.h" + +TerminalConsole::TerminalConsole(QWidget *parent) : + QWidget(parent), + ui(new Ui::TerminalConsole) +{ + ui->setupUi(this); +} + +TerminalConsole::~TerminalConsole() +{ + delete ui; +} diff --git a/src/ui/configuration/console.cpp b/src/ui/configuration/console.cpp new file mode 100644 index 0000000000..c530af0e6c --- /dev/null +++ b/src/ui/configuration/console.cpp @@ -0,0 +1,101 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Text Console. + * + * @author Bill Bonney + * + * Influenced from Qt examples by :- + * Copyright (C) 2012 Denis Shienkov + * Copyright (C) 2012 Laszlo Papp + * + */ + +#include "console.h" +#include "ApmHighlighter.h" + +#include + +#include + +Console::Console(QWidget *parent) + : QPlainTextEdit(parent) + , localEchoEnabled(false) +{ + document()->setMaximumBlockCount(100); + QPalette p = palette(); + p.setColor(QPalette::Base, Qt::black); + p.setColor(QPalette::Text, Qt::green); + setPalette(p); + + m_highlighter = new APMHighlighter(document()); + +} + +void Console::putData(const QByteArray &data) +{ + insertPlainText(QString(data)); + + QScrollBar *bar = verticalScrollBar(); + bar->setValue(bar->maximum()); +} + +void Console::setLocalEchoEnabled(bool set) +{ + localEchoEnabled = set; +} + +void Console::keyPressEvent(QKeyEvent *e) +{ + switch (e->key()) { + case Qt::Key_Backspace: + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Up: + case Qt::Key_Down: + // skip processing + break; + default: + if (localEchoEnabled) + QPlainTextEdit::keyPressEvent(e); + emit getData(e->text().toLocal8Bit()); + } +} + +void Console::mousePressEvent(QMouseEvent *e) +{ + Q_UNUSED(e) + setFocus(); +} + +void Console::mouseDoubleClickEvent(QMouseEvent *e) +{ + Q_UNUSED(e) +} + +void Console::contextMenuEvent(QContextMenuEvent *e) +{ + Q_UNUSED(e) +} diff --git a/src/ui/configuration/console.h b/src/ui/configuration/console.h new file mode 100644 index 0000000000..28a1135ded --- /dev/null +++ b/src/ui/configuration/console.h @@ -0,0 +1,69 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Text Console. + * + * @author Bill Bonney + * + * Influenced from Qt examples by :- + * Copyright (C) 2012 Denis Shienkov + * Copyright (C) 2012 Laszlo Papp + * + */ + +#ifndef CONSOLE_H +#define CONSOLE_H + +#include + +class APMHighlighter; + +class Console : public QPlainTextEdit +{ + Q_OBJECT + +signals: + void getData(const QByteArray &data); + +public: + explicit Console(QWidget *parent = 0); + + void putData(const QByteArray &data); + + void setLocalEchoEnabled(bool set); + +protected: + virtual void keyPressEvent(QKeyEvent *e); + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseDoubleClickEvent(QMouseEvent *e); + virtual void contextMenuEvent(QContextMenuEvent *e); + +private: + bool localEchoEnabled; + APMHighlighter* m_highlighter; + +}; + +#endif // CONSOLE_H diff --git a/src/ui/configuration/terminalconsole.cpp b/src/ui/configuration/terminalconsole.cpp new file mode 100644 index 0000000000..0e5330355e --- /dev/null +++ b/src/ui/configuration/terminalconsole.cpp @@ -0,0 +1,264 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Terminal Console display View. + * + * @author Bill Bonney + * + * Influenced from Qt examples by :- + * Copyright (C) 2012 Denis Shienkov + * Copyright (C) 2012 Laszlo Papp + * + */ + +#include "SerialSettingsDialog.h" +#include "terminalconsole.h" +#include "ui_terminalconsole.h" +#include "console.h" +#include "configuration.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +TerminalConsole::TerminalConsole(QWidget *parent) : + QWidget(parent), + ui(new Ui::TerminalConsole) +{ + ui->setupUi(this); + + // create the cosole and add it to the centralwidget + m_console = new Console; + m_console->setEnabled(false); + + m_statusBar = new QStatusBar; + + QLayout* layout = ui->terminalGroupBox->layout(); + layout->addWidget(m_console); + layout->addWidget(m_statusBar); + + m_serial = new QSerialPort(this); + m_settingsDialog = new SettingsDialog; + + ui->connectButton->setEnabled(true); + ui->disconnectButton->setEnabled(false); + ui->settingsButton->setEnabled(true); + + addBaudComboBoxConfig(); + fillPortsInfo(*ui->linkComboBox); + + loadSettings(); + + if (m_settings.name == "") { + setLink(ui->linkComboBox->currentIndex()); + } else { + ui->linkComboBox->setCurrentIndex(0); + } + + //setUiControls(m_settingsDialog); + + initConnections(); +} + +void TerminalConsole::addBaudComboBoxConfig() +{ + ui->baudComboBox->addItem(QLatin1String("115200"), QSerialPort::Baud115200); + ui->baudComboBox->addItem(QLatin1String("57600"), QSerialPort::Baud57600); + ui->baudComboBox->addItem(QLatin1String("38400"), QSerialPort::Baud38400); + ui->baudComboBox->addItem(QLatin1String("19200"), QSerialPort::Baud19200); + ui->baudComboBox->addItem(QLatin1String("19200"), QSerialPort::Baud19200); + ui->baudComboBox->addItem(QLatin1String("9600"), QSerialPort::Baud9600); +} + +void TerminalConsole::fillPortsInfo(QComboBox &comboxBox) +{ + comboxBox.clear(); + foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { + QStringList list; + list << info.portName() + << info.description() + << info.manufacturer() + << info.systemLocation() + << (info.vendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : QString()) + << (info.productIdentifier() ? QString::number(info.productIdentifier(), 16) : QString()); + + comboxBox.insertItem(0,list.first(), list); + qDebug() << "Inserting " << list.first(); + } +} + +TerminalConsole::~TerminalConsole() +{ + delete m_console; + delete m_statusBar; + delete m_settingsDialog; + delete ui; +} + +void TerminalConsole::openSerialPort() +{ + openSerialPort(m_settings); +} + +void TerminalConsole::openSerialPort(const SerialSettings &settings) +{ + m_serial->setPortName(settings.name); + if (m_serial->open(QIODevice::ReadWrite)) { + if (m_serial->setBaudRate(settings.baudRate) + && m_serial->setDataBits(settings.dataBits) + && m_serial->setParity(settings.parity) + && m_serial->setStopBits(settings.stopBits) + && m_serial->setFlowControl(settings.flowControl)) { + + m_console->setEnabled(true); + m_console->setLocalEchoEnabled(false); + ui->connectButton->setEnabled(false); + ui->disconnectButton->setEnabled(true); + ui->settingsButton->setEnabled(false); + m_statusBar->showMessage(tr("Connected to %1 : baud %2z") + .arg(settings.name).arg(QString::number(settings.baudRate))); + qDebug() << "Open Terminal Console Serial Port"; + + } else { + m_serial->close(); + QMessageBox::critical(this, tr("Error"), m_serial->errorString()); + + m_statusBar->showMessage(tr("Open error")); + } + } else { + QMessageBox::critical(this, tr("Error"), m_serial->errorString()); + + m_statusBar->showMessage(tr("Configure error")); + } +} + +void TerminalConsole::closeSerialPort() +{ + m_serial->close(); + m_console->setEnabled(false); + ui->connectButton->setEnabled(true); + ui->disconnectButton->setEnabled(false); + ui->settingsButton->setEnabled(true); + m_statusBar->showMessage(tr("Disconnected")); +} + +void TerminalConsole::writeData(const QByteArray &data) +{ +// qDebug() << "writeData:" << data; + m_serial->write(data); +} + +void TerminalConsole::readData() +{ + QByteArray data = m_serial->readAll(); +// qDebug() << "readData:" << data; + m_console->putData(data); +} + +void TerminalConsole::handleError(QSerialPort::SerialPortError error) +{ + if (error == QSerialPort::ResourceError) { + QMessageBox::critical(this, tr("Critical Error"), m_serial->errorString()); + closeSerialPort(); + } +} + +void TerminalConsole::initConnections() +{ + // Ui Connections + connect(ui->connectButton, SIGNAL(released()), this, SLOT(openSerialPort())); + connect(ui->disconnectButton, SIGNAL(released()), this, SLOT(closeSerialPort())); + connect(ui->settingsButton, SIGNAL(released()), m_settingsDialog, SLOT(show())); + connect(ui->clearButton, SIGNAL(released()), m_console, SLOT(clear())); + + connect(ui->baudComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setBaudRate(int))); + connect(ui->linkComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setLink(int))); +// connect(ui->linkComboBox, SIGNAL()), this, SLOT(setLink(int))); + + // Serial Port Connections + connect(m_serial, SIGNAL(error(QSerialPort::SerialPortError)), this, + SLOT(handleError(QSerialPort::SerialPortError))); + + connect(m_serial, SIGNAL(readyRead()), this, SLOT(readData())); + connect(m_console, SIGNAL(getData(QByteArray)), this, SLOT(writeData(QByteArray))); +} + +void TerminalConsole::setBaudRate(int index) +{ + m_settings.baudRate = static_cast( + ui->baudComboBox->itemData(index).toInt()); + qDebug() << "Changed Baud to:" << m_settings.baudRate; + +} + +void TerminalConsole::setLink(int index) +{ + m_settings.name = ui->linkComboBox->currentText(); + qDebug() << "Changed Link to:" << m_settings.name; + +} + +void TerminalConsole::loadSettings() +{ + // Load defaults from settings + QSettings settings(QGC::COMPANYNAME, QGC::APPNAME); + settings.sync(); + if (settings.contains("TERMINALCONSOLE_COMM_PORT")) + { + m_settings.name = settings.value("TERMINALCONSOLE_COMM_PORT").toString(); + m_settings.baudRate = settings.value("TERMINALCONSOLE_COMM_BAUD").toInt(); + m_settings.parity = static_cast + (settings.value("TERMINALCONSOLE_COMM_PARITY").toInt()); + m_settings.stopBits = static_cast + (settings.value("TERMINALCONSOLE_COMM_STOPBITS").toInt()); + m_settings.dataBits = static_cast + (settings.value("TERMINALCONSOLE_COMM_DATABITS").toInt()); + m_settings.flowControl = static_cast + (settings.value("TERMINALCONSOLE_COMM_FLOW_CONTROL").toInt()); + } else { + // init the structure + } +} + +void TerminalConsole::writeSettings() +{ + // Store settings + QSettings settings(QGC::COMPANYNAME, QGC::APPNAME); + settings.setValue("TERMINALCONSOLE_COMM_PORT", m_settings.name); + settings.setValue("TERMINALCONSOLE_COMM_BAUD", m_settings.baudRate); + settings.setValue("TERMINALCONSOLE_COMM_PARITY", m_settings.parity); + settings.setValue("TERMINALCONSOLE_COMM_STOPBITS", m_settings.stopBits); + settings.setValue("TERMINALCONSOLE_COMM_DATABITS", m_settings.dataBits); + settings.setValue("TERMINALCONSOLE_COMM_FLOW_CONTROL", m_settings.flowControl); + settings.sync(); +} + + + diff --git a/src/ui/configuration/terminalconsole.h b/src/ui/configuration/terminalconsole.h new file mode 100644 index 0000000000..5c8a91182b --- /dev/null +++ b/src/ui/configuration/terminalconsole.h @@ -0,0 +1,92 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Terminal Console display View. + * + * @author Bill Bonney + * + * Influenced from Qt examples by :- + * Copyright (C) 2012 Denis Shienkov + * Copyright (C) 2012 Laszlo Papp + * + */ + +#ifndef TERMINALCONSOLE_H +#define TERMINALCONSOLE_H + +#include "SerialSettingsDialog.h" + +#include +#include + +namespace Ui { +class TerminalConsole; +} + +class Console; +class SettingsDialog; +class QStatusBar; +class QComboBox; + +class TerminalConsole : public QWidget +{ + Q_OBJECT + +public: + explicit TerminalConsole(QWidget *parent = 0); + ~TerminalConsole(); + +private slots: + void openSerialPort(); + void openSerialPort(const SerialSettings &settings); + void closeSerialPort(); + void writeData(const QByteArray &data); + void readData(); + + void handleError(QSerialPort::SerialPortError error); + +private slots: + void setBaudRate(int index); + void setLink(int index); + +private: + void initConnections(); + void addBaudComboBoxConfig(); + void fillPortsInfo(QComboBox &comboxBox); + void writeSettings(); + void loadSettings(); + + +private: + Ui::TerminalConsole *ui; + + Console *m_console; + QStatusBar *m_statusBar; + SettingsDialog *m_settingsDialog; + QSerialPort *m_serial; + SerialSettings m_settings; +}; + +#endif // TERMINALCONSOLE_H diff --git a/src/ui/configuration/terminalconsole.ui b/src/ui/configuration/terminalconsole.ui new file mode 100644 index 0000000000..1ee9ec87cc --- /dev/null +++ b/src/ui/configuration/terminalconsole.ui @@ -0,0 +1,187 @@ + + + TerminalConsole + + + + 0 + 0 + 889 + 531 + + + + Form + + + + + + + 0 + 0 + + + + Terminal Output + + + + + + + + QLayout::SetMinAndMaxSize + + + + + + 100 + 0 + + + + + 131 + 0 + + + + CONNECT + + + + + + + + 0 + 0 + + + + + 131 + 0 + + + + DISCONNECT + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + 0 + 0 + + + + + 123 + 0 + + + + + 220 + 32 + + + + + + + + + 0 + 0 + + + + + 123 + 0 + + + + + + + + + 0 + 0 + + + + + 123 + 0 + + + + + APM + + + + + PX4 + + + + + + + + Qt::Vertical + + + + 91 + 23 + + + + + + + + Adv. Settings + + + + + + + Clear + + + + + + + + + + -- GitLab From 1549c299a57e3e58eaeede71e98460c0ecad450b Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 28 Jul 2013 18:07:27 +0200 Subject: [PATCH 092/460] Fixed qrc file --- qgroundcontrol.qrc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 25152d21ad..728844e1e2 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -102,10 +102,6 @@ files/images/patterns/lenna.jpg files/images/rc_stick.svg files/images/actions/qgroundcontrol-connect.svg - files/images/apm_planner_logo.png - files/images/apm_planner_logo_splash.png - files/images/apm_planner_2_0-07.png - files/images/apm_planner_2_0-08.png files/images/mavs/frames_plus.png files/images/mavs/frames_x.png files/images/mavs/frames-05.png -- GitLab From f7f1dfaa0fad62b012f5a9d16bca70fd74a64ce1 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Mon, 29 Jul 2013 09:39:13 -0700 Subject: [PATCH 093/460] Terminal View: Store settings on successful connect --- src/ui/configuration/terminalconsole.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui/configuration/terminalconsole.cpp b/src/ui/configuration/terminalconsole.cpp index 0e5330355e..e3d890d7b5 100644 --- a/src/ui/configuration/terminalconsole.cpp +++ b/src/ui/configuration/terminalconsole.cpp @@ -145,6 +145,7 @@ void TerminalConsole::openSerialPort(const SerialSettings &settings) m_statusBar->showMessage(tr("Connected to %1 : baud %2z") .arg(settings.name).arg(QString::number(settings.baudRate))); qDebug() << "Open Terminal Console Serial Port"; + writeSettings(); // Save last successful connection } else { m_serial->close(); -- GitLab From 64cfb10be25edc62310b0f56b1fe59ffecb323ea Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 29 Jul 2013 21:47:49 +0200 Subject: [PATCH 094/460] Fixed indendation --- qgroundcontrol.pri | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qgroundcontrol.pri b/qgroundcontrol.pri index c20a4b3d86..fdf608780b 100644 --- a/qgroundcontrol.pri +++ b/qgroundcontrol.pri @@ -65,8 +65,8 @@ macx|macx-g++42|macx-g++|macx-llvm: { QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/Frameworks QMAKE_POST_LINK += && cp -rf $$BASEDIR/libs/lib/Frameworks/* $$TARGETDIR/qgroundcontrol.app/Contents/Frameworks -# # Copy QML stuff -message(BASEDIR $$BASEDIR) + # Copy QML stuff + message(BASEDIR $$BASEDIR) QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml QMAKE_POST_LINK += && cp -rf $$BASEDIR/qml/*.qml $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml -- GitLab From 95e4e9bfbcb019d88cdfe6fb4311c436fbb5e741 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Mon, 29 Jul 2013 13:10:37 -0700 Subject: [PATCH 095/460] Fix: mispelt include in SerialSettingsDialog.cc --- src/ui/configuration/SerialSettingsDialog.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/configuration/SerialSettingsDialog.cc b/src/ui/configuration/SerialSettingsDialog.cc index 40c317068d..fbb8d2da60 100644 --- a/src/ui/configuration/SerialSettingsDialog.cc +++ b/src/ui/configuration/SerialSettingsDialog.cc @@ -35,7 +35,7 @@ This file is part of the APM_PLANNER project #include "SerialSettingsDialog.h" #include "terminalconsole.h" -#include "ui_settingsdialog.h" +#include "ui_SerialSettingsDialog.h" #include #include -- GitLab From 56efe884240face4b175888c59e9c4b5c0448834 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Fri, 26 Jul 2013 11:02:01 -0400 Subject: [PATCH 096/460] Initial commit of APM2.5 Firmware loading config screen via Avrdude --- avrdude/avrdude.conf | 15478 +++++++++++++++++ avrdude/avrdude.exe | Bin 0 -> 313344 bytes avrdude/libusb0.dll | Bin 0 -> 43520 bytes files/images/firmware/FW icons 2013+logos.ai | 2008 +++ files/images/firmware/Tir_off.png | Bin 0 -> 30545 bytes files/images/firmware/Tir_on.png | Bin 0 -> 55407 bytes files/images/firmware/X8.png | Bin 0 -> 42226 bytes files/images/firmware/X8_on.png | Bin 0 -> 97409 bytes files/images/firmware/Y6_off.png | Bin 0 -> 34453 bytes files/images/firmware/Y6_on.png | Bin 0 -> 67982 bytes files/images/firmware/apmcopter.png | Bin 0 -> 18050 bytes files/images/firmware/apmplane.png | Bin 0 -> 16805 bytes files/images/firmware/apmrover.png | Bin 0 -> 17585 bytes files/images/firmware/heli.png | Bin 0 -> 6988 bytes files/images/firmware/heli_off.png | Bin 0 -> 23558 bytes files/images/firmware/heli_on.png | Bin 0 -> 33638 bytes files/images/firmware/hexa_off.png | Bin 0 -> 39931 bytes files/images/firmware/hexa_on.png | Bin 0 -> 86172 bytes files/images/firmware/hexaplus.png | Bin 0 -> 25486 bytes files/images/firmware/hexax.png | Bin 0 -> 27058 bytes files/images/firmware/hexay.png | Bin 0 -> 18117 bytes files/images/firmware/octaplus.png | Bin 0 -> 30192 bytes files/images/firmware/octax.png | Bin 0 -> 33230 bytes files/images/firmware/octo_off.png | Bin 0 -> 45119 bytes files/images/firmware/octo_on.png | Bin 0 -> 104867 bytes files/images/firmware/octx.png | Bin 0 -> 25838 bytes files/images/firmware/plane.png | Bin 0 -> 5604 bytes files/images/firmware/plane_off.png | Bin 0 -> 23873 bytes files/images/firmware/plane_on.png | Bin 0 -> 38640 bytes files/images/firmware/quad_T_off.png | Bin 0 -> 36228 bytes files/images/firmware/quad_T_on.png | Bin 0 -> 74315 bytes files/images/firmware/quad_off.png | Bin 0 -> 33111 bytes files/images/firmware/quad_on.png | Bin 0 -> 64898 bytes files/images/firmware/quadplus.png | Bin 0 -> 18387 bytes files/images/firmware/quadx.png | Bin 0 -> 18122 bytes files/images/firmware/quady.png | Bin 0 -> 23602 bytes files/images/firmware/rover.png | Bin 0 -> 13576 bytes files/images/firmware/rover_off.png | Bin 0 -> 30490 bytes files/images/firmware/rover_on.png | Bin 0 -> 59171 bytes files/images/firmware/triy.png | Bin 0 -> 15037 bytes qgroundcontrol.pro | 13 +- qgroundcontrol.qrc | 37 + src/ui/configuration/ApmFirmwareConfig.cc | 412 + src/ui/configuration/ApmFirmwareConfig.h | 55 + src/ui/configuration/ApmFirmwareConfig.ui | 446 + src/ui/configuration/ApmFirmwareStatus.cc | 30 + src/ui/configuration/ApmFirmwareStatus.h | 23 + src/ui/configuration/ApmFirmwareStatus.ui | 68 + src/ui/configuration/ApmHardwareConfig.cc | 6 +- src/ui/configuration/ApmHardwareConfig.h | 2 + 50 files changed, 18571 insertions(+), 7 deletions(-) create mode 100644 avrdude/avrdude.conf create mode 100644 avrdude/avrdude.exe create mode 100644 avrdude/libusb0.dll create mode 100644 files/images/firmware/FW icons 2013+logos.ai create mode 100644 files/images/firmware/Tir_off.png create mode 100644 files/images/firmware/Tir_on.png create mode 100644 files/images/firmware/X8.png create mode 100644 files/images/firmware/X8_on.png create mode 100644 files/images/firmware/Y6_off.png create mode 100644 files/images/firmware/Y6_on.png create mode 100644 files/images/firmware/apmcopter.png create mode 100644 files/images/firmware/apmplane.png create mode 100644 files/images/firmware/apmrover.png create mode 100644 files/images/firmware/heli.png create mode 100644 files/images/firmware/heli_off.png create mode 100644 files/images/firmware/heli_on.png create mode 100644 files/images/firmware/hexa_off.png create mode 100644 files/images/firmware/hexa_on.png create mode 100644 files/images/firmware/hexaplus.png create mode 100644 files/images/firmware/hexax.png create mode 100644 files/images/firmware/hexay.png create mode 100644 files/images/firmware/octaplus.png create mode 100644 files/images/firmware/octax.png create mode 100644 files/images/firmware/octo_off.png create mode 100644 files/images/firmware/octo_on.png create mode 100644 files/images/firmware/octx.png create mode 100644 files/images/firmware/plane.png create mode 100644 files/images/firmware/plane_off.png create mode 100644 files/images/firmware/plane_on.png create mode 100644 files/images/firmware/quad_T_off.png create mode 100644 files/images/firmware/quad_T_on.png create mode 100644 files/images/firmware/quad_off.png create mode 100644 files/images/firmware/quad_on.png create mode 100644 files/images/firmware/quadplus.png create mode 100644 files/images/firmware/quadx.png create mode 100644 files/images/firmware/quady.png create mode 100644 files/images/firmware/rover.png create mode 100644 files/images/firmware/rover_off.png create mode 100644 files/images/firmware/rover_on.png create mode 100644 files/images/firmware/triy.png create mode 100644 src/ui/configuration/ApmFirmwareConfig.cc create mode 100644 src/ui/configuration/ApmFirmwareConfig.h create mode 100644 src/ui/configuration/ApmFirmwareConfig.ui create mode 100644 src/ui/configuration/ApmFirmwareStatus.cc create mode 100644 src/ui/configuration/ApmFirmwareStatus.h create mode 100644 src/ui/configuration/ApmFirmwareStatus.ui diff --git a/avrdude/avrdude.conf b/avrdude/avrdude.conf new file mode 100644 index 0000000000..8883bd12e8 --- /dev/null +++ b/avrdude/avrdude.conf @@ -0,0 +1,15478 @@ +# $Id: avrdude.conf.in 916 2010-01-15 16:36:13Z joerg_wunsch $ +# +# AVRDUDE Configuration File +# +# This file contains configuration data used by AVRDUDE which describes +# the programming hardware pinouts and also provides part definitions. +# AVRDUDE's "-C" command line option specifies the location of the +# configuration file. The "-c" option names the programmer configuration +# which must match one of the entry's "id" parameter. The "-p" option +# identifies which part AVRDUDE is going to be programming and must match +# one of the parts' "id" parameter. +# +# Possible entry formats are: +# +# programmer +# id = [, [, ] ...] ; # are quoted strings +# desc = ; # quoted string +# type = par | stk500 | stk500v2 | stk500pp | stk500hvsp | stk500generic | +# stk600 | stk600pp | stk600hvsp | +# avr910 | butterfly | usbasp | +# jtagmki | jtagmkii | jtagmkii_isp | jtagmkii_dw | +# jtagmkII_avr32 | jtagmkii_pdi | +# dragon_dw | dragon_jtag | dragon_isp | dragon_pp | +# dragon_hvsp | dragon_pdi | arduino; # programmer type +# baudrate = ; # baudrate for avr910-programmer +# vcc = [, ... ] ; # pin number(s) +# reset = ; # pin number +# sck = ; # pin number +# mosi = ; # pin number +# miso = ; # pin number +# errled = ; # pin number +# rdyled = ; # pin number +# pgmled = ; # pin number +# vfyled = ; # pin number +# ; +# +# part +# id = ; # quoted string +# desc = ; # quoted string +# has_jtag = ; # part has JTAG i/f +# has_debugwire = ; # part has debugWire i/f +# has_pdi = ; # part has PDI i/f +# has_tpi = ; # part has TPI i/f +# devicecode = ; # deprecated, use stk500_devcode +# stk500_devcode = ; # numeric +# avr910_devcode = ; # numeric +# signature = ; # signature bytes +# chip_erase_delay = ; # micro-seconds +# reset = dedicated | io; +# retry_pulse = reset | sck; +# pgm_enable = ; +# chip_erase = ; +# chip_erase_delay = ; # chip erase delay (us) +# # STK500 parameters (parallel programming IO lines) +# pagel = ; # pin name in hex, i.e., 0xD7 +# bs2 = ; # pin name in hex, i.e., 0xA0 +# serial = ; # can use serial downloading +# parallel = ; # can use par. programming +# # STK500v2 parameters, to be taken from Atmel's XML files +# timeout = ; +# stabdelay = ; +# cmdexedelay = ; +# synchloops = ; +# bytedelay = ; +# pollvalue = ; +# pollindex = ; +# predelay = ; +# postdelay = ; +# pollmethod = ; +# mode = ; +# delay = ; +# blocksize = ; +# readsize = ; +# hvspcmdexedelay = ; +# # STK500v2 HV programming parameters, from XML +# pp_controlstack = , , ...; # PP only +# hvsp_controlstack = , , ...; # HVSP only +# hventerstabdelay = ; +# progmodedelay = ; # PP only +# latchcycles = ; +# togglevtg = ; +# poweroffdelay = ; +# resetdelayms = ; +# resetdelayus = ; +# hvleavestabdelay = ; +# resetdelay = ; +# synchcycles = ; # HVSP only +# chiperasepulsewidth = ; # PP only +# chiperasepolltimeout = ; +# chiperasetime = ; # HVSP only +# programfusepulsewidth = ; # PP only +# programfusepolltimeout = ; +# programlockpulsewidth = ; # PP only +# programlockpolltimeout = ; +# # JTAG ICE mkII parameters, also from XML files +# allowfullpagebitstream = ; +# enablepageprogramming = ; +# idr = ; # IO addr of IDR (OCD) reg. +# rampz = ; # IO addr of RAMPZ reg. +# spmcr = ; # mem addr of SPMC[S]R reg. +# eecr = ; # mem addr of EECR reg. +# # (only when != 0x3c) +# is_avr32 = ; # AVR32 part +# +# memory +# paged = ; # yes / no +# size = ; # bytes +# page_size = ; # bytes +# num_pages = ; # numeric +# min_write_delay = ; # micro-seconds +# max_write_delay = ; # micro-seconds +# readback_p1 = ; # byte value +# readback_p2 = ; # byte value +# pwroff_after_write = ; # yes / no +# read = ; +# write = ; +# read_lo = ; +# read_hi = ; +# write_lo = ; +# write_hi = ; +# loadpage_lo = ; +# loadpage_hi = ; +# writepage = ; +# ; +# ; +# +# If any of the above parameters are not specified, the default value +# of 0 is used for numerics or the empty string ("") for string +# values. If a required parameter is left empty, AVRDUDE will +# complain. +# +# NOTES: +# * 'devicecode' is the device code used by the STK500 (see codes +# listed below) +# * Not all memory types will implement all instructions. +# * AVR Fuse bits and Lock bits are implemented as a type of memory. +# * Example memory types are: +# "flash", "eeprom", "fuse", "lfuse" (low fuse), "hfuse" (high +# fuse), "signature", "calibration", "lock" +# * The memory type specified on the avrdude command line must match +# one of the memory types defined for the specified chip. +# * The pwroff_after_write flag causes avrdude to attempt to +# power the device off and back on after an unsuccessful write to +# the affected memory area if VCC programmer pins are defined. If +# VCC pins are not defined for the programmer, a message +# indicating that the device needs a power-cycle is printed out. +# This flag was added to work around a problem with the +# at90s4433/2333's; see the at90s4433 errata at: +# +# http://www.atmel.com/atmel/acrobat/doc1280.pdf +# +# INSTRUCTION FORMATS +# +# Instruction formats are specified as a comma seperated list of +# string values containing information (bit specifiers) about each +# of the 32 bits of the instruction. Bit specifiers may be one of +# the following formats: +# +# '1' = the bit is always set on input as well as output +# +# '0' = the bit is always clear on input as well as output +# +# 'x' = the bit is ignored on input and output +# +# 'a' = the bit is an address bit, the bit-number matches this bit +# specifier's position within the current instruction byte +# +# 'aN' = the bit is the Nth address bit, bit-number = N, i.e., a12 +# is address bit 12 on input, a0 is address bit 0. +# +# 'i' = the bit is an input data bit +# +# 'o' = the bit is an output data bit +# +# Each instruction must be composed of 32 bit specifiers. The +# instruction specification closely follows the instruction data +# provided in Atmel's data sheets for their parts. +# +# See below for some examples. +# +# +# The following are STK500 part device codes to use for the +# "devicecode" field of the part. These came from Atmel's software +# section avr061.zip which accompanies the application note +# AVR061 available from: +# +# http://www.atmel.com/atmel/acrobat/doc2525.pdf +# + +#define ATTINY10 0x10 /* the _old_ one that never existed! */ +#define ATTINY11 0x11 +#define ATTINY12 0x12 +#define ATTINY15 0x13 +#define ATTINY13 0x14 + +#define ATTINY22 0x20 +#define ATTINY26 0x21 +#define ATTINY28 0x22 +#define ATTINY2313 0x23 + +#define AT90S1200 0x33 + +#define AT90S2313 0x40 +#define AT90S2323 0x41 +#define AT90S2333 0x42 +#define AT90S2343 0x43 + +#define AT90S4414 0x50 +#define AT90S4433 0x51 +#define AT90S4434 0x52 +#define ATMEGA48 0x59 + +#define AT90S8515 0x60 +#define AT90S8535 0x61 +#define AT90C8534 0x62 +#define ATMEGA8515 0x63 +#define ATMEGA8535 0x64 + +#define ATMEGA8 0x70 +#define ATMEGA88 0x73 +#define ATMEGA168 0x86 + +#define ATMEGA161 0x80 +#define ATMEGA163 0x81 +#define ATMEGA16 0x82 +#define ATMEGA162 0x83 +#define ATMEGA169 0x84 + +#define ATMEGA323 0x90 +#define ATMEGA32 0x91 + +#define ATMEGA64 0xA0 + +#define ATMEGA103 0xB1 +#define ATMEGA128 0xB2 +#define AT90CAN128 0xB3 +#define AT90CAN64 0xB3 +#define AT90CAN32 0xB3 + +#define AT86RF401 0xD0 + +#define AT89START 0xE0 +#define AT89S51 0xE0 +#define AT89S52 0xE1 + +# The following table lists the devices in the original AVR910 +# appnote: +# |Device |Signature | Code | +# +-------+----------+------+ +# |tiny12 | 1E 90 05 | 0x55 | +# |tiny15 | 1E 90 06 | 0x56 | +# | | | | +# | S1200 | 1E 90 01 | 0x13 | +# | | | | +# | S2313 | 1E 91 01 | 0x20 | +# | S2323 | 1E 91 02 | 0x48 | +# | S2333 | 1E 91 05 | 0x34 | +# | S2343 | 1E 91 03 | 0x4C | +# | | | | +# | S4414 | 1E 92 01 | 0x28 | +# | S4433 | 1E 92 03 | 0x30 | +# | S4434 | 1E 92 02 | 0x6C | +# | | | | +# | S8515 | 1E 93 01 | 0x38 | +# | S8535 | 1E 93 03 | 0x68 | +# | | | | +# |mega32 | 1E 95 01 | 0x72 | +# |mega83 | 1E 93 05 | 0x65 | +# |mega103| 1E 97 01 | 0x41 | +# |mega161| 1E 94 01 | 0x60 | +# |mega163| 1E 94 02 | 0x64 | + +# Appnote AVR109 also has a table of AVR910 device codes, which +# lists: +# dev avr910 signature +# ATmega8 0x77 0x1E 0x93 0x07 +# ATmega8515 0x3B 0x1E 0x93 0x06 +# ATmega8535 0x6A 0x1E 0x93 0x08 +# ATmega16 0x75 0x1E 0x94 0x03 +# ATmega162 0x63 0x1E 0x94 0x04 +# ATmega163 0x66 0x1E 0x94 0x02 +# ATmega169 0x79 0x1E 0x94 0x05 +# ATmega32 0x7F 0x1E 0x95 0x02 +# ATmega323 0x73 0x1E 0x95 0x01 +# ATmega64 0x46 0x1E 0x96 0x02 +# ATmega128 0x44 0x1E 0x97 0x02 +# +# These codes refer to "BOOT" device codes which are apparently +# different than standard device codes, for whatever reasons +# (often one above the standard code). + +# There are several extended versions of AVR910 implementations around +# in the Internet. These add the following codes (only devices that +# actually exist are listed): + +# ATmega8515 0x3A +# ATmega128 0x43 +# ATmega64 0x45 +# ATtiny26 0x5E +# ATmega8535 0x69 +# ATmega32 0x72 +# ATmega16 0x74 +# ATmega8 0x76 +# ATmega169 0x78 + +# +# Overall avrdude defaults +# +default_parallel = "lpt1"; +default_serial = "com1"; + + +# +# PROGRAMMER DEFINITIONS +# + +programmer + id = "arduino"; + desc = "Arduino"; + type = arduino; +; + +programmer + id = "avrisp"; + desc = "Atmel AVR ISP"; + type = stk500; +; + +programmer + id = "avrispv2"; + desc = "Atmel AVR ISP V2"; + type = stk500v2; +; + +programmer + id = "avrispmkII"; + desc = "Atmel AVR ISP mkII"; + type = stk500v2; +; + +programmer + id = "avrisp2"; + desc = "Atmel AVR ISP mkII"; + type = stk500v2; +; + +programmer + id = "buspirate"; + desc = "The Bus Pirate"; + type = buspirate; +; + +# This is supposed to be the "default" STK500 entry. +# Attempts to select the correct firmware version +# by probing for it. Better use one of the entries +# below instead. +programmer + id = "stk500"; + desc = "Atmel STK500"; + type = stk500generic; +; + +programmer + id = "stk500v1"; + desc = "Atmel STK500 Version 1.x firmware"; + type = stk500; +; + +programmer + id = "mib510"; + desc = "Crossbow MIB510 programming board"; + type = stk500; +; + +programmer + id = "stk500v2"; + desc = "Atmel STK500 Version 2.x firmware"; + type = stk500v2; +; + +programmer + id = "stk500pp"; + desc = "Atmel STK500 V2 in parallel programming mode"; + type = stk500pp; +; + +programmer + id = "stk500hvsp"; + desc = "Atmel STK500 V2 in high-voltage serial programming mode"; + type = stk500hvsp; +; + +programmer + id = "stk600"; + desc = "Atmel STK600"; + type = stk600; +; + +programmer + id = "stk600pp"; + desc = "Atmel STK600 in parallel programming mode"; + type = stk600pp; +; + +programmer + id = "stk600hvsp"; + desc = "Atmel STK600 in high-voltage serial programming mode"; + type = stk600hvsp; +; + +programmer + id = "avr910"; + desc = "Atmel Low Cost Serial Programmer"; + type = avr910; +; + +programmer + id = "usbasp"; + desc = "USBasp, http://www.fischl.de/usbasp/"; + type = usbasp; +; + +programmer + id = "usbtiny"; + desc = "USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/"; + type = usbtiny; +; + +programmer + id = "butterfly"; + desc = "Atmel Butterfly Development Board"; + type = butterfly; +; + +programmer + id = "avr109"; + desc = "Atmel AppNote AVR109 Boot Loader"; + type = butterfly; +; + +programmer + id = "avr911"; + desc = "Atmel AppNote AVR911 AVROSP"; + type = butterfly; +; + +programmer + id = "jtagmkI"; + desc = "Atmel JTAG ICE (mkI)"; + baudrate = 115200; # default is 115200 + type = jtagmki; +; + +# easier to type +programmer + id = "jtag1"; + desc = "Atmel JTAG ICE (mkI)"; + baudrate = 115200; # default is 115200 + type = jtagmki; +; + +# easier to type +programmer + id = "jtag1slow"; + desc = "Atmel JTAG ICE (mkI)"; + baudrate = 19200; + type = jtagmki; +; + +programmer + id = "jtagmkII"; + desc = "Atmel JTAG ICE mkII"; + baudrate = 19200; # default is 19200 + type = jtagmkii; +; + +# easier to type +programmer + id = "jtag2slow"; + desc = "Atmel JTAG ICE mkII"; + baudrate = 19200; # default is 19200 + type = jtagmkii; +; + +# JTAG ICE mkII @ 115200 Bd +programmer + id = "jtag2fast"; + desc = "Atmel JTAG ICE mkII"; + baudrate = 115200; + type = jtagmkii; +; + +# make the fast one the default, people will love that +programmer + id = "jtag2"; + desc = "Atmel JTAG ICE mkII"; + baudrate = 115200; + type = jtagmkii; +; + +# JTAG ICE mkII in ISP mode +programmer + id = "jtag2isp"; + desc = "Atmel JTAG ICE mkII in ISP mode"; + baudrate = 115200; + type = jtagmkii_isp; +; + +# JTAG ICE mkII in debugWire mode +programmer + id = "jtag2dw"; + desc = "Atmel JTAG ICE mkII in debugWire mode"; + baudrate = 115200; + type = jtagmkii_dw; +; + +# JTAG ICE mkII in AVR32 mode +programmer + id = "jtagmkII_avr32"; + desc = "Atmel JTAG ICE mkII im AVR32 mode"; + baudrate = 115200; + type = jtagmkii_avr32; +; + +# JTAG ICE mkII in AVR32 mode +programmer + id = "jtag2avr32"; + desc = "Atmel JTAG ICE mkII im AVR32 mode"; + baudrate = 115200; + type = jtagmkii_avr32; +; + +# JTAG ICE mkII in PDI mode +programmer + id = "jtag2pdi"; + desc = "Atmel JTAG ICE mkII PDI mode"; + baudrate = 115200; + type = jtagmkii_pdi; +; + +# AVR Dragon in JTAG mode +programmer + id = "dragon_jtag"; + desc = "Atmel AVR Dragon in JTAG mode"; + baudrate = 115200; + type = dragon_jtag; +; + +# AVR Dragon in ISP mode +programmer + id = "dragon_isp"; + desc = "Atmel AVR Dragon in ISP mode"; + baudrate = 115200; + type = dragon_isp; +; + +# AVR Dragon in PP mode +programmer + id = "dragon_pp"; + desc = "Atmel AVR Dragon in PP mode"; + baudrate = 115200; + type = dragon_pp; +; + +# AVR Dragon in HVSP mode +programmer + id = "dragon_hvsp"; + desc = "Atmel AVR Dragon in HVSP mode"; + baudrate = 115200; + type = dragon_hvsp; +; + +# AVR Dragon in debugWire mode +programmer + id = "dragon_dw"; + desc = "Atmel AVR Dragon in debugWire mode"; + baudrate = 115200; + type = dragon_dw; +; + +# AVR Dragon in PDI mode +programmer + id = "dragon_pdi"; + desc = "Atmel AVR Dragon in PDI mode"; + baudrate = 115200; + type = dragon_pdi; +; + +programmer + id = "pavr"; + desc = "Jason Kyle's pAVR Serial Programmer"; + type = avr910; +; + +# Parallel port programmers. + +programmer + id = "bsd"; + desc = "Brian Dean's Programmer, http://www.bsdhome.com/avrdude/"; + type = par; + vcc = 2, 3, 4, 5; + reset = 7; + sck = 8; + mosi = 9; + miso = 10; +; + +programmer + id = "stk200"; + desc = "STK200"; + type = par; + buff = 4, 5; + sck = 6; + mosi = 7; + reset = 9; + miso = 10; +; + +# The programming dongle used by the popular Ponyprog +# utility. It is almost similar to the STK200 one, +# except that there is a LED indicating that the +# programming is currently in progress. + +programmer + id = "pony-stk200"; + desc = "Pony Prog STK200"; + type = par; + buff = 4, 5; + sck = 6; + mosi = 7; + reset = 9; + miso = 10; + pgmled = 8; +; + +programmer + id = "dt006"; + desc = "Dontronics DT006"; + type = par; + reset = 4; + sck = 5; + mosi = 2; + miso = 11; +; + +programmer + id = "bascom"; + desc = "Bascom SAMPLE programming cable"; + type = par; + reset = 4; + sck = 5; + mosi = 2; + miso = 11; +; + +programmer + id = "alf"; + desc = "Nightshade ALF-PgmAVR, http://nightshade.homeip.net/"; + type = par; + vcc = 2, 3, 4, 5; + buff = 6; + reset = 7; + sck = 8; + mosi = 9; + miso = 10; + errled = 1; + rdyled = 14; + pgmled = 16; + vfyled = 17; +; + +programmer + id = "sp12"; + desc = "Steve Bolt's Programmer"; + type = par; + vcc = 4,5,6,7,8; + reset = 3; + sck = 2; + mosi = 9; + miso = 11; +; + +programmer + id = "picoweb"; + desc = "Picoweb Programming Cable, http://www.picoweb.net/"; + type = par; + reset = 2; + sck = 3; + mosi = 4; + miso = 13; +; + +programmer + id = "abcmini"; + desc = "ABCmini Board, aka Dick Smith HOTCHIP"; + type = par; + reset = 4; + sck = 3; + mosi = 2; + miso = 10; +; + +programmer + id = "futurlec"; + desc = "Futurlec.com programming cable."; + type = par; + reset = 3; + sck = 2; + mosi = 1; + miso = 10; +; + + +# From the contributor of the "xil" jtag cable: +# The "vcc" definition isn't really vcc (the cable gets its power from +# the programming circuit) but is necessary to switch one of the +# buffer lines (trying to add it to the "buff" lines doesn't work). +# With this, TMS connects to RESET, TDI to MOSI, TDO to MISO and TCK +# to SCK (plus vcc/gnd of course) +programmer + id = "xil"; + desc = "Xilinx JTAG cable"; + type = par; + mosi = 2; + sck = 3; + reset = 4; + buff = 5; + miso = 13; + vcc = 6; +; + + +programmer + id = "dapa"; + desc = "Direct AVR Parallel Access cable"; + type = par; + vcc = 3; + reset = 16; + sck = 1; + mosi = 2; + miso = 11; +; + +programmer + id = "atisp"; + desc = "AT-ISP V1.1 programming cable for AVR-SDK1 from micro-research.co.th"; + type = par; + reset = ~6; + sck = ~8; + mosi = ~7; + miso = ~10; +; + +programmer + id = "ere-isp-avr"; + desc = "ERE ISP-AVR "; + type = par; + reset = ~4; + sck = 3; + mosi = 2; + miso = 10; +; + +programmer + id = "blaster"; + desc = "Altera ByteBlaster"; + type = par; + sck = 2; + miso = 11; + reset = 3; + mosi = 8; + buff = 14; +; + +# It is almost same as pony-stk200, except vcc on pin 5 to auto +# disconnect port (download on http://electropol.free.fr) +programmer + id = "frank-stk200"; + desc = "Frank STK200"; + type = par; + vcc = 5; + sck = 6; + mosi = 7; + reset = 9; + miso = 10; + pgmled = 8; +; + +# The AT98ISP Cable is a simple parallel dongle for AT89 family. +# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2877 +programmer +id = "89isp"; +desc = "Atmel at89isp cable"; +type = par; +reset = 17; +sck = 1; +mosi = 2; +miso = 10; +; + + +# +# some ultra cheap programmers use bitbanging on the +# serialport. +# +# PC - DB9 - Pins for RS232: +# +# GND 5 -- |O +# | O| <- 9 RI +# DTR 4 <- |O | +# | O| <- 8 CTS +# TXD 3 <- |O | +# | O| -> 7 RTS +# RXD 2 -> |O | +# | O| <- 6 DSR +# DCD 1 -> |O +# +# Using RXD is currently not supported. +# Using RI is not supported under Win32 but is supported under Posix. + +# serial ponyprog design (dasa2 in uisp) +# reset=!txd sck=rts mosi=dtr miso=cts + +programmer + id = "ponyser"; + desc = "design ponyprog serial, reset=!txd sck=rts mosi=dtr miso=cts"; + type = serbb; + reset = ~3; + sck = 7; + mosi = 4; + miso = 8; +; + +# Same as above, different name +# reset=!txd sck=rts mosi=dtr miso=cts + +programmer + id = "siprog"; + desc = "Lancos SI-Prog "; + type = serbb; + reset = ~3; + sck = 7; + mosi = 4; + miso = 8; +; + +# unknown (dasa in uisp) +# reset=rts sck=dtr mosi=txd miso=cts + +programmer + id = "dasa"; + desc = "serial port banging, reset=rts sck=dtr mosi=txd miso=cts"; + type = serbb; + reset = 7; + sck = 4; + mosi = 3; + miso = 8; +; + +# unknown (dasa3 in uisp) +# reset=!dtr sck=rts mosi=txd miso=cts + +programmer + id = "dasa3"; + desc = "serial port banging, reset=!dtr sck=rts mosi=txd miso=cts"; + type = serbb; + reset = ~4; + sck = 7; + mosi = 3; + miso = 8; +; + +# C2N232i (jumper configuration "auto") +# reset=dtr sck=!rts mosi=!txd miso=!cts + +programmer + id = "c2n232i"; + desc = "serial port banging, reset=dtr sck=!rts mosi=!txd miso=!cts"; + type = serbb; + reset = 4; + sck = ~7; + mosi = ~3; + miso = ~8; +; + +# +# PART DEFINITIONS +# + +#------------------------------------------------------------ +# ATtiny11 +#------------------------------------------------------------ + +# This is an HVSP-only device. + +part + id = "t11"; + desc = "ATtiny11"; + stk500_devcode = 0x11; + signature = 0x1e 0x90 0x04; + chip_erase_delay = 20000; + + timeout = 200; + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 64; + blocksize = 64; + readsize = 256; + delay = 5; + ; + + memory "flash" + size = 1024; + blocksize = 128; + readsize = 256; + delay = 3; + ; + + memory "signature" + size = 3; + ; + + memory "lock" + size = 1; + ; + + memory "calibration" + size = 1; + ; + + memory "fuse" + size = 1; + ; +; + +#------------------------------------------------------------ +# ATtiny12 +#------------------------------------------------------------ + +part + id = "t12"; + desc = "ATtiny12"; + stk500_devcode = 0x12; + avr910_devcode = 0x55; + signature = 0x1e 0x90 0x05; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 64; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 8; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + size = 1024; + min_write_delay = 4500; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 5; + blocksize = 128; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; +; + +#------------------------------------------------------------ +# ATtiny13 +#------------------------------------------------------------ + +part + id = "t13"; + desc = "ATtiny13"; + has_debugwire = yes; + flash_instr = 0xB4, 0x0E, 0x1E; + eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x0E, 0xB4, 0x0E, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x14; + signature = 0x1e 0x90 0x07; + chip_erase_delay = 4000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 90; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 64; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 1024; + page_size = 32; + num_pages = 32; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny15 +#------------------------------------------------------------ + +part + id = "t15"; + desc = "ATtiny15"; + stk500_devcode = 0x13; + avr910_devcode = 0x56; + signature = 0x1e 0x90 0x06; + chip_erase_delay = 8200; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 5; + synchcycles = 6; + latchcycles = 16; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 64; + min_write_delay = 8200; + max_write_delay = 8200; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + size = 1024; + min_write_delay = 4100; + max_write_delay = 4100; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 5; + blocksize = 128; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x o o o o x x o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x i i i i 1 1 i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; +; + +#------------------------------------------------------------ +# AT90s1200 +#------------------------------------------------------------ + +part + id = "1200"; + desc = "AT90S1200"; + stk500_devcode = 0x33; + avr910_devcode = 0x13; + signature = 0x1e 0x90 0x01; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 1; + bytedelay = 0; + pollindex = 0; + pollvalue = 0xFF; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 64; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 32; + readsize = 256; + ; + memory "flash" + size = 1024; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x02; + delay = 15; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s4414 +#------------------------------------------------------------ + +part + id = "4414"; + desc = "AT90S4414"; + stk500_devcode = 0x50; + avr910_devcode = 0x28; + signature = 0x1e 0x92 0x01; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# AT90s2313 +#------------------------------------------------------------ + +part + id = "2313"; + desc = "AT90S2313"; + stk500_devcode = 0x40; + avr910_devcode = 0x20; + signature = 0x1e 0x91 0x01; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 128; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "flash" + size = 2048; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x i i x", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# AT90s2333 +#------------------------------------------------------------ + +part + id = "2333"; +##### WARNING: No XML file for device 'AT90S2333'! ##### + desc = "AT90S2333"; + stk500_devcode = 0x42; + avr910_devcode = 0x34; + signature = 0x1e 0x91 0x05; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + size = 2048; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + pwroff_after_write = yes; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + + +#------------------------------------------------------------ +# AT90s2343 (also AT90s2323 and ATtiny22) +#------------------------------------------------------------ + +part + id = "2343"; + desc = "AT90S2343"; + stk500_devcode = 0x43; + avr910_devcode = 0x4c; + signature = 0x1e 0x91 0x03; + chip_erase_delay = 18000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 0; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "flash" + size = 2048; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 128; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o o x x x x o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o o x x x x o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + + +#------------------------------------------------------------ +# AT90s4433 +#------------------------------------------------------------ + +part + id = "4433"; + desc = "AT90S4433"; + stk500_devcode = 0x51; + avr910_devcode = 0x30; + signature = 0x1e 0x92 0x03; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + pwroff_after_write = yes; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s4434 +#------------------------------------------------------------ + +part + id = "4434"; +##### WARNING: No XML file for device 'AT90S4434'! ##### + desc = "AT90S4434"; + stk500_devcode = 0x52; + avr910_devcode = 0x6c; + signature = 0x1e 0x92 0x02; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s8515 +#------------------------------------------------------------ + +part + id = "8515"; + desc = "AT90S8515"; + stk500_devcode = 0x60; + avr910_devcode = 0x38; + signature = 0x1e 0x93 0x01; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 512; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "flash" + size = 8192; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# AT90s8535 +#------------------------------------------------------------ + +part + id = "8535"; + desc = "AT90S8535"; + stk500_devcode = 0x61; + avr910_devcode = 0x68; + signature = 0x1e 0x93 0x03; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "flash" + size = 8192; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x x o"; + write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o x x x x x x"; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# ATmega103 +#------------------------------------------------------------ + +part + id = "m103"; + desc = "ATMEGA103"; + stk500_devcode = 0xB1; + avr910_devcode = 0x41; + signature = 0x1e 0x97 0x01; + chip_erase_delay = 112000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x8E, 0x9E, 0x2E, 0x3E, 0xAE, 0xBE, + 0x4E, 0x5E, 0xCE, 0xDE, 0x6E, 0x7E, 0xEE, 0xDE, + 0x66, 0x76, 0xE6, 0xF6, 0x6A, 0x7A, 0xEA, 0x7A, + 0x7F, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 10; + + memory "eeprom" + size = 4096; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 22000; + max_write_delay = 56000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x11; + delay = 70; + blocksize = 256; + readsize = 256; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o x o 1 o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 1 i 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega64 +#------------------------------------------------------------ + +part + id = "m64"; + desc = "ATMEGA64"; + has_jtag = yes; + stk500_devcode = 0xA0; + avr910_devcode = 0x45; + signature = 0x1e 0x96 0x02; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x22; + spmcr = 0x68; + allowfullpagebitstream = yes; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + + +#------------------------------------------------------------ +# ATmega128 +#------------------------------------------------------------ + +part + id = "m128"; + desc = "ATMEGA128"; + has_jtag = yes; + stk500_devcode = 0xB2; + avr910_devcode = 0x43; + signature = 0x1e 0x97 0x02; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x22; + spmcr = 0x68; + rampz = 0x3b; + allowfullpagebitstream = yes; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90CAN128 +#------------------------------------------------------------ + +part + id = "c128"; + desc = "AT90CAN128"; + has_jtag = yes; + stk500_devcode = 0xB3; +# avr910_devcode = 0x43; + signature = 0x1e 0x97 0x81; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + eecr = 0x3f; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90CAN64 +#------------------------------------------------------------ + +part + id = "c64"; + desc = "AT90CAN64"; + has_jtag = yes; + stk500_devcode = 0xB3; +# avr910_devcode = 0x43; + signature = 0x1e 0x96 0x81; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + eecr = 0x3f; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90CAN32 +#------------------------------------------------------------ + +part + id = "c32"; + desc = "AT90CAN32"; + has_jtag = yes; + stk500_devcode = 0xB3; +# avr910_devcode = 0x43; + signature = 0x1e 0x95 0x81; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + eecr = 0x3f; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 256; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega16 +#------------------------------------------------------------ + +part + id = "m16"; + desc = "ATMEGA16"; + has_jtag = yes; + stk500_devcode = 0x82; + avr910_devcode = 0x74; + signature = 0x1e 0x94 0x03; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 100; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = yes; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x04; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "calibration" + size = 4; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega164P +#------------------------------------------------------------ + +# close to ATmega16 + +part + id = "m164p"; + desc = "ATMEGA164P"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x94 0x0a; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega324P +#------------------------------------------------------------ + +# similar to ATmega164P + +part + id = "m324p"; + desc = "ATMEGA324P"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x95 0x08; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega644 +#------------------------------------------------------------ + +# similar to ATmega164 + +part + id = "m644"; + desc = "ATMEGA644"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x96 0x09; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega644P +#------------------------------------------------------------ + +# similar to ATmega164p + +part + id = "m644p"; + desc = "ATMEGA644P"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x96 0x0a; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + + + +#------------------------------------------------------------ +# ATmega1284P +#------------------------------------------------------------ + +# similar to ATmega164p + +part + id = "m1284p"; + desc = "ATMEGA1284P"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x97 0x05; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + + + +#------------------------------------------------------------ +# ATmega162 +#------------------------------------------------------------ + +part + id = "m162"; + desc = "ATMEGA162"; + has_jtag = yes; + stk500_devcode = 0x83; + avr910_devcode = 0x63; + signature = 0x1e 0x94 0x04; + chip_erase_delay = 9000; + pagel = 0xd7; + bs2 = 0xa0; + + idr = 0x04; + spmcr = 0x57; + allowfullpagebitstream = yes; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + + ; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + + read = "0 0 1 1 0 0 0 0 0 0 x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; +; + + + +#------------------------------------------------------------ +# ATmega163 +#------------------------------------------------------------ + +part + id = "m163"; + desc = "ATMEGA163"; + stk500_devcode = 0x81; + avr910_devcode = 0x64; + signature = 0x1e 0x94 0x02; + chip_erase_delay = 32000; + pagel = 0xd7; + bs2 = 0xa0; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 30; + programfusepulsewidth = 0; + programfusepolltimeout = 2; + programlockpulsewidth = 0; + programlockpolltimeout = 2; + + + memory "eeprom" + size = 512; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 16000; + max_write_delay = 16000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x11; + delay = 20; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o x x o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i 1 1 i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x x 1 o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x 0 x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega169 +#------------------------------------------------------------ + +part + id = "m169"; + desc = "ATMEGA169"; + has_jtag = yes; + stk500_devcode = 0x85; + avr910_devcode = 0x78; + signature = 0x1e 0x94 0x05; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega329 +#------------------------------------------------------------ + +part + id = "m329"; + desc = "ATMEGA329"; + has_jtag = yes; +# stk500_devcode = 0x85; # no STK500 support, only STK500v2 +# avr910_devcode = 0x?; # try the ATmega169 one: + avr910_devcode = 0x75; + signature = 0x1e 0x95 0x03; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega329P +#------------------------------------------------------------ +# Identical to ATmega329 except of the signature + +part + id = "m329p"; + desc = "ATMEGA329P"; + has_jtag = yes; +# stk500_devcode = 0x85; # no STK500 support, only STK500v2 +# avr910_devcode = 0x?; # try the ATmega169 one: + avr910_devcode = 0x75; + signature = 0x1e 0x95 0x0b; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega3290 +#------------------------------------------------------------ + +# identical to ATmega329 + +part + id = "m3290"; + desc = "ATMEGA3290"; + has_jtag = yes; +# stk500_devcode = 0x85; # no STK500 support, only STK500v2 +# avr910_devcode = 0x?; # try the ATmega169 one: + avr910_devcode = 0x75; + signature = 0x1e 0x95 0x04; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a3 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega3290P +#------------------------------------------------------------ + +# identical to ATmega3290 except of the signature + +part + id = "m3290p"; + desc = "ATMEGA3290P"; + has_jtag = yes; +# stk500_devcode = 0x85; # no STK500 support, only STK500v2 +# avr910_devcode = 0x?; # try the ATmega169 one: + avr910_devcode = 0x75; + signature = 0x1e 0x95 0x0c; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a3 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega649 +#------------------------------------------------------------ + +part + id = "m649"; + desc = "ATMEGA649"; + has_jtag = yes; +# stk500_devcode = 0x85; # no STK500 support, only STK500v2 +# avr910_devcode = 0x?; # try the ATmega169 one: + avr910_devcode = 0x75; + signature = 0x1e 0x96 0x03; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega6490 +#------------------------------------------------------------ + +# identical to ATmega649 + +part + id = "m6490"; + desc = "ATMEGA6490"; + has_jtag = yes; +# stk500_devcode = 0x85; # no STK500 support, only STK500v2 +# avr910_devcode = 0x?; # try the ATmega169 one: + avr910_devcode = 0x75; + signature = 0x1e 0x96 0x04; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega32 +#------------------------------------------------------------ + +part + id = "m32"; + desc = "ATMEGA32"; + has_jtag = yes; + stk500_devcode = 0x91; + avr910_devcode = 0x72; + signature = 0x1e 0x95 0x02; + chip_erase_delay = 9000; + pagel = 0xd7; + bs2 = 0xa0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = yes; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x04; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega161 +#------------------------------------------------------------ + +part + id = "m161"; + desc = "ATMEGA161"; + stk500_devcode = 0x80; + avr910_devcode = 0x60; + signature = 0x1e 0x94 0x01; + chip_erase_delay = 28000; + pagel = 0xd7; + bs2 = 0xa0; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 30; + programfusepulsewidth = 0; + programfusepolltimeout = 2; + programlockpulsewidth = 0; + programlockpolltimeout = 2; + + memory "eeprom" + size = 512; + min_write_delay = 3400; + max_write_delay = 3400; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 5; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 14000; + max_write_delay = 14000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 16; + blocksize = 128; + readsize = 256; + ; + + memory "fuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x o x o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x 1 i 1 i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega8 +#------------------------------------------------------------ + +part + id = "m8"; + desc = "ATMEGA8"; + stk500_devcode = 0x70; + avr910_devcode = 0x76; + signature = 0x1e 0x93 0x07; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 10000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + page_size = 4; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 128; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + +#------------------------------------------------------------ +# ATmega8515 +#------------------------------------------------------------ + +part + id = "m8515"; + desc = "ATMEGA8515"; + stk500_devcode = 0x63; + avr910_devcode = 0x3A; + signature = 0x1e 0x93 0x06; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 10; + blocksize = 128; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + + +#------------------------------------------------------------ +# ATmega8535 +#------------------------------------------------------------ + +part + id = "m8535"; + desc = "ATMEGA8535"; + stk500_devcode = 0x64; + avr910_devcode = 0x69; + signature = 0x1e 0x93 0x08; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 10; + blocksize = 128; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATtiny26 +#------------------------------------------------------------ + +part + id = "t26"; + desc = "ATTINY26"; + stk500_devcode = 0x21; + avr910_devcode = 0x5e; + signature = 0x1e 0x91 0x09; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 16; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x x x x i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny261 +#------------------------------------------------------------ +# Close to ATtiny26 + +part + id = "t261"; + desc = "ATTINY261"; + has_debugwire = yes; + flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +# stk500_devcode = 0x21; +# avr910_devcode = 0x5e; + signature = 0x1e 0x91 0x0c; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 4000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; + size = 128; + page_size = 4; + num_pages = 32; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x x x x x o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny461 +#------------------------------------------------------------ +# Close to ATtiny261 + +part + id = "t461"; + desc = "ATTINY461"; + has_debugwire = yes; + flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +# stk500_devcode = 0x21; +# avr910_devcode = 0x5e; + signature = 0x1e 0x92 0x08; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 4000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; + size = 256; + page_size = 4; + num_pages = 64; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x x x x x o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny861 +#------------------------------------------------------------ +# Close to ATtiny461 + +part + id = "t861"; + desc = "ATTINY861"; + has_debugwire = yes; + flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +# stk500_devcode = 0x21; +# avr910_devcode = 0x5e; + signature = 0x1e 0x93 0x0d; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 4000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; + size = 512; + num_pages = 128; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x x x x x o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATmega48 +#------------------------------------------------------------ + +part + id = "m48"; + desc = "ATMEGA48"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x59; +# avr910_devcode = 0x; + signature = 0x1e 0x92 0x05; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 45000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; + page_size = 4; + size = 256; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x x", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x x x x x o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega88 +#------------------------------------------------------------ + +part + id = "m88"; + desc = "ATMEGA88"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x73; +# avr910_devcode = 0x; + signature = 0x1e 0x93 0x0a; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; + page_size = 4; + size = 512; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x x x o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega168 +#------------------------------------------------------------ + +part + id = "m168"; + desc = "ATMEGA168"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x86; + # avr910_devcode = 0x; + signature = 0x1e 0x94 0x06; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; + page_size = 4; + size = 512; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x x x o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; +; + +#------------------------------------------------------------ +# ATtiny88 +#------------------------------------------------------------ + +part + id = "t88"; + desc = "attiny88"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x73; +# avr910_devcode = 0x; + signature = 0x1e 0x93 0x11; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; + page_size = 4; + size = 64; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 64; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x x x o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega328P +#------------------------------------------------------------ + +part + id = "m328p"; + desc = "ATMEGA328P"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x86; + # avr910_devcode = 0x; + signature = 0x1e 0x95 0x0F; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; + page_size = 4; + size = 1024; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x x x o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; +; + +#------------------------------------------------------------ +# ATtiny2313 +#------------------------------------------------------------ + +part + id = "t2313"; + desc = "ATtiny2313"; + has_debugwire = yes; + flash_instr = 0xB2, 0x0F, 0x1F; + eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x23; +## Use the ATtiny26 devcode: + avr910_devcode = 0x5e; + signature = 0x1e 0x91 0x0a; + pagel = 0xD4; + bs2 = 0xD6; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, + 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, + 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A, + 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 128; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + +# The information in the data sheet of April/2004 is wrong, this works: + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + +# The information in the data sheet of April/2004 is wrong, this works: + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + +# The information in the data sheet of April/2004 is wrong, this works: + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny2313 has Signature Bytes: 0x1E 0x91 0x0A. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; +# The Tiny2313 has calibration data for both 4 MHz and 8 MHz. +# The information in the data sheet of April/2004 is wrong, this works: + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90PWM2 +#------------------------------------------------------------ + +part + id = "pwm2"; + desc = "AT90PWM2"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x65; +## avr910_devcode = ?; + signature = 0x1e 0x93 0x81; + pagel = 0xD8; + bs2 = 0xE2; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; +# AT90PWM2 has Signature Bytes: 0x1E 0x93 0x81. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90PWM3 +#------------------------------------------------------------ + +# Completely identical to AT90PWM2 (including the signature!) + +part + id = "pwm3"; + desc = "AT90PWM3"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x65; +## avr910_devcode = ?; + signature = 0x1e 0x93 0x81; + pagel = 0xD8; + bs2 = 0xE2; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; +# AT90PWM2 has Signature Bytes: 0x1E 0x93 0x81. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90PWM2B +#------------------------------------------------------------ +# Same as AT90PWM2 but different signature. + +part + id = "pwm2b"; + desc = "AT90PWM2B"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x65; +## avr910_devcode = ?; + signature = 0x1e 0x93 0x83; + pagel = 0xD8; + bs2 = 0xE2; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90PWM3B +#------------------------------------------------------------ + +# Completely identical to AT90PWM2B (including the signature!) + +part + id = "pwm3b"; + desc = "AT90PWM3B"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x65; +## avr910_devcode = ?; + signature = 0x1e 0x93 0x83; + pagel = 0xD8; + bs2 = 0xE2; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny25 +#------------------------------------------------------------ + +part + id = "t25"; + desc = "ATtiny25"; + has_debugwire = yes; + flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x91 0x08; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 128; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny25 has Signature Bytes: 0x1E 0x91 0x08. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny45 +#------------------------------------------------------------ + +part + id = "t45"; + desc = "ATtiny45"; + has_debugwire = yes; + flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x92 0x06; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 256; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny45 has Signature Bytes: 0x1E 0x92 0x08. (Data sheet 2586C-AVR-06/05 (doc2586.pdf) indicates otherwise!) + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny85 +#------------------------------------------------------------ + +part + id = "t85"; + desc = "ATtiny85"; + has_debugwire = yes; + flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x93 0x0b; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a8 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny85 has Signature Bytes: 0x1E 0x93 0x08. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega640 +#------------------------------------------------------------ +# Almost same as ATmega1280, except for different memory sizes + +part + id = "m640"; + desc = "ATMEGA640"; + signature = 0x1e 0x96 0x08; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega1280 +#------------------------------------------------------------ + +part + id = "m1280"; + desc = "ATMEGA1280"; + signature = 0x1e 0x97 0x03; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega1281 +#------------------------------------------------------------ +# Identical to ATmega1280 + +part + id = "m1281"; + desc = "ATMEGA1281"; + signature = 0x1e 0x97 0x04; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega2560 +#------------------------------------------------------------ + +part + id = "m2560"; + desc = "ATMEGA2560"; + signature = 0x1e 0x98 0x01; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 262144; + page_size = 256; + num_pages = 1024; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + load_ext_addr = " 0 1 0 0 1 1 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 a16", + " 0 0 0 0 0 0 0 0"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega2561 +#------------------------------------------------------------ + +part + id = "m2561"; + desc = "ATMEGA2561"; + signature = 0x1e 0x98 0x02; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 262144; + page_size = 256; + num_pages = 1024; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + load_ext_addr = " 0 1 0 0 1 1 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 a16", + " 0 0 0 0 0 0 0 0"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega128RFA1 +#------------------------------------------------------------ +# Identical to ATmega2561 but half the ROM + +part + id = "m128rfa1"; + desc = "ATMEGA128RFA1"; + signature = 0x1e 0xa7 0x01; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xE2; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny24 +#------------------------------------------------------------ + +part + id = "t24"; + desc = "ATtiny24"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x91 0x0b; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 70; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 128; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny24 has Signature Bytes: 0x1E 0x91 0x0B. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x x x x x x x i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny44 +#------------------------------------------------------------ + +part + id = "t44"; + desc = "ATtiny44"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x92 0x07; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 70; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 256; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny44 has Signature Bytes: 0x1E 0x92 0x07. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x x x x x x x i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny84 +#------------------------------------------------------------ + +part + id = "t84"; + desc = "ATtiny84"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x93 0x0c; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 70; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a8 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny84 has Signature Bytes: 0x1E 0x93 0x0C. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x x x x x x x i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega32u4 +#------------------------------------------------------------ + +part + id = "m32u4"; + desc = "ATmega32U4"; + signature = 0x1e 0x95 0x87; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB646 +#------------------------------------------------------------ + +part + id = "usb646"; + desc = "AT90USB646"; + signature = 0x1e 0x96 0x82; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB647 +#------------------------------------------------------------ +# identical to AT90USB646 + +part + id = "usb647"; + desc = "AT90USB647"; + signature = 0x1e 0x96 0x82; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB1286 +#------------------------------------------------------------ + +part + id = "usb1286"; + desc = "AT90USB1286"; + signature = 0x1e 0x97 0x82; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB1287 +#------------------------------------------------------------ +# identical to AT90USB1286 + +part + id = "usb1287"; + desc = "AT90USB1287"; + signature = 0x1e 0x97 0x82; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# AT90USB162 +#------------------------------------------------------------ + +part + id = "usb162"; + desc = "AT90USB162"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x94 0x82; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB82 +#------------------------------------------------------------ +# Changes against AT90USB162 (beside IDs) +# memory "flash" +# size = 8192; +# num_pages = 64; + +part + id = "usb82"; + desc = "AT90USB82"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x93 0x82; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 8192; + page_size = 128; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega325 +#------------------------------------------------------------ + +part + id = "m325"; + desc = "ATMEGA325"; + signature = 0x1e 0x95 0x05; + has_jtag = yes; +# stk500_devcode = 0x??; # No STK500v1 support? +# avr910_devcode = 0x??; # Try the ATmega16 one + avr910_devcode = 0x74; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega645 +#------------------------------------------------------------ + +part + id = "m645"; + desc = "ATMEGA645"; + signature = 0x1E 0x96 0x05; + has_jtag = yes; +# stk500_devcode = 0x??; # No STK500v1 support? +# avr910_devcode = 0x??; # Try the ATmega16 one + avr910_devcode = 0x74; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " 0 0 0 0 0 0 0 0"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega3250 +#------------------------------------------------------------ + +part + id = "m3250"; + desc = "ATMEGA3250"; + signature = 0x1E 0x95 0x06; + has_jtag = yes; +# stk500_devcode = 0x??; # No STK500v1 support? +# avr910_devcode = 0x??; # Try the ATmega16 one + avr910_devcode = 0x74; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega6450 +#------------------------------------------------------------ + +part + id = "m6450"; + desc = "ATMEGA6450"; + signature = 0x1E 0x96 0x06; + has_jtag = yes; +# stk500_devcode = 0x??; # No STK500v1 support? +# avr910_devcode = 0x??; # Try the ATmega16 one + avr910_devcode = 0x74; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " 0 0 0 0 0 0 0 0"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATXMEGA64A1 +#------------------------------------------------------------ + +part + id = "x64a1"; + desc = "ATXMEGA64A1"; + signature = 0x1e 0x96 0x4e; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x0800; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00010000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00001000; + offset = 0x0080f000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00001000; + offset = 0x00810000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00011000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + +#------------------------------------------------------------ +# ATXMEGA128A1 +#------------------------------------------------------------ + +part + id = "x128a1"; + desc = "ATXMEGA128A1"; + signature = 0x1e 0x97 0x4c; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x0800; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00020000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00002000; + offset = 0x0081e000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00002000; + offset = 0x00820000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00022000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + +#------------------------------------------------------------ +# ATXMEGA128A1REVD +#------------------------------------------------------------ + +part + id = "x128a1d"; + desc = "ATXMEGA128A1REVD"; + signature = 0x1e 0x97 0x41; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x0800; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00020000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00002000; + offset = 0x0081e000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00002000; + offset = 0x00820000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00022000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + +#------------------------------------------------------------ +# ATXMEGA192A1 +#------------------------------------------------------------ + +part + id = "x192a1"; + desc = "ATXMEGA192A1"; + signature = 0x1e 0x97 0x4e; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x0800; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00030000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00002000; + offset = 0x0082e000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00002000; + offset = 0x00830000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00032000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + +#------------------------------------------------------------ +# ATXMEGA256A1 +#------------------------------------------------------------ + +part + id = "x256a1"; + desc = "ATXMEGA256A1"; + signature = 0x1e 0x98 0x46; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x1000; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00040000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00002000; + offset = 0x0083e000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00002000; + offset = 0x00840000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00042000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + +#------------------------------------------------------------ +# ATXMEGA64A3 +#------------------------------------------------------------ + +part + id = "x64a3"; + desc = "ATXMEGA64A3"; + signature = 0x1e 0x96 0x42; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x0800; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00010000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00001000; + offset = 0x0080f000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00001000; + offset = 0x00810000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00011000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + +#------------------------------------------------------------ +# ATXMEGA128A3 +#------------------------------------------------------------ + +part + id = "x128a3"; + desc = "ATXMEGA128A3"; + signature = 0x1e 0x97 0x42; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x0800; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00020000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00002000; + offset = 0x0081e000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00002000; + offset = 0x00820000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00022000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + +#------------------------------------------------------------ +# ATXMEGA192A3 +#------------------------------------------------------------ + +part + id = "x192a3"; + desc = "ATXMEGA192A3"; + signature = 0x1e 0x97 0x44; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x0800; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00030000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00002000; + offset = 0x0082e000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00002000; + offset = 0x00830000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00032000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + +#------------------------------------------------------------ +# ATXMEGA256A3 +#------------------------------------------------------------ + +part + id = "x256a3"; + desc = "ATXMEGA256A3"; + signature = 0x1e 0x98 0x42; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x1000; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00040000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00002000; + offset = 0x0083e000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00002000; + offset = 0x00840000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00042000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + +#------------------------------------------------------------ +# ATXMEGA256A3B +#------------------------------------------------------------ + +part + id = "x256a3b"; + desc = "ATXMEGA256A3B"; + signature = 0x1e 0x98 0x43; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x1000; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00040000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00002000; + offset = 0x0083e000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00002000; + offset = 0x00840000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00042000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + +#------------------------------------------------------------ +# ATXMEGA16A4 +#------------------------------------------------------------ + +part + id = "x16a4"; + desc = "ATXMEGA16A4"; + signature = 0x1e 0x94 0x41; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x0400; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00004000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00001000; + offset = 0x00803000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00001000; + offset = 0x00804000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00005000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + +#------------------------------------------------------------ +# ATXMEGA32A4 +#------------------------------------------------------------ + +part + id = "x32a4"; + desc = "ATXMEGA32A4"; + signature = 0x1e 0x95 0x41; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x0400; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00008000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00001000; + offset = 0x00807000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00001000; + offset = 0x00808000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00009000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + +#------------------------------------------------------------ +# ATXMEGA64A4 +#------------------------------------------------------------ + +part + id = "x64a4"; + desc = "ATXMEGA64A4"; + signature = 0x1e 0x96 0x46; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x0800; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00010000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00001000; + offset = 0x0080f000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00001000; + offset = 0x00810000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00011000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + +#------------------------------------------------------------ +# ATXMEGA128A4 +#------------------------------------------------------------ + +part + id = "x128a4"; + desc = "ATXMEGA128A4"; + signature = 0x1e 0x97 0x46; + has_jtag = yes; + has_pdi = yes; + nvm_base = 0x01c0; + + memory "eeprom" + size = 0x0800; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x00020000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x00002000; + offset = 0x0081e000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x00002000; + offset = 0x00820000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x00022000; + offset = 0x0800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "prodsig" + size = 0x200; + offset = 0x8e0200; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; +; + + +#------------------------------------------------------------ +# AVR32UC3A0512 +#------------------------------------------------------------ + +part + id = "ucr2"; + desc = "32UC3A0512"; + signature = 0xED 0xC0 0x3F; + has_jtag = yes; + is_avr32 = yes; + + memory "flash" + paged = yes; + page_size = 512; # bytes + readsize = 512; # bytes + num_pages = 1024; # could be set dynamicly + size = 0x00080000; # could be set dynamicly + offset = 0x80000000; + ; +; + +#------------------------------------------------------------ +# ATtiny4 +#------------------------------------------------------------ + +part + id = "t4"; + desc = "ATtiny4"; + signature = 0x1e 0x8f 0x0a; + has_tpi = yes; + + memory "flash" + size = 512; + offset = 0x4000; + page_size = 16; + blocksize = 128; + ; + + memory "signature" + size = 3; + offset = 0x3fc0; + ; + + memory "fuse" + size = 1; + offset = 0x3f40; + blocksize = 4; + ; + + memory "calibration" + size = 1; + offset = 0x3f80; + ; + + memory "lockbits" + size = 1; + offset = 0x3f00; + ; +; + + +#------------------------------------------------------------ +# ATtiny5 +#------------------------------------------------------------ + +part + id = "t5"; + desc = "ATtiny5"; + signature = 0x1e 0x8f 0x09; + has_tpi = yes; + + memory "flash" + size = 512; + offset = 0x4000; + page_size = 16; + blocksize = 128; + ; + + memory "signature" + size = 3; + offset = 0x3fc0; + ; + + memory "fuse" + size = 1; + offset = 0x3f40; + blocksize = 4; + ; + + memory "calibration" + size = 1; + offset = 0x3f80; + ; + + memory "lockbits" + size = 1; + offset = 0x3f00; + ; +; + + +#------------------------------------------------------------ +# ATtiny9 +#------------------------------------------------------------ + +part + id = "t8"; + desc = "ATtiny9"; + signature = 0x1e 0x90 0x08; + has_tpi = yes; + + memory "flash" + size = 1024; + offset = 0x4000; + page_size = 16; + blocksize = 128; + ; + + memory "signature" + size = 3; + offset = 0x3fc0; + ; + + memory "fuse" + size = 1; + offset = 0x3f40; + blocksize = 4; + ; + + memory "calibration" + size = 1; + offset = 0x3f80; + ; + + memory "lockbits" + size = 1; + offset = 0x3f00; + ; +; + + +#------------------------------------------------------------ +# ATtiny10 +#------------------------------------------------------------ + +part + id = "t10"; + desc = "ATtiny10"; + signature = 0x1e 0x90 0x03; + has_tpi = yes; + + memory "flash" + size = 1024; + offset = 0x4000; + page_size = 16; + blocksize = 128; + ; + + memory "signature" + size = 3; + offset = 0x3fc0; + ; + + memory "fuse" + size = 1; + offset = 0x3f40; + blocksize = 4; + ; + + memory "calibration" + size = 1; + offset = 0x3f80; + ; + + memory "lockbits" + size = 1; + offset = 0x3f00; + ; +; + + diff --git a/avrdude/avrdude.exe b/avrdude/avrdude.exe new file mode 100644 index 0000000000000000000000000000000000000000..12c3225ed2637beeae48ddabf10c5bb5863552f2 GIT binary patch literal 313344 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
uY`!(d{bH;rjo$ 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 literal 0 HcmV?d00001 diff --git a/avrdude/libusb0.dll b/avrdude/libusb0.dll new file mode 100644 index 0000000000000000000000000000000000000000..9387bedad1d4ec91bfb903486d1ed37abccab63e GIT binary patch literal 43520 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/OCGs[5 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + FW icons 2013+logos + + + + + Adobe Illustrator CS6 (Windows) + 2013-07-07T04:01:27+03:00 + 2013-07-07T04:01:27+03:00 + 2013-07-07T04:01:27+03:00 + + + + 256 + 68 + JPEG + /9j/4AAQSkZJRgABAgEAYABgAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAAYAAAAAEA AQBgAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgARAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9UO6Ihd2CooqzMaAAdyT gJAFlUku/Ofl6JWWO8SSY7RqgZwWI23UEUrmDk7SwjlKywOQIfSfO2jy2cC312sV7wUzBlZV5EV2 NKZVp+08RiOOVSrdEcg6p99dtfqv1oSq1uRyEqfECOm3Gtc2Pix4eK/SztKX856CrMrXAjZdiJVd DWlR8PEtT3pmGe0sI6177DHxAvtvN2i3ESukrMTQOER2CE/zELT6cMO0MUhYP2FRkCZXN7a20Qlm fjGehALE18AoJObCEDLkuTJGAspfesLiSGWF0liuf3cRJUbgPVdxUb7mm+1MxNRCQlR67ff+NkCQ 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 vWnfFV2KuxV2Kv8A/9k= + + + + + + proof:pdf + uuid:65E6390686CF11DBA6E2D887CEACB407 + xmp.did:B7D30232A0E6E21186CBB3ABC4A69F81 + uuid:6e717a34-d9cf-4b98-b305-8191aa11dbfe + + xmp.iid:B5D30232A0E6E21186CBB3ABC4A69F81 + xmp.did:B5D30232A0E6E21186CBB3ABC4A69F81 + uuid:65E6390686CF11DBA6E2D887CEACB407 + proof:pdf + + + + + saved + xmp.iid:B5D30232A0E6E21186CBB3ABC4A69F81 + 2013-07-07T03:57:28+03:00 + Adobe Illustrator CS6 (Windows) + / + + + saved + xmp.iid:B7D30232A0E6E21186CBB3ABC4A69F81 + 2013-07-07T04:01:25+03:00 + Adobe Illustrator CS6 (Windows) + / + + + + + + Web + Document + + + 1 + True + False + + 600.000000 + 300.000000 + Pixels + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + White + RGB + PROCESS + 255 + 255 + 255 + + + Black + RGB + PROCESS + 0 + 0 + 0 + + + RGB Red + RGB + PROCESS + 255 + 0 + 0 + + + RGB Yellow + RGB + PROCESS + 255 + 255 + 0 + + + RGB Green + RGB + PROCESS + 0 + 255 + 0 + + + RGB Cyan + RGB + PROCESS + 0 + 255 + 255 + + + RGB Blue + RGB + PROCESS + 0 + 0 + 255 + + + RGB Magenta + RGB + PROCESS + 255 + 0 + 255 + + + R=193 G=39 B=45 + RGB + PROCESS + 193 + 39 + 45 + + + R=237 G=28 B=36 + RGB + PROCESS + 237 + 28 + 36 + + + R=241 G=90 B=36 + RGB + PROCESS + 241 + 90 + 36 + + + R=247 G=147 B=30 + RGB + PROCESS + 247 + 147 + 30 + + + R=251 G=176 B=59 + RGB + PROCESS + 251 + 176 + 59 + + + R=252 G=238 B=33 + RGB + PROCESS + 252 + 238 + 33 + + + R=217 G=224 B=33 + RGB + PROCESS + 217 + 224 + 33 + + + R=140 G=198 B=63 + RGB + PROCESS + 140 + 198 + 63 + + + R=57 G=181 B=74 + RGB + PROCESS + 57 + 181 + 74 + + + R=0 G=146 B=69 + RGB + PROCESS + 0 + 146 + 69 + + + R=0 G=104 B=55 + RGB + PROCESS + 0 + 104 + 55 + + + R=34 G=181 B=115 + RGB + PROCESS + 34 + 181 + 115 + + + R=0 G=169 B=157 + RGB + PROCESS + 0 + 169 + 157 + + + R=41 G=171 B=226 + RGB + PROCESS + 41 + 171 + 226 + + + R=0 G=113 B=188 + RGB + PROCESS + 0 + 113 + 188 + + + R=46 G=49 B=146 + RGB + PROCESS + 46 + 49 + 146 + + + R=27 G=20 B=100 + RGB + PROCESS + 27 + 20 + 100 + + + R=102 G=45 B=145 + RGB + PROCESS + 102 + 45 + 145 + + + R=147 G=39 B=143 + RGB + PROCESS + 147 + 39 + 143 + + + R=158 G=0 B=93 + RGB + PROCESS + 158 + 0 + 93 + + + R=212 G=20 B=90 + RGB + PROCESS + 212 + 20 + 90 + + + R=237 G=30 B=121 + RGB + PROCESS + 237 + 30 + 121 + + + R=199 G=178 B=153 + RGB + PROCESS + 199 + 178 + 153 + + + R=153 G=134 B=117 + RGB + PROCESS + 153 + 134 + 117 + + + R=115 G=99 B=87 + RGB + PROCESS + 115 + 99 + 87 + + + R=83 G=71 B=65 + RGB + PROCESS + 83 + 71 + 65 + + + R=198 G=156 B=109 + RGB + PROCESS + 198 + 156 + 109 + + + R=166 G=124 B=82 + RGB + PROCESS + 166 + 124 + 82 + + + R=140 G=98 B=57 + RGB + PROCESS + 140 + 98 + 57 + + + R=117 G=76 B=36 + RGB + PROCESS + 117 + 76 + 36 + + + R=96 G=56 B=19 + RGB + PROCESS + 96 + 56 + 19 + + + R=66 G=33 B=11 + RGB + PROCESS + 66 + 33 + 11 + + + + + + Grays + 1 + + + + R=0 G=0 B=0 + RGB + PROCESS + 0 + 0 + 0 + + + R=26 G=26 B=26 + RGB + PROCESS + 26 + 26 + 26 + + + R=51 G=51 B=51 + RGB + PROCESS + 51 + 51 + 51 + + + R=77 G=77 B=77 + RGB + PROCESS + 77 + 77 + 77 + + + R=102 G=102 B=102 + RGB + PROCESS + 102 + 102 + 102 + + + R=128 G=128 B=128 + RGB + PROCESS + 128 + 128 + 128 + + + R=153 G=153 B=153 + RGB + PROCESS + 153 + 153 + 153 + + + R=179 G=179 B=179 + RGB + PROCESS + 179 + 179 + 179 + + + R=204 G=204 B=204 + RGB + PROCESS + 204 + 204 + 204 + + + R=230 G=230 B=230 + RGB + PROCESS + 230 + 230 + 230 + + + R=242 G=242 B=242 + RGB + PROCESS + 242 + 242 + 242 + + + + + + Web Color Group + 1 + + + + R=63 G=169 B=245 + RGB + PROCESS + 63 + 169 + 245 + + + R=122 G=201 B=67 + RGB + PROCESS + 122 + 201 + 67 + + + R=255 G=147 B=30 + RGB + PROCESS + 255 + 147 + 30 + + + R=255 G=29 B=37 + RGB + PROCESS + 255 + 29 + 37 + + + R=255 G=123 B=172 + RGB + PROCESS + 255 + 123 + 172 + + + R=189 G=204 B=212 + RGB + PROCESS + 189 + 204 + 212 + + + + + + + + + Adobe PDF library 10.01 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 7 0 obj <> endobj 8 0 obj <> endobj 9 0 obj <> endobj 20 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 21 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 22 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 23 0 obj <>/Resources<>/ExtGState<>/Properties<>/Shading<>>>/TrimBox[0.0 0.0 600.0 300.0]/Type/Page>> endobj 24 0 obj <>/Resources<>/ExtGState<>/Properties<>/Shading<>>>/TrimBox[0.0 0.0 600.0 300.0]/Type/Page>> endobj 25 0 obj <>/Resources<>/ExtGState<>/Properties<>/Shading<>>>/TrimBox[0.0 0.0 600.0 300.0]/Type/Page>> endobj 43 0 obj <>stream +HˎEEz@,ddFLF<ݑ7sxz»o=B^#§FY5Œ-܎\-҃X]ܞaqNڈ{\|'â!_`&dV™kLT߯єG8mb| >g| )<4%//? M +$GKj8RUqL~2'8'83'v KYbW?chC/H.PL@]K[ Gxmȸ c81CCѢDġƲf1'afYh̸8+qu +Cx6QS +w$ k\9K0s >"P+X@nN 49x/ljC|o)ÕЅ-:B}K]*x?e\1dMPTˆ</mct;cCE +sV%f(=TW%7W i-bAPZFMW AҤu䓊E!` Bw :QͷeLIܸ5;:1Zx-t΂[ +Qb+Nn4"n:)bj<\W)dD|+YKns% S>2CB/ ;JʜybPQU˻ rVVJDvvU[V+P21SpYFJ>5@<[`榴glhE8N.6ۜR%ˠ#\VXtp܌ IP|iew+0Ҕ xyy(d5ŰFg*ƶݮ:P%h'Uz#U?S?]jtDS9}Ș"U&,sUކŨ3KXO.$)nWFȬYWJߋ…/_"'YRԗzvPj~)TYjH[(-DdlW8.mTh́KRsexK0)>0rKd]Wy{;S_h-4C|_M__+l%ŕo^P.oCۆQcNJ@7}j״j'{J{nT_v̻h7eC99̯JoL'7gSі%Z 7r#KIu#@4neN3H@]SF:j]Lf ]P'*{a׊o\W]#[&he>Ho@"/Z^f{mt.}5ށ, ^V^m -RD-v=s_R[.'z)UUzލ^O]鞂M~YVvGAi9o]S%=ٔ Z{RjU#, wƓɎρ?K +endstream endobj 44 0 obj <> endobj 46 0 obj <> endobj 29 0 obj [/ICCBased 49 0 R] endobj 48 0 obj <> endobj 50 0 obj <> endobj 49 0 obj <>stream +HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  + 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 +V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= +x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- +ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 +N')].uJr + wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 +n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! +zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km +endstream endobj 5 0 obj <> endobj 51 0 obj [/View/Design] endobj 52 0 obj <>>> endobj 45 0 obj <> endobj 30 0 obj <> endobj 53 0 obj <> endobj 54 0 obj <>/Shading<>>>/Subtype/Form>>stream +q +0 g +/GS0 gs +170.0126953 -24.0030041 -24.0030041 -170.0126953 67.5302734 162.8457031 cm +BX /Sh0 sh EX Q + +endstream endobj 55 0 obj <> endobj 56 0 obj <> endobj 57 0 obj <> endobj 58 0 obj <> endobj 28 0 obj <> endobj 59 0 obj <> endobj 60 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 16.0 +%%AI8_CreatorVersion: 16.0.3 +%%For: (Max Levine) () +%%Title: (FW icons 2013.ai) +%%CreationDate: 7/7/2013 4:01 AM +%%Canvassize: 16383 +%%BoundingBox: -83 -938 3544 -20 +%%HiResBoundingBox: -82.8662 -937.7588 3543.1553 -20.6021 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 12.0 +%AI12_BuildNumber: 691 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Registration]) +%AI3_Cropmarks: 2996 -940 3596 -640 +%AI3_TemplateBox: 790.5 -630.5 790.5 -630.5 +%AI3_TileBox: 2875.0098 -1087.5996 3716.8701 -492.5801 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 6 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI9_OpenToView: -1733 1529 0.25 1821 1035 18 0 0 50 116 0 0 0 1 1 0 1 1 0 1 +%AI5_OpenViewLayers: 7 +%%PageOrigin:390 -930 +%AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 +%AI9_Flatten: 1 +%AI12_CMSettings: 00.MS +%%EndComments + +endstream endobj 61 0 obj <>stream +%%BoundingBox: -83 -938 3544 -20 +%%HiResBoundingBox: -82.8662 -937.7588 3543.1553 -20.6021 +%AI7_Thumbnail: 128 32 8 +%%BeginData: 4352 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C45FD1DFFCFCFAEFD07FFCFFD09FFAECFFD04FFAFAFAFFD4DFFCF83FD +%14FFCFA8AEA8FD05FFAECFA7FFFFAFA8AFFFFFA8CFA7AEFFFFFFAFA8AFA9 +%FD4AFFCFFFA7A6A8FD06FFCFA8FFAEAECFCFAEFFFFFFAFFFFFCFAEFFAFFD +%04FFCFAEAECFFF84CFA9FFFFFFA8AEA7FFA8FF84AEA8FD49FFCF82827B82 +%81827BA6A7FFFFAE82825781578283ADAEFF848584FFA7CFA98584AFFFFF +%A8CFA8ADA7AF85FD04FFCFA8FFA781A8FFA9AFFD4DFFCFAEFD06FFA7AEA7 +%ADA7ADA8ADA7FFFF8BAE85A8ACA7AF84AF85FD05FFA6A6FD09FFCF82FD52 +%FFAEFD05FFA8A7A7CFFFFFFFAD82ADCFFFA98BA9FFA8FFFF8584FFFFFFA9 +%AF84AEA8ADA7CFFD04FFA9AEA8FFA7CFAEFD4EFFA7ADA7FD05FFA8CFFD05 +%FFCFAEFD05FFCFAEA7FD06FFAFA8AEAFFFA7CFAEFFFFFFA9AE83FFFFCFA7 +%CFCFFD4CFFA8AEA7AEFD13FFCFA8AEA8FD05FFA9AF84FFFFCFA7FFFFFFA9 +%AFA8AEA9FFA7AEA7CFFD65FFAEFD11FFAFAFA9FFFFFFAECFFDFCFFFD4FFF +%AEFFA8FFFFFFA8FD0FFF8485A9FD04FFAF84FD05FFAEAEA7FD07FFA8CFA8 +%FF84AFAFFD4CFFA8FFFFFFA9FFAEFFFFFFCFFD07FFCFFFAF8BA8AFFD04FF +%84AE85FD05FFA7CFFD08FFA7CFFFFFA8FD4CFFAFAFA9AE82FFA8FFFFFFA8 +%AEA8CFCFFFFFCFA8AEA8FF8485A8CFA8FFA88584FFFFFFA8AEAFFFA8FFA8 +%AEFFFFFFAFA9FFA8FFA8FFAEFD4CFFA9FFAECFFFFFA8FFFFFFAFFFFFFF82 +%CFFFFFAFFD06FFA6A7FD07FFAFFFAEAEAEFFAFFFFFFFAEAFAFCF82FFAECF +%AEFD49FFAFA8CFA8FFFFFFA8AEA8FD05FFAFAEA8FD09FFA7CFFD06FFCFFF +%A8A782FFCAFFFFFFA9AF84FFA7A6CFCFA7CFA8FD48FFAFFFAFFD05FFA8FD +%07FFA8FD0AFFAFAFFD06FFCFA7FFFFFFCFCFAEFFFFFFAFFFCFCFFFFFAFFD +%4CFFA8FD07FFAFFD05FFA8FFA8FD08FFAFA8AEA9FD05FFAECFA8AF84FFA8 +%CFFD04FFCFADA8FFA8A8A9FD64FFA9AFA9FD09FF84FFAFFD07FFAECFFFFF +%AFFD66FFA9FD0AFFAF84FDAEFFCFFD2DFFCFA7FD08FFAFA8FFAECFFD2CFF +%A8A85AA9FD12FFA8A7A7FD13FFA8A87DA8FD13FFA8FFA8CFFFFFA8FD05FF +%A8AEFFCFAEFD2DFFA87D5284FD12FF7D587CFD13FFA87D52A1FD11FFA9AE +%A8FFA8FFA8AFAFFFFFCFA7FFA8FFA8FFA8AFFD04FFA8FFFFFFA8FD24FFA8 +%52527DFFFFFFA8FD0DFFA853277DA8FD05FFA8FD0CFFA852527DFFFFFFA8 +%FD0EFFAECFCFFD05FFAECFCFFFAEFFAFAFA9FFFFFFCFCFA7CFA8FFCFFFCF +%FD23FF527D7D7DA87D7DA87DA852FD0AFFA8527D52FFFD047DA87DA8FD0B +%FF527D7D7DA87D7DA87DA852FD05FFCFA7CFCFA782FFCFCFA7FFFFFFAEFF +%A7A6A7FFAFFD05FFA782A7CFAEFFAEAEFD22FFA8527D53527D52A8525227 +%7DFD0AFF587D5352FD047D525352FD0BFFA8527D53527D52A85252287DFD +%05FFCFCFFFFFAECFA8FFCFFFFFFFAFAEA8FFA7FFAECFAEFD05FFAECFFD26 +%FFAF7D7DA8A8A87DFFFFFD04A8FD09FFA87DA8A8A8A7A8FFA8A87DA8FD0A +%FFCA7D7DA8A8A87DFFFFFD04A8FD06FFA9AEA8FFAEFFA8FD05FFA8FFA8FF +%A8FFA8FD2DFF848452A8363636FFA83684365A5A0DA9FD06FFA77D7DAD82 +%AD82A782A6A7A6FD0582FD05FFA8A752A8757C7C7C767C7C7C51A17576FD +%05FFA8FFCFCFFFAFAEFD05FFAECFFFAFA8FD2DFFA9AFA8CF60365A368436 +%0D600D360D5AFD06FFA7FF7ECF81CF82A782A6A7ADA7AD82AD7BADFD04FF +%A8CAA8FFA751767676A175A07C767C7576FD06FFAECFA7FFAFFD06FFCFA8 +%FFA9AFFD2CFFA8AFFFA8FFAFFFFF8485A8AF84AFA8A984FD05FFA8FFA8FF +%FFAEA8FFA7CFA8FFAEFFA8CFA8CFA8FFFFFFA8CFFFA8FFCAA7CAA8A7FFA8 +%A8A8A1A8A7CAFDFCFFFFFFFFFF +%%EndData + +endstream endobj 62 0 obj <>stream +%AI12_CompressedDataxɑ&T*= p.=I=݋f$nR`Z}=9$vW:2#fno +7޽ɻ_~wރt͂(_w޽9&w'zwWoOAݫ/w{v~qūڃӋtMY[W|ŋ^xX(û~w_ q]w_y~7m.7%%kMo7.ƀnn={~;{w?W/@y_~B{͋;p^w߿{T\?|GQ_!o?|צr[~]'7xD=~j~7/ kMuⷴ.z|{&&_~2ЗoWn)&iLZM,KkcH޽ڿ[u]__߿>P Ӫtׯ}sUܽ~߽x4޽ObO!?cd>�w_+Cعnqw;ω(Ѯ@m=%c(M_۟`*.:7}ܳsSھ>|Asa-7-}7x yK?_U&|MޢNV=a"%1 +ov} {/^Rٮ!~O?R!NJG{|޿~PQ^f/w򂺬iηI|_y zԣ^|#1|g 1UoW߽ +Gȷp߿|wݻ׽#S䞿ŗ@Wx?zy ]Q%'6nyEʲ~Ň$_uЋWx{-$o[qpe7~Mĸ|gawx;n7h!a޾}8s*H<??/ϟnH@eOr)L%QTV.䩸ӂr;r9u?cctT 7=z(|HTan^iO҅}ݗ}ާ}ܯT~w^Xu_k-5D%ֵꫫK+'zCK)ZBŕ,ͥWK9He!-uƑ^rOSJ1)$YrTxKD >}P)TBe[o~kYV:pn‘C +1!\XA85O> Iw֝n#E>ιe[n1| u0/T%?-GzDwTN74Q0;{PJʽ~$=u:pogBEz ~CЃC"=Y'3R[ܧU+zS:]/zgw{7oj5FAKo1*oHF +|cdԨ<Fc([Jo)QGJo9i/<컕ž7_mXOj̟;N8Ҫk[o)u/Ɵf]߆6 FVƖq1Q'?<2+?`F,:'˝Ώ[> 9,9rYr9rY"3es?یI-f tre\_j|kY^矈v+2"Sn<؁2Fؕϟu,ig˴Uh0/.YhӮy$Y6Ѳsz]We}>$r")v-4RJ%9@̩ܖ;ZΎ6@N8IA{$;BG$3E2PdT0iK$$HB;vGrBѓҦH+$I;w{#h[ 5dLc%@rd;ΈӦ`ngI<z{{G mԱw5wԴ;z;lHBX|ޮA;uw<` 0 +nO<4< F32rct`I#EcEhaixé&/1)VoSWVw/dZ>9ϥ}cmW'YqIpW\JzZD5u&4vMM۔aBQoj0m34uiSVG)60I1l&)1H]6I5ԹIʌR4W,FnzQj' UIS7*j/Uje(~E|RoVܖey*~죂aA*"MbO܉݁X^!֗hbV[ +90$1$$ZbA +| UPI` c6H*5`"p`4xc 2cUÑ(GU늩uM^ Y̩Ѧ"Ifh8;g E[b3,9ΆѰq5Tu6}ă7mx3oFzecQmTDM;Z:f{u5iNj"{`[hԌ͘:EDI JPwC{1 0ݠ:bkjQFDi5M7u01{@ ST66]Y~FFfN-"ywqmyRXF7kUc.W` >}WQ:WDj9W~k鞩`m +XmRI?Xp;*Y|kUL +h1\[ذ}ZʖxO[-.,wΆwagvݱ.-#Ő.KC,i"[N us$A#Etx ".Yű9c,~Ǻz4z. RX RM2Kyq։N5']fAp|<8q<6Ut-P_Ϯ DY/lWl ֆ[7a^YnL \ٞ +cfe6 OM2oOqteϙx]188 + yp +rlN1|\<.UIf956 +qU:$8CV jZyJjJ̊?qu(2Ʈ'Dڲu82,- cIG8H0 ЖR:Mpi;߂.>oOg'uw[r=s??h=zf4C sFه4z.{/DN;n >޳H {͖-!rWQ @pӃ%`N/" vo,Lĸ<=4YaN+mA-ReΧC][Y初ѳ3~)1Ph5?R|2>GnW<{oq٬3v|@kT?~g?`4;v|D/6gԜ%;m5hQmC^8FmnsV8dWΣ#=OuH2^Sߵ[^ qٖ^Ji8)[29ř<<6A\99;NK|}7>8_A `XE +0xZӰl7Y/ϩ_P/XXds )S]݄̓ OU&XM:6Tn83ĴMU$2fS* fw۔WR_VHخ\8k ⪚RCBi5ljH^Q[^ܨdMrjזM[E۰ pPe9emR+{+^P:8`vT70>RW+q*_eSBNޟrzK +. OhiS!=p`Y7G^uI+PT)2ݠv/vՈ`YZ^TXs漽lɦ,|z'̓yFu[qdc"m<@֜8q$OP4Sogq n!OuU1'Yìz;da/5Iʳ:4=I;hw3~3?OhQR: s9T%4΄ùə):>r+kKSb[svMz \?2&wɻG-L='vQ]2>MFIEXe[Ǚ&"UTݬIκMd+FHdZe,n-2hwykYh_JҷIG+k/TcJsS3`cTxPCvp7Wtrqcף4~rM}qc9pV:z?αc4:ivI݄7ah.48g'W 8n8B6\dГ!:Xuv,L~ +әJ6i3.4d9s.04Y8H?B$9ܩ" 8%Bۤ+p*5f%Im:n 9Pd= ^ e8l_|".@Ĺ~NR4ew=]!q)~b;,;3tE|_qRmIAiflͻ΃{qȿ,w6ɔ13 S +T ed^HQx=73K^fœR Yb#pvLTzh?MhbHKn25ϱ3ճmKYASC/;)` S^N>$-bO_NQ3.ANVط9GpvjdYM1͏Ӄa1f0>!F>a33<]db+?4D^m*z1tfW'cZy8 fྻ$2*/"ĐhVG;p>Ʃ̆[6F> [69403xlN:e8_%Y*Ĩ@\Iʼn4Iiq/=TZSi}?&Fw?ȘnGqѣ|O;4 ҹ]V¶ʕ~DC_C_ܓa6l쩅0twMoom+d +lBIYϛ(ws^9FbN'XH9i|'hS hW> Of͍@ .rvux\Dz7z?2>0H3G#_Q; +XQ9$y8jA0df3iHނ`T@u pI)TK&(k4@!FP5M?P)4Y zĹ?F^.z\;/]]1HM~KUDj,9A)b&F +K&_  :?3f'X7f31r&5uxn7e35cZ35ͻ==}Amḇ^…^)0wrvt@Q3'\l'-_TV##k!{4ю=?Q]O v ; ݍӁ''5^;9wQOiΖ j.r|n6Qth?-xuw.}BiW3B5qk_)]HOVaYR58fP8:!> !4(0z`kUBIZ1 jn!qIޙ*X~ +&D,wT#;g@fNe +X-;Pᘣ&(u.8f^$1LaPmnЬFiԆfe+_zPΓ +8xyx=qe}LhŏB5>H5f9.8\9FZ8d*#Q5|<+iJ77a:?<][ivu 9غ9}c?SaC6aǦ+4D(I(BQGx6 /G + G +l[g5|H5^^> xR1EHxf:+|“5Q~(?r9#GQ~(OWf#{_L_k̡f!(9GqƻI<.¿K'FՅ]t7 qɳA$wts$79~M *>r|͗j^ka9_#x€GT۷&jitVVm+y,sV,|yʇ9Gn_mMc֣e5!6:M#n\nvҘQz;$VːfuH$L0"L* +eDeu/q(թWG >V )`@ T0UO<}|98gfoy!-H6}X4E/\7`]29?G2g_.] +W<IJ!+8.TTRT36&i<+Ь.(P_ +C2,Fx;&.2+=И]\ցe==3zF,7hOĆz! ir XBC/OMYsft `p. r+Tx`OWa Q1ww6m^g_hSÅȚ9Wy 3 +1)64BYM1 +PWyZgKct'T>-9@,Gvٳsŧ;+g`άXG=[>QI?O|jE7\\Aa .a4":ēL?"ز=ދ`ܣ"?tGů~ֆg.\g8z˱,g9-0G+ |xrr9=.P$koNS׸o3(_| ԬD?jT<(YDEBӭK1 !n'S:eH'Džl?v_vh=xzϧQRO9{ԏ/$"/ 5Pə#`)D%4lG%V^zZ5 z3y SĴgjY7MN3HjEsB{6 $C:,ypm3~s,\•/-8J§/?im-{;*oiY@o) &ؤZC؀|׏5>~BHj@R^hqC:!z !B4YP,1esM +@O +Oor>\?1p`ڙv,<"-9ԡe;4>Sl<l>(l>}f99 O)$3EY`"quY&aH= -hzweai֌'=P%nf5美e=+J qy-TgT5У+.sg(~LF!OfIA?'"aF3bnd 9EI#h'+ 5nmR* x/ pht_lˊzEQEs9Sr6H6*Ev69IveMLY 0l?+SkB}L!솋۫(B^$D U"$=+(}dQiط#M]lا`'jjeu)eI28_?g_V(r~~Q 23Y*X Վ">(|/"ȥyòglGΑRJ5Vo/HQWT+Ef0s%gVTY`~C>r<wtt{u޲ܱ\΃[v뚵ܫrǮH AaU<>%ÈWKWڹ_kTźֲ6t5."jgScbs:1B$Z+Q 80y+z2']@ebT7[p_ F0rS|޸G#Nħ3uQxz0o@GG 5^狫?U%z7*ԑ/:{x]:[N;i%;)!or2Y~׍ߊH:и>5/&+. N6xDt1 XcW;ꡌ]/SA3/9#Bs8Auķn~z6,Y}[K x%^ +DˠS|)j="jq0> hޣ9 ~`98.vxp2v0|ad;Ϻ]G<;;-a3=Z0p"$:8S>?>B Ğ[#ƄCɧP^=]3-| +|ruKg~$&յ44f>.&2'ئ9]N199)-Ou\ҽ[SI璞59$s +t5uK"4,}r,0W\N?y:i/9F8x$句Xkg_%_,,up]ʜ@r +-G9Cn1Z(]s6~t@?Ήďs9S}B_~j"߿z?|ըyۯ_|p-i]75.5zC> M$o'^>4?Y>w!꟨+vyw'wo@={/*. +⿟8zջ/ys1k_h|}ͫ}x_ݫ_凟3??}//sK1:y֬4[fvZ^H]sOnhR@Jvӓȶ&L#pC]:Ň]7%W &!Ԉn7@$"GtZWo@\}r=e7f`/7e DYִ ^^ Kj zQ+yG#_͇o PKjo PZr%gP?nu7]jwxO$eRӥt\Mu!W*IupE-CCrv+$qK"{`j8f;Qou6e%S4b"_,Vj/+BOV5˶q >tJԽFRNvicD!h9]N/ܕWGh訢D>h$Ԇ]XQ&@YiihtI[MZi6)F += +4x~g/P&Us{^Czߝ:O2^8o&*M3SNs }֙D/G|)C-Jh.T52f7Ϟ}e-VѦqGhr N@L]eWhs&A 9҈Af/[ɽF}oHJSaxZvY{qhӾ>a/w_mwwo߿[L.o_|kzvשtOxe*<]KOyYeǝAڌγ\#mXLNEx}iքB1qTSȷL#A)$ZE.GU-UoiOw.)duȭnBrR݌Rrg`.uw7gb4Sy3SI_s6W_sؘh|S]hJ=TG[V" ]4m$60-k%Mp"rNLkH$!sľ1ǰ/;W^\ 1Dkp5G;d]iG.cZ]*$}2m; iê$2 +CU8hөշ9y5<$#Я$@U,amuVh +IնS"l;h6pjn\+L#OСK\|d4>LokTmR6wVOF?>}~Y{khӸsOPk!רƌƚp +ĂI ^Cq1r1iJ Qw&zE5@H4ײڋ[E ݨ*t,cGs'B")] ;vq"'aeEL byL,:b,}hY+'ohKWrbB@и($58ȩWdwA4"̛T Sm.zC))$NIOpYsxGL)s:&ˊ`S/$7e}id@bDDhxRV{;`m[;_&%z1%42$/dqdthVnV*Eo 7x!@ e~2k¶C?>"73! +.HwE}G*GlcS/KEF*2>e|B 4_ .[E^[eS.ZvY{VѶ}Mt!d*l[P0"ͶVHm[nif8DmA]um[Bk-0S~^m9l[Om3ٶ@~cr~1PM[$83m1k$=f6m1g%L[VV3mi Lu]KsI%myZul qf2ٶJ(um7@l[OM[Xi̖-ZqAaMdZ1lZ`gY!f"Ngٴ* LZ`O-f5;3h!6{=ٞ̚=܍m71OɞnN9/Sz2gaKcѸɴ[7{B;8ɭ=˨Q"jrLɞmC.l9Oak4d_T5CY=PeOYN֖VѶq3;'1jYf(P٩HbEZY่.[FKV^کFs]^ٴW֬/0$ +LdZl-4omm.prPǓbP)t0P/JXHgJ ;#~WI!(EP<@:Yޓ>bJUd`#i h /uփN-}znȋ]aVN&IJ*fvqxN ]h]xPYU]YVT2G{j޲VY[@AS ݇qa@7G yH;Bͼl׈Μ&D0T u!̥ːvBA|C٤-՜lӱ;<4݆AP\WB9%lȅvs_Vn2 58Tf}Cw(Ze7S2 Vٶ<,Rm\0T4w)g}{0eO 5E9{1v #0eVӶAD0N]mMs쟬9豈b3^`*O} }L!Sf5B 1$2Eabwlǂx#pn+5VRVڻt`/[YSի f @v3.a8B`2mUzhe% w*P%{] ̨![e+ ᩍ *]5:kG'YSbvZú,ݼ2,p8ڑolyWd%qym}l,2%yU0:Gg56%pt!V㴈72>umͭlًݯk^WCgO6ol0 lq=fgp5ڶg(5M 5dSC1Mآ3`/;xSCB0trRC͢P3 6&|P(ˠPnZh<)h:(l I-[j(0gZ5%G/XJf%V!L3-K +1oP6;"^Q&up +ke꤄Zˬm[{ǿPF& 9>ǙD3r[ Ŭlu.b(T,Jjh">6jZm[@W +f?382@*I "tΈlY9{j-C;a"PWQF@TbbXV"t:L HJ tD-lWH!˭lFSysB@H` .xa.YHm +$i8v xa7K*8g={n6NӄU*4弈9UR#VDɮM!CU,X ʣOMk^3M5 + @):_ iu%E9(LWeovx=К`mJ>6ÒI@ : +AcBY|s`/8$\;4.Adͬ@Gi4E7c".ڰUTu" V)BT^ZRd'$UvA 3$kg(/вhSŘFb>c#`j/TijձDfiaO='1Fm–E]dldê* &6s.^$fԉM6"lwM%eid 6ͽNt0AC|fC bhIkQ[a"c(<3k0Kx(a4vryln7T SمlWHӘrXِTa,- P(EaNJÅ}*3>nUrVU/Zm[~!3 |3g$,>Am05V$! C]Fi[ }2D@ګzZEg] pa` + Z$#%ti} S-}#3_U6Pz2x)OUzv5A+;oj/.҃0A\0i |tX딗Map!0jZ]Fi5Bj k?T wkWFΚ =t3Z⤴ *Ex ֏P=Ѐѐ@G +It>FAVDհ160< I +g˚֎gÃㆺãu2<< rm]ر4_X!PhB?[é?B5J{UJ.қV=bR]ڶIds&SueDÅ +~uAw6İc+]?4vv5*۶t`w0#Q +12_qq$-ѩtYZ0k;1 yMi0, +_ҞiLKȰ+ZFQP^.׷@ )`9Z;!P(3~H0 T=j(*I@@nW|T7iPJfv BXFcenFb0,vJ!n52Agĸ 0JN+|SyÄ.%FN(Z HoD t-vSPMe6`&УP}Wf,zP +6 3^~HM -ΧI1(o6dpfu h0 i\PQzhu+ǨVٶ@@LޜșN ^Dv7S*Pʌ2?zV5a֡S)fKdn iX}o7LQi1_zeO}٦lze6?U)BkB쬭$`ɵpYaq~`8?0\ڼU +e3,.`Y@:eD dYewθ8{BkB쬭7 f1,B el0Td6R[խmi C1f`22Yȼ&# +F="U>/$V7Vf}jNPSGaxvaoB쬭""}UŰ%(ِ--AfbB ^Q/PAB"8>U)zk{;`um[:([.Y840q *D\T=mUZc*}F{eDLȞ(zք^ٶZ&ءvle5 0N󪝢֧Bڒj+3>ն?#Vvex|ګ6i5V>{cT}ASo6d`tip;XJx!o(T1Y2Y]+ q}v*ẖCD ز:Q 9UcElȀ 5 4VYoUuNчZɤ9Z]РT˦<مkl7ٜ_~/TgmɊi%q2ZAfPiod5Oc༽Sn!)ƍ`/uET=Jݶ$OR1YCneUc "ʄTd}ר*WVU`cy-xh۾jQ I lȐyx,^I(RaPXQ唜>TVTO-C*BkUmI >Q,:f&ðw6/bc97KTboex=R4z]l4 +exf,lJLkMS"4ffE ]B'fnp$xVb4Rp0*C[W*Aﴗ[Uf0=FӢ1`a݊"Q5bIXkHm`S VE`COko HyrNDn~P[]ZVt~ମ2ǵ#LYc^-m`ֹW5zgXsAX{u:.Yr|Cdkj~ W=ųU#;U1М> +H>CScef 8ܩ +~)>7¨K)sֺ~Xbu63[X4=MbkvuOӦj0CͰi}F/՜7;p^~3Q+JA|i͕*lg_m4„\TE8zmJ"kId۴jrK݀;UaP7#yPh h NUV[[EFʝ^bFltvxh۾t"qFmPfZ15pF"E;>٭>Tf8્0;UVBq#^]dmilw{d^nmBnc6I]ZK#LE6U@ *߫(+_eܿt՛}__~Å?x_W7v/DnJ@>k#|?cw>z/jK?s97z=Wz'oIfn@|/TAO +&͚+5CsMɂsCԠ9۷C9?NZyP!"O<X 2D_ػhB9EQԭ+KRweπ=v k?gbLUO``{&(*bVzj&fBur@ݱ=Ȇ/6Ƞ}YGzZ(Uhi!p?hyaCG*G[ 8 gzަ¨oկ #~GEf$ƆI]El H$,_@Bpz:f,"%=#S/gX@x9gZSCfHNPY +~ʖZVsiN[>#@flؕu9= w@ T̠lIT;YcLoQ":sHnbhu2ÃVNxWR"7e^ES/pzc$'Q +5zQ0da>%I"E +?]{;WR+L Ű Lf@ tD&5Y T +䩁q*]W9 #-p(K/c2:Pb$hy5;wҘet(HIX9߮CCN +FV8\Xd*R9*kvP[AHncȹH3` ACx<;,Apj>fEm]`t\[HQ*y[@Elia¿3وO;?>1"UZ/оΖjHS.\E9y^FW+V"P K *PzĩznmD ^*&6mk8(,8:[5~s],8i+vJ09 "J8z$bD7\;d3P=5I˹eȌ$ AqF XlMIrKx+2"j]&FF>Rٖ'LCs4<‘)Ɲu$۲SWPFBB*Pi?XfF#x `ly!(/CB n!~y m+ih):Vf +lc\EDl +gO5@ŰR/vD`#II<38ގ0Y% +3 +_v8@yGawCB3ȆŒ- b,LYX4dY- e֜]#8k?.(F@wmSUH*+H.0CX>OpP}v%i х2 擃DF+ ?L ..&;Qإ[f+R/6G&Hؕ϶T e`8L}ѫ isA` d* n[d5Y6>sS*[MiAs!P] Uތudem\xCegůjk9&lDMa2{مTYr$9J"WpY%>"I +~:yee"ay>!3i]ڙ 眉Zf M4W0]Ⱥ'csT]BEdm^"ʧ dJDB}Ue+ +HT%#@́F0͈*V4gǬE 4*QG)n#wpdDA柞b\bBZFaV-nq>;Au!udGL' _#"): 1 \Ȋʉ@YxԴηi +"z9k Am3:vi~1a `D$h`4V9Ԃ怣HULs+8E?LYGvjgrc9xyT6ᙂMq]I¯ ѼAcD"r\b@x3sgVD|g j}#g>:Yv*lfdE=a*AB@ X9l 4-hHg(ۭ,%+̢2>̋?I˫DIl_$X ˫G¾fHXul$KylnbvILЫXS%%›_&WI65JB0 z>Yt,0%̑\> +`ycºHԄuuaXH/|r B yˮU9HnCMBϲqU} #CEaL4ȉA ɗ bGXUR/* Zf]u^ý0mF'g*ґU:g'ET 9;E^DJxMaEmo,@`*RܶHQT2m8[䏦rR(4qXY1PgO"2$SEX,A(||#丗[mpy-H˫)› +L/c #&D_=q~Vo{uy3hb4H +⹂QjDCr{3CO&?EpF8|cTv&EVe ->Ȑ":ӪyU뿩N jLUĮxԷuܢ ΑAVrVx\ &H602' + .`mSQ2E: XЙOTl)~>/k +>"pH^=*P &Թ$^"3,@IcE3mld('w\2Ep +{~ +ڒ8dm,}Q6`Id1RWIVYa|8y(ө$t"ËsALm]nc5FkrtS #ds|0_"2FYXK `jd`$;y"r!>>y-02(]L0X"H‰p[! ";T4+6`;iOjs +^xc4v5 +"O|pUcSdm1^ԢYKAs @M` Y#c1 +QΩWCPq AamB+g5`PIp><+)+N҈Dջkޭbdxq//wf rFzW,Jβ1Ge8yZ\56SX!HYKOE6t +I7- Y> kp% <\NC|~~آPY/b-yɚ;T,S/4 P1/3BDサv@8 +2/;֪EM_=. *VcAs-tjWIP.^r6N ;(ӧ+gg*MMHIJ"OdHDP9 Tަ|T *5YW:XTQ|ƒC`Zߓٵ\xjx6i$r %꼏E<8@@noQgb] +AW&Ow?aao~ \=k@`l0i'niBWtHnp"9Z=q UFJďF!ˡ=p$A)b1@P/ =Zr~aWDj1MpL^3/@`b7泎8 RfsdF1%&TkdPزaZuF,;Y>@Nc + AaxfsQ3sK*w^pD0tt9L k`69*1dvILߪpmBG_fi]sJnn0_liox,w2f=^L@ K1]ۃ*h % +-u_=p6&"G]GSf5I |0|sq6Le֑*- tePE&DEWp&C>rR[6eY\Ȃu\ $qzۢ]U™p|9>] +UWbz +dbph "c*lqq,Cz.i0 .~_Ji9bt]DbR#.h{Uq>x.ѽ +1$=U$ +ibx!Ij!ovֿeK4vyTט)(N͡QU+-UN22%֩y#hX O^uQ ̺=Ȥ:N/SNW1.Dvk̿@e& נdr%|AX?ؽHy}$B>: PjZqIƂɳ\Kv4-ܳHSо +N3caQ)LeeaH')ů C؈}tG&i}ֱ@N\()D gJĎq0tbQ[5$ YG]oVDR쪾j5j?ddWh|3fO$fYOdV^Nt d(9xyB-W +ŕ?ѿZd`PgvؼE{*G(򐗫X;؆F?4C4TVvױ r1 7 bwϵ#+RVN㖕o~fbhd +?ހM}xB|%+|H@u*X` f>ޓƳrv/pZb!wXΖT=J!LqIxėK>LC ++K (L0)h=C;9>ǒUuKDyq+Ij[Nي(F,sG9+o+Q4 +о[MU^<<<9|ecp +ꬫTdPR0?l6ǁFaC-':5>ZrJҀDSNa6ޏtXUd"AS#Ѻ" qQXASM@.x?;|iH[abDSW~[?CHڵxX=08tJp4M\!V$~CS%W !L^A\ ՓŊ-H/kqad: Ν(2P# +I{.(c#bu!^(:rӾ_ʝoI9z33S22A8I2(,K2K٨³H-8( ƆR0`y?I㞏,V.q=g%(8e^p$ ʎ룯M,Y1E_&b-{ј }Wy\5n_>S:M5=\ S3lיxӯB8uHZDA5m|SRMwvLLf`p>Fi|XZ~mx؍UfSqoA{,m=xx!XȒnbUdb`#0jr8z }X#T" <4PBU’0 +KNjfK fB2ge+*U |Rpe'9 o5XV"Emy *> y308Kw/KNDKC3&~qj6ouF|,&y6ȼ2{{C!|Fʗ9g:Ό,dJ&|fG10sZ[}kl JxvgE ZpF&P/"n Y5Z5QÆux!rSuYО )R%&DrimpMς`̚A6Ļ9BTQ;+ɝXp?'c ް"3h3tv$,3iI` +^v^]kb_m0k4c} *%יP$Z#K@Y;e *q~х|8WZ@ aW 1CGYa8M\"u!=-Vr8]uDY{uVL5UT]]zEF9fw8EB(KN&ߴ$jĵb[],%|yUf(CBD0:X.>FT8Ifm`a%&ST+2 iRݿa6܆ h{ijbǢSU(MA&ULTAnv꼐D]-^TWzLkƅ +OI+Pӕg, eyCSsb0 ug/w +O91DL΁_d|ʩMtV3f4Oe*d4f u:^%c UP/MK, qJUJN-R2\ yv" 2 8h#QXM]7 \GE㛎\j.˂\djEbT^c< iL87Hd +JDDnY@V \ąe~Ynp|8+L .kmpaV-/p5aX NM y# +C ! 88PONmo0O߬G5 ]4[tpeW2 AgQKUU.0H8b1EB:݀a(tlu5"ǚS-xo0(o +0` +1SlŊ +c.B +Op(*(w]8h x$[QA. ?O4a|ԷM7saU8ᇕB:ao9hpw^}KIPxo88.05IsH i1j0rqKH c h6G1/0ޔqSF* P<CƌaXICCrs`~0KUM]갰_8Pi}ɪԦщ~,u!Dp1P5w|C^`C1w90c >xvӂ + ذ2ͤ5+bW~rjIK1q bp+R\`x 1BM /H2&z>F@ڌ(]T]fOMvSqy($bӜ/ 8zO|`(6X~w2r)\|`!^g|`iyg@0Kv$4>i*ր`S `" \& +Y`S2Wypa;`>!.B0rVʏQ6!Xq'!:$L(-~^`!]yLz/B0Zf!hKD_ wL{ Q.B0ɺL!AQ袲'! ;}W&3|4}X7F7 , x٢|`n7Ǚn80A|fK%fR(s4L"..20~#Fs"ۢÀe 9z F+sR>Qz[`=hn 0![.40&LX0Qc0(~G0NH; ̏]$`mdk w f/&Q4 (`(`Z^(`%iF_(`Q8m#V%GPkXljC13 7Մ' Vf!`5dӀ`Mi`L9'A% cH@KǢs3LnAN钋 +A^JPрI4`Xs D +L4` $ 3 1]<`XY[@Dk LO ȓ0@`H뿀l~e@U.gU/ Vw' CMEdpS5D`D +EC "QߣBK6/$x /"05I z'}ÚX7D`X< LK<78vF`H`P>z#q )[)ccD`ʵX}D`쨊 fq7D`cDێ@`Q@`vjS@`:`S]@e〿:Ǣ#y; . +-p88fߘł,;o0~N c>Ti./Ʀ 8<'oi +Ű cd6 )^q~O u (c8$66n'w -kNoo +Q,Oqp;No ;y_dp/#>RG_"p O/ٯe,o`pp~a÷_lp~[6eL<7+_|uzt8 A +/: !|7KZp}i+y}ĔErp}$czX\_$1ַ{]yQ}#Z"5"\˺7fƬwN4Ƿ;a_?CU:#_и[%pdރK*Ÿ/Ò; +x/D28b20rY^,ZÕ]6S{y]ֽqr1{o5O8/u` 8;,l bRA}' ./QX^ALT^o[@y{`5$ ><kY@^Vxu3pNi;,x%//]tLX_7 ʵJ, /б\^Ԋ_75m ^q־0b%^Hxȹ\Bc.oUِ*.. +0$<E6VcN +" dˆO)лͳOwq&ྕAFԦr͊{X](UT];@]T]d8\T]S(AMեPDEUŅ<$]6B%ݥ ieol.; \L]͘=_ P]^\P]XWP]9TY"..ipXT:yե K6 +qOXsBuSgP]sYP]2ƒCuyUnꑽp2uaԯu1ui@LbJ\0uoK2d.br4a|¬P]=XP]nBեO*ucvEXo.qWWǂ e%e(vൟP]z6ejbO%U hpR .BoEF龒/~;y&B偨dt G{ӡ\]Xo.%Qa.".b- q90"@ ʅυq+z.bX\dBB@ɹ9o#ȹCob.fS2ͅ`pwB3Dr252l~rmd,6e׾,Z.`HX72u] jnR.(Aޜ܂])0eJ#KJ.r$A*1NFn5/;p|r B'a։]t\)2;M%L}Lr8Ѹ 6w/ 0nB*p5eO7aW +"IE%8\EÅ@8p1m.d,8QFA=`nסP*ٽ8A\Ӆdbܨke2v[Xѝnm5,"Sgm+ ѷdsȷ͍|,0k&͋zۊ +\Ꚃb='P Ɛ'^ |H6@zna|peɆH-̽v`@ό+;I'dOPP7(7OSQIɚ]r*yO-+r[[Q""uo_Ut[ym321Ol[޼pm`[(Ns -,>6Х W2==nd}Lʲԍp7 66yZ5/EM7oBIl1qO-kQJeM1A +g-d?mlÎ%~d x,Ű b r-iY"OZļZazPU4zk`f߁e4^\ -  +['}ւ_IGU.~>TTǷ.˂nh-€Z ;8BX0kYZd҆X=E8-%W +ih̀>nTms>HHY"ZY W>9 i@'6vov3 Scr :-f^Y|7g7T0@EyTu1;"ip'x_|Y9ů^v$ݾE,.5j,eң~BvD_dYG޲źKܟ]+./A0ʾ0/D $n)8dڳn,6ۢɢ&z@+nlQNm,Eo撘>ځ$&rL(ب "WR!†ŐE~E4hB9Xh 4ni>PUdAra-vljmrc+끢A&V/p,&̝S`c?1?|wGRc㨱Ea܏7Ԇ|}2alU3%0WKM/n n4usy#3Aa@,`nMGu9V۱2Xpj^}Ca#J[:9X$y "A ).uw` +ҟZ%H蠼%9+fKOa!R`2`)ؕ?+`bUᜍ%0FWv1^z*V+wĞM'\]rFm(5\Nb٫pK=ݽ!S]w]PLZZ7vUzݚ E{(DiyFN Ɗ~ET|j^Jq)PflP{q|\w}cwÚW^u7"owâ%߬/ X1Cfa:U^|2. gl|m*uδɦ'aԄfi0g֗vja& + c1Ҙ7ReO,n{\4hY¢<ա6p=L30"V ]ms#;v;7_&igXFUl %D*n /|=6@! v|>>^~S59~4SSrkt"zRncaq"0;);Tc<J5A 8WKJ4HWĚ$-7&!'pX?ʯg~*rVIzu1(jŕ 'įigҽ"v͆@T.uU6Jp@2ܙK +Ԇ83Ŝ\v\Ck3-eMfH^wYJ%Nܥ {A4 +!1DNk@ꯔkæD"7=CM^AD# nQ=FC{11!Ӂ% jȰ|L +j@pz$t,e䇏q[,o~aLuq5H `9]b-. z'"xdfXQr}3z`IY.Lj⎳-jFa7lˬzXuGĖΧ;0 K ]"^u@+]"5}[n+-vq[Υ3]2 nh}=QI#~M{A<\W1$$|M!ztZhӮk'ZcӕGp S.&~ ߸^ zX}˭&_-c)^٤HDo;֠-d53,d=G$,-Rd|^H?jւ*F+8duםcs{_3 + TvfurQ@8_xtSڡ dQ#jTsՐ3^?IJXfUmgXx6;(uJ=[dWwߛhqѕKiFb/izے>2=Oy @*}4X\ϭX F⓺Kwe$L1O`Z~)b[o܋bG8[7l LA*F8V2bMy(P7=\k>nP JG mU8}#ň5=0{&%{J MٻJRHLqR<0,\'xW;E,?H"Ex?ݥ]SIb$JMVzӉC/ Z4cYA"ٵʝXD5INnӅ/Y=_- >xxsКNFMb\Z֢n+}>,P&wyˌ 4=n%^~^CFygBC$Ӹ] e۳>m8+Pҕ/n+~|rr;| ++F)ÀvT*Q4Ը 0SI.!L ܛ@I%bx'PYRg\0/L~.TY$jH?aׂ (l] muh Svy&iaW(qFyODI*c +Z;4xZڕxq^VһsGJ2Bw/S>'(acg ̊YÌP:, +WV00e'\gGӴ!$d[eMʪ3j7Ƌq0ow Q (p*fUpT%>LOa ),IuȘ~S1BvBc>Y` +GO A*FQP'"F:XX6FQۖ|B4-իD1V(=m'X8CDp벸1A?鰳Ͷ5X"e[¦Y,8qW@i2rѺT[]YJub'+E,( '^} 8̝bLu!kϼ^#v ᭩7(<'$*94tBe<= @kDCcsr+8.ړX8ު/MkC2(nK>4vfi:J93QJ4{Vde;gL6e6oeR +Z 3-u]m.ڐ h (ÓbCG#P ۛ]1s珊 +c,!aQu(G,X ;\eQ,/ +6WN4:T4mHW+J)DL(Gh*%GiDwf_o֝3eG5MunbF~ +% + frH d_je|YFC-Vx8YTݡ- YSB$?mARǯpdaQqsRW/HhWMq1/hMO y?|{ʹ~V♠Wp.*xbrՎPUA. +T?AJ%8N"I2KCh\Ϫ!:5 s_h Dr$٭+/C-Ls@dX HM{WǸ4f򣇔yX?=C)QID":$K/YϚQa,G;sOs:CD|Xb׉4}E)%gwq"x6ۈMG} {]xK_kO^΅VˤeL]xc5gqGX-:S\\CuZqeCPrf"CU 3X +M.$aB8CY\u`azv|kW)X@UKg91]S57Sȫ;"d)<$lD1T|C@ bp-,L{ +I^̜Lk7Odai"e$\+`( .=B\)~ +5r(2Kcdȏ^ ԬAbQl*}R-f†ߥ6bY,éV~1?0knW@o/,'# s +t%0L$pLEC^ yܚuw^i: +jXh6L#S=SZ%&噌 wOP5o>RqJỏ#akQޡ/x_}p*d }ap F_[ um@sy.{y`/%hRS~3Yg'A #:Jlo9ww#ܐy0Q֐/LD&1XU6Gˆ7[HZYD7)< o;.^w*!vO=N?cdxTyۭr4*R¬>\p%fXMj9k34}DxCȊGM ΜR3{?$ IqkvߤyFu#AM?0=9CN3\6-ouN)` V2Ŗg0ws- n]Jw|^wVt9DkVi2h7 +p\G_uqIDa`skL>OgMMid%-N +;[e g5x]R{ +bW?J,&mjWUWTk=UYBVR,|04?fb'ҜH]LWb#D]hqhDzCk1KCE# 4XC~=EDX[/tKX@絓Q5Ta: 0 7a-_&O!3PC kOf‰؜xlBhpg(Ja̤o.e b"CwJthOߏWZ\mVzňi.^rtRI}]5-s"R}v|u ѭl=øYHUc=4yAVUD k/啔@qҿs$=JR䋕ą@@q݈`z7^|Xv0񙇙vےbu_עCz-,Ju&B (e&6sSAmZf7Gf PU"Ԣߑ<hOj} &LAJ8cW 1;9^Z=8/,~i%n$>a >gwxBBtWHvX%򈪱ABh;Jإdji^3fC`Xkw`]\Eӣ$+Z:*"ɐ.~Xȡ\7,Bv<(JMy#U@:4IXs(ZxM֎ +9|B ,<^G5*Pn 1l&-i +bz=`7ٹ`T84Eq٪W*}SZDūrI HZ0bFk\XZ@!6ޕs99nЏbfd`5LԠLuOOwl1dufh2WE^OHٴ,W*'GR.X&ʦP4(ye McLiVY%tBknE]+YY ?vt&Ts @aٺHQ)R9v_%tW2-:K@ &4 ucqǒhq4M~Q%li=q i@ SMɻա41Im8+GLV[7ȕ QJ:-MVV˅xÆ|,UvKД =ҹ +lzCZ8|~NqУƠ# h"΀!舣3r1tZ8@Wm%E,3=-9ltT2w䡷5>~I: .y'ƞ#tEPϛŀ7<-9[8JiP&oXH9.90RmٻZpΙͪ`RC3 :W$n؃0笋B2/Ab9J9㜲R>!Λ}k⛳W!k(ylyfF#ΥF&c1}\uy7לxJ2PPs=*q.I|b :ќ+9欖4@qQxC[0s96jvJPe.$P$*1,∩E1 yC̱`?`O LZrs +]3`˧V:ir6^֍.S\>zg/p9JV "4Egc*>np9,J\D7GN`9LA+4Iw7+.dV&{v?.R9L2|4U&nH]Qަܽ(otrhrS9Iezɛ&o@ð~k僑=;6nTr&H(4tn0[u!ɑR$39zk>+%%,F^6Z0\"FDtWFQ3˄8@X%k@SUSƐó#wRB9# V1!dL @A'G|rYZ~5g'/8M|\o 1}"rk ˃;݉o8?8:^g GՋ99㬚1a6?_t0Q(f:q Nx 9AqK5 'i55mx{\4gE#( xsċ2ΪNJR9$3Ʊ'b'{q:XV04_+Ƌcl4袋B␂2pqОTuőAnxmVY9ӇX"G[yTEV\|Qš85D/%0G?[v'HlxF1N~"䨻bE/̵JO0ᨊ%ƌK1lĈ8)yĠ4 ש0>\fA0FM-8Wxmߨq?qƇwg<͟ >a1O)†W6UBR3|0ݾmf# FOgwnbtr2\l\8#} J>Xh>j +wXp_oR2\e Nt# I :boÁ_ Ux-/>8J )ƒcRALȭ PƃgYƃYc8? &q,:xǂ`O:[1<q&?jX\dpPu\|̖u:HǴ((rq> o,x6aQKVƂc0dC򺗆t +QZZa**X.8V\. +@LZg qsbÙ|]/$ _C +>NL^\؂ +Nxp\5 ++e,ߔ=5dEFWO JU} 2\m5ME߾:&C O2w3cAc0xdiƷB~c;C%4CH't`繀߉ź~e#U0X9]ZS)~KLU>`m)e2(1io>M䆩 MM+c!a+$~@PTt }Z]o(ߔlw"F~B~SXl a!Mb1E2*gk!RB3TB3}!)c(7l04𝿐ؽM| k*o7.KL@~C{ )R^D~gs|V,RgXLyJ#h +,lR.71E- V}q2W/ f81}J]aߨ>Y3o2U@߈_9ۘo +vBڛj7 ¨1񍈠MfԑJ |<әᛗ%S{,lQ|O/7;B$;̋0׀(,7?.w"mC ho;ٲ S f׌M Zۛo7, +7 yÇgBmo7mj ۛ%*,$V;(<-޼KC=Imٝ{1}gýY\{RiQM$V{TsթT$oxo)o7ޛxoU$)[xoXj@7f9'{hiQ8kgMV DHBCҊ |'@XDg8 2[6S0_EfW +,ŃZPB&P]S?ou MAZMͺ>#ip2iF$* f)T 8*(2]%!<߸oRG[τoHTl7#pkb|ݾƌoG[f|3B3J.E/d*e&/5F|3FF|##ߩER27M?𝖒!߲luñD{#aA"Rg$u{L) Tf)AIea|7٧,Ȑ2xoLb+3" ޽D~7UE c642z^+zQBzYѱ&{me&!RrF +^^ޘn6uS_- Y }f!nN) rl2)sH_{ K<ʍ0m5/&x-_M3 b3h{uax}+rp#AFyӃu]\OdԼl7VLĽ8j 7x9ѫlxAg0`p' +p3a'z sX[{ACEX a鬝701j8!kYmq෉CA42y&ae):_m>T͗-voh\ 9caySJ7#]n)%o6j r" +)x #rqT.io}.r};0*"p ECYf'W*i]n8] kID +܇ nf!ܰHv1ΠF*܉ttԭa;"fpSXRa3U}1QGZ Q& ӧ<nsW 9/ 7#fHt"4c4S4%<k˃m6, +6< =G6D6|{t-{UF<N@By (YQyq3=*S:XM#irC:qqݻɍAM mpެm  [}ɠm2պ7gMyi8_Ǡl%7&rE,X8 ` ՌAFVAzD$:@10tU\J^BNb8&bP5'-`mesA~jZY S[fŠSV_ U3 p<ژCo ڭOO90LYiCi*{AncL:3Ovbr 6ΨSsXS$mLTЧ&F~ h0DО lѤ:}!Vѱ?[00~Vk/ó CFg3…E#ِrGf6{Ff#ǣW]I@7L (*/j6B[—-\g5!fR]t3g qxf迱eH6' 捃Fdìw.(ٰHlnCEɦ,(wST疳 +O%:#409!Af3Uw7%KtXgHF "{[Bw$Q ,:x矶v\nmu/د =̺ŷvi&cx/0`M$E(dLl/- +F/"v3vAήx0C](`f򉅝]5X0ZY< &ґ15Pg:qBaP(`jaK4(ؐ|1"l + l .-NKz5\Nn5ʒ~fH6C } #A.!W 5RckTE3fNq( 6"`^3r8F^CEFzy]OP*M~ Gfb]7kE ]7Od7#A57LBVLk +c\ õ%M) ^ :Bm2unS|s_l,J܃j7(5.QeᰋH#(bG}4&4b+`9<`QCBQU**,z.5* >1V162^j)]zji?zPSeɵ(~ Y1K.PᎥHbP"AD18!!4jê P`L%͓ʔO!'坼hҋQ0i"03Kz˽QҨJƹF1zIIӊ*8gQb,/D!kOP4cQh.6tD#pˏ^$:`D/ÅV_d D^Р+Ptk o84(]" %0FCc1'04d u[Un*tzdAArjm#{"4X|;`2>鿥iZUsϟXXaOåya +(jM+ΝKdKww@Wߞo/7ǟ~?>z ?~گO~?uqBqUkǟ_?l>7΍ӿ㗭Y1zWO~Q?_zg ?x7i-moֱ~_Ϸ|'?}ao?oǿgHụ?_D0!{׏y{ rQ!XcY|/- |㧀ٮ)~ 0VA>*OW=8߸B>}{cn}~>qi_nro^+LAT09Ԍ|,GD,noz/3 px=RgaqncR^Fw8Ö}9]׼k-Y8~9>,6od"j턫߮Âφ㯜:F]ot5c7X ꊊf>0x2wx@}Xaua[qvߴ;{Aݧn}~>qi_w/po\@$g{K;>w8.P1 |saKr A6fx?m?:܇u'xM~1i0^a>1sύ׋qvs8s_ o}}x>8=m=mײ{\>}n^x?m?~9>]lhҾ+a<I>0[zxE^v]97^ymaۏއ=.}.鞣ۻqa.pv߱ۻs~8}Ҿ܇5iۯ8Nc{ aM;ۯ87^ymaۏއ=.}./.P!'^z6|z=>Pmpn>xö'{\ڗ3q?N0^Ww8oqn}~>qi_w^ܷw9O8x]a8c9\w?9lqǥ}TԞ!Mʟݲv̶}3as&¹:/|ZA$8$x^}a +tܡAG/ޯYc~= Sb}3Mf1< 2>OFk;f }&=}6fi.}maۏއ=.}3 6|1%Cruu}ߊpa:>6 >|5.o/?!61qQY}mӶt|_Yϯ]mpv(fWx a1}ys3y:ôx{wq#9{տy@uBt}՟ok-)sS<9}8/}EǗ:þeS T5S ~E~L~<=O}>~t퍖ucn}{}߇}Ou}nWrk ?3yG4Ml=Mla=M|=6\,׺Yj`my^Yn}6~^bUymaۏއ=.}nn 8x]a8c9\w/΍ג<6 >|`]q{pa[qvߴ;kpvsaKr[2>z˟2> NTaL> {׷8}㢾܁|q‡þoqظev{׷8}㢾܁voxs؟qþqظ_7v{׷8}㢾܁c?\4!rJDzq~;{^'9@. J(fMƄSqEח_<֏4|APʲ,%wQ!c+ON?Vv%,IL8Na=ǩ2z \4=F">5x>{coay̯hNO޴b1熾BzTSKUuM@8[ݳ ?= +/ȃ|lU{K<\_?귛:4'|mhbk4F@7dRŗq^cNg"/b]_EaҟioMIΤOFT%6鑌IUkh*χozS`fcm$Ww>![C+L//p_=8GWqM':txX*,{5V 2ƨ|yjĀ5~j"~d]g$m>8v߯^(4v@OѠ0+?;_yleh:!G_?#Oo+@ͦӿɣᴊŤ9|1 TymA/s ㌷MM^o?Ǐah`1fa|< _dl\DY=؄׬ol4b.]C<L=j-$xa?yl??}}@Je#6(W5N O̍7t`Nʜ~^Է1߱uG`Ox\bcM8lIZ -cWaOOC}0=[Jsu92VOzq p{tEvm~m*Fl׃#aWfa|N[Wq~t[5^G1 K߆=AdlnFE9k?%&s[7vg|LQb8IϬYZDǜPE9q8U*`M˖(3݉"vm7 +c-bPGޱ&ud!#76Tdx\U TCl@[̌DMPr:#=^ +XջkkmQ-y3ŁFJ;rwQrf ū[ +1BtohT]y>QENBq;}>Z\zЊ}S&X4"cHjX7l Gay6yj6yppfdyitj=״]UsLV1-$XC#ŴECR/X` 2ętҷ52P\67K~ۂA+"$,L]K7ld`UCР|H"Q8ȓȘu&򵆙g:17p +@=/4(% *( QV/|].F% %]i7[ ~喲+6ʄm#T"Q w`[1`(l׺Z3ATT1ÍbN;b߼3fH(C e@7LA&q5'=CK bEeQȊfکCohԑ~ȊՅnx7 ӎ eWG5 t0`.MkA.gP"A +܉~\Fj֍(QŌ0זX&\"2 ذh{^Ys=bxa٤vxTgui[0IBD؅ZDZG&(4vl均@[lAjy:|ˍ&:I^ZavMOAy-W.$&n&6et +e1fWgĦM٩w%:/̸15[9[G"zVHH 1Cx詭Mμ_1#-3n|l+p + |v%Y>ul샀,k= ᆬ9TӉp_xi\>DHQZX 7vZAiLqm1*I22X(BtZQ=4 <$xEWn"BTib %[!%eFEٰn4t^MxQP0oa @M+. +1֪(MA`PLYk֙iDd})ȫxѳ(Axvnt&(-*Uv2C,[^hc {^bnIxF2^ Sm e։Gh:bRG^A1q,"ñM_AB =aΌ{JҀzu?[Hz>fVar R"J@w|#cHmc-JR4KZQfœc6. $@@mvW;C.:2|5A(m5-l\d1qzɄ:$wgo$e2ҭ򹱗- o͢]"gukuMV`ZFH^ ^ubmsbi(uH +j]Aa6x`XaVF/倁bV +^Y axD\m0P:1oF0jT6v> kr]9H9&ӭDrF!YxE-sr/2Q'U8LK!bF63UwpS $8`pƠ$C|Ԗ"INJɊKHBε.ِ#9M^dMa $GV +tb8%cU6H.dpD.^&'+d$A -%~e t!mkٿpI91krlcNtA'us\6ֆs|:!PA5Vc`tVY6|I?,u8I>@hl|t<:1fw1D +0d*8XK Ug<$Q%7c(A+6uBc -^e}ph9=sS2+qs8A8.'[dt(k + Fs +ukX?3'#Ō…*gOG XYia,\!L&mrp'9<iɍ}c$@q6p7UŴ0 u$@f}Yͫ[S2S€%r3@`r+C}ܲ%.&0¤(x<7nMk?Zi1,H>A5c ki,˕<kْ1-HA ɴmֈL,|݉`U>T6CoqYv76b #Q(i[Xu!hQJ 7⭲(\iĈPBdkPIx9S."rmu}y9|8S;jcrdb'ܔ) EhQ٫@_n ρHtiq^8) +jœG9ap \}E)Y쑹$d;V)J2$]mފr"GT%·\VDr'޶dA` =P}V.>q"K)gʕ+B6xnt g5ŧ+X3+V D|&"~@-+~h4[mS=XIgBbu*RZ:sJnC0 +@_J(~MAMڊed/@%1 r:Ud9) 0:*8p@PZ$K]B]>jC9f8c&{}Ԅ0`tpزULǦC>Jb:VgӢ r~/O,0fM>AQM#c䓄 +8zwI?pmH@Aqg{Ԡ7696%Չ_"2Uf^ELM4^VH.,bp ,k($LĉI}ձ>,>X󥦩0p^,*Yys__X<-P-SAg !q +%x3{pRv|TA\-Щ,A2Zu\S['5Z ߈$"U| 9SK#u̓`p4ϑ\vB1/)e8:&M|B G󪆖-ӽBz} EFB6d!HU(3-SD:H>5':& ak8jY-{זO x8V rgE2S Wo$wБL@-;In qY&A_'!Y0}Ù4x!7d)!& +KhhB"C#R,S갖Z΁D 9 K73c< ,Xb*Vq`oJ -[P=5$nݱ~4m%9֒P}"\/sR,I`]D3MFwd%<dR JA.BH Y9sґ`z'kbC~%4roN<8\0d +bqXr ;l,>;7AoHP b#C/. p<8SCǷM}A*ə]! +GiI: +(ˆo(n[GG~ cAo0)1%((?% Zap/c XVO[-'XV5Z)jMU4^dfxi0|6xDr5eqZ M9Ԑ>Ƀh }/ɨι@V+hyXm9bV)W ,VU;|&uVpB%)X1H2XRyl/ UZP/@2/)7L"QlSNr2Up\m@ ˫Wrp1H5<1CG~#g(y@Lh̃#1s~1j9Fzu +/:G /Ƌ˾VIqU˦OF$Ǖ +۲"5mIA1-Ui- +]1ZɣLK]/>l ż^&̵q ggTlxjuV8bx~Z̡uInU\ab[NjKJex㶑 jK +endstream endobj 63 0 obj <>stream +!~l`f Z9kYl@A+'QT$+p(md*8QA$("*e+|4W4UL̲9$ r=fu e7tU5K$†11P9*pzJjw&ꓲ{%' >b)Mغvt\qK`sc2PĈqmu:z]bC4[1!0رi/t_4@K ^=UK2aMj3R2P[J̀2rQ+%8^su:(,a+Im\J#-ʬ7}k-3CT't#wdMU.AR 2(Hn 63+ +•P/mism7H4*H5GQrY$͆N@+*Ō:cNRW)ɮkbm]\NIEC]M#Z:g@A0%M0)*agƪ jXqt[>K%l~4s[cL XX+mJ]@-ǜ@@+Zi.>Tk a#qfN'.3`Ɗ1sBk*`SWU2a[r,pF TC$9Avj Լw/1ZiWGabgQ; _w1H 'jTu98 F]/V"T!W/é(hUf %x)FI4qrJ<^dT"sg*fh%3+TUsڇ rGIr6G[ō[ɂk7JuPqeIPWt(o%-\iPKҎ<&V-<Oʔ"^*r"+ɰM"j$E^ matU\7s䚁N 13kpxihE~C8tm)ffJLj$`,yڂ +H*} jbn[p?D0Uv`hɶE8O2ElKzI ]Ok]{9~s\3VLam F UC2/@dNgThmE#ҡ6yЈ4:LGCІަQNdy +Wh^Z \ ppbToi0Fjf) PHG eТʑ60U[** %u{Ec. ט|EԅROùuA"rGQUBNQ֗[2$lbhlg*вK{Z\$g Ri4N@_Ns]8\r: lN7tl(5[h 2xjY)D$R89083?.׵Ū!S cxLyZDʌfsH$ +R1Q]k<7u99(,eY RBi> KlM+veR3 +͌^L9 "*JGC((q\K7$IŻT]ב2UU%YШ@bU 1Bla<#teq^>@wvXuT/52:IPvJ%:k1˺F%79{6&`J@d{\o##_(J7ZԹ"Yl VufN-[b-KMnp6:j?fH)kY] >Zw(K^P +x]i]]:z4G~Ke9b?F X??8.R-XW+MK$?'Z)eOB`c;T_ +#9.rR;p#0JG&'#)PDdvܪ[$O.3w[qN1sC*)F/^uv\)u x.ș@)($.sL +`rַ)?kPf/Fqjx +@_5=ڢ=zivpځ~F.ȵx$Tú\*K})+MYԠ"'ek&*#V]) iKqeP)MVy)b鋔*(XھKKs,~KXr+W_r +0oq+C$zeP\ +-|˷J . +SvmC^ +G11+#rPUh^J\|C[6M鶒XRe5rC墐gQUSJaPZ[-|ɏr"4hDU)zD%K* %,{kP!`y&p%ЂnJ:"xZ2\ӫ;e̒j(49(n\OᲾJpհT1wT=] +$sT]XX,)WĕӀ(lJh]x%ER<#n'0rQ%Hh)T輣{%lͷRT@#QhPަQ3;dj1[lz~GmN^O9Ѓ/?_?c|_'' ">hz19]مO~{|l'Ӌףc'mF5,ήOSxhpͧ}܉|@oed1t|~2ޘ.𦤑W6||y5ddYoXN:;bkZOoG?S@?:א> +D3W`\Ͽ\~=~3AS5ʗӫ[d||7Ο:ևo"O{pӝO{{Ӯ٫WgY3.3)( z2FWG,7χ_z Ԟ./'Ϯnh;Wk3j:||cOp{pv~m3MɌLlLnNޣmiG}kދ⨗/7/>.+`Dv%WpB0;1m;jmfzh ds-zW=CV_1"#!~)Q+BqgDvQ$O'm^&o3#Mo@b,06{K~ ^;:(>/v8Mn{`y2wxQ +UE|}GV.ZOڮ{,l:msmp9=sߞއ/ rαv?~/vg +hz(]c37Vx;r$(HrKS{̹#9=$=F5ch[ ~n\:|=:?O_^'k?mzO޳Xzry1F,F ]ݚoQu>n<|C^wEn9aسp Xf}&hGS#ϻ\hs1͇CۥL7ٛj҇qt|\]ݞ g} r>F{bqN7}F)Oh#'9fqbҲG؁;Q?||vCD`hӕԗhOߡm-npUHOȭܥǛch;4CmSLps( +OZgfvt1p}X鸧'pX]]WUݪ=[܂-=[ۜ{g{87+{eqǹ)1ŽWLqLba;|y攸.FY;m;-osJw~ݾ\3pgs ~Y=r_`&'ϧ=O>{p||6͎Vi_Mo+w1-S;z!עxZTTxZT1)F6J7A9*0|ڢC5ܐ\[->Hkp$;ڕ yw94;]&C-n}C.3^gޛnuFdQ|DuFdvbD=(wEowE$}LyBM;vtdu@Go">[m,毌k-uU?Uw%n}CraɫWWyS=ʃߎx:"588jw{Sz2. :-uaswoOӷ~^{c1q99Zr'lGz#P@PKGY xb_vry1>Iy3?/ǿ wsŝ_}r{'jz'jD}P~'De:]3Dݟvſ"mϹo#<=jE%@gvLHޙ;#MIՙd|4-ıB&=|/evf,}/H)w1Ϣd cg@Gc'x=:/_e\wc[x,%*6t󻹱}#wF]aW. >i?n,#Ua?ML3/m>x19ߗ(U^{I\q ߕ[^|櫴f~y!07b{#&>:M7{y S1t7{qހ`1ꓸw<̀Wb4q6qߔL{{⺟!m۵WpX/Gos5>?a-=v_#QYڤol!^,&[4y23C;%ebeXYU8fW|vCj`ףT 7q1a?6Vޏgc!4GH};qpuǽǹ  s|K}& X0c@EbCqG90Gh>YiG}*{[>ۧ{to}OGa>Gnn^ f ǹ7P@{uo_+=^v@[:=P>5B}ܗlnKP޷{ܳ{9~c μÜN+['rB肀ڝ ەͦ=_Owwt=8XϿ bcW6 sy螙ѷW'?2zpZW\ccOBgPUr<ͮx|wE!>>ƿw0e>d:}(gcg@GU'߫S]a@?Ο',X ß׿|ɏҏ/ޞMŚ| |I3O?7g?C߆dz6PP&D>иӇnt_·>w1PW38M/O?9hzہV%C665*@ۡkM@sbzρvC؄06=a?h6ѧ04^ߪ uÅ h0j e+|Q۪Y;7F=jp4zP)kBo4L84Pw5mcʻM_z`J#f.24V[!jG:)>BIgtwxbf[,qM &Mi'Lm >D&D#OFkX{͘҂&! ȣҌLdjjLASZ&M, +:s€T[+0H+A \{eh% mDeQVՌ.(Ja5iՃcv@9]ҁe!)@&:lOPCP4i@!dMXsaczۘVi%Esc515(mSնZ,i3̝W~ pNӋ1{=^x[n]%GlѭZM}v}vܟ}vwKm>;^ڟs+\.Aώt5mݶwoڎz߆&ۊGq>oR>;^Ҽrώ 6՞Xh Gۚ6]I=(20[ J3ZC!qZ?zDiZ?f- X@KL]BR,rGրqfaVAU/ytXC)o ] +z*m*h`-"GZ`5t*NЪ^]D_EJe,6yr󟒅scl!J[ش|b֥]VYOєtB%A|ro3li9Ϳf; tPv: 񧟴<:#b1;?I W@ȯe_^g%$1Q qFU&$ttAA(-4 + ?)=t槷w8Len8$gƠ!SoIgdV'A?B.} VɿV,)Wt;{ƟS5w:Pw寿Iq7 G7(b&$x*@5`HMBQ܈-XH/Y5T`Xm=-չzosscv1_(ц8 4e&|P7ܷev#,7ؤBX2hw/8Wy4G<o,-FT)N,,<]3BGyKGhu|"62>ëRTMWeYCPktkFtOGvM6]\ˮQ5|2Mtr|8t|\]Z'۸ `K0X,C, @Z/LQzAV/Gq!px?].wUv^ {F2IDa Ibu9|;1jFk%&2S 5=2#3쨂̲>*ϮUϾ!$7mDY{MaX紊Pal5 ~]e*͊0jl: F&Evjoh?k@l@JW[dvs! n{Ml ) W)5Au@Ho&2CjsQ|ߟӼ +ҚUzitI8#@SfdKPAooh jH:ta>}=Zv~;/~?k:}8!Mɫ-4[W:1#AޖΖru0ʺi>naOX}wy^3z6E=zePhx^dWhFd=KHm[g*X`6t醉t;B`lPQ8A+)VQPPCzPRZSR$ϖag5@(BLIpCPEeycD`/&ڥcZ гVeVĬ8\A/^t8ÉxXЙU‰F5 +28JJ&>{˵@PLҋ݊2&Q;SqZD$[Dt ikrIeC& 1 ۤ5 X`~5 (x͊x2;oJDxv]!SpH*; Cm.$]#b5iW`v5 F(tɊt2;nFYV+* P*Ÿ6Ji +[vi75bUA]vVhW`i 7-w"Efw& +XdۤƬIzfkaXJ_Z]Ḋ4{ukCR~T"jM<?\CLWQA<(zREMUbA1R^K@XXysba!gw2U +\E+XբV=Ub K`+b S9cq}WQG OkZg씿875qZi jH$N}0m%|gf ݬ}0n]Yoɑ@ Г+%pp <oYGCxNcr ϡg椧s=":u16u=";8B36I x>B{pd! oZG .:k"D.FF=D8HD_DB7#A5$,i]( ]LZ'A}Հ xHu.thdƛd6'xn5ԅnu!ƝEi nTyP +҅VRX!{d.MS0@P͚ɚUy*=&z-WJ 8CZb!k n +'UiەR{*r6u]*-[ w4^}"a:ݥVѰJgxXѣ4**j]o0.-KmgܥV54Li^*KbkV%VJS^m#-C-oܡv!J Px0\Q;"JqC-"uEuh]х;D"bJQܡvh?WIRi#ŷC-b~Et_Qm;4"WQF^_IDVnj\=~7v eTKun˸Z0 K+s nj}5GЯui [H7xEDtj+bfeVj;^skp:ޜP-B$T.GߝBf&AZW橚)y3VUx.ƏoW*s[Ƹ2s\y Ng E)=x|8In9jp(c1 '&*nKn +9_sV޸cP5[Awso5V}z>G=샭z'vc_.noU"Eի/t烺с@WX{ לi)k?qz/K¾& #MQi=J@qGw?ݠDFtT˗ј>zO~9uDnXnzc4jL]1GyTO|)j@*p(E݊r (_šm_x-5o{ESSKܚ\T3TM]E}&>Oj%.N=oUD+ +-Mx־qotc+xVj. Yo<}]oz\G.(oz_ƸWꤎ8ոhq+ZZMF|۲,ٞؤ[ c.2X] ~x wM]*"OQCYVIK hqشV!!˯:Xrgh65j&rhՙnh~JC+ԿńFy }AFMU'Ji9p1)b"8ލ{oZc1. +H4y(8gӃv :#>Z}WfЬzA V߻HRteΙLx=k偃 5-.gYCnwZc囓.K˫Rh;h2wg :")Z> BJ#F+#|)* %NI6 U'X` i]J71OSwwX,җp_:d2?<.=~\>8\To&#Z 3$5ز PN;7ir!op-~lIn (VHdN\n9"[Q-puĝҌvi]0q[6@;(i> 7o!PyLB' , M Ub +(BR9b t۩~ޙ^Z$>85P}gm.վ?7J3q\A,&bBCG}CIpCeHMPefm iuXC>I$Zߴ /H/vag/\IɁ(!H=FfuT4DoZȷHVWZ٥R{Cfh +p P# &cZҔSmDs!nuaQJkK?Rb)zys޳j /4!4[WN8"[RQ0kZWQGQ?ʑ=zӴ`$m2z+2e,Թ:A +5n07f!C9(e+c0FAZM(FcQ-͒d4/6ȩI"Ymc~F$G `΀2iUV& HsaҴ:D$LJ/\kՃ ˦tZGfLZZ!.!5~M2'~<ʑIBCޏΈtv ܌Ǡԅx!mhч{\l(M3s4 JEsMX%ab6~NFK2<"E +M jl*_&)Ji#QhbZ!=L%VŜ|L <`e!3Te:,R1( +q(H+< &A᭔w%e<i]0[g̬=ݢ s57 ZtUʖ hڴ*,pNz5>TCJ>7{BEA6Z|!pSV@Ʉ + +-ȁ@<HD/p{ DS.@sAd6 n+RtT<]0[L:Mn|" %a$ ~]g@?!&n d^ER<'<24[:atPDy0t F"s_2$5mdyji0 H=N4:ji6RO0*ɐ7N`5zeϣOGLC9߳P6 -G[;IQwxE3^-Ovׂ{$ h5%At }FJ]IOce/2-]/z$ը<GZr( ~ ?J ^Ko{u} zw9gr9#JΪﲌ:^kVUugɻjo*%yI"L{Vh߬s$o֬]޻v9iB]x5)s|kyUL]LxZnx~` zU~Y*~l7|x׀*$(/vO}\]:Gfd^\(6 ~}rL+U&qU9 "n];kKZWz5ۘH,˷#v_|/w=AJ}' |l~ +-?t:I"$79Qˁ\,fW_bzy H\ķтHyNףl4 O&SnN8NmLsPݯf+v5I{ҥoRNTlL͵xSo|}_ Oo//G߽biAl}$I7ciƷi2>|@ML×_@qIt p<]NN:}Phil +0[4>%xRLA>GczjOWPCj/$=a|vӫbތ +ދ7FL\y3>vJuąbd}F?d%2i1WH.^ԃE.x"Y-X 'KA9w֪ ;mG t:>?;}{՘ +t~DkX9^w[IOgDi^/yOWhPQdqpH:ի$R'-Ϯh_O./e4ϩS3WG}o]:R?3챎ik1brv1-b(dj<&Rn;y5&_V*-urPJ>khc@>iPS Rd(0}pcNCY뽘W?$Tj7{Qñ҃-9ǣ=embG{+z7㷡q[?UfVf7ǡ:x&&yfi$˚-dYȮIe)?qƓ^/XP`bٓej'Ж$_qb~u:>]\m4;nbm!Xn52EQl:@i@͘u4'~e)#E}b|$(dd.'\d-OznU4#EԿUV6|L 4?}˦@G?]'~iIm\̈́I{t ?v_׿`y8MM^A O:[AzYLF?EAl r@Owms={Ȓ +]|x@ep8'ENMmWâӳ܇Hq7=LCt 65x?B `Cr۫ MlIfiߎG@M%ԕp6qvlQ"E(gD2ӫ{݄CthsIRFr9굩puMe;K7 +(s4AGOWմX+r]Lc%@ \P1/%k~§ć@!z\7Cuh\&Q@ pw +7j?J +`LTXibK'F@{dy4=w9 G2Zq3􉾁ug% ,v9ob 4[}VPTU7\tN/kڱ6F| +*qx ֍#ӵ& fo}Ym)e*nx Ǯw'>NC|ٶ_/҂|vM8 +h>)Hד_eGh_ummXfij<_r>9{/ڴ umU;{Ge6~=lL;qu~ R5>=*N7Cp +?Fa +Z% +l@?L gJB1;ɥ#ϩ} >qʴo3|rcE"$N]h~/(ZPh~/׍\utM%tkCNKч_D:kϡG0&糋ף'qz$quV؍ݝ &+fL|=s>SsGov1:Y>O;YΛ|dh{Wɢ<[58X7ϋQOǯf [_{ٳ2[{9\ +b!4VaZ;L_Gw7H-&5\p:a[]9+wpݎ>r8P~jI]U_;^A3 >.k.$.MAko9?~x0ܼߟg}}}@~d>דŘT'T{:i|*/hj#& VlPc<OxF15VV׾1"_̭6>_䑤˥`Cl*s:he`}UN`~5aj໿voB6iOE[mFO)-.>ҴtʌY'j}7f㫩 I1бQ 8Hg(컿M%%:QĤi`tpH"CmL̕uTLtk\+60: `PCp4~m,GG53JUlUD&<_FNg=vt2i@yxdډw4ӐbK5@?WLH{Q7ҲB*a0igL(pEkWDua ,@r~s6r0U"Kun18tr[ $U>|B2Н ۴ 8hm- IݷCr|Bmq>`ڂ/ӈT!'pKc(qYNcWCQydr[*$Fѡ'ظiejm$Ť)n U`>&-0Vlī#.׆jO\$o0Sm/4^  ؋J+i[8n:Eb2{(,E^he"<Ii,o"C)C*18-ZQ#ϴɭFƟ%xx2@2DZXwFE-n̄N#իEba%p ?CM Mekደc `:.v0ɱ8 U7M޵I['<0ϏvRS#aU$a4-NO25TxNX,&*|(עɶ*7Ijc|-%cHxJ f `m>t +ó2,.[4Ic6y&m0sa!Wʅo-q7CG@N5kz"h)ؙ+;PFdmN3W7 T7pV6Nb壕;ca_I(3U +ƭ颕[NkC$$#AHHe,KdM"{W'%pǖ?0@bPXVV{@ laGKcQ [lh]Kw+/g+{AԋM+Xں6W$>:`wEهy'^oT'Vv?oDוfG24!DRҀ ʣD0oZ+ڹ5V4&IK +'1q+i +Z&0\H=ѸCl:qM gρV-'e)iq{xj_ܧxw&r)cMxӺ̧kUAweqHowv$_={9]->,)zvq dDHћٜؿQ'Ru|lFz6>_ 2||gk~jg`X'/ + yjԷ||[qX,^ϟ?oF˯u7#5 !3˽~yRaM(Hbiy=_@ᚅ MrQ;!̈́l'F;cٽfsm"q&1=^_/G+Cpʗx{8trxظ'[IcroAVr:v \x<IsMP՚0 .m\o72.Ɍv;Z̽W0(~Pr9]α9=wyjfCRYd9?o[@ Q:i+ix/V yY;y W~ (\gD1Z$v>A^l2[Dzt?]nvzE#To躆"oF=_'ym݁aUS*IZ,F;YηCG|QCFu牗\}&?ܶ,\Weϓcq|\guJ.?@.rߗ<_|?'@bj8&gk +8Nlm܌.Qg*tڝM>qzzD"zZL]msq(E6b0|P'@Nk$w|>,y~N65m]SL@9}Ǻ-'RpJAqa;/@C])V@\~:*D´ >3ָ̰a}Tl6fW  x w SOj t~&Xm0 pu8M`0 h1ڢh=maTҼ,N0a\(Icly;ϡb7Оvn473xWT=w@[.rBxarJPlߩr}z4guJ4d<~BK #RIPO "*qP ٓ jNXNٟ H=HUh;\:k"P۰8, 0%l^k~'˵Wf$ +(Ti{)1l@5s1`DNDn8.8D;i:h 8&G%+蜟@4lZ^GF7-[]s3՞`ξ'N0XtZ =Kܣri(1p`H'f@r:"Z&j,) \Igs?ٴcy ~U%7o!<3<cnPB Hш2B43#шodXfh_S6ǃ^\o4_D4y$0J0eQ9b@{|=26PW>e"% +2d3X6pȾ|8>j5;3}LؔՓ{9Gۑ Hh Z쯦Dϋ^TvۄZvٺ~g m嘑!j*xsKж)r/|e5F\Z +nTR)?%o7Ckv(_%aא2GA|F7ď*4ݮŤ hl@q*&qP )"`_$l%⶟ ވ0`)y=u@S4L57~ +힦*{ qLO ދ1;৻yC-՜uBN9 d{!>/{-f~# pB,2/#Dc +=o`ظp_$`{:ʌӑA@rw:zƕ)&GxDQQ0 +8D + gj*REl[?w0uFX--~ښ|@I6-ˊkLQR3x",U/:_2MS_a=>Ͽ4&8@}]jqf2, SQty}.}Ë du,Dozu}=@vO]Om@9ow~}7I|s +@O#S271FϢk^cLE/)/F_ls/ŘؘO3aYx6xP\`vHݛW|tY::?'wKxmt$ݺ /k|\uF`IICJ&zKN0kWhw@cO;,gI|,%i'6,Β3qQl LmQcku8o6G̅;<ABttrlY~[Z ;:bP] Bq2a\ϋAa* bM)ϱNEdDP)mrjw㐴L':=&kaEkmEDS3|IXD~ +Zq+U`;asJz\BS + F EY­κHjGx4Qݓhyq" 8er-h6Ǽl5x= pXa]BZA mW oǍax"RJ^)#B[?5`,'['|Ëy9wކ=u,iɮGklL!~.~VP 9dEʷcfШp52IiCEGW詋mN%mEp-K/4X K䒷Vkl"Ǽ_Cӄɤ^*:;R5׏9FCtw(\k\WK~K%Von4%7ᅦp{fMMav~$I#iO&=[4^܉Em#۶o[]+wʢHZ H n@/rpTDvbFϟ"Z3x' iYW?UU؏aՍT|~Ӆ9?7Z\V8jJl2Hj&csh@XBUVs͉CDn`io'9JjE5iT0hY1-F6;dߑfd{QT™ŭ ͳ53uE-9C$pZ}Ho!4ɡUߌ9ڹT|^5b+f\]`u}p:$Ʌ>xӤ[k̒se +&~E힚dաL;Q.nU,rOEB::Y\yS"RUOGKX1_<k~2KgZ7MZ85.r(ᵮ-e6T뉥Q5RangY`W*Ӄ&eK!?9!f /%ŶfܲƳ4 :@cX F. C#8hRw#GW#`QΗR>xEu5`Pml?^]nȈyWc5`4jQItN :y*lJC\R!.p*?&b<7ȽfĶ xbFr䒧8쎝ՄM]i1ZD>&4]Qt%dY7z=Z ypeI"v6HeX+vr6UDRuQ$:ׂ޳ali*W)aN&kiM6&3W{7 +ͲluęJ\zՃ򕹅ff`tZj]K\+oFr&dW-hON+ t?K)zZ~I&vz"w@,#./ `\Mlހm&䤮t 4+NdV2GJqE]rey5wK3cawp\>N8ߠ4j$`-ȕ3!PR]\4`jrDW H:`+34ƶf Ր&ГN@ͤ 8)9)hasKB?]HN#5o@oq%_2ǎ oq67p?^ pa^db"=892.`ɛq # % yэ+j?V ]*772 aNbxHjM[/ez4\>_ |\$Ki7@h8{%4_FWK+])LmYqkcw85hu{["`/blW +9PFhcq:`,6Tef}t'΄:r[bSx:gaUߢqI9sQI+:;c +yҒM mDzT9` UO~LsM&s8Lvϊf-zڭ~#t8WŒNCofm#hɻċ_Mi%55j@u@`$1\Ց@pS q)df4]v 9rU',FyF&è3럠-Fhh:X@PNhQ=xb,JR;r1.HCe;h`=~L-I}OyUhb\9B$v3j'q½"+D*Eғ:2ИKw?7#qc7*DNI;H!~Ы:{ץMivm~cy;2#X/!r]PtKK0zkWKr%%(En܄Ⱥ&&q(Ftwf@ioo6}t'kviM~[jԿ`TyM#rqjTraIflR54dI-,._X\2@њspeZGD`4u|MFk kHQ hG%j .]ľ1u'tk \vj=J:z Q BIe561T:6'hݪȒ?nNګ0w#WBN7D^ԥuƊZڽVo\WtƎgsF %knލ 'M9m,4^"3%n!аChQP mtfӛlMM? uvnȪ!}]oUѫPHGv!cempQ9laa>Lk7&`4sxF6( 9jQZgd%E29C}է7T +Trj:*»lA2h  Tqaɛ N(dOK?5Vڢ(/?vnY0#SJw*)un*]8_0(a: 49g!Yls%kg] [AYdt,2O=R`g?i}MG_cv? Nרb?z I_HMQdմrc ?$X(u3>i*>?jLB' 0Θm59ho.nDg?/m,Hܢ&{!r~5D+Df !zM ̀>*VD^%>˨i_u+^NזČ1jғs^SXStOg@ Z?D?90Tu~~߬2 +VhƺBeWܦyc&H ^Vn;]bWe/dDw@s?cFomȠ;qlTNXۇ EV܅@dŒE:j=aء={"V,K3 kFLn0,a09aTFLVחaڟ :&7 ˿\-V>2B&TLarCSLX,CBL1MxiM"a栉{?41j1r,r^s.*0œ@sm1OhǼ)G5N4aAUˍBnXdoc1.C,:+T2c˖r,oEX9~z-VVXe]clс5,ּɰĺ qavÍ *6; ؤYaQ-f:Fe`;_J4vN`Ȱ&cE*&W4vC-2E9Ycn-ϗy~߷Bq@9wNZy,ne^$+͊Yu[f]ֱ@V&ְlMn;/;=YnY!W9+v=iɍ5`EZܩ" yו'~r%yfI MP^U_(ȵjy{Y>_v?[.RxPK~^),‰5v +ooxRGLOXՊ=jT-j-/虛e'U,b3kڤ7T +JM Լ^F*Y5ezUY)VYs"ʎVrv)TlP7ʤU̯򕭿: +U̫^UWn%=Q-kj9wIu3j[jեeTuT˽PXZkmUT/\zWM$ :4qy]>Ms$Sd4x6fqiLͧZs\_ֺ 68dq#p^hWǼ8.vũNo-sqa.iS<tnN sx!gy奈kޘyVw4W |ud_ᴯ3_}z:w)"~?k +X4rg [ʫi60Ӣ; +Ýx0i?48l*cis(C?y]64! *l47Ϲ. 8eHDZ7b.͑ۮ4J,2mQlDu49,ekSWż.?ZαA,-ShM?:{'#P٩z෇XbMo`08tBS>Xu0=Čf5 ?V&T3h񛯆fmsAX\[q\l"]bF!{cuE (B?dsq2y5rd-Su4^ג:T0ZuQ@cWTq +\BƇleUr>/uŐ5| t.Եiz>SY ܷ\1:>7||Mok/*Xӗx?P kӜ/Vksl>*P4 +`u4cu'ɏա%Xa导qkI.bvFcB4PYs:/tVV${^a"w  bj:߭U :w Ue 4VC㈇j_) < +a_]7/ռʏ׆N]޿hpn w#%~NǒZ~xRK@TKq!cK0jcM[AXQ0-W!L`5"A& X +nbq4Yf~pUF@>rٸ `uݛYj 5a)^qgٓ/wbvAynÊ6ǯRje|ýoWTXkhB[niK3 c-ؕT$zB 7iUȿ%K+Oc-A/m+oqRX{K5c;J^AY^geM `4,.Njca4w.=$NZv cjS4X X 4V"pNb *&ek6`.v2 |کXwM+KfO7 *4m +hM*4zw +>єVz]=d8 >2ѢM 8Ѥ¤ +tQ{ӑµzB83PViH@-9R@lq(nmYN}Ԁ:la8DDu(:X3B5&8B87 i$&{1:[(= 3b_;~ZFaQ?-#LxZpMҍ{ܦ$!Y2+UR`fKmz^,ҧk8'{DzOŠ9})a +qmEƽRTxb `7:$h َQ0D?I4t{cGf>YE͙}~z3t]=kG2}/kXkϙlfK2؟'PGjZ'@ S?7kx_7*t9=!3䁤p@0zBXz=k>'LwlDG +O`plx%BɊ"-#:_;TQEdNx@<|p|w/ [`՚_Ҵ`GZF;X+T.%%} EbgыZ »1WzyǾ(21CvG̑url^t~c,(`CQ#6;  's7e狳 +8=Mȯs[N"H AP@14C\Gql GRBKд!\5zRGRpíZ{jks׍cvӻ!߼>А#@3''C]8⤡P@o_m}ʨUQDG'(̕:[fzP@A:Id({[JF{'.1LDNJ-( tΠ ץ<9>n^ B).$rdiS 3Cay˜R fg3O ʉFѝWQ.,'a$Qc_jyКSx *ث,nf0%(l B}6Q= }/-w}ɍo`zrGcYQnIu~1c)B{_6ǧ58s{x5  +m +?oY{䌣?$ "(/rdfѡ,2-Lj8gڻ1E [h4ar6! LIҊ96+{> 5pqwxMMfik#Co6iԔ&hg?kHj?fW8Sp6&i[FlgHD[d&/bz 9{^ÃwYb}elLbƨ}3||_E31\/N||@: V%d:x.3ut>\>:F:x.+ut>\/ŧsP}Yoݭ`V.mx'ˇiX"neuONFH88V\'-i+ŵ_Mpc'do<7}̓7 +eRu,dRFJRo|oA6B;(O9.u#ě%_S{N_ˆz.T| bY׌_l{cݱ.u% &]O3v't1 Lљ 1aٯ$'⋕, ;z3&bJ_S1<]8T/Ww0NiGƍwz1d4G{I)="p0Fq 'ራ0Ks%5s~#xc9gD01h ݲaa5ŶXcdQe8_< e;WFSH`<ufihߐv_%ˆqveqbE("π!B΍4 wK!$HRLw7L@}  y"]p[鹂7g9 BҲ` XxZZ ,Rba+yZUH \G|gH󟉍@s㫨?iEKɇ{1jL6a_ilw_R E)~cESɬɰZe:E$|h>|"lO<3Oyaݧ3x"3O4syRG<B|#3jEtf.U<9әyǛyC/ !eYkBB0pX%:^6B/JjG1.25,^#')O@}:)#DR|<) _'h&3IyLoIs?i- +_ŲVaRniqIj愔xЄ{VBٓ/F|G@ 4)~= |{R. KJJ9&[2UDzjaw[OtH414BHO-ӄƗ("QW8SLNOKEӚչ)K(îX-zL4OYZBXG"XF/+7#̧0vܴ;G{U6rRd;]пJs'׭'v+{w +LAJ[k7-Ha +aԂK }"'~`5u +@:e\<*eFR-w9Ke+=1)SYuLr`XEIBgk"z(x0q?Y^ 0|Qbs&$Gb>Ho|"vQe=A\o +H + +67=nszLR=p>>+t}0O}6o&y}|Y}_&b +'IcXI@}=ľW7'yc}|Y},gF ='M&0 hbÊRLb_Vߗo$i%Q^MS[>7|Vo&qA=Rbľ'Nb ^#Ӊ}^KtbÉ}|-$ +ľG+J쓰|" US}>Ǘ2hmD9%\쾆'nj}uzYwT7銎>]ODF^h:.aCmC"R#ұT@Ft}R@S-' aa#B*:mkl)l]8&]=>/ʣ5ob%Q_a{upԵo_B er$\<7_KJQ6o#5o³vt.{a'r< :iu/GZ\*|L=p|ĥ0{I9}R"!G‘!!' Vo )M*XQj%t`.^/cZz.9 +z&9 +@D.Ig1?IEn='Y@" I5p0jX]oL{MR` nom[zC#uqN"ؘ 5|)?I!PLb u=M)%<( 6K{ Zto8'}лq(bwϧqgPw7 _g=U QSDO|V~ێZ/h6S04wXThǗtyOӱn w!ܻLX1ss;kawO2J5L{M%y>g+'\ebee4ySfzإ|ߎ@fV8| I ]r RGp-iy!UB4/*&ric`e]n]aIj¿[> $2+%pMDdR8( `uɕĈ& E.a銼ˇ dX\U +0db +@}"Boq`/feE%$qQw\u:!]C4._v>љN-:Nbj6 kRauLX "7Dt/i\98{v>]ROw1`wF2៊hĺ%_~OPt +=刮d/c'y*ƼfiY {?cĸ(QcA+v ɻ{^J?f(JJI|#͎RE)ޮwݗ`#;IE9* "lRǩ;a:'CEX}<}:."a9?`\m3xQNQH-b%9dҏS$s o'=*$Ke$l"dK%#Zv̧6D{1%Qj>ljjB%$JGC?(5})%Qj>"~9%/"V]s)R^OII*.Aؙ^Ϧ$JG-Rt:{t?~I/RNBh +b_}X!"_뿔<Nj޻- +yC?_KR}w[.nTz,\P<1扂.v J킇}V+O@ZP!򥂇.$,(~ %0' +Ў7 >L(X!߼]P|p\/Y=vuSP|HQPRPh[oHF&Aק$GϮ9a ![]j~u=ţǸŃ  ڡ ў-xMl7 +B!l,~^Cq0q/x(KnoqBъj?YaOCIy]?X'V5irjo+ЛH)MCzf[]b%,iz>^Ϻ>h6LWF&ϗVquGR^V +drUF +9>z!r_Uhn +Lp(R3VfRX692]Wܣ I,ו|B,#0rG{i"!2cԼJj"k 1_fW)'[PnJo^4&PDj&Vv;qEw|5' \ޚ`*7CVUW\.&5ɪA>g@|uP.2=#4F7o̩p3} 4ljPv䵘Cn-*]ߪ[lzƃ"hgq#6,0DhTdW$m~@x6tA6~ӍQDz`Rό @3j3v֌`_m8@I&#sCU1᭦8Tೳu)iJW'7k;xZ767#MVض5e4LHCqm"CyxXu - V7gW3 \}1[ u~m@`j6m!G2ГfKd[&Jn +v-1-9OۆtZ-Op05dm-Xׇ*|mS<׵13h]<'ьZX<~PmMK]<],Ve +u*sq +o9٣ Į5vI|JT;;ѮrSV6V=X791FZp9B +\.|Q y%D)w/Dm QKM+b^ĒS^r4ЁwI! 7z|jcbL浬+Ţ1]D'=G^ZաEd/VPD49=RJ )|0DŽ|PAD,XxX>k` xX#rV:\ a nfMt9[1vr:!9YI&NQ`UOkLvVZtRX ջ.bηÕ[.\N+*!PoxTެ^a& + Nte@\NRLƦv촆~Be'AԶ*uRJe.sY+v`5,*p248= ++ȂI~j_vDaq6%(m[V(OT9eA}釚VtnL^5 sEa)ernnĊ`Ex+'mp`:=A=2}HO&#W}$6ci=AĥF@[rEϠ>a\B!ޝ H","ϸC:tD ѴPD uh>:1X҆f f6v0'q:c_`a6" &i\z>|#P r&7bgdIë͈U7`H74 + HE!`%6 NR7 6KNEY:bo{v6i>ipylp{(%,Nc-jfysF-r +§;a$c9^ڧ4xtD{m ko|xa{vIt,8sɺmd{nK7iN?lw2DTbLϳWtfUl_{Z=mVW.cfVfosNþn Y`deڃND +d$͇PmL|(-͡!hffy|2{Bv&2d3^g![wnR:SgH:}}6 i e-3G>ïC(b$,eb8<}Z 8cp+[CC? !-P)uZ3Բf);iC<\_+Lrzp"Lna97NAn*fBWm;4\x`@:*9p=X6^)F5ғi3ߍuJY))1絬]2Z) gJ{m B;;ծ;~ͰRsҢe&-|҇zOJzZ?ىUŁHw.KNw)wB}26ڙ<7Nr4]C+&U$m鴠ܷRlvťN%5jv GJ%MZם2\HPR`n(V_P^3IڑhD8qhp4Ĺ uF.=7Ɍ%G)ZOH8ޔ Y}5~µ'W +2ǗZf7>h !:&ȲG4P b Ml+ۧrK-`=ƈ%i  .Xxe.-'r¢F@2.ڥ9g`JWT/`_ns9#.l_nvm;?zm/YR>k0ųY31fo\L $Ǖ eh5,5<lˏNEH/}a\G,Dl̅43Fu !`,+yfŒ_/>BޗQAStVUL鸁y<`bOgMpcb/7WzQII9T*w个g-e@ Yt)a.Ʀ| #RYԲ12jK0f2S#9CvCHW}7)c߿{=_ڠ}w$~GE~vE| yhѷo}73O kʰWn<ʷ-yw~v/~g_S +|~Q^=}cJ?q9>;>yhGLE=|'3f~8Á7xwi]|¢?H];=?;?;()pw\͜GS̓?__m(b A?q?o~TQ鏞[[~wU pmX +ïO]LJ_.DͿ+߿ί>?oO5񇯊avs4e0i0˴a`U\EN݄2֭1]ozx$vɱ&7L~UhiѾ|T7ބ ְ+.Ҁ}ч| ç_=~+&6ooλH{ wsxdGM9`oiv{/7?o-=/ Wv&;bfwvpګӧ $ʂ%~~{3 +;b ^.|v)}grg>I퟿J|kw֛wW%xK&}-~'xelC52ce_c;??ڥݿFz_Wqa?F8/B>gAΧp2eAΧpj^|QOvG"p44N.˂ODPAΧpk^|'KO? ॑2}~K|Oz[۸ R? +7᝛{}>|t޿据~nWNsϿ{ͷ?~wxocso6Kņ Z+qd\s +|n߃!Y?x7a?r!{Z/7b|cvPhv0h)^ؓR-1o=‡3ן嫒s\Ym.zmlc+qz (!ȓv~&,RoK7!]f+XV+e>"l%~jmݖZNJ;/Z|%mȡ{o?ݼ|O~GZA #i6X*Ws{˖-[?($~۲9FoW5م(cG'=H-Ƌ Xowއ']\cJk#ڇnu`XiPZþ~sK5܆XHLid,;]_= m˫~&OjLx@W[A.aoSM<DXK-W`JT}G%\o7#B9olHJ[;KՠD656X=B8nj69&R+em3Q).Ϡ)م0qOo,٧,092akH!$)QpRہ^1>֭X.bUyw[3䟱O&Z[nӂ M]a"[2C4"GV3!Nƨ#;~,. Εz( 4;\AcCfOjqjkƈm^N.n6(vr0.cHńϻMRc 'Cy !^?\Ė!,\>b~m71;G^j&͘.L>,KMڍJLɆ1k ۙ;I]@IfM_lz޼k!x>bwH9^rbh&`h󳌉%-lEъ}I.ik[TԷ0M.\;2 n|>eIҫqLbJzLD_ȡc +THr7S8v@noG,-d8 CiL6dOvvIG?pE[*zIE]hu y]&_I/8vq?4YܺdĤ Goz"5oC6XXN0^iB:XWzr+Mlhа]]9dkn.#=edT#%e8$|Av[ @_'0wI6o &aq3j"hSZv!rA2GϮ\BI hcHxeibw%4͞Myj'/wk|{=33./.@3p@cr>.0z 5g]* G~BV!pȵIc,i0v&ܒuNki&+b-7Pr^ =4elT"1 i0)$D@+-,[`FHLZYsh|e@T&~ +DEx/lDOG('Vڻ-M!K0A3CQ]^ g83K̐(4 D` 1G.ŀMjVƘ OBdU0 j32H3sa{7 { +v%-|QgsJNע=.5 غC9m 0ʞÌp slP-lvvA+Bk8Ġe6{b5 ${Op ("E|3;vt{FX\]&W7ش_\I +j!O$l[NT:C qn{|5jF}y!tFa12ӎl4Ƙz "Z%1F`Ǿ = !׆k( \bwmc<{VH=I +8H)5#?u1GrFړivz3BH-a @-cBޑ2msw9&JV|*-F%R^/]t(ͣvV]UMFiM 6rÏK +L6Q2@Ɂ DՍȵop_-qvYcZ{+k:f lv[a,W`Ka[IaTV@Q2e$<&fRlzPr$t"h>"|m hP<Id[1/dci@`LXMyJeV(d%/[2jl-Nw֝~ +8j}))(KMu~dw 0Wޘ(5N(WhX: WvLCCa 0R  C + VfePGM6F˄' +in + LH.-_Υ!T^-[P 5 !lKܘ T,S@ѧ*&m[ KX[_ӐSu᜜` 铦MYť؁F pFxyaMB@S2VCjtNg +if^4 J $g"7?`ps +ЍhץIj!ݥC59;n7*>&1>&-MT.**+kz -屒S!m$Grʎ ! +/ḢKpcҦ%]/_o퟾'ۥ=[nv(iZ߿fڤL+/^Kc GFI]2aJ"-L[a+jaS2z]{4,r^5x*ܤ4 m1'$SM]S6ރ0‹JDbLLKepUQ V<_u)`dOM`:bTf P.CF 2Tl^.P}aZj>{U⥌%"ΕI=; [4, 0bPA };   E>a,L7 +B>;xbfnV' ]D><  bX-8DNhmѶVȁmsD9]˲5Jd<&NJܲBDހ:@BW)<1yBbQLpg +&? +GYcUF:iR(n%!VHJ-07\(uPC91j\K9 Y|34$_,q^Y(I&^]|,OU]X)?6,|%f yPZkr$zIdxӶ=ك/Ojgƣ}ALVVLn$۬F3m`J{J@#@u2B(4=S + %fݚ쥣Ee)4c$G L۩ yuNFR(Ju'ijĨc[!AU te`Q`f!`E6ϓ /fKWэlr3 +edOW|,UM 'ÝT h"$ ܰl D>O!h~ @HUYZߊluB]fpm[8)Nnj l$vAjddqF|Ee!4  RXnphPhWw=#G\@w2/J]}-x}H^,:#"t(c%S>.<3._@GG!vX>TRYGK+[aЏ)9z&1 VqAM|s _{J BqHIe2vRr#U Jל ,P-' X WϬr{PF"BR]lbNDq+ssB4gG\G+yY?.6VW7+2̭C,6&O?oqv5h{2E(ŲiC>3}IW >4)80Ҍ3M(1&!p4Xp]e:h'&RC,vG-ӖfP,plxjYYɲttUp7n_L4842'TPmsO/6-FS !2!{jwz!"nEypy%ee(Pخ.`*܍L3SF,+}=PXd^D2^P7/2KvNƮdקF#8QN3m8-AzGFTGʓ ;M`nǝձ%<_Sk ް3Iް%W(Gyj-n#\vGm*Uu[Xul(tJR I"mu1 U߅QI'O+ō rSλcTu$MPsW~ gªiU-֭2vyq ,Pq]cL*hZ5STEw +(i7j CE]PNM&⎄ŸŅ&SHnz!ˣ_dy2N9bwfQ-0NxOӓP{5s7gN=SL h➷X YoITzlG`8>)W0mHήPw`& \VHS<Ɔݵpl/RIFtCc58{GCVLg1K5SVXbX(&9o=@3S`#^Vl5*3l0ByG)Û 3A/^ R?2 +1TEN8tH*PjdīU,$i]t2G]|g$aݫsRjY(n;4VDdec.Tbx"I"5ySMA`٨AVcTJuiEc6hC RHJx+C8WIlMѽMrg?Y$*Ao+b:XTc&r +lStw68VD-¥ctJ^8ٲ'5 ٽ𖩐Oe&a&&ueXԱ +A%t Gu[&vT~Mj7%f$#:i-]<^s(_xTok..|*FA5X60 Vex- :'80aM:AzG-O6Bw^콚wȒNfm Eev x) r@#V< hºQ|\']gc\C" cGg>Ɇ$D:52r X8(6% ׹EIgvǚ" j\ FP dUH* ThKG*ȬH*^%lOCp Jk \28*eˀL/\0AEӹIU+Xin@*CSbd6!ҽMR',3K )V"bK*jcXҺqyZ M0 6&!Ț%I0 /VUd5q HÂ?yjչ|.gup!p8F8f-r4Ln) ~S۞zAЦ_C]2Bljw̑MABJ7i%WP4FէN49^)l6#"6{c ȃƢt4AzEe]u~{Jq3Orp\Qm 4o%^,EecZ۽f~b7n;/-nA@D(p$wpVb<ɼ!{* {jV-=uYZ_o˚|q}kjsw.zZ^ۅS*W>6%ytL(VTJ#! MD|oqg,H1a筤 vP[B29Vgݎ{Fep3V@92sfwϩ%aoK*m|w"iNv혢ۅh*wsۓ6^Q'n£ܻkfD@p5aG84U \F`oBkW:9NAa&0*o1ޗ2lIӀ5kj8t%qt}Wv~AH^O İ\ +?Ʌq+Ȉݲ2\O,E) 1#T# υrLKut!]r_83^lQMQI#ȾC_;T_d`d^gCC9ѭ@L;uJvWf'uQu5_#bV+ o7'vWBI1iN1Djpf[?mGV_LF4@ ;;:i=z!%'y֨p&bxnGdy4l^^;%uN,v<ץ 8Ex^TP=3# V[q &5A Wb[Ƴw`׌ɛM0ULTdփP ++ E.T b>I، ?(|WiY}J þvMn0SS't6ZZ]Y{p?4{fQ9GjE˖/:6vD=g?Q;yEnOԫ#N*S_LZڊ?'!ϫ:g7f냤brHl"Q=VomI\m~fbQ={}F +Pq7h#FFBXQč-+t: hU8+sXVT V]H\E|ͦ#zӁ,YF]R1U)ʚ7 I5<`iHIٷx6z-)~eX&'#5z8%eBҘLkgmH71g*FW#_op\KׇOζX+IJYD[:vC@HX&icJ>Ԝ+e4)J-WoT*y|"ibWTMe9 EmzpgUeY#RՉx6t"Wn:!j08 1+ڤnب\aY΃$ ǬG/24;?*'Ampe}4qG)siM0kY¢ahIA&/'wV W X2\ k۠!(Z=}e%&V<9Bc]E垡N_h;˕[P*mIbB +Y.MEi2F7sQˍ%禦ŝ> rANBYiȫbzzpc Atqly}G;I>zt:,F䁍¸E9p1xJAoaNjlfFNI J +CpP/vW/*ڹn'cĬBzʼn*#3'Y9cv(b- +zۍ93(m=bޠ{pB8dPӰdYeq*_9ܱRʆho TEB. aeYAE1ɮ,EU-b,7E82*b5.v_{\9^I v{+}Q`z;7!FIyQlEd#GU=IG- ZS߱=i'%^q. +)<7>aTDU;N[n`-G[4}# +4Dw SQ.`-;kZ\=- AF:AmAqZUA-gj2ڢ,Ae)q\Z4DU +jj6z]Z/}_Q[5#ź,P-4.Q-jyի`j}'tj*Pߊj9A#]ZvרSGxFv]ѷ J=J+sL ƼF6TF|Qw`w=jZPF {`Cמ`-~ˉ_ij<]Z] W`-"5Bsj + HvVl,ŰCN2n| NɱG۱ZjqvV_Z /p +&{\+Tp-DY^`=ŵ!ZJZv'o' =;\AE_q֢zDv۩v?{\[_hRjb~M(akOP +65UVq-QW\ G?mõN(wzkqd ĵ>מ<9^Zx<;_q-peBq-jZŝ;Xr|kꐻم(7وiAa Ӟ,ǟ0mavT|{ +L .=nǴpǴۻ0-|lߴ,xiq c(|bZ@҆i SӞ,0-G0-nti5T, -{)7!-H[ -:gvF+%\sH'dNHBړ {|~ 5avFO-zz؉4ۈ]PECօiv +1p&M˄zƼ$LbEGmrhX + @t1DIθI߱1e&߫-7D#)H4+. qQJC  Ĉ`DaTqĠ2B%D]QU^hjg܍BT?(C8l]B]Gr _wSUmHE(x)U1YAB;,4D[p.C Sn{H$9%g` [B[ 6t:2A\=c37ˀA삯J攂Âx:D2 C8N")l$}W .gm[$tʦ!6)x*"mu"y"xS%U#$DW.]XRגz]6`TN||P *9F/7񗼍`0l) *۬5ˇrbj +%b{4`rOD$RUx-jS<S &N)N0n(XF61f>BK~$a-o:Gu$hOR9".w HmpuG/m^ +g+)jS*A Sal\h4wP,HOEF4;E4~!IlML@_Z^~*Uulk~ɔkAق(|* R&͚8;ؚ qSrfᣄCxD#h4]{%ʧID-3jh(#_UwnE!݋ 7a سowTC +%\ωJlyAl;rN<3E)4Du~e[N +.L,ʚUZ` k" +!c5Ha1 +s4|'9=UI\F<-?!FcLԙ7Ph Q]>Q@i8yG^A0++4NMTʬm6h݅ؐBcxkke%@xii|)zrbn(1IJ޳* r90䀡0"8dC` KW8e}t.cq}W߻;a>]Qy/F-Ǩ@rj s\Ҟá'_q7eGC̄ I6O)דSf446(Eislqq>^Mp9>1C6<0m?4cQ5POƣjU +8lN T&ru,KALV#^~f{YO+mK@P$#Qd$6 ֓-Gl4]!vY'O7÷dJ¢~Jd8J`)`uz&jC(J ܠjVKܠa5½)0)Zj**AbW78X/~8mš쌓vi(ltJ~HқlCGH\(46T85Y +lti IĪ^] ɀJ])ʁTٺj %bDWX-$i=/׊fāCh\ )rPA|~ۋ&edN?~_9(IKwjI|a{کm":15frGT7~D=JS=uAMp*`эk7f::lVNcRLꑏ6x9}e&sesX`zBe0 +&2+ۤjZ4-N v .:Cw4fES)]). twYs(8#%<[ V|4bi5ȧy.N4.`耘1]#SCx{.˺4}0xJ +'F8\+d{]R/bx9[O@ O5?B;`ttqHO Ă2rAwzG4x]@To} @5 A#['ʸ#إ"ʹƒ:^Gxb݋~0N?ןyX~ߋq5cɣ"fO{{MGg]_R< d'xK25d pAqBi'7&:q\8x@caw)o~ehnorI9 +x2w˜-_`$.k^zrYн3?g߇&嵑L@=|1PgerZLf&Fb'NVõ,{Ƣ9x#♠PŁp +C\%%w+bMMhyO3 >gdZ* ^`mAojop~G+>a~ *|, ė<ވ|4p@K18v?W鸬Ã*Hu aźlpE(Sa]J3(:VE!LYMJɚ)KRivqוfw+1bvXf\?/>sE g7 и0g.jFkQisyA,jIdt!4>Rym05(Rbn`A191KQGRų݉H)YM瀘%7FN&q%ٓPyD+vA0)T [IN*!lCZnCA3 Z;"(lhI,>ݗ!@W 94O|q?E_PмQ{ Ӆc0^A(w8vLH{c1d63K%bY'`fs* {?I +O+A1#l9^ˇ"<'U'gҠG ]$~/_$OoL B[Ԑ1kB6eQB i.(SF+l6qFVRCil/2̥\'dA<Ass2(s_loBUocQXp sLuOp(ԩz.,Kr; IMHnMs4(4ixUD[OVi?O[M%NT'TZ){%7y|$O/ cpw6d#3$kTS!)R('o\FO"{[`X4iVM.@LpQ"];X_\ 97}Pimm!aq}R,";b^D3ip'rO9=*✤9=3y<Z³T_Qf׀54M# 1څJ^Fbeg` Jf=si,(&!.p] L̮ed13.Xcdg\7Fsꋑ<鴬hD& 39>mFS{S eK! aj6DWk* {4ԯA?tgT5'.ۨa*_oJ#B'[E?T96E$H}N2Q8& +7ިJa3{~pl.Ԑ5_{+GdM(a> Y Q%i7`ufarr[^si^<(&a mF\ &򂳟$K b&}$OϨbVp `9 {fa:B:һbv3U d;,K#޻8݈pыLp0 N!jeGBu+lOu2 s/g+Gۗ|gP^Cˁѽ&2+d ߸tεG7:#t HoN:]=TȭNF9sgu7q^8\N ]ΜܙvJR;5kgwg٣Y|\w?v0'[c ;^ +nwn7Jy +׼Ck<ȯoAotpݞ9\/s^U强*g{.֙˞krm7~mǽ׮{ك]Oݔ-GZœ^۹Op_O&N~~/v\Ù/e/v_<8@)jp"ⵃTz&pt > +H? g_G$hh^gvMs1?x0\ $8`2~g[IGſmgW}_ϼy?/?I|ݚ>?G}k) +m i_o4qő/ HXQM%E֦Y& I ȌFZԶ7ۨ. VAQ?S#TWc.~K:.{r"gtNgCT%5qlo@ ʟ!~%36cdi#)g(2YarP$Ff5}|X,f5J(YhۄFXhmV'WN~,NNJs8A]q qiT~h]ϥC$y_eR|`8_gu}n/7Z?.W̍)8=+C<9}ggpۓS"ez5'Ttȸ3Ix䣣l=Ilt-Oz/Oȉ92Ltd8<# +>'xÎ'5~zrOĩ89StbJT&^k{""Ao|%ۏ +DQ=TϹ:Uj(ǔ.3CUØ1hV:  je<$#Rb|{EV5 Ƈ3j-H#RE( ZʣOA)1[FT#8>8o3o l +YvdZr-![$<'ʢ̷RVܐ┣A2-OS#OF8fl@#-qơ}+wt W,PX{0sSA~>Oٛ-Zӵ> +OPpD vk5E[w)l^`s ,rMARд~jlP-6@R41`K?Go*6ҧJ7A(}C^5xf2 L1Ǹ +Y7JG\(F`` .`D;Yŏ8 4p.ǧ Lͨ8HS%.Kuҥ/Al 'l ͿtڢS&Hm*v~ j*@f`AiW'akU'UBo;U)-M1e= ] 3% DGũA Kf{o/EO&30ˆH +endstream endobj 64 0 obj <>stream +Jc9;Hem𙚳Lh:]AbH n2:Ls)Աޮ ,&?P !jlu1`j$VTl) ¦:2RC +X׈D4 L c;;_Ӻ +q$b=8' lR$4 -@1Y${٬fBe0 +.?R#u![ v 6]qE(Pr;s8qa|x dlx_ch"+})NMJu&tyBKY T}-SN$AB˱ ;yw;Qhk-p+JNZU#D]ţ|=Sm|ۣ~?#X;#8BYL 0 Gмx =N1aMw͋Z `uܒ<p0/SH錣,B!(6Oyҁ͝nŬ#ze6))9LeɰЎ3ie{FOr؟I]L)rOTuVCc lˉK!;?,Hɋ8P~!&/5|}3*'pF)b QnnSr $%Ne8y qUεZ`G?8*Oqs<5SO-G97TTo-g@ҕ)b)0rCa}lmaVY#e@D6-_c˪:`L0( +jN /< 93+Ւd] `t^]zB*ˡg, >+S#ClfǃocESJ',)vN1"N'\L )J~҇!8Ho S '70i7o&Ege'Naޒ1XВ ߀A=}ڔ5"&1:ؚ_ylE*kJL59ٗ)5x +Uߓ3 +ݛ\ ϹM%3)l5-UfRCX@VNxf5Mk#F$x΋BPCYc& {V#g^Wa=tL#aH.Zy󓢊,Pa ot0c`zk ~k7\qCD;{hid\!z>vYP-!&DM'NsvLYPɊged _`1E|2]x'1SCwC }q;-.`]谭F2] aDt>ޭ)y1yƜ™%,(/\93J܂JȜ'Jc\C2:qD%*7%4uhxghMŖR?lgL~8ZPdz6{#7M'=gYxreġ5}I=% XPX(C[r7 L\j?* {Aŭ*E )+Hpb(Ք rZ賽@47nǵdU+ yDGiu"ӎD:kI{g2D8}sPK`:j"QU/䠡Z15CĻf#[^.gxR@lQ._!?Gq"TNeQD#Z(|=ᣨ>G 2dA_=Pڵ;hHHާzbP%kr6P pa!#>! +[#=\~(A-+}9OeSaRsp[clrӣ CF$ͫS@<041C'C +P ,tY:ٻ|!\8A̸lV&VPMς2IP,yH0\[t4&a+떦<EzPK L0!.Ua ]&23 SSص㓢PH $yXkAd{pH-ޕr3HcPns*WP<j7}bA݃&Q S9,Ǔ0CFk<^ӚubJ.G5^1: 2,搃Xj!(a Xb416MGYjyEI [N-RB/+@b䉍ymz*3vәgV"FFG Es"I : +LQ]838WG`S4%=N*[5@䢲HI|&.H0Nt,MY}!N&GғKF"RP=!0 NMV :\LsGchL^2C5F o?Uր)c3ti]xi< Yex2b7L^o +G3:Y!X=Z@g|UqDnrE0N_v4,5Sm]57;xklZ'O@ق׃9Ob^HEF03fzU*JnO[g X:qlQ)1y#8N9_xg 2؏E.A0 작K)dt"T2JPcKŻAn+y)q?$Dp5&*%BP_NXq RŻGoFJ S&cNz0%ſ;-=Wwc1wΓ8, a@dl,vS;a>>SqrzNa<9'g\HH9='2(hwrN89žSltN5";m'#,3GB#x1;TE?R!Dbpr9xdER\X"Bˌ@*D +ɇG)&h QX:5ӮIeQr9  )3y5Ztpu!coГ8,E'k1}+GFjh襲i9z(]tuF*.C[XS òr%1e ȓ&LD/ti"6%,0-M0Bt"l)PN=kScc +^)a(w?}si:I񎔐YqxVX f|:g{wSg"`LWU,gԿ;.n\ f۳1;#` +9tA6A?Dhd dRYw=;%1"W_{3[k5 eƒ(5!#Fg8B-fyMO|9Ojs]<S8/p ]1k}rNى: ^ѳs|8 q-gJIx{\s{.OA7gZTduNԕ:_މv<;k]>'h6rWNp 9IG8u\ŝa($H?yүQ =`-`#~ PV A/Xe`͡h1HIV-z4NtA.$ءM)gàTaxM֨eL ϜY≿eM,f?e%-2g8qٻ$՜fnK[)Zg\H&Tl[H"h1Ҭihw2lSe#Ea.?ܢ85t/-ٛ4E/Pͯ<妏:u(F\OۦI3 R (M'g)SGG@ꈲ@m>PzTuzq$}OsL`!zf)5S{ +0HZ$+Fݲd"_8ExSSR(Zc(rϊ )$MXF9H95yjxOk\QLJX>ZH e 1-P~<f,fC5ocmsuG4wRoc ࣺMॗv͉Rʜ{T/N!uգ*zϣvfDO#ӔM{Ցt@kg),/h$ttXC@?7#`dSJx+TY=S5 Hyu؄MY^Y-TsЬJ2 +l=LE$vT=yT$'$g'ڽ"4fB }_G-B FtnMf)HBHE o-㬲Q)hgM 0 [!^4*8Qd?(Τ8)-4BS:Nً-JG9eN=fJArŠAkڈz|9O(w*"FD8,z=Pu8Cf?2GSO| lxlܝ do%nr}Dtb$ %'@ EA +CM?[ϬQ(!Kbm aHXΝ֟ +ᵉ[#ejP0twl:!EpRu1m;"Iq4cYriH<^pYpbqc_ORZ\I?@oޮՖ}?C7\+~\hom܂}Ըk|D+sr[ sBY1⨰WyKIۻr$L)P;t㯔>~iv.Kn`}le;xWXKOg37cxn}Ƈ?> l#&&bqm LHHK}stD5Կq]r5sXS_IG凎gMfɿ&}pG>-kzk} Zo9$ĝXlJbX =ў}Ƚv1ب Lj]WE肙R`Бyh/-]VB:}z3:\@7zC35=itY-N0CXS9)g/2L#sZ'޳X*2¤G08JӢγjmb] +*2Η`>jrGѰFwp"85.pKvlg6!/R&)@0L響(~! 7v-@ej.%e6Ak\qaԘ}j_ΨQ_]WBV ]% $x`d@ܔ4Yx/c`[զ/%MgZj6b7ɸڥIǚR8)HYSOc ^Nezh&9ħt_.,;ڤL'TPb@QNtD&gAWlPD /}FъDH`r1`zpNmWs~Hk4rn~RƇlˡ">hFRrNt7CrĚ TѸ 8|PbB@hjFXW5jFI>}W]7 K;բ}Ԑ1?CIηtIJ ]d +ҵj ^5 0NG_5! +e!P$Lz9l$EP]anuݦ _ʗig$_g_\x,9 $ +KDMsaTi|Z/18a NRRGX,YUS`$8[з8{d_ #"^E xZk: kG +@C%6*-0񨇸䬩1"A$_G+#dG^pIILz߼rE7?uoJVoIZ rh/ᮯ`v/uX"R,,B_vvϲv;rs[|qv|?c{8<"7tq7/s,c)гF5m׸ k^#п O/G3F<=*tLsT[co1j@>R҉d(ME%QR%AjP!|i$mL")Oױ,Or;o~>PJQ}z;. + +IG欣Q_ަw>ҤAZv:8F_LhqZ*Jx҅857d߸VwˡTƄK5{;ӈr|e%57s,f$Jr]Fo!!3@]C]LN4&}.%yƴ8MQ!F/@d.'?WkcKX #CǰB|xSEy_F 5gn+yi5.!)f˔DE'ƃDE_'cQ*'h|pUB >Wq ]!uHUUaȋY2 +"r$w_d|[)ABRħoX4ސqHrh`Gl\_ +5E'WS{rfÄy5U +Vx{ˏю}s>)obַ|YEJ[$Vth`+|ۭum7纇muX~SCA[\ց~v[zoKx%Ū&nWwwHFmRLbA^_'+kZ/OxszJ([3\Q H +X'd jw`'cZUj=Ա39㜲sdb75R%dN;.';=4lghAE7 @89 :=1+oj +2^q;'۬KFOfb7Vh_uL<(GXlN45|9;GFbԲ;lBCxuK)ޛ|0mOTU0VD 6`1̻/qc&E’![ L%}}"}ϸ,[@[Yåqyh}} +jcoTf,,V4m&4tOnUA=\2YYHx!HLM Y,\r<|]SM +@ RlMrZFN;lq0:3s:hH(łOe[`:٣O:HYMW 'r Nc*Y 8Kv8><[:ӧ'kC /S`>raL5?R3rn<ƿqFQpu8-&܇*#$2krC= bReSz^w`Ƽ+"#Dcv b>B׈ˤ];l.' fb\ہ9y::9@ / P=PE47g01}~IX}eܨgKLԾ3ϐ2Ʃ4@M\cb~1)D4BSA^T8\_H:OP 0>;g +jF$8*sP>>R@=l,>J.ii`uNL2}(QHe%3RÅN& +-M|,ԯ)( 3[Gns(ah%y+MJS8)^;.' HPc%~L)SKKA61^4r,< +[eTCsEFZ(@q4L.RsI+ѣu4;dG-vvc$3Ozjmj~{ +wCVO.ScDm=-!IљMC b\/>qi{|ei&KVi:Q_DE? +'&,bi5 :$U9(t!kZ !AT֑#m¤BLSw` 1-0bLWmwx5N)g0ԯPZܼb>ze"]BhEݬeA Yl2\$j垤ʽTf0[h:ǒoPe"?goDI r4R+8 A%J1jR]hJLP1r@EdUx#ҙSza7>%WP}dY9uH(MNꆰ5+qpN(-haKl.~gW `ͺ?8:v.IZƷt˛#!FЂV">*gr{T@堮40CbLР17pZACvZ0by?.j:AZcG=8N@`@T1(6gjq9:qQoŽED1 +*` k-MtpZ@XRJ!:H Y}j"k"ԩ&83 juUH2-7 +@D=~tQjСtjbD!x,ed9y6Ii 6pqIz(S3هu$]H$ZEsBb֬ޟ5Be:$15FJ =sd)EJMzDȕɶ)2ᅬITh#!Z p5o=~Zʢg>F8=_=Xuͪc2.vm?gj^8Uytr#ZԆIћ/ob(*n +8ITDcyҹ6#N}ZRn]U߼. +ȟzpaqJPpKF:?uv{-_&SAZI[~/K2zԑ|0& D˵}3,5U|BG>!;/G +a Z&g +׶ƤCjsЈi$GCgi~Jˍ9Xi3*kiJCVcaE&]rN FsxVu]0QlėB%nKIԊ܀v,&L'`2=C nom.I=|LEl8ˆ0?bXxDz2BZڒ n&!Vli[ >g"[Mτer05¢loGKEi P/vV֪4M!A}'rP-Ztӗhl֡q)o5+9>ƃ6"c[! n5aX$MwL 2?8x9tXaGS6s3ӨW9=ax ZƓ$;6.<`;Am'%;D}&I%xip06L;@Aiol& ӆKv=s# [@%et"pQucd㡼eزE؉.!h7O e/ *OiAG|l:?(ms/?p~Mr7+(V(C359e]5$-5rh<;I5kXYă)>.҂'v}ntQn3U`h@r/HM: @޴Yvr&=w|S3UnQ̃I1L$]F$ +5gO׮ׇwc"]z | M`d㟝BpiZM۝fab7Z `-Ya,!V J'!:ZI[BrZyP[ʪz kez-0ı)v@[j*|…Ad-d!ר9Y֎LR=<qhҒ`gsB 1cT<%"#+To`h =K"R`< + +c\WME} cXs~7՟Sg˭:p>xV5mfT^yrY't?ϱC){TNaSUD3 Lp8Q4g po{gDVp~N!#4%ʖ~{/rGa-SpWpw$KuBP#5DOQFP$ tݎ}D Q▘x;@snrL-{AqOdoXr0rKd:"L(k ;&]\#П L:Ķ[tDMĖ!j%"zfe2ǕCօCaZ.̗ZO UO4Օʺnj{ a JTL i!.Dyzv$Y%ՓU^ k-L-%m]1T gnì26LϷ'na%n{ Lɕ惨esXnDa=uuq];Yi;>4k'%+yOޱWn$joOۄ5KJ }O&/ ֿCF/ +: .5/|h%gS=Vain$e2y@3yT*_„b3LY}'$vX  #:wE OlUAo2Sr݂_]s•`]Z s\y_z|0"1w4pE=nS;#Bt#|8Ckis;ΡKsI_K?@YC̜7͠;龔#i*p??_ih~(R!XxLfG,J!LPH5nqs-0TbQFsvCu7:$F@1tzx,bL34TW]I&mi–sͲ+RKU܉8wiڤ=>z|\{|`ZfqG$<ז{Dj']prw[dCOymLb2y5#5X 4u{$$g4Ux7G)چ2V"JV:;뗧WLoPk9٤"<>q,q@ C$r3)R<9ǚ S./ឣ:8 #9F:pG\L6g$Tݲ=Ls1`|~@!GwvZt#؃wRA.'Gf7 uR!漕1=thf1?sL j-f 5k p +%)٪J@̽ +P"=n9 u\ZS#lȞJ S7M&{& S\ GJMuN$c HMᓜRvrDID*EZI=9P^wVQr;CAg '!9TF4g$|588)jl” "HO(`ꦃS634,"*DWLᢩvhpv4FCZM-/٠U8c Ŵj84&+w6!pR  $p#R %AREb̢͚ tU6&zM N,O5U.%^Bw +=NHmSucaͱLY%$x=<1n4N>/^U7o贃z&E8zÅ'zMRw+!#>&fLҷbMn$!S<|їF} 4sF 7ĿDmLV: 3` xff˿W[<%U`"x>A8Gᚴi RėoPaOS#IhΕ\]J 0cHfJWw/z_[etVǴ:m.ss^ϯ` KdAGZc[s[;TK^Wlvthd+|fyKnݜZA=7uOY}Ë|#^s\W;_d3K(Z՛^F5@Ix5.M#n}MLBoǒlӘ5YmڴfW l&%1:Б`{HI*6v=j0!:\['Q +6z/Vu @yFetlT:Y8ԦzTX {oe"2QZ*@4^%TӼTAsdsDZ+=^5IU2\R~gA IP"`B RQXwKzq6Gpʽov&C))ꁥ$R+S<,iYYIQBdE,+q59t+;x};:=-T@̒gW.Rc٠a@yގY5<"]cqT8 6Z!bQ,bZA+[&2b]Ҭ&*T\ H8mEň+)'Y9}6dMm(˄iz2̆GVf'3r{)ers+,4O\j0 +%ZDԟNy=z'21'G aq;4xx`'/D]ͧMdxŰ*3{?5V!<?źm@=\V6o`,um-kwY%_MJ-5|leso5VyY->[<֓\7/N~ 00V^KPۇBK.m ̛ `6>$,fl5g]Kzpk +##\5|s 蚣ޟ5'^Sr%2|qf||!_q)ukB cRae'h|e Y#ƧuQ 8ŨaT#$b^~SZW_,]S;' :՚]pw6"w-4%teb4I6z-+(\Vܵi(Yq\ș鄣zAvIr$!H=BPvaD({E돒Zd p5;g3NMu LZGprtqKA'H|OmJ]E2Aڜ1.[)VOi0EN| hR?I.pbqqxx~tբzvqRT{4.g s `K.I jvE@uXHeٽכy኎wwA.{bTN1IJ2 I\sD rzl$}يXv`{0,'G^Vțͨ-t$Da!n%ShD,S6Mx[I*܉(H$G4]}K+^>S 1nI>)=fU SK+L# F?<YH$1(ŴtO1@^-PtL avバ],iHu K\[O~ Ku:gߤ%\m?D~.uKe>{ac6[tv!ˮ_]d4[{/ƫn|Go|6af G\uF5 r swQ| SmEʱMO3牄>dk6&[ܧshny2:F*EVSa B ͠3iIi,)|>t7vN%W+#F zIc(bNH2+!BGbۅ.Dw9NƃAj"U. 2t?Rh ~(p8h;w}C<5iO55Uc۴vv:E[1/#mDjKv#˴ozP`>uH#cE栵uM?1RBq֛'2̈#m 0Mqiވ3p;43ܚkKc1ȞڄA/w/巑+WϚrmQ@I(UEOq'P˳S:5ew(˗$|]ق3;{@(A<9V&YP(~:O4$d|jw٢adHbBA^t׈rXG]?W~ٙ6Y%R汻)SҊ:܁`Z3@&eXҕ c":(BIYqU6S4oHt(r4($K+{б]aSoh)1o8&" 5ˍ^d#Rc]J<4\|Fe# t/Hlh5g4s>e$>{^ P;ݪd2&j=M:5q~(`; FFG)ĉ4|΃hn:]T$50Рi[2R@c\H؛T +s1704ɨISt54wԀ@&#"S`+=ܞoQ^6r9_[ +wt#YXqUJ䒜jrgIJQ8Pqfbf ̀(5Z9ĩaJa3KB9r@)]!vRT fjb|&0ߞ^%d*p*°I*a|mr:W"lJ =Rb(N5}'eB/Ʌ}mWPT\[)uiw&ornժ~t4Ba-0GAS#Q OHάC;, <f(a4!BEh@T+1F[XQyYk|K,}Z9,Pu?$6xM|4KD 蒕Es(}hbJow:C`خsfNϭ` *ڼ^Nn8# p$K0DeeFɂ3łw:)IDz(Tưf'1[+ +X+8Sh Vf( W]S@D\'24TѰ$;#C+ApW'9r!Gg .!rƲ>_T|*E5^L402jR̢r ˇi&@ѡ VTZ}*qJd0u ㏯}t'"ػ j{8D6f#|3,ָ nK].9ocyk\ޛ.e͚Z޲@ו[A}lHo~WY=6lu{"wCjͫEg2X#& -ʡnk_D5Ln&7~lMOE69&٦@k˧-dhЗIGUj{J&Oisy]G˼z>w}tw=~GA:n&9"j >jڙ ^y`윩+ ~CbvAtӌ,K +%`JѢtӌPS2p/eNQyhؕvkk @WI#E~Cjxa^;ԃ"P +>66Q*d/-qKpiJP $E}+5b`TGt\-dB:XSM*ZSX+QHHԪ%`:m$feL@d.\c &j\{m"; YU<- Zg=GM7*Tc֎#4m@'ex +-R$-QCO\1q0F{Բ(Ù9GCfͰE؂ c2#ICf*n,&5]jP4 '+WvקBcNLž_R_ G;Z<ޯou_x>\s~ P5謱mql rK(|K瀹5)k__W e]R[W޲8%җͰnE;k}&y+}V߱Z=֛Nou7^=Ư!@23ެ1i ]Fg|SP1|wI6}*x$?[˚l5WZmڵΖn0(IGs/4%=S +_]' +=,{-:CO!_TAo,MbDN(Xڃ'396CQϘfFd v^\,=Q 4 v-`ېIH S 5`) iN'wl&W{'Cp·wy@NG{IEUp(҅vR}HpWA/wxLf5 <=)<q( +2C<.< 'V7qƩ4uyKKoTw|'ͭ!501c 5[W$/(oU^i![iO"`+-3t I]fGՔΉ-bqly9}PQ9CEanQ! O sDg7S;y@+cT%g}J[ƞuD8}j&"Z:!(өVĄ%:x" +vp_(@W';"jQITBd6".;nl!Q [dp2C9|̧-_ir#iA˝R҇ޒn(fT݂.(8u9 +X +C>s|E $i%h#JpH[ZXHT:&tR&]zDJ};mN4>fdUt !X5fQ'M_eb/S3WBl'vSܗF7IQ>q܂HI=Ǫ@9=x%c3G5L!-Cg𺋄@Dՠx=֗ +b)QTǖF}T刊H-r<3VW?+iL&. tInak~r%'/#S.IejU +/Vi +ԇ~V#^ꬎ8_[SoYu}|Q8ONGay'1M;J9eGzЂ3j)LR}%,' +7&s!oM@q+JVAEjn/LGTw` z\7ڑ3&4L흟r %GW[VG*&8\I&pxάkm5يFD8t~LB#gC483  R:Žn1yꘝ$A F WSPOg !HS2c*>|: +Hrʓ)s,>B2bg`&1arɌ ]Ц.潱Ku`FOsIC5f92'!8!TEdX2thC[m5Sg 5. >dƟc/^..WG%daa KyQ`4GFS>/kyw,i[VԷ[bw7_cîzpXm,=|f?xWb^p㫫_#Kρc .k z1k{M<*m"&62/{7&o'LdWvi&YgLք왶$ݒy[r.vnmʹLbRtl=HԨ()3:Xqbp7DNa4MvyN"E(Gb.ee$Updj֖/^N#c tfE|qXwFƱXՂୌךD>!F*;@CIu`O0Z5\!ց6Mln$b."`14~LX;8 +/nCLSX>}T6;3gW]+0*OrUÂJ[!V42Bj~mj00 UgK Fm0 6`s6RR4u%hC#m,̾nNgQtԑξoB ZSul=;x4gcs, ܼbZN,mLUg[iykhMʚK%۫~pp9 Čv}ZCq4j隷aaJOR#.nDz|xi#"u`Ϝ-t!F1꯸~Ԙ.l^媣asLn]?;N§ۛdUG +8Y!d".:/Mc}Uwm|WL/Vqtʸ3)vPl=a4=l>#OW~/'<핃ELC$CI|&])kZX(pU)\KkMIb>ꕠĴ2<>\c$ +#`&)Uä1R#N>;.$3ȹix ey[%YlR6|hтЯodw:$6tǥN8qslzt?hV M~d:5HF`Os=B[ 9X̾ۦI_kXX]~zLH{d6D]_g3L)CKΚ?nbs4샦SXglMőp48v&{v_tR%_ZJ*q +"A?srwQDfq d.Cx^RfM1U X*+\t#ɡM%glA~a>f]4kx9B7 ezYjp 5D34!qm5wKL3i-Ԕ UbW@ uANǮɬs(>¡Qj m:&0K*r,[ZOZoCI;L/EWHCb): [$%զ +$Vn)GEgVThj'sH"LhFc)0Qv%d#`%Um 3j 7̵YYЖ]Ro}0p@AS?cd)ޘ\DP d6M֒y6?X8ݨ| <Ԇ7$6?Ak=~,ABK5jPE#SipT25FT=C ?(DYwZ[d^:L $2.gqXLSغRߵTCjdßy@,JE$V92w#p`T2< Ijp0b`'@BH%r 4?)aE| %F^>Wyzerd+vP|[5X +\9C$ +4\X}ơ6A7Cg{UfmX}0&1n*9M{k;D3Ġ=f[,7}vh )ky RPƼи݃>c_ޏ"7{Yv]@e,GͲ,&luK{qI;yo٧gظx<mkp7[^Eg@؄5x<&\qn (^_K]>2MIC&٤?k%P#g!6y{:qR8bU2UjԖ 2,?C-xCBz8U[ I*<)Y!(rQ> +{1\!j@w9wtZuϹCX m’U')m=0FF~ +A»0ƻ=yʀW^I9]}~*͚gw) ?.=Vs}$H wKX>-`yR@UdeX°K1 + WF:'M- Ute3/o I fT-%{9E"-3&|( ++RnF"M=Gǝ$}hAOj9iK:ݖ5p[ YK P"o yj9s499nt(H^I8&TꍰIXZ$ +cfig˜b\Z. d^D-Q|!U "iw#r%C*ߝ8c:?{Lt +G:0lWm|m=֓.vu{׽MMdşgzk&=_&.aߛ &_cvu\͛ Fym6f:/| > 6+/q7q۠ EKڅ%]zM8].ӑ5>A|LHִ`<,IƯ#KCgI)&Zү}K֤onMJ?.u_*qAZ,ヌc裖=@,ũJ0Ixv4npreTG QSeRԫ|Ȕ~|4`gzdJ f6ԥϞчǨTFcz OrJ1IcI-0tjvQE]&i,]/ZsO_퇇+y>Y&cCÆЊ(P(@(诘X "h҈ae:߈)}4;d/, `G!Cyf -e<GP +PKZUZAB&f0o#p|Jc{#S"N4)yiY`4n'\rVNf@FTiu.;H*:M#V%g{ɬjOD2ay'RA=Tc{ KU@bYqLpCS>-0tL pyp摒c4:N]sY^Er&ł̜jB +jLIHIğ/GdZ5IiSLWlN1z}Y:|lyR.CiP&>Ea%^Aq璜@[o2&_'$)KwvaݻDƨ`ZDŘ*I>T%SOcTwY$[~Ly YаyޗFؘK`ҙH,Cfuɥ,AEp eXT)!ͬՉv,wLZ3A.ᰬ`77c-bl9C?_))??3'5R%f'vX8ة8KeJ!WrQ$jX;Sz,q,Е(a`\ 1D溓oҩC2QP욓\KRZ 7 lƭVwqzwd,Zٮ^7~ c6|vakᢕ1PދZ0̙EۚOV4(\)>PAG X+ ?c/Nd''*=4S &m16@1ͪVJczM`ҝk "'DB?Z|"9;<])'|cHnK= AF,Z}j5UظFg|-"O%HAၞk:.< Wqđ"`-8pkr9]!o MN}x R;L΃`;#~8#:krl܇M{&m*#vOT`z 3aQ=ս"b- a>")]v\Œ^,cۊ[D` +pgkxgS" LsXF?PTvo~B&0]=wE ϦypFxLEv%EݔIQbR֓W\A7$ A/21K"/iʪc;z +9=%\gujƓxpbMwC0\b778)M ecS*?SO83R^ ; >r ^ڲɒ/Pl4eف#Sr%+AH-00 l"5ra,/#eTѧϡ{%~M +Rh3xN]9OOGĎx\,]:x.׿xOpwrɠvH(}[G!=E4p-8 <68,yb4ZE;@F 8\AGPzE(Ʌp JSA@z5c)GJ_B kv|/8n/Z7*^%^MϭkWn뺫ﵺxŕ]5ksLV:չr=}OWn<&<zj3+agZZ#,InpXSշ)@'w!zlF#|yJֳőhL5{Iɂ>Hrv,u;bLit 0$C Ȱt=ZYU{gP# ep'zٵ2#"#V7Lo 6P󌏛$dThaDmFcu@.,݇HŠL |ސ)>) \HJZw czb$M/2!9 aeJfy)hgh`n}&Wdu15<0l1aGBHe%j_ڟWǵr: lΞc(.'^u e h͢ud%_@ylKҜO"՘d(ς3?/ X@l}e4|_HZѲXMo0*'nc(/6>- +F`!&Bya".<~\L(w-I|Țέp>Ӕ4GX k^8 ,9bOkt)B +-z ɯ9&X_UbEZ:Ѱօkc/Ȩ#[/z5QĔx!@D,mPj%~¡4BdZCbs|@GKPk[ +Ul4=^UN2  Sm }7[b9KBG +knV2»g8MA5'¤+t0V88s7J]v2rԒ 5P>-] zN7v9P!YJ*!܁3ng^(`M?s妛k?s[^7X ?%!h U|kH5B~|Mwwx-_uP~].1.kFuovɲ><]&l!|86fvkul[wϿ]Ɩ khikO]JאGʱ71) Z&#y\>l2%Z&Ymm޳5=T䑛l--urߒOńMμ&k> =i`lY Մyۆ&8($ϓ-/`| ?'4 xRShpq͞wC'O&3 /: :|R\\fҪD aB \,pQguU%Ntfljs3|aAXi7lX/(i/dT勬p,k¼ZǠB9la+l+Yԝ+Meruz<(2t@"ELqps $9JN6+օ\Ż6+L%pώLF \1l_H -l G5 I;} +P6jipx> +u&xQ¢jξܟ,= Ag!0 Uǟ4wMǡRPA. +C!B,D`ׄvfh4~ ~ iYGF^\+ P"3Pe L.͈xMyDmѧWYL\lJ-y:A{C`Ly|p ~FJys@8)]p`afsP?A3v;o͖aZI\l%Ug)2MI1`BJhIt% Pe[\JKQj胸'dFnEKS˞f Z=ǝe@236̛^#h3ʱo9} ;mfBvfSQ?TzytRFB(hT0O{h?8CcI|O}`ΰ0eawA +gvGԐJhD9iaIn[G%0IEcdPy"\FG<Јof]Ȋ[!PiNl {J*')nhI$hOVJ/|L +9zZ +A@&r?9hCMX[o:ʵ8#9;ZAe"Hcf RO Бk@\;=q0n>wؼ?y@D< IT%"8I:djѱGFZ).ry$:su%0 1+JTq\:.]Mďɸ BvgEIƑ_ +4h2/q5@Fb'"8j@dS8\Х)+`Uwj Y,29)4`:x&O0,iV&qǣuXT{[FAG` c޼kf ,k;r]TFż]lV[䧶oWOK7.cXdV{_ś|׼p~7!a;>vA%m"{dۄm\&~7!|:l/5_YRMI6yԒosk^Kޖ,i{:Kiw+/2]~Wy' CgL3;DρWoNf@s~a =RsXTÄ%ʠheeaAS8ܳDTA!^H,"禱4l]\)B(7:QzVQ}bSP[N&a=4:?$PU!΁GėMe$vcI1|{V"qTsT$/g!cL_R +?.ϑh^;S F%]`+!刢)^9=`yK1.ϩaDBSY؁. #gP(] %!.OvGac8jsTTFa)+>( (]rK1$US֢1O7HmΌ )D0٘`7-|Qm^u5\> ̀ +טDBDj#@Ҵu؞LDÛ\ue+5qp&S_}u[b6Xx +25I&?aMf&ָf̞3h<4 S pW&1"5;569t8 ' נ=$`MIzРщRAx,*?$B16CUx'cR5"rA3B?1g: 9[^j%eNiN@k4N +Rn@|Z D 0;aPڠp /RookD:r9$:(hBG,j.>53+*㏥ hvx2yP@(sY/ +$XIfTuvbϮy('c/ f2hjWO0:&T=hR +똩 P!rgJD&9ᐖXhu,P6ML;c8!X4 J^Ve{hmA]ٺ8e,׮Nh㪾i۸՗rͭNw57!a \rkYкȊ[V'f+dndtlus^d.V>;7qftd|w]|#ԻO8#.ָu ǫmlk:SK/(]!凅x*2 ʵGҳh]:!lZ+cji0E(ZT&tv~L裳(k| #NIfLH" M*-9zbިK8P#'Z4P +& 3K7u ;\%z! O`#X +2@Yh>vi,RE=X\RgPsI028+9<5\/3 )`$,N釾bPE>ĘLG`<-\TT(Dbzyn.&)Jh7JH#Jq +G +@zY!BY5T-uC|yjWwz 4U1n]7>w\t`kc܂oKt:`.(eR%j!엫߷WDžԃv ,`T6M2R.IVX3Ip( ۢҔؔ4qT +ލ@ 0W"BHϊM_a% +3ꈨ%oP%ZR}WV?]Q7QRcqa?W=L#@*Tg9.ÝxS'iʝ+Z*a]Wxf~\†n LWJ\ךj@iެTEX%k42W.Nwxg.5TpdsC`+t=ǬNml(D"=O#0We&Hx>4][$ ]R̝BJV)OT=W)>nAsȟ.z0#ĹjbDEpB5U*ʎB60:B=G@SU{}m|9B\]_"vjfJîؔ)xݜDW$ǥ ߷nq\Η>jE_Em~4dž߾{{]Lx6幬jlOcfԱ}n\`ys?==?.nn|?TY ֠}D%6mb$-ރ6e_M_ҁO%oXMuʲKo1'& 8kU:O4E\zNVQ‹DB:ܑ de:) u(|7qĀ|ED GaP9?Ȅ;lyd$9 6|qT{m zԎd@&d>*Yn!h=MЌEb& AO 6I*$ʌs2: Mr $VȢIőu{%mD +dը?G'C69l'/_ +l89vi:>4I; vpꃨwpn÷9(@$-㤍^ɝ:FRGh|l1 x?<'LĪhalQ.4te5Dտ8 ݇/rį"dJTrb!8ˮDc뻾"Nu=AT1{ށ2*j-} Eɂ{=_EkC|TcFI#ܭ$L3$,d@]>:Fv&Z #T +0b'NS0ZR/5vDY0QL&EXz}պn-~juX;~ +hZ epj +e-P*"낁R/N:2L3HE\&L(=bl؇qIT "N`(BD+r#`))Dh":Cʹ4Ifz&&¤"鎦ӊL L/R0,AtIR$*sbŋ.1ω8VLnD5_ŝ zgl&x1E_~uN4<R,~eiH=Y |D6/ڸ1XIf5 ? +G ˆ7IĒfruL6a; Ut> &kj ́ q BH&rƁp +"<?iBn2Hw_-K#PՃtX54kf_2c$r?}/&yuڇT()tcdϝ*غ3@udP`e&釫f5)sb5{~donI:BQ$h5[ì(L7.-M`핿ocL 7y0gMlWV.*UEt%QCך+_|1mZy TIN#_ %(w^<2,. +H}I<Ҳipǣ ;Hвw_x$ok`x@9D$/K4Ze:T!<_`xoXn.s2) ,z@(FHw_ϼI(Ts0QWXa0mRZp#(F 8l9?C-f^Eo*bk69\ߕx\x8U#@&X3Dnu&GEX;kED(`I2m:RZzYez?FO,rlq ~)ok} w[5B A(\XKC+ b6 -ߕglϞVA5i P [j}ב"ZkDk1Cֈ@L| Xx*|0y&3Ҝ>%T|${ Ñ1Oc& t!j28ggK~<ХJP1W +jp͏j}vij.IU42JR'#4*4SL&ZqD4*Pqjo,}$ "LH>l[n4`80n~)ؑ~ +8"C{GȞuا G-38G"[* |51b}Ҁ3F +G3QxG;'pkDfjF)3`oP?Wu%@,Pm-SЭx +6BsG9MRf״SII^C^dJeQ#´lC0OSf(v$>ČK "=#0PQ C(U.kFQĽ`8^IѱIW ~%W!ۤMB>#mhD3` :RHy5ǖVP%:QkЏhOw5;4p.ksxl8ELr ZbE>uiUa3 gTl8b] "\Ctcxin*KmMSقd69O_nfkUg\A?;ATRDp6m0WK]Pp9  M~ėrȜDY[c;Ƞ&~Y#\iq~[/qV/UfcHYd͒$(| k4-B%F +Anʯ \*"J+K"l%F,=׿~ %ڃJKbWxw|P^ٖNj,,ŘmfWYk@kh_Qڕ6/+Y%Mal[A۔v}nSMiqSV*7%Ms_R7}]vSݔyMx[\W_՛M|SH⾖7}%i|aش"žil%ʦmмur>;>?TihZQKߊn\6/t|<{F#R!ڌTё6FPGeO\s[j4%Ԛ2hv(4՘G:fFrLJg0Y>K.gp2s.Do/%,١$R~y1ۃ p2 /fi;aٕ#nv#?9.ѽ~&u7w[1>S4cp^L) G=E xr0\%{Ռ5.0ds>BS\2yE~o3ĉv謭D+)CSglYױ +{TϐwToTwڹ)$U|\u#2_JS4|NP*a5Ǩ9#$ZK- +wJ nNAA#1NY +ԋ1+ SI<&Z9eTE:^Ezڤc s* ^ SlQEYҟz½ĎP@8DTLNui?J}p, +H+.Cgՠ1Թ1HԨ;Cl[Q *~ n5XkaC-j2 U$/vU`.9LO8[lEnYIS.5GSNS^2?GsS'Uճi IaKmą+CvZ 7`*"XD%w àLy-K/,K6> '!>,?ab} aMU@OǨ_Exi0o:ꥧ!Z/.=Mg~iME;,l +a )qh-*d`LX fel/ JfE!7;ll0A;S i+-OCO;+WnPW 6kq}| Z?lj +LˮRJ2&hU_&h5M꣢U>ڼԳD0uuYq^Z4oSŪ/U+iZ0w57uҤeڣܧC#XH9jiꖌH?pS |cͤ~8Bѐll0USw "GwYFNZwyXhBy~`CWh\dTj6u(aE๪Z\:&Z-,5Ү DS2ksq~P'|b%(|ũl!-S+X cY"?ܝ-,5h? + qKL4Ywk’[qlJ/!&ddkUKVwM4Jhϡ6]D,l-e?,Zexxr1&J.)CVn1R$ab@&$KdKKhᡞ]Rz@t0E:](|G+71ID /O$HͲX?D2>umx4}μ8u嬿vvc{546G  rq_Oɋg~М?Է2oPYm"Oȼf UUp/a*-&Vh +4}L2_>xLnw9±8*WǃADS_0`AU QbzcIb/Ej„|Y~F0@U(r 'Lv>5]lU&4Xr+f(WH5\>UUժ,vSKA nל&E LLE̱a2Uo9USe5rGib&W-_K^Z c0n%)W(2V=Ts ? ts¶ ! `܇t;;n{0z"7g)fw8?Eɶ 7XT)w +\s!"V⣂<.o4g304 [Z6T+//] 64 ϼ ڔvow-޷V/7][՛~[ۗn:>[C>Q<-B prV>dN6w u qw(sHTQjҬggMgd$, [V0 +8 N)[]"F X9?q }](~EjgB0!cqEd fjRёY!9; 3ɹDU4AT07n&9u&1>&s~ +jh!R)UqP;h2kH^s:QzFk[k1 4ʰc&1Y2HUK4•#"A] CDp*u,JP#;ןTeBPG.uBqPe'Gjgj w{y:](,*Zt}2fω):IIzc^t42IU/]*qRI3erIJA#ׅЧ. `N 4cs&N1w*u]25a)~7^@#Ѥ~d-H֔ +*>)(ms;HPk&GJ]bwaNx!?"d0DɿCZ3l}[Yrۘ)\+.̦WϦGL򵛮қZXvnצ'WlZ^i]-I]hg64 CՆfCw ;TQyiv.ސv=!OFLuz-YT{)Ǡ^#ތ1 l!E6rXS)%+8b3ТsRŃPӈ ^iY؁)xm¡xg~rEp,G87ޑ4c +#.prG\Na0t3UM;CfgHJQ>f"@[ ? ໟ` 0)zYj +8! L@|@cOe aH +dA ;@ aI4 k = :ԕTe ֬i"ҀmAkW)Cy\ +a&,j.GɼY#jfVa@ږ ǡ` A4Y1~Hhf6E07!Ls.|j cI7)pa|ǰ +ubeef;$4lrI"fڃ06UCM&h +ŕT9ȚU2MRiz5fNdẶakǰ.Q=0͚DO$qJkPcT +? <:!DzK[X@=zCC5C O`4D- +H񖅞aFTȧDAR +njJAU5ɰ74ʅ.Eޔ"P(^!Jr9ȳe'FG N0}Q=b+]cA +=CJpP!|x%f?%&^EE0Y)a(Q$C$ +Ͱ0LEaiS+&m*I@QTD)wv>7>tuCyz5bl>l6&>n..1y _M&eY?U_ݬ/v,j}Eg社rha7'~;×Kk$ZWam6QrN7qwa|7Y>}Xӌ%'-kvɁ\ I&e^K[*S rf.שA*}ds| +bpPq ? q v ^dq҃`LiXe G2aoE\\~XX MEtE,20q:͗z +}V"aZq,Slqʹ HkQB$Y1BwLKcY"Fנd\MEɣRD]GL 9E_krL<'Ġ zgHVa7.w:AojlZ&[Z(;8P܏:Akt\¤Mz#o!8QQ%H򼴊ESBh\є|qH8NҠX9:rBazQEy7}ќ5rM$V tKNJgH:{ċ s$~7D"sT唳N +'DRY䜕Fb3ay %dv@!=ɀ0c,@s)lBǟʗ\9h,wѱT0X=F/B|VQ쒧FlX·SCNu)`Y7 ?p[ &r` +RDPNh +DaU (tAD,P#t9@[xim'YQo?tNȳΆ5q"63Q&Q|4X@ و9PRD:8=[5zS_ݛE(L4n}VXEa +ux‚IE1O 4X<0d̲[% .Z& T'/&au]S*s^QuJjƹ$xfu(MwL$T3zrRZ$aPL\Tmj#0qRKjbJp\A 6 +^#(<ʡ2Ǭa|/7 +7ˆ֙+Wv :~n~/~i^[/[֭^֡o<.>q6qi `\mk5pzGM^57>N(vk]eoY؇7n.{RoN`*] +zvjVs{q[wb*гQ`yoS׮1th"/݄M|&e$oʒpN&@4iN-I&1&pKIw&ܤk:kzi&k%G]6esb01.ZNɪ:g}pIU.B*Y態>?O' 45KȇƬ5 0aȩg!=,qOb +6)Px05QzBڕEZ!ԓ!3D;M" qG`׹f#ȦT7ǣp#M{ǎL%dB 8*(Րh\ĜGqʳl/MzhЛUPW$/Ũ:" &ڲP=yL<Ԙ1w7ȑG(91йb^rl¬twBЛH8&84 $Uࣴz-2L5 fL]S oP\gM4P"gl5lp{k 3I^W%who!φ#ylbpđ Od'&A.L E7-+Eۦ}Krd@tsevnפٗnM +D^j|euvu"9dg ne3y,h'y-IDQ +^s* #C&SN(8+)K݅B݇+@QLJ(NS./`=1eGm2懌[::nUo Jc^s<"{*uC&̀MR waF>ʝ*4NK2R9.pTŢCofR7^=AtAk.-a5#/t;)Qk0r_B&sHiP@O4yh@ҩESeBd4eڴl4hޤj|Ff|3UIg&3ӷUg&k>G/8aɗdK"fqwFНƤ-LjlcpŴAdEqxY\s|] mFjU͗nV}78_ʽڍPFn{ۈm6|龭F p +n72zөh^*[.RATDITm( |4wMC9qF1iɵH!Cxt,]4پs{'# fB.5z 6˱'lN3͏zqa -=uq8OK4 M׊Gy>nS>eD2F+h&zP]&4#ɔ.>NA~)pC +NDžqaGs;Q&*q,K`=Xg310vn!wb)ؕ}1K=>.QPj\'ڔqD@]X4bBc CFlo&k7i]76_ +md|1(G`dZ9x@NE9RgҪR(`CRf2)Y֌"sهQ$-^k!SfRhIVY" _H6 +DoREv4ZefdQڨ-2ڍ~FE jֈ&Gf=uѤr?hjS_eN71BӔ4x̮%Uw gRuIva&Oٝ$Yc8&D+6g>9~Su `O[Xr~ nbd;_'eȕ3Ľ01HqA2"lFF"2~8>ț 7k#4}kÒT$"t1!}L@2)@єK؅Mз5R%gD*|V3k6Izsu$}IVps8(1>#<lԄfm +|I D:o )“W췂҃(M 4Әh> :=*K 9 -UP(V +PGO 8?vHk4^M~鐍ϲ&P#\3 tR C"6 Tddn<|$=fkgR +fAgqp^QU%=RoHFh#;: =M$ PUL(K'x?  \pec`5KKgĒǑ$r$ HK!M2bCЗȋKGM9=.CYhZ)>d02uPhfM*A1_?ouY?~)-O7f}[zօE:.ޭe|jݾ[66貓:z!}] 7.ݳ~;~rC>c&"}kM^Cȿ}%6ǒ||k|=KT$u?^3'838,băwyZHfYe8[թUNiXsOpH@m LJE^YxV%^,{p+Pw~~+w?{:XˇY-Nlu~ޝzF}uY-e]t7~&z-[׍8-sl˫jh.r;w{uk$XV51o umOX]_˺){YB?$cދ&f0Dshs6U Ĺ ԦgO&ΐQa]Wel(a}%gle^`׏S~j +CC u?И|0&G j@˜. !^&+y+$0ԉ VZa2&`a"Mgu#_LX ՗K&wswZZ~7սBc"xq>G2q +8Q"JӃ(p qfS5H' "/V0O+~kYQwA5py]dW+;u6KJG]HO 5PFO[B ^Ĕ34v}侄IZCj.=BJsFr@ayIr Z8G +TF\|IRx3d«$tG +x!WVїMOUc@rU9&zJ1>n2kǿ_/K62K~*O gF3"(w/l_N??_{|臄,?qY_;[g8857 x0J &0o^Vp԰t.Ok,;-I ȑlX"#qcFjHÖx.[=mYFz ō䌋44mm1E{i^sF5bwP[@irӼ%!isRCA [+_"a"?w8 u&WER%gvgJ5NC+M zQҷyUB (<`t K}4%=M +Mg85r"aV@eµ9IÏskV7I j rvjC*>"J TwcRli"ć^ӖQ V+amK5Gk]hs!/F(sjS7ubzXZ7r9`nà~/P<@pnbMC )zJ,}(^p-K јRV8x3Bn!- + +sܼeJb:?Kuaѣ@Ί:6^+qvP.EL^-=30 4-5ei)Dza&vYlIo#<_nFQaΜ"flE:{M~M/i6zoޭb1T*T=vBfo8|;8ӫK^&zϡ𽽿{ \f:58vh0vHAG〾5-spr8&1q Sx^1+3Oӽֹd_ B19AAp +|zsv &|uϝ F|#(kÄOloR~<ꡩg:5܍3E2ƺ8lFs`do!<\@=+Up`8ni9tegş#\)? KDWL@G(#zn_`,i`;C* +]7Hj3Rjjg ^ +,9o'h\BC? ]Ƭz@?z*Ƽ6Coy=T[evԔs5 d_q&!*pS|OzJՀo 1, ߢ.GII)dCmYA=`WS=s滙c`5mi + +̿90yO#Y + 43'H^4"w R-]8x01JFM(amG[ST5/UI( +&*sZL0o? sڷ`F~:lx@iP` +Bh sG6_UlPnuzvU.b^wl !aBBB!tyM!r릏пܿsG\\e~EOsGc럧o~֏H{Is}iݏX?`)V͋ +gE8/"3|I> ߯vߐ@$ w@%~@?҇#'!(WgO׫/eba:] bĒ5;hT2AJO[#F΃/1Zbև_+pSòVF۟n>2ըyJVh1njJT#j5"T>VZ09Ć\T(b4rV@x(8px~;TQj n*"+z Y^ Rt1L'"5NȠׄG'5QK-(xp s9d e e%-FԹ1<_ q? +Ax>MbyOGP.^wҍkc{s{wr̖O޻{uX4w}z׮ɪlsEkw УQuzXH>Įp+Uz@4HfwO qzDH*wo_1& U̠1KQ 'Ҥ>R˨|a 5#}w1K~d*U]6ˮyܿ2~-wp~da-!z߀5#3cys3|PW +rzEsjR6Jq4uh&Რ݇?t%(W?Måwđ0m-{3A nK_l{{LvxY8=ĿPMf{5 U?mz~Ê6g+v̲&gLuC|2iCxGA7Epv W# f1lIL*컘aJB~jn%0£"p\:yg쏞wn &^5Cwz}*XrŒ^B KEp%؎dzSREb?R<5y9Ea*4ɵZ7a}8~v%PmMɍ pdJ)=>U9u4euX)Im.PtGgi~ k ga,"_Ԁn~{PU]#wX! f2I9\Yez8{\`$2yK ! @u3?MUR3s@ͤaϙAhtFh5 7 gFě!:<+?{Z9y񎊠LstՁÄL^LUʧxGln|\)Mঅ0w.y'`aK~35֕WM4 ]j+؈&&n&2:OI(A ;c69'CǟM}X)O5~ydhju f)#a5fB)B +J4՗ l'}NլQTZi=:_% s +TKwtJ@3 ƁDB x Y%h<JH~Z˹rxT 5c>"qڵ:_0ƬVbݎ.sQ1F݄cת +H{!e˘x%e#zQ0cߣFx =El|Kw!(G<-pZe`3C4 D]0u`΂0%)9ig%F! |0&\no b*1a0 m1gJI![yR.QCXxOӕG#y*!_*B.(HA-'FG8 ^aLL36%y XNq:A!4%c$}10 Ű|2 $I\n[  zjQ\d=kSt5.6 :ђ~U.n$Н XrHG [F@4tjp9v&WMN7);74~ZHn;^# 1&o +]a}:8OZiΎƅ b,ʼnή@%c ؖ?.:L Cd6hRZ{aM"՛S"aGzƐ5 +h`&ikDCE3j9ywGE]$YB3&,RI%F={a#\6L,ɟq4fR:(`22BH?`s@;3r}޿jJe7fraX.Ju/d/ZC3~|,<>}[MO]f3]PLE@ *$m0k:(a"g\noS"z+i-|:t{'y㻅LkaIbA0gg% M`-Sb[+):<q堔W͡;UoWxAYsr_kATHcYX]sPAUsNAyJW +C֫RP a@sdAAJ(J$2ЫyؿrXg lrYϊuDT{Aگ:"p54/r#]rGD~Ur`typs#bJGD"yYrah%|tDdkmtD YrXotR^j WJrbK \|RCjw媌Yjr,5ruW]i+UJx\Ґ+Wu\=+ wJ6ճpWrJCt\]U8a|U+/ɳ/ +/e]Y* ,>+ ,s p륲JC(?* weY| +Ҡ2ϕpWJ+la`Ri`eYp_* WiY(-sJJˬiJi&}DRN^Ϥ:CTI[gHz!}"e멅qH#}"Gu$I8BGR!D8rIup:>TGv"bկ0hvFc}>އg>yaK]0FN-=iT)D=O>>>aTv}Vè8Z00hv]P5zU FWQ#MGǻ`?x +F,~ƣ( +F|{]0z U0JoȻb,@gR2fj +T_8s˰x:X,W#+dqsv{{ıLk!d@i_JV +Hă7I1a:㔩M[E mKN A 't#RCGoUߝ6R' jA+R.!+g +endstream endobj 65 0 obj <>stream +K&4&zO_kkH9p`Q)KX_MϯȤ稍q~aos|>h#RK1~4!&8ݣQe|{Ji;<|hR) f +43o^iZQi?yBƫAwHaG@O޶/.0l&˫{Š{5.!Pey;?CC-u pɷ@O!|*~=؟՜FGg:PFT'O/T^lHwU~2o |?9xCo66֔ A)P:4e>=6(dIQ=C[Zcд7CFo"&)@ \OӋᆳ&DW(XbcQ [KFIe84D\]e|DP1)ԩzǛ=/ FÆ2 /XIɡq?Mԧ5{ZXL;ES;Qp/fo5/ue~ۜU_| 7t?OPQBcxƒMCiw VEI6?lF3.+d%-AszX/S踂2j/zЕ1#]/Yl\5HfVȄcW`u=N걫7}gΝ;'ۧH!~e`/ˌ[Dfrߧe>aǼFgtwծ}]KM"XN@F 'qFlB*HI8_D}xś|1W?T# +HڻtnY|%G#sHY_Q n0+ }ːB~o?vG̈́ʅm$LUoxys^[F33ÓȻX qlx"6R9$:4e{`uv/%3"$ +√{b +Y"vۇN+HG^YdV;fb`8WRr#Aڌ{P N?v TB(Jp^ebXWA<^㼩QYӽ:!ۨvQtY}02,|cj!pS@abr_bQPTkg4+0RS#9w ;>;\$ T [-}c4X0K [t EC6+NR{ <ذߢr07Ci;"揋1/kG(Li]Y0mY"/4OoSߒLR afd-]F|f\Жwt"a YWwwSEiI0 RS- >3<8J< -ڍG +kn8 +m{瑍J6vg?>:8 sRƝﲱdSCJA|+ ZLf!U1G'm6 17;!d⾼E*B~>82F!#@^]ƪrj8|’$򕸙 ><9|?~@K,Eq!X,5rE9FY;iCm +TbMDʯ}@xBUH[z=a?/=ӴbJʼnmtwiNS%*j>j,pԳnt;swoD? tO;v^;AoGvSW%.|/x칿huC Ե&T~r'ͷx~͇/Do_|~??{o>߅?_~/~_~/./u*Wh.|S +G)!n +U=-܂ԤiA+V!ל-Vph #3хfXehFudBxsEPIS=Ds}A;HeF[V@։>Z~ィkx*X,r~iDxM׽[wk +2n +| ]/ׁV;]q&+ehcF/UfiM#nEЖᄭfi ,E 5`YN$;t]WciF@>Zՠ 7_Qd\Xt|PVLAlq1dx;aH ypmN{Iva 9E/BhN02Ax. L>ȴr7㥨ҭ)}K|JA[3/8^ |o̱4!Be<ԸvD],729lz9p Qui2򦔉~p|64%bb}z݆^ӛKRtD'݋ODT@%6Z]qk&5:\E=ވ9iF$4-rs3#i*MB~ kQ?>zF7)c&/5+:CؘFXQw  +Z$z<|^@e ,C6$j!sW:|ZJ\~(3ewTWO5\c<.Z&">+RyExq iҾ8G,ˡ%c\Čw=0v j ,E&I U,#L!u$110ޗJ<ֲYSDWɦpx<ŅWd=|e?d +:4A"Dn+%BTގfNG=9w3wuntY/K+g2ajT!Ȕ57(FԂ?]{Vcvq O-Gl,9@(]"d* 6.1hR#>Ýg ȴ-w +jZj~\W.ӶqhތaIM5 +ڍL0Pۢ-D H %C= lN:҆ -d+ ;5dYhYbS@REލOU87b^s>l>z݇bqBgo> "9r)*xe=lx{ٚ!5m-` +'fjl 6{4 *&R +zP${V j +X1U{ +v2#hWU^;8İd^U!.p @ $»+)Z + +y@ V4q,UJqxYXڨ!s_m`$ݘ**+ٔ1YJ*]sE1qdfX?2JxA_o]#ą,qe3M κڮM eoGqa#Vmғ7um*]<&W2::2Msgqx%5){^/>r\h3IW?.SlW񬚷/XfNlBσyȳ`cَZſ5:闤) '砜k( }+' )BC:Ha%W )32̥ \c=ӶIYQwW*U4X J(LYTpۡy}ew~0pvU)~-FF{\8BQY=og`i|RqaC0 CvG&`}NunSGKnn޹0}wI"P $e?e*(|{DEBEnö9[,\WB".5Җp2e;V;T޸|AɰĮJu\m(` E=l+JH:]X Dn`b".͇& &RlF}h%nJeIpofw wP~۟Zc4M^L(/~z㳥*¦W^4hF6KRU% N$YiY9a2ELurd]E5)nlt"lv"c ZU;;Jm#/gP13a#JAs=ns&}\nRʛ~Nuc 6xJpB3hSV<ۏ&ɽ[SK3- qE u/~O`ep!$ Rv3ye=8ķ}ZP~ mo(aZchC|rF$'(F;9o0ےѬ3,oBZsM>RҔ맪ib 늪c}AKl8AbMS,XԻܻ )IN*/EM_oEMYtTQՔO 㦯.pK݌(k"V_gY\!`2!nǤ)FC S01˽7yL]8mZ3?mmGσק#5c6@RȭcƃNc̺C<Er-bIZ#J(!`:!) d˂x;jL1E*.I"m )ۿhBΫR(Ai@6)ENPwdȩ/_IZh8k?rPOWh_fEZkfS)( $OO;3B?AAy6sSUUTۧ,G\!dB)??d[B]j0 &f&j?@9G5v@Dٹt1R>%\᭸^iwfS|=JV xE(<ӝ~j`sQDQZ*<}i_gP#̲?Y"2S]ws1\pcs".0bxyNub8G˶KyLªfFO*ZqW +"2=LBp5WqGS oc-B¬bx̳Re0eCāVD2+YU| + BrÕ * |X6{5!{2*_ + RĆx]K<w]פa*p`/]UzQTMC&RV$EKk"J**|8tW7n#t]h $[ET&H-n"woʚٙ`;AYRgʜke߮6.h^d&odUD}5Jnވ-܈iUUib^ /Ŷ@AQfEQؐ˾eTQvnE\H30nsȧle:ֶ9]mmb0cN2.텭oJNl'q|ʖy,ܣvv^[%ԅ\q4nE~!Xra2 R|i{sˈ)kqޠ#lmWz>7FLpPM:㸻X6}զQg3?`T֡Щnu!+|j_`u 2`>Q[AB Or-ں]YH[w̜%j>}#qrPB4Bݳ^8mP"j][lHs%ǚ48z{%GJ'qDuœqCQ6Rds7ڒvL|bEة L=l|bHP}b,ж[У}vq_vn̗Knixo7.1>[FʓO Q|b=ö'>eR,Fg]=nbolfС7,x:f7Y2-?vٮҧ^S~L=p`!??qX_HAwqa<ɠR.g`1,I%-#_0GFY,Dt֯Bߢy1JCy}?JULϏ\cdp Eᒵo 0I1A&w"LkIszk )켾~ySן;w,y}R9xhgKBzd}, i7]y ?|E"~R]V'& =닷8{"|ׯ 77L$3&}c'qZ1د`y4-DPs^#WHAZ?o_/߼W_}x?~~5u5ϿO7 noo +endstream endobj 47 0 obj [/ICCBased 49 0 R] endobj 39 0 obj <>stream +HdnS t:1Nց b \"#xK<~ۗ[(ȫZ c#-bG5y %O.=^CU{#ň̓9?7qb,.=Z ?rȹ˟_ﷷ/yPqg-]>$HG_:J +32nRv KVc*ԴbX'Z+a>eBKhMaq6)1ᅵ'Fcu3:񇌷y^Jì8+'\ =CN杕1r>/6 5->!fҥ2̨=Z䡄J]G cR7kKΒ 6N`Jő(A~z<{/~jUKNW*ɺ6zr +ATD24AyR6NIZa9L]#'Rͻ%_[K +_A ܈63댆% i<,2+ O4ŽY۲4 +$ #! QdGQR ZX|Q#`w(?LgT%W|60IT2CI̻ܞqԷK£^ŕId0/+$ Dgl6(NBH.~Lj:h#FWҚ!VY ( I1eFl*:l!1/gQB̦MYkK LEW9?G@n7 +{6ƨf(xt&Ԯ==̤I.17- arvMrP}[هH'8%cQUK5Wږy?mGy8)*$B= M"!--9B2_5*AdUWDUx‴cb9{(0 +ch+u(==T4k} RhQ I+LP\Jl"ҌpkX[@Cl7C^Ŧ +%WIeCfJ=$S=RzT6b"gMP{xm)3_žc3^O`8 B$3-s@pka(g<8qҼ1Mԁ^zXBNTk_6en7 rΛ1]kYRBx117%Ѭ!Ĕ2ڑ&)}ŏ'({>] 5-iLh޳kԊR!ZM~]h[y}|l_!HKvڡ;JidGo_~O) +endstream endobj 40 0 obj <> endobj 42 0 obj <> endobj 67 0 obj <> endobj 68 0 obj <> endobj 41 0 obj <> endobj 69 0 obj <> endobj 70 0 obj <>/Shading<>>>/Subtype/Form>>stream +q +0 g +/GS0 gs +170.0136566 -24.0031414 -24.0031414 -170.0136566 46.3515625 162.2246094 cm +BX /Sh0 sh EX Q + +endstream endobj 71 0 obj <> endobj 66 0 obj [/ICCBased 49 0 R] endobj 35 0 obj <>stream +HnG j6j⻐ćYHi&Y,u}r§_S!hiQbi3䒢pr8gcuĔZY&bn!8Sbɼ-Z߷5^6)&+͉m{oS##G=ǧӷp{ +/oa{ ItCxyL9<  ͢*VO#ylU9Ǫ}83US +]_~4tW+[(Mq4o=f"X𘼇(vtr9J>U% +ɝ[\Uhߩu(zR4ZM@ra9YkWǥѷ1_ú0 ֻl1K)TRiZq0 [I_myGvj<&R6> endobj 38 0 obj <> endobj 73 0 obj <> endobj 74 0 obj <> endobj 37 0 obj <> endobj 75 0 obj <> endobj 76 0 obj <>/Shading<>>>/Subtype/Form>>stream +q +0 g +/GS0 gs +170.0146332 -24.0032768 -24.0032768 -170.0146332 76.0488281 162.8457031 cm +BX /Sh0 sh EX Q + +endstream endobj 77 0 obj <> endobj 72 0 obj [/ICCBased 49 0 R] endobj 33 0 obj <>stream +HWێ$5 }T&s}!!-h5|@ ؇$'s!,>q?}u +1sH4ó>5[_o !OvL)=[8?-)ZŤ>-#dAS̩B,H# OˇO- _bApG,{0j +})%v>+kX~+ؾ/c%j7^+Qhb VwﷱzX sM\o?b-L9Ūm^.7dz0-k}]>׺"YkN8uFu?W +J{b3UH4^E#-@1r}d.Y9oKL RW;TW-%|*8`b;cEa 9x\F,Ջ'19[jzgPk RU4Vk~v_WNGl!wȨ`Z [)* G@tvׯfJ t1,dY>0&_RA[ IB Aw8pbOLl&Hg n!X&!HP΃_{^B`jG ~;),x(B 2e%,$f J6'WXSJ#Ys)ѡl"bE4.XE*IT>UU!<4YtI(p㑼QL{oȼ ;8Fb2鵿}I7*Lq\2zag@Bkĉ\O30U9۝[/#H1z0bYm +@]Ȉ Jy &2sL9-V` |]=Zh:l_}Lq tnVIC>S +A|T{Y[] {B |ȜLN+k녯2qJ%Hq8ΒRgwEƓy:>Ed/!V~,{qKU.~G8Ѥ ؞:p@rXo.1)p^n.=@4_^d,)b' +endstream endobj 34 0 obj <> endobj 78 0 obj [/ICCBased 49 0 R] endobj 31 0 obj <>stream +HI$7Eq +^Y4*Zj$4,J?ߌR(csgÛQ}=r_??>UmgJ߾>R HYO:$gYs*ExlVtIm]jKB:ǖC6j߾0jgc{cUߐuOD3?{c 2eV=낰oduxKQ_'`W-V$OHne%j^h(gqdF_a#v:{Yh><t&,lo6؇Ѱқ01 -`8A^bli~L<٢S$#{⑦ i햆`ys,qlk-@B<-Fx(~ F>OWC1z"\~#%9h-1\MOUh.qfXiUrF)JA0\ -ɬ D*냫bYönFg lzJ]tk!7~.3ont;1ݎvLc~|g qY! U#((^*|f :3CM^ՂUD bwe‚}q LA$As>r|M%ENyZ0W#$vs6JX9]?w_ykZ5(ᤈz6:1\<:XR բ#W.{ɬ(g`NuXF,[4C-Q,mԉ`8bX/^+# ^0$ U?i6:]Qf:-*sO˪ {^ 𨁗x߀w$k!AlDEù Sߎu~ +g:Uj-cdv:P+Qa2V +^kEU ǰUD"j~3 ݏ&1TW;5[َ6RJ=eq:> 0w31<Lj-U +`⌿sa'f%UGCX黏l:]tuE2Y ?(6D߰st>aH_lzSs~#8T9{4w~e:)D0b;.=X /A/nDى3wxu)ѩzqqfyj5$_#ن_:zxxҷzfXknaրx&Xվ^^hrYm;F.(}B> endobj 79 0 obj [/ICCBased 49 0 R] endobj 26 0 obj <>stream +HM7u +^ )2u{0+h1hg["Hf. 1Qy/~ELǟ[~٨ׯH )E| J}}zCYe* +ET!hlTny%Mɪt0YmYtAa_zj 7&hVA{U4:XtNr H[zSҮӾNCG$@r2Q􎹴֫L.?{wk躵y>Y~uXgLAEgPeIX6˶EI]attNv)FPU /6}pG)zaKlk0,f:cg2褷qj3qgbdbuGBt{hai {8WSmKc +RTemF΋r YD5BfhsKdg-0 yPNds*chhsalu2)C.jIt~8>CBʆ%:̽ ޯaɜsF =wX$a$H$`?u-gxGyXPT˾L<Sm>)Sc;՟-{e/`1X>O**De\$N|\DڮjZ/yd*LZI0u{R\{%{\kNkԚd! .mUg>|Y\>e}.>}9/z llO><3#ɌPN8SY^rRz"H~5nxg,;G9h$Ѓ.{-z}Y{=ggYMt+TrPē6o7xK&~-Љ$'fkwҬ"3Qqxm"b/JBC;D,E +]۪| aUj‰nDcX&5cɸuњf]2QjMKSW/:T=}p݄c:ю<2V˓8z]r=W<_3(򀣟qǸ v1<8ǴXAv]bT|l{0 +cVM*#Hb,,Vbq9X,G,ͮ+fizG5PcMv(gPKxIN?Q:h_t%=3i1q1v +Ol%ՉTo +a Vw v&1xD<(q{$>e.u]?czH V j&"-Ho^\`F[_?13a8m<0HfYEtu qm[qAz M|a'ZmVLwZ vFw=bRZY!mj'yP\|k ε9މ s1HAVk;CA-uukV*dvb,Uq=)f\YY 3S4ϑXլKW,|[ͳ5Yn"&)] x?.Nzca +aCu'i1Exp.ɥ0wc_h yQ->u1L0%׹\oU8ID'"-;D?wiA2߄&"\쾓OY ;֯K]7a ߋf'l'hiYXuuVͮ( +endstream endobj 27 0 obj <> endobj 80 0 obj [/ICCBased 49 0 R] endobj 15 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 16 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 17 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 18 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 19 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 89 0 obj <>stream +HI$E~ +^H픠UKj4,7#鞑ˑȈ9ã _/xswΏ}wE*>k-??o<Ԏzt!ףm|۶ǣEBqvX^D-C=|*.GlյvGŕ~ԜPbp{GOZ 2{w]lq,rq!Qt= '^娭îsJ6uIr^9f+ + UzɗvX4`y 4̄2|$ų8$yN0 !Fo/%_:TKc[0Ol'oK +ԭBxri8]_GG/O9[G\x6Mc%Ն[,{2s8 k:q>*0rmv +S0\A[CjkPSa$Bj)0K>GЙU 3 jˠn})ee8gZVn8eF(բ3M:\#6֕#L %#s iv:xiH˂f%Ci4/8;ng5KM v'ok] Zx»޵kjλb]!-Y$S0wDe|MJ|FTEy~CaUK}b0X2VJz|rS![H$^Q[%63cK#O!T2* +#|yU4 Mbu_X28/~.j L)ºp)&qjZ8VPuc +}Te:e +.ԯQ P1CJBGapEX he"ĥŮZvJLg8qoajafrV&/<E@IU?=LL"GGɏЖ!{$u_YH€ ]ШxOf8 Cᭈ0AyH,SHiF" ާVrSS^KJSgOjA ^_)UlRKRAJ'*V҅Z \(`BWbe*R\XM'(3e2{K#ҫxj ,BJKYtԳWQ.dz.aǽ)HY}qS mh(L̺5|M|a%!4dtS҃bnД9iM +ouŠw/*Rz[*fW +:zN:4 K#LAj*a(0KUTꚇNti@';U +VP0jLJʄl!H&47J5 ɪg5PeaW`D HCTy֦ {zҥOY*`YݩIׅg7bmDeQzIOY*Stҥu|שfVϩb.=5?g^ 64YX2qrF-J+<>inŀJwVd&qZ!YiDuU*e~ra𭜸Hf~p&~e$Yv"P^i8Rh6ĴONi*fX4ELY,$MX/CY{aaT?Z7 [C|\K{')L({/(di{W9T;:Sik?EHVjXMCVj%flKqF8ol *nTq;:0oFL !rtWo@=KA̺oLT1#Tń\53a:|"M 0"9fR)䰂q#~s +p3Du%} +qDJ3+EAle  iI1~^x b(jhSo!LJAFC+zѻֲƶڕCieIv^#s8.F?rOSG) +endstream endobj 90 0 obj <> endobj 91 0 obj [/ICCBased 49 0 R] endobj 87 0 obj <>stream +H͎)gv4dapf9UE}ӶnQE~:<凗=~y??xkp\gS}{??=~q.Ő\oo8/q,1^GMkt6GCŋ s,OГCK(+x}T{]{#Xq'A 'f0ӷf=Pӵ5 <_qͷ)70* @ ^:X\>ź5I>քgz>b]bd!VK1 +G,8F[O-ї4 NÇHTt$-t"3[v-4t@Հ'K b]'P*b($FC+,Vi㔁6 fҌ 9tL+]:k#MmD؎J |9T%f?[wgjF?؞z8^V%%2}.din) PHI GAI>dt2 +9cƇo"=SBVgX91~Yu؊Yvޞ@ݲV|}lI3faQT=8䜩iһKR:01q C_Do2_fC3ɞ*+M$|͢ա̽ ^?>WZ羾d#+c;~`r>ȸs7x>^%X}2gMS#Pg@&2JȐ%hfS2!"3ͿX&5DՉ óTCAcf='L,( N] +ÊF $ZkN؇u7KMs٘BYԺB/$;BEdM,{my]@F 35-Xc`%00S\4M\ȱFCɾLpM#Q\sT'кVM/eKc ;NK*1}M6\r'7NL)5Ģt((YVLDbQ+NEe+&dPɑ,U`RĀ̛B٠Ee#.;ҪPwrv#CYL~Xfj,Q-I"nMi)>UNJ-%U'Ym**l:~NRpA@;`} `Eixhqb 3,[8nZz.5| _MiX4 8#eGRQ#qgݖ!gpTFSaJOEXk|uVġJfsBP"*] +5i[)n8I)V9O7MwP(`S''ʶu)% +` '$I9Jj:R#~6(*6]&flc! g8#p')ty:+N1鬘jkߞP~?مSw%N7:$㻊u⡊PMy/2 RԖYռf㍞/u ` +`b?:0\xJ3͖ /m4wK> endobj 92 0 obj [/ICCBased 49 0 R] endobj 85 0 obj <>stream +Hn7E{qmZy,U` hY&UO_.%/nwtyꂯZů^o.$7_SNdׅ.k)gܮWf[֎ɴRЌ6-Q:{[K{yc ̔qmѼp=!xףUMz0U/-Ws2B6|Q|..φ}ѻeB#XiQ| zIg6p[|&-4X!-Zf \g3 `V/4x)&GXz@)KUݎ+eJj K;(FRcD#5۸^ZҺq'yxƊU da0 )aN;4Sc+05HTztPAěqnmmc#‒ uIݣnA,5$>|z w +D(63x7~t/zXK|r$n: ) Qnrʈ ARFjYCr2lrP)T`AJqkU`;bN/)4[aUl@~`=7h  ?_Ƹ)X^ʎ:Or>X癑S4 4iFaYѵY蛩> -*ߩ"^'eU j{tV}^XqZz dqֲ\r,*5N!PJ8&)˦"Tn2B&d$u~umת$vUAtSU)an(5=c h64lꉗECNP@ XYdp.AG` +endstream endobj 86 0 obj <> endobj 93 0 obj [/ICCBased 49 0 R] endobj 83 0 obj <>stream +H|W-9 ܟ8=ɖ +!ĂFU>f's;Nb\O߮m\k\vƽ˯9aekܣ5:w|ݙL.ϺW_e\_?_~?~t5. u/jhvG\onrwz=h7bp;Zz{ކ"7=S0.3{yz[{dK$`NqA9+D0oâ+>\|x1L@i_Ge_k8at~T0>l\Bx sυ }q{i J B:]̍@L`}>da1ô Y1fa$70O'' .E|q9`rl90--2YcwS* + +xiԲ(@Eh!`,$qx; q_ gZ G֝6/z#9w4Bu'Ȯ^~׼5A y=sXBA[KI툢*SLA[YvOKa='N ZGVO6X_ 9'X7g)9y:XIp9Y8R<$(<k &VË&*ڂzQ(7 FI]SX:^W_"!ɨꤘcw.wq YjIMy}|0~0a rJҐpz֔yY2 2x&S~<ۑ>PO>&f)B`MSqVnuT@"V7ɞM<'MlH6N.v)5Eɶ0F6Uȉ>mKF][>l+[,i!41ljk;N\dVtI-&k@Q`2Rc q<2" lfZ8{7jq򧃃x;,jW˴,50A 2f][)οPzJ{(ZE(\nzQsIq-N˴n`'|kǎ29ML-ps346s )4v=}C.==M7"jIX%bBK=Ue|CRK2ؾ{aPf#WPِ@/~ ya0_X΄r 7NBlq٠zh`m勷 +\. a06KF[oKNoaW*j蒶9 +tSE@Rջu t #S1wxأDi/!h<7jC_)$ڼOh&Y)V mXA,łoNR\0:<xP-)2iZX'@NyY86?Ef I[0Eh=gF#!Z0Ù ~[E6q+3նyGWChr)߄;Csb6~G8~فI}dUnYOjP#nuySn L#8%<"^~M63[J}TM:Fl5W{ѱ4\~C64㗮b@V [)7w?S:X 0s !z1gT6ѽ;L:Z -֕#hDrT hh miޣ.ǻ:YAWWd:vG.` _rt@\,R'Iyy)qZ2N}G?`T^*v֌^$%jfAQtR=^PؖZKw;_ia07OeuK9 |QUFe:;JJҢn] 4ձTkG u9UO,,6rpJ'Gޙ$DYv.53<=+n,!$z%~ 5aP,٭j˟9f^+QKn N^*;_j^Tu{-rX6ڀt"Y2 ,ƞ#rb<ۈ +4B7g?@{~\5u 4piM:LjS/}p_#X9MXuγJnQ. aW);u@wnm+!XS8t@Ogh"-=89Y*.%;=2o& cĘb׀J?ZO-^6YG\05ٴW"&#vYfRrH¨D 'QDL*\iP)7HaBzqC/I7UeiU[arOp9̗zv8}l=nFxiO!Pl;) k^=^c37LZfeQ&iYRk^1j^܉yzG|Ʋ3)>_͙NVs=Qme"[Z_qң=b^ȓx85}ÁM1H9*#*8$ Bf,Mm =TSkK(ZaWNh*-8zvXj߆Bs+4'DIK!ĉ +X[^\6HO/6`t'>")O@ŧ]$B(GlbZ `1c#fp9 +^w,J:hi8B_}Εf_%UGƸJ>u%Vv'AJ5EH]I%NhJ˜x__, Q|&cֿqj%m[B||Xxv s}[蘿>& 0to)}f-g2|>J7xK AlV{YsX_mk軂Gue,c&|Zn1VgT3Ӈ)56k0 UQRn3|F{s5Y/.04;6\믱A{z E5CX[Q3Lw>ٮ@eqV=T@DrC\IK 6c@urj.nDG5uqҖ {hDZPD5gO7د@;Y +&EVhr%(ʤ=ӥۗDh6Bw+Qd/XU?+aDWh¾,Yvxu +.KL\QaRǢbkSHceTp}Bь >ߖ5"vKyZ` +X#d.vvʵ F bI~Cʦ+lfp8ѽQ +$wjx/ϱrNmܐ{sg=骢R峈1HGy瓐 th uKN@8^˚ҠZHb2tb>eW^ -T`}p&<[ؿd;Bߨ זc٦üp 6QkR%xa1Cq Ʒ)_`&husjmiUGVTv2z4#^U ^nguDk=U|f6s?-^wtnm6v7uPPWGꩺo{c +ZZm=,P\ 8n{,t~|+Ll-Q5g&C/ns1%Up9U]Y]\yA t =5:LGD{i{px|=]u7F:GMN1} 6VJ5mKu?جDqTY˿ f)8uC?2?[ԲJ|uk IEXD1!DM\*GO6lئ + a1ǪГR~mӇֈ#&D uGź'j+W, B8jj"y$/w];Ö!\C4P|7 wUeWes-?38Y~Y.WcSp,rW_䱝9t&t䔝|m6=,u̡0ZU-P0%h5BrطcAj4kד"T1_琁歽և:ٙܚVOd??$ D+͆SN RX{N7\4.+jU1Ñwkp TCrbL[LcC$Yc&>؟͎$iq!LjwQY{+@%hb`Uݞ/Vf<]a4bKF#w$)>xy[ +xQuːJ bM"bsbg.ou$TFg'm9Nh8|ǥ^3&'f 2je&n_6#no-HqUv2lT_DWТhz0 m.|vӓuYb-(bWM;βVk@nAc86t|$6:"e@rrrGL4W 7K\ +~juອy$;iλbN™禤ְ5֓LVX 6]k^祀:|lP=%o7E䠴$Q9ԂBkhUP=@Bh"-)Xǫ:+x֣tI16*s2e8hm_D;.;ixSd9UrEɪ sj-e|TNbZ|7|3_,,{Ե%\#)ARkfVA',se >1R׆b\Ku2k xbʐ!N ,,˻8rj"r[襓*4D`qvBk)AsBcs'jiƎQ^iIv:&=bZLd7RʹtvHBmԫ0i?&%FHxAcfH`PĴ |0mg5׫&&󶊅}A4z~_:p^*0LBazpр[jo߂&DI0BG}T= ڟuGYBAag1D0RA҈GG<:uf9&FȨ/s g<$7Ns'V,4Eo/8HX Qսҍtaa j1襫Յzwv_':_y2mLP#7S,N#Ǘ;p3nf5qf *m}fO8b"BJ4Wu{ipgܬ2h06b>}>7ILg-?`nvLԺח$lX\ѧzYfu+&w؊c cLK]ő=JԑQ pg\WT87IQ0Ɯv8֠F(5 +R}׆oa] |4Le<^`5mOi[[<<7\_rKwv20@~Ib,85 c<|ehe' 5Ue@;j? ,xW\+ۙ.(q|uě`}nZ׃MΗ93D˥b>JPv;\|e5C(Y$۸Q'$rI$x\q=7hּ 6XbbUQts_ }lg8tHFdkiOO!2qRUz*8;~eq>uErtJ$ZMk=0u: w{yQMJfؓ:q 9ToމAa P/#`'U!I!*QDTfI^(O>L(i*RC+><@f1EQq#[Og5uCJxj[`{ZHwf ?Xb'u=o*D{^Yr]c5O.ԜslVTJ@g{u^&6Y +[ +?biBUcU>`7g0 0?<=5c9s(E[pJt^z!o1/k #Ejw6X1-}b)İTR +Q釹)C1wHwkm~h>Yȴ,\&ujIEg,:K`|4f i\9D8ܰ(&U^LyJ:VH\;p, R&9bsZHX[+[2w[p% O`5W.yF%&m=#&p(Xijhs`IC'ީL4&pbc0eg&Hn8'w0  NXPWxWJxE-;9plaxZA +v/im!W6rs߫Pqƃ&h$P+##ӑ<)f/-ev%|]ʨЩӸ uzfStܪL\e˻. GJZ@8u߈6RzctKilquNI.Mv²Ю !_nAumն n}"\{6FE)b&_IA(P&)Y/X܀C&RhU/v ]BhKsi&ʪ)WC6̠xVe[@,B;lr=(&6k;Wv"@k‘s+{ U<}[=ymc ŕ?P^}ͶuӘ> g^'f84^&K\ΓG(ga3\-fN[\JKԱsk7*eam,)f餏9{j4_o_~a"#ek3@Gl˰!gp?*' S'_ZJL2$EJBĪ'pւf yt<#%]30 c``A}%7רf1GQ +ToM̾Shxsh[ff%/=V +["PD]Bd@)>pE7MH{eѺ +L +B49MzY*dmIJaًV ҆wPYwv$F3\sKG򅮴(n`:9\pt`UGfQ&k,RF`]q5cjWPdTo:/nsDE!0L_Y.đ*y]O/Z hRYrZu=Xk5D@tOdO[& \|d^qή64Nߊۼ"eͽLKaALiFBx\Md"' +]&TBh +R"wsТQ61̳!FEfjO1^speAz߷fD ĸdg}&>Cn RdWdА=T3Ԛ'+RlDt<37ѭz5|X 1V[+tNY5.Hs +FUf Oz>пT VI^э$PRm||KB:UP -ZǮMn<:zZ99QsfHXO.2Q7Wx!uYaϬ@(+CR멞W 2OϿlWYeU<,khWx3U6E*+"pb>l.J0$$͌P&dFoQg%MP{ߊF#u +Vp+yZ Ii6 FP$&Iѿ)ij<G+m)PRCsSNbOi*ާ[:-\tiGnSCK]<;@{u2WeBZDUҤO] +Uv>{CbֆЇ(c|nhyU劥@o~ }vո j +t~u*"?ќRw4ireG*ڽQYH"p0tRH^aؽ,m +@v\)dJbfs1`e@#\@9q3*p2G56g+9 ͚ψE}l}=" Z̩;nnKӵ~_hʡrNe+S%3`0{hgY*Qqsou+K\17%(jg4Nq'҂㊅?tm{],HFĬ듵]7`mҤ͇ nź6dGےkF,wiLi 1 ;>+-9-9&v +U kk/ԮC.z*!SJңڐi"k̜so0м+% vT0ˀP.8SM_6!PvF>%v2qcv Fhܓ9Ҩo?7%oR1>kT%d^rOhHS=VEkkE. 9d%̒ZgD_dUS=Dc}_Þ~f idGJ-kQ<ڵ꒗<+eUJG@)bD-^ YY|*ed5)4?V ?52Yhduf& +:_ZpO=۱yQ#"f3Rhᓸ9Cs(IpbѣDsW@k)ִvd<ɍ,Qd<.LJI R1Ėln}QH5zx; Kƚ+#Q*S*:Gynv^uS)VsL (dWK3]V 1Z쒕*,ܓvA"ߺ;O `)"M{]B;݌e({eށ^giK拜A;;d FN8fiOzjeýIIڞ#yDlWҞӂ}%f4-SrsJ, F@ʈUKߜ2H`JZ' ف΅*V'Iw= gGi:jҿ)˜S$ zi5b3rͩ&`սAHJpWp"&10_X3#:MXn}5K;M-kM@6GތjOݕ5v:$G;engmGm}X?-~6R-D,I0o_$$0Ѫ< e+ŧȯM囿!*9nR]b;߭vagކRWiKAK=0ٟ "EyيLg]+FQЇj,ۍs@OXuMv:'qx50D4,;9?%ojxF1 ˨x:XkzF<"i>2N!Tٖ`4ahxC._E>FqrXsgTi +x$'\>Y#l|a.`fಘ:3nJHaAq()c]0?Q&rg; +/ !qr1TJJA9,-MS3«C,.yOWLA%)f^Y#?F +ķ!kɄ ioA^*I`Pg6 ( 򰷥bP9V0j|8mw{A &NL\q!~b| Ɍp~}Կߔ,Sb#яOzA(5_  L1Ĵd*Ehn%Bn BUTfH3"@%ǺQO#YvFz +.Iq3J%؝xv92KHN_|*MO򓍻]0O1YFހWwmXNPLF;Μ&šy@MaY+ 5\Ħ滽ʍ귚/ +l5h$Ro] +hUEM>-f~.fs@{y ʸ=7{=Th1٩/ b*-^|Ez]P)$Q[#L9#)EoۏhnGzvKe>|SGnlA0:<WcGqÐcG` ްMuA)XPEeSD@ sHD٤ƣ{ v29bUu&E,msG9.4Z)QEJzI؞<^f +~j\hQToj(f٪.5hyCe4Jv Ԅ7]/uhws0'O5J:7*_[F ~8gX:oAQl>d`R>_ICgo;yRS:xͥdXU*PVX ^.F'.-u='UEwr& H%@ܫ0:%oEt.+"%}|\7r'}g%zrةuvuԌ k+K$ ,+>cnvm>on]uąo :Ka<8cvS,qQ48[G޲=eS%J.P#7®ki?Ɨn8ab"Q=z6槉\]Ưt䜞b+Q] ̯5Ѓ!bfY;7&}3H4qGLu% 3Õ-BxrGk}<ٿv1Kgȵ倿S r@Y`U?N9 nR*"Wb:4jߙT~5xԦ+IU7OԺ XtO}PI)˖GiWЗޕ9Dz q%| 2$H]r@vX2;}ZxX?ڷGsu0h'`8W5y-Qpת~frrSx$jcr8bðKlMB9Bu4spꆂ>lQME jz}]鰧jÍӭa۝񰱌WL/ddYû֧ *jn~tl6z!y kB5=;T=Rm$7<</%;D!adjq] sPOS F*zsޓ, +jNRb,qLO|/,'=/Ϭ%}gPˎ{i{a5 ^%\'">e}&oi/he5S^5,O!"6r@Дjo N%5Ѯ/DtQsNjHZAmX#5@8R6Wdo3pf ׍ۼd}Mō4R O^[d0$O>VHEL>Ce^vcUR?`2(D%;1-DTb;Bwe,=ˆ% +oXG8G~#r+gU?/"㎭?̡ L[2zZ)4Oh1-.aRr?ZIAv@?5dBƬգj=h7̺xTc> ý8 QN^6<<$%QR.cf7'Ihߩ2:*5܅$s●9zZ! Crޓ8a,Jh>x, {zҙgְJ {~{#(ӶBx<hyܒ4{^DbX*[_#ė1 6 +3U# +͓S3 +7>BYX455ݎیu>n!K/ $Yщ\1xDeh;郆y"N6 Z15z$B1(kC#b$#8mTwҮud)e[']>>%Z7vi}ӌ̴lѸd|d|\SZ\ +lo=F*)Q}n]㢴a{r81S̊brFfE15%z~/c,xRyx,4'Wܘ{^lYOmA /DTKQ~Wf[ERkW;<@j膃`(qЙ.Y f9; f/SXr둟*lf T4jЍ`n_m3'F/g2Ⱦ* qQ +yGXTM'%vE4~\(vX];aG T C 6UK[l o3Lˇ0zlu72;= ^퇡,QpqGŽ" bv73J6lXVI2ϖYāɁxR J֗}qϱmZoK5^܄ko{h=bȡ,8AZWnb,Gπգ a5N;\/5!ED;NM|};c7pUDhl rhFHFZSD(/O|EV=WuE~=%V&%gCn{wMMLI2Pҫ6AL]7(lM^\+=8Fl6˓cg> vdd5`lDcUelVhaj ,aBn4!2[+%/pauVyq +x?\Z:x@ޏ[08 +O6wssd+9AŃЃv#&|YwA~_;ۍp㼣XEz }-"묞ftޭf3Z%>JMz'?ɠu y0k=b+f–rX0®=&Q0FaT*4AV9.>$?">C eN5w';nJ0^Eh V0PkZ63I +B^?#K{c.#[:طH@o/L#kڀL2Qj1~iuT~pWIJÉCBozv4j3&#ǔx`V'Qm:l9Xn~w pVczXmKfzXFNPߛn}j[zP +uGP\Uyl+x{k3-dehUaQXKk<~Ѵ}=6=Zkq^M}Vb5@OrI#~m滭=]gc߰O֭kEC>V3k&U>#属fJ$}d}~M\e=mjV%d0׵:Emݷ Xr+ŞZO>Ob7jlwӖX n{֣`N;'c,+Q]LSY^:%)nkn񒅵Sg2rSߒ6g}GTDN6ZXDbK%hgWcp{Њhw؅W9\poUO4r62'N;߀c^dE|ilW::rT8vtH.jǽwWiKK=tQ@]+^mk^tikY +\a{aS5oKg#>nf*ᦓbF W^]̀"zM5A 㫍IX?ҪYs<&}q?c>?|+c|p;뎄.#o8QWr*fО-;ewPM去վ泗. ;Vbv(rIX9Z0N4G,"GR&ibUC_3jUXU7*1F 0V2BGfC`0 n53NK$0&Aoы{{mI &%:%)pmo}ibo\ta],ɪl4ȡcS ;V}] aWx>F&3UmhON^Bzk-AbG@jK3YgNJ:y[>a˴iQkFQq(ALN6[%TgMBu]H*`֠w4kM^tEoM>$}>9zQKyU]ukuPTCHz#;B끽yd&&viqPq/KyNć8в!GLs*m͐o oK3`caٚ'G[1i_AiڃRhU7h1 d4;kȗ)Y/Mw8W_aP57X^Zt{8 θDAM_6Ʒ:5DR3r2zHЊCJvUPcy:jYmwـN|YovEDj|][\[+.Q>Y_U(#٨sJN^50pz!*# +QDg[PgX]i1KH)-'`-&܊UX8^__ qZ#s랾8/ 45©u]^._$Cm[]-FߍӠ+E{&uo524L13Haވ81G^"Bk \*io琉G 2*՛Ъf^sz;iEh^Zi#UYIF̢RǶg\PH.w)bU)BNAcky)]zX#0u-(~>BV{IH.qխU@6FsLBc>>bD䭖UQ ը̢?O˕uR\ٍӪ׮*g\dz^Q[oӊs^LJtKifN]STlvd$XG۴QgU +$!I@Ne8#0ɼCJBm?m.(_;͏XZʮ +!~^<{Wo {6M: LyB,W=m9 %H) =΢oOsd >5ǰ/9EV|=IpCظx(Ҁai#רF(LmxzsjR7/4$>D - +> endobj 94 0 obj [/ICCBased 49 0 R] endobj 81 0 obj <>stream +HW͊& OQ/P5))?W'c=4>ypD(xaiחm_zjׯzv~h=<9擥=՞~rv5|=}_^]v5ß/>UClw>Yvfg\=4 c\v&$q=c’8Q8O>94Ǔ>u` |q'O"-ĩf{v?9|ǃZ8gOKs"i'Xg-,(Ҩ%a@4#@XB2n`:ξw1}=)xlF761Sm4EWs*Zeqifź{r`c zt +4z@1Y8bkwaD8Ӑr3g.^0(FRpT_|?\ \s2 | &O@>@p͊3Aș"w/k8f>nx5Z͉DŽG +|ι@<ڱY4Y 'v +TUIH g +!P1^t{eύ{0,tr^ !w2IO¤jTcơhK_vyaoM/Hg8kȜMUZ|%:EUdiX␷Dũ?Fcq, +n:qJIMIe¦7S Yz(YåX +LQ† _XdkҒqk-!!tטTsl#ŐX#4t'TC %(^@L/ ~b&!/4:V.B.I _eA ܾG#_M%HMvIb8]0_~mmL sVD<>!\.<ůUDG}%BQ*-XcR O@=J0p iLs(@`w!Zˆ8Hء$/Ũb" Sr_nDU8GT(HѤZdd ̖[>6W`C .WjO%M{@6:}L2HРv9.R{)>Cjiy:2!EVZEYkW}M%֌]ގKVb&CjDW-в!j6;i_PMVEr~lMMĉfBiB M? ~~ޫ{Is&Lr[tB +@$i?fB,:jJE+! EFhBU'ƢX 'Ó\*@C%SFQ;J=LDR2Sb5ԓ=_u)<;+E⍧MgaTeptqg >p`I,GuU!Focj4I$S), KZѬmt9!%`]SZ"JΰCPNV +俌,@{;1w8I-v)/LǜBAiF +(sڹ90VBk lv8hst  1خ + ,faSČ(:dzݧ2JXBb.KCvn4ǣ" vױtݍԘ]DƠFjf>:q$Mu:HHVfju67+.u](T:9TŰ; h##Rij 1|n~(z?"T+U3kj l yZu% 8q 1gsj4s&ҫC ]:Fi=qqwOu&Kա.4Ii t!M!{}.I" );qjʱɺW9`3MKTEWԏmt&whϣRɆ~ m(:0Ғp`emE"ٓPF~!XyZ"p:^$dDs3t/ǁ±ƀo"i*PeEBƬAD=vFzS"uDk;ROgxU*W(=^UeӔPt0srP5\"kJZj.t/aK Djgthp:9",pU,/2D'ۻa)$&Q-2E \ /^*uujYVxo=ͪFQȰzTgM5ᑽ@ f\ #*7*.I}$(ٖ^s$d'u"aK3ԵcdJrچ* rW-9奫,j.AM E/5Pl +7[r^)UtOK6^_ˮVa=r6./թvڒ | pBr{nu_ͣCb$tgFwۃ0X$ؐ:vei l/@%' /w()He|ekMXbW |ҳlcжIT[ݧ2;dD $[^F׵,̌iT3Vdqji[i3g:G;e L:蚅-P]Vu]9n!4۝D_S'#g//|C|%v>W=>Anlc@q5r[i}D/ANpkt76fܞ6fic: P^늹%q-t$b|bO#W >G~<qQmݯNBnŲ |s_%ŻRܨlM jœkWG_ Ɛ4a$>StHeJ[ej.$KKmIDlZ[cAb`{<+ - J{6XipoOws|qӯS|"Ǣ-'yBV4TױiP1P޼>A'# N#Kn7^FM_]hLok*Fub4dZ|=5pr>ReL +>?M2Zn삣'z͑IlkcGs=ݓ+nїrX"!Tx]X5Mc<k4{q7!dfM*;j 2VP z~X8kdغ1j0p=6yt^ x88cDk ?TTv[)zOMF**&`=q~1GLuq$ئ $Z4LFjuciÔk*! X@7ڴщ}'=O5D1.`\ =PUNSjv2c3Kv.Fu&'h;t3;ӛKdJ}=(4?.*EkŘc-.ͯk49|5^95oA#u7H(+x0aC`pDHG nL{V$ m4K )HS⎓87Rns`Y#iBy4Uڪ~ \2O{8޵cFG<+knD垰TTܮWcJ).* / w'Aܞtx/lV}?&[@-#x }Q\y+ nW{ei|wb' x֍nTݟpqth'$eHḒ/dlI6|ipR k:rX\>K;B>hWp\zp銋'WoXy3go[V>j}v݌.L^WD0qć$8k5t*Pzi|EۋU㏙9 /Czsn֣"ġmCK,02R Q' aI'u[LǟkH&K[g\܈Ru'89QvAՋ(};-JOꮫJz ٳ/Ҕ$1tv4~| kL;]i,ƿ.!CUxklyvL?H6h\ 2zj2m362x=6߽KeWjSK}]B1׹kմ̓'N$e\j*~!5VJ|Vz%o '6'u޶λZ.Rgi*J1+ {WF +^ECc_<2n8}Pto~@ W؛VH}!y>aE-1+#ք^BN]A|אdtcc5 +s&Α7ah}cEj $<tZƋjjϡ p@H{#Fg2^4n&S%79(G nN]s4Pvn;xneUqkcc5 a^?;vPCK4l踢]\&j^ZKPPgjnkS]VM0Sy<%ڼ#DgMֈg3)Kpc69 ]dծ`=3 >\~wXϾo]vHEj$u뿂H<`OLԢT# ]lW:XA^ڍ`Q1YWq\k;|˓k+vQW-39~UKU֎HPnE.k~n`j`sA5tFFg'KVyBw:o$Ȟ|uo J5=[A.l vG0<Se=AL { ,{Ad/[/\ˍйW g=oq^vx"oUXd&pt>NЌJl'6 A^ޗ^h<9tE%epF yvPEk4/5ASh%ST[`UBR|,mw}^:_'RR: ߮#!>6ٮڕ^&.V9DfVwM}H{dJ]va~\ܪ/J <4+zBuã1Iu2tHvS=Js"^/ mǹ]?3Jc43iՒ'WR 5۰mTk9>6фkE‡.*m S umN3V7.,)49VV̖x^Y oF0A z6wa8@tW2sRg# ~ã|6[m 9^vj'-Ղ#=ҥry*cPIQ$fovȭܨ 'w3Q^ `}sK\2:D7-hV[D6nԧڛ4jlY6sO[m@xh*>1kFzM;7O0J%hxxZ:˚uwIMe&gz ީ %YƿM51‘/ZQu}Rfbb7ORTa/8^@c76epTY*uF-{2zf] dg{7Ά]ٷ +1QCTo]TO,T)1BqվAT=N=&h;=sZ-61%,ʈ: +S4@‹^0 |z$Qit-Tya2/%DǨtR6U|_S5{4FRk-̫%ܸ>/5ݶ(kJ1#e9la]8zU`g!Rn̘\S3# hC|n]q ?9g} >Gtd[zoU!UY\vL?lQiar\uN=+9rM`+{B8ŝM \w^Mo0MMׇ5*kvYCU|)VG8 Læ+#/4oG#JW5L{&b[w dH>nY`BϦ2\zWx%C7WTk6q^ݶf)[W>eR-{8y,!r@OzZF(MFI;+x\ғMY#g6-rbohlY 5}pO~ؽ،1M,fRT-)_pY4Yݻi + <Oo60ϙ8c5 NbNB>I +eY5ZF"UkDv sSN*_{/pQ]%ă!w8E$498Du~qjF_! +Hm wS/7'ѳ  ?_<q7szqG\?9*Cm+D䲚W^ }Đډ ugmLRƑ8^`%jvIB<Ѱv]k;ÆWuzg;u**V7Q7C3q2\J-ey4윹jqHe4BܽGԩO]PpjFjt&,LwYa%;=%{rz` U 0Ϟ8SM܉'jhT8=9]}9#Mބ]tK$GQ+eLr츁 z@ h+x1d[Y޲ΓdZt +^e$j| +O+VTpZƗ-{iz_T=0%N1cZ ßMomk!64{ ^ݨxY4( a܃9M@g4ԌV`i}e… eA\]$@Uzd᎝37g ãA3teݫ'ZBLKݰӍgB_V&-Lj] {jd2?Hur`y^X6q +KZ]jpWͤ%@Ժ\!2TJ&q0"O>>%Ҳx +f0q:Hw-qPhfq+#6,Нx2<}4V +GDyˑwo]iwLm+Ww:I.RR%MQ5j_Y!+OV*,W ,:qXj[wtefU-\>QXҙMT3OAz ͤ8lBFB\LU5$m]Qn6;Mx1YmQ^8j8luVDCD_Ψ @@$C._ĝN+ ɱn|۵cس ױW&YnBS4Xa5DDMl#vHr01#ju#3'cO쀱vSOg Vř6J&%NCU⊵9$L*C)}~Xq?;բmUv^){(󿡨8 VuH/5|.!ZNIm}Yݧ/;!BooG?fwZkTJBD_U[:s#d +֜j =eÏI4JZg굺_rj~V#af||*VzREXYӅzs3:~VÛ9]CNN'iT٩P+XdǪŠ2Gv< pjCNfr*s"EƞO۱@#VF$7l,"{džyIPk o[H&Vb/TzF\~RSii=7/ńQ%*2Ð$zd56"@{-IrVlyd98zdFi0ÙV3c{W\l'*`cos Lcg^X4kκޯxj[KF$z~ $_M;æ02-wm֭`#8$ 5u>i7E3\) W") H¾ OPvN€-x!bKfXR# &l +#=na )0 $TcyA|1Z(8U>z(@:LLd Jף>z3%4:I5vLjݾ_ԕqZ ѽƆpMtSߎ+wtA\DK:yc337* C3daF3sxgy5Ca17j)辩GgQ֌N=&n3kefɔc3Wbt []8%;G;?Έz 5jaʲ{&ԯ0 +fj .^^/Xcljjʬ#{KP+ |v\l;ج̓YLc_Mq6FY$34zGc1pe/3/oL +u*g3 VL4|r xbu)jGM f 1djL?1ܨ2m kYp}ګ`#WK0Kז(sMYƅ!y2w:f;^h{σԖ$%ZJE (^~zwH[p x@n4O9MK&=\95"*l}y|[5ՂNƝ4B:аڈPE1P\Ugo#,~#uX_@*=P늨pq7zyg00 z_] ײ"'#q4Z xBuED;\m@]ҹ}]ҝfֳdG5 iOmӚ؂UBw нHpAwI (,wJCA-T|wxSp .B @Tݮ~-ߓ-W#|NYV&K*ƒ 4bۼHY=0A$+2Ozܷ/SU>]E#Ol+LA׌D\g\u_rEDLE"Z2*5Ρnܗ,h6cd~eiߓw;#M69D." +<̵h$j**TsFU|K0ތMׂi7aT"TqEpqa g +L|a{֬Rg,Z״}s#QwJl iw>ՉDf5@FJOGuP$F-ӹF<h.{]R ?w f $ dnN2Yu~~Eפ Є}%iڕi'Sq1a>{Dc䚆? Ϸ)Oj'ט<`MVX*A_28x9n3 6d萾21ԓ4-ntRc +7NC+gPP!'@a2hR[*43]o:]=(]][nN 0x<*kwlݣ,Ti"qg>zVAIU ?= "Eyyw56v[ق>NTuiK/ +n$|i4ۖx|%->

K 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�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 literal 0 HcmV?d00001 diff --git a/files/images/firmware/Y6_off.png b/files/images/firmware/Y6_off.png new file mode 100644 index 0000000000000000000000000000000000000000..ee33903a50127bfe076c5cb1decc480ad985c478 GIT binary patch literal 34453 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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�PV*|l=S%D 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 F0RU8&;)(zO literal 0 HcmV?d00001 diff --git a/files/images/firmware/apmplane.png b/files/images/firmware/apmplane.png new file mode 100644 index 0000000000000000000000000000000000000000..16b14ddbcb3aab6e26865c92c1e194d25a549ae2 GIT binary patch literal 16805 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 bo{^2Av;2b57h7G>P8 literal 0 HcmV?d00001 diff --git a/files/images/firmware/apmrover.png b/files/images/firmware/apmrover.png new file mode 100644 index 0000000000000000000000000000000000000000..f3000622859d5177df0770e4f1b762c311602d64 GIT binary patch literal 17585 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 TedZ4X0|SGntDnm{r-UW|6slGg literal 0 HcmV?d00001 diff --git a/files/images/firmware/heli_off.png b/files/images/firmware/heli_off.png new file mode 100644 index 0000000000000000000000000000000000000000..f958a9e5e9d2ec727dfa96adede6f4ec903ca0e7 GIT binary patch literal 23558 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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 D)6+QF literal 0 HcmV?d00001 diff --git a/files/images/firmware/heli_on.png b/files/images/firmware/heli_on.png new file mode 100644 index 0000000000000000000000000000000000000000..1df05837830cb69e22411ffcde8cb2b7a6c7dfdf GIT binary patch literal 33638 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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 literal 0 HcmV?d00001 diff --git a/files/images/firmware/hexa_off.png b/files/images/firmware/hexa_off.png new file mode 100644 index 0000000000000000000000000000000000000000..317053c25507c0b255d743ea44577bd44798f99d GIT binary patch literal 39931 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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 literal 0 HcmV?d00001 diff --git a/files/images/firmware/hexa_on.png b/files/images/firmware/hexa_on.png new file mode 100644 index 0000000000000000000000000000000000000000..0975848fe7a40dfa068531512d6af0a36c5daae6 GIT binary patch literal 86172 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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 hVeb7<_NX4x;v78km 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

8PBr`GWtYRRm@XK8R1i^F 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 Zc($kTaa*N@FfcGMc)I$ztaD0e0ssm(>!ttz literal 0 HcmV?d00001 diff --git a/files/images/firmware/hexax.png b/files/images/firmware/hexax.png new file mode 100644 index 0000000000000000000000000000000000000000..86bad85c0851cb51b5ce4422e8ab56b1b4cdec07 GIT binary patch literal 27058 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 Tw<3Unfq}u()z4*}Q$iB}bY5~m literal 0 HcmV?d00001 diff --git a/files/images/firmware/hexay.png b/files/images/firmware/hexay.png new file mode 100644 index 0000000000000000000000000000000000000000..74a65b89ac7aae2febaf9b64d08e26f22022e24d GIT binary patch literal 18117 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

Gc)~X+ z>bl>Hh$nlQ{U-$6@SQhry;4y6yGGZKZ~14R54-qEIZWX5?rZZd?hQ`3TB9qOzG=et zZ?*@PrnQ-vJ86qK9(3~K&3n@R<=_W#tD9`MZo0kR`s8Z&(qM~&m)IvRO||D<6R_i4 z>eji5-%B4G&6(i(<-nwkcQT#&&z$UP`1-P*_ z_4Ja1%C%(^CZ6M28ngGhsEV|I#ZLA8rFUMpR_)5^ab-I`@ooMOeZgz0J8rk=HafJa z@8HXR!oaO}_I#e++t=FX{>Dikp5>Zcyx(tT&v`u?+v&Nqvj_*}OVR5uc4`xNAdpY%i8{VKdbh|XC-PfxNp_3*zEWFxfcJQ-Lp8adlU=r zRu}m6m8&&ScE6;3#3awV&XV;%v?BakWRKlyKlW{vhMA&>PRa|7MN1=er~egeI*nyx|LRe8Y4U^j&1b*vyQvTop1WqdXD-9@R;~yOxA&JdQrr%{ ze!FI$)Y7Fq!UTWL0>{=HN+VzJqsnKQT&@UmN~Me(Sb(i>8G< zPM)eadx|O3_r{~H+%h-))=5t|p@wOW8FItD|Dx_gci;U0V0! z_(Z-9eB45NCv0lONNo$!+x=&Eu+Mqj`6(gwHy(UHvUvxCfJxk*2lX>@cPqGCXTHq-$B|DDP`|k5lp0jJuVM&9KZ7e@y;#p5>wRElu zSnJJ-J4BbUi)O&?xGSdf35XDx15ZB!FkL> z_UoBPoM}o4|DW_Pn<>42((0wNRJkYZb5dpHcw!hK^Q)bI|F!2)&wKt(dkt#qIWVx7 z>KuR8*3>%3DnVDL%{l1df`E_B+x08D{k!M9I^@2gEbM|-eQ&SF20+ zC6+%_2r~CIuvqE3G~r$5u9edsR-P`qw(rfosxSVv*S6fPx)-(FaWeC|=cY=l!O5C) zhe`gC=#{z~HkD2OlK%6--qQ|yR%E9>O7@U9{h=GQGLlXDS<^4Qv)3)tqfOZydDhP1 z^eUCgzn&Yrcf-~-=L0hy@Wt6bXFYVs(b~*dL?`7zLtm7{`BOp>T>Dl2o`3&DKtzut z?y}&zMqLBzSh3|zhl!Ld|mo+ z&1%=na@jhY;xep{T7kMz7D=BNBO-&A+ca<8Q1Wg5o;PRqN2VmC?U7mXJx5N&SU=^1 zcwhbf*Ia6$8#YRM?Yz6<(L8moJMY!@@~@WYko0JFE;{8(pmg*v~3yM0Bu}r8Um@|M{u@9?%xuqy9TmKK(tna%cCNGew1S zTBkAZ7dzP7D7_PNNN47I=AKNXiV-sv(hV(d<_yc1Dz?*EA&m**Ya`_Mmu?Q}O+ zr1r~G??Vcwm7Z9V#9Dgv$SL0fN#>}C6B9N}n%1sp_xV#_^jh9qyzS+KV1sC_ znO7O7Ra&Us6Hd;)oVVzyYK~q;qT=D@%FRD!yta)u*|Y66`_3SLrix z;|xo}4({tkVP1)=eV=x2JvjGxypeZgXhE-d-+#OPdzjap_?)rwkXlnyE02EKrA?Yr z+}WVztX+T=OjdmJ@lOfbt$I;XmBW@V~i zW5rdDmeoZ9E(a6^G&SzTxke@oF#m65$2z>5- z?eJOAT`BkV`@CN(C>K|ny$_bdOhtCXUkQC zMu)tgI<*VSw`5vPH<~hc#vG%(_*h>PvA{!FH5Oml`7TYEb+LzCCwNA9#p(-RnZJvE z+P=Tj-kM9SC~a4dLfoBOx)D+vHh-I%VRT(vHc!|`0xO9mYV zU3H1&P6wUNaT$4@=ZP_VKke$4yxZ@1o^_srw_YA!U&z?#w|MBUJarD8fB0Fbp z@XL{vj61C>Afl5pV`p#8%X3Ct4sIOrE6y@IiE)&-E#9~x?9~q)&10$h8B(tZC^?YG<^fZk_-B_`LCxbV=oz$6V(dQNC;f$)XK%GqZP6uU}1x+ zYS|KvA36MXx4b<+?6mo@z^Ro=*wcKTg< zVO8_1nJHcIibOw*2|)7asNj zx#8c5q=aDp!k!7WJMx&r!}hNXXSh0-AzVvRq&S6(@dGtOeV{NewvU*s-yV(j)}|LB>k&3f+7Yul;%6Z2QatG{q~ z@8$GQqh!@%#(f-{wG=+rQF{sEO!#~QfBZD6cBjc zIjOpBp8p@Y88tjs?@qrmn>cIQ-Poo_A;0G)sGa**w8o%+4%fs8R{ku#paYAHWPBYM zCh_;1*G<{7`p-+hNKvB|oRQZj-FYH;M6P6@@MIF zw`z=R|Hm=Szk70XTjqyLXItKBfy~--z-!W8>+hj^m8Qtm8$M#caA&qz*3216a{8WK z^`bL+v=<-9>1tg0@O|G)t{op@(nM{XvKl8YjZ({D4l|#9&xtD{q)jm5t;MGn0ZxSr zBHCvnosOmHeE5Cj+H7SBUe0OVzwVK>vF}A4UA>s+%)){G`Hw#cPvc`` z)i#~Hv*y$3O}3@y>J0WDV~o&MW`3-%#mF|D=h?H(+~=wc6PnzFmTzyXI4UOhFUB)p zH8monZQBi%o8g~BkIw(PLwJSQ7g1m7uf_)dYxZCKe9fI*IHd9BRGIu+d3WQ!dEA)& zqCmqN+ur%ygJ#f)1|wj`X63RPw&|q|IPE<{K*zR3T_jQ&WhyN z^_I0c!BAiDUyM(_4XcjUNA>R8HDAR{cOQy%Y}{<37~OgKb&*HckK>w^+dC#kOgkOE zf6l!su85FFK6CEPx_#=^y{A{!i$A-o^xER`-H$c7Gg^8%Z)Qykz4*mY@JEYb3)|$N z1B-;hlQzFFUOw$={+kaId^I$cLIOr#60mcK-ByxzFFvKc76^ezxbe>Gu}gul&-_TB=(u zKQSd=_gc^OUsfCEKRhwzeY@rT)w1yl5#oWq5>A?bJx=@BjQ4_=UPp3m2|XcV5{CE2n2ytbKi1_*|9e zU!}77en$N}&n-G1<$Sf#NJnd=k9SC9AR-#31E^c-K| zZI;0rA+tDo+v^uv>%Ol!(|ogTxsoVXL`ag0%T3{9>k6E_ zH=SR7QL!u9W@=6NUzXiMJ_{d8C`!*^F0*x%6i8eP-91Njyc$ z>}%AdbPIpaK4r8vSnd1Oc2SdP&#s*dYAjyd^6dZ8FfX~Qvd#0ymUD;OOLD{as+;`Z zb=CBO;gzi~7ZhK9{%nSvSn5&E?x(wz&-{^Zldj-ZKcHoGQO%Ccyz?@H}6`ytGA(j^lN)SmRTloG)zF@(c`XT4(FdnBBo3s&PK6ZGz!{n`_7R z*Q^kYobrs_@x!lLO}kk?y4@ruPwVln;qp1EUb|@%*F5$$Zj%G2zv*b>yzY1Hx!U;( z&d8v0#>Ep^nr$ktU09}=aC7g!X$H1toGaOkKCp6i-*)-Qx;%cP-PZF5l|5V|uUjyz zyEFT^svU3IGvx)@-}y=(NS)f<^37`dmbFg*t%=vHT-?M>%3R@Q}(z_LQ z`u?ZFz5fC>{}hom!~TiPxEX^ z49_mzs~2CZXmo<(z}m<=k^H{#@#F@F%DSdEX~j#u?*~tqH7iXa{YJ@)*-8m!LdNGU+|*y_xXt72xoEij zMa~zmn#JK}EoU6RxHinZsX8@&%h|(+wKD#mo$_R@!+m?dOPj;pDxd26n><_iH!0H{DovY6VQ%YnfK(Ze6_8=7&Qn7pv8+{w=@G8-L6R zTsBc#Bm3iTyR~0AviY``amH2bnHn7I5c$=2!Gq0<_x#e1FkHAdVdHM&P3vwZT}(fF z`GrL5q&IhWu74%E@XL?x*g64o#tnroewSE}f8Fy{N0;%o`ZlX=HO1lWDew0@nVE8H z#e7+oZI*Ui$-8w{WSb=ztA3TsytKZ|w17ivE~j3Dcw^t$vxc3|m%OUHV#=`i{3qek z+qYjjs>Euu%(a@HJhM39dc#`p1l@w@)pufFNy+7Z{bHhd_CV-Crb@+&+nm^0*ZkvR z=)JD1we`pMhhp{b-p;>LzDw%i**(ckQ)4pCm9uZzUOHqi%d%qMy(>u!Cso55_g2JD z?q_a&)ZF)@qv-MtmQSCJbM2PL|BKx6hxdlX*Tv4-n{K~rU?u z+thFK*B+bbz18gRgF=zUuH+L__*dPz=I%Ay>Z)l<(1CT#yVw{ubCSo5h2gtt@`O4s|g{b)FN)F(WjD}q7dKvA4khuZ zcTDJ0cEp0StG}6kp35lC^lb6-WeZpfe+LwtIKKC?Y}h*K3o5%G{hj4^kn2s=r-!OH zQ__|_RE@|rYTCBU+McB;$gfH@8ThmTf2ZsG zpKfuVzN>zHeOziACqvr)E59mkG%mjyz17ZWhG~x4#cuE2Z$mU^_B~T?5S8yu4%>Mo zHQIj%$Ezrn4NjZoBhTJXPyg{*=TGp8Y=*GYixy^^HP(uh=K3sp*C?L0taASBd14m( zq68x9LxS8FEzK6$P_^??gJ#&BnVfA2AI}|)yi~eaH}u2%DGC9uwX3BYz0VuYRQ9=} zE&brf3+-U;Up9+4qFzt-S!`J<%3Lx*y43UfgcnnE0Ge1G@K80&F_1YS2~(YvzMcyf!sm)_}V6Ze*Hbr9n9{vB}O z)zU3LpZ?W3>{3$ksMmRe$FD-TfVFk6?{MU0iybm3ddM~5BXN{@emY-7(r|Q;OPTDMecHRE- zrv!R!nhzeDeByxhPT7}kd2P`l?|z&=)Dd&Bxdu&q=-c@Yl1t;J>?WiKyN1bUz+nN+d&e<5c?hEw8;rtlypO|ywlzAt4oo5y0F zUe0r8&Laf6RA1l(kzWfqg&LI3)nYTakQ1P;`H(&0=6+GXt@GS#-+T|{bwD8sY znS%plGy8jlW-gt!ETT6$inaUXOdV&B^mXm&`!dx&e7m`$2c#BUy}BkjeD9~Zleco^C@j!RVOmryJGX!L`ZH7K?N!*i^QL;fr^t=vNl*63 z#x`Di?>*aNuluQEoQtk9s@|-&FRKdMzwh%4t$QjgCsZC6K%{o3>`WM7Np^xKc# zd`phrSh`#L-=Wo?l?@HV7^>_q=9OQ#_GZ^JU{!@gC{j)#=RnPiE{W=G{=p7G~eL(TG&(~6=W;JQ^nf?~O&?1%o z)N^t8w8TZm`~R+*_#@RdMevrk>-Cw5WK3XlZ zVbPXdNp%VvCLFN59}wi8wzs+|a@XE@bEYmierG?|f+y3DpWHenY02-$mxEkN-|#$J zELr)CXHhKE>#80j{WFn58qzjwH?FZJzf-(Ee>dk@4Y7zDXXWZI>nGJ7Ft7-HaAtZ< z!Gr6Gjkz;Aczd!Zx4k))Cw$|!+`YRZ7T2!IUzyZx9=dTwwy{y~i}klGZ}5GKyL3a^{69aIJ=RlvvYG3p)UnHFPZ(4r zChpOhSHgQ*Ix%ix)b$U${#C7LWuLZn7Spt2N*m4?`8Wpb|2JFHb5eMaoJ!%02b^91 z=nA2%b?(6Ta`Re8POmxYnm%*RjJ8PfV?^S=~PwsJ@ zO>YnEJ$e6X{=C;;t|h2HU93{Z#AA5!*H-^ia*D5_K5^_b{#>uj`1{w!wtdPxZu_Ke zx>q}@^(+f*4!`s%f?3V8>f15-e(#$5z%p+>VrEp6tGX%>r~ zCps|sywW^V7;@UXJt{Kdr-}CACcX-WwdKA}Qj>G^IJ^~(7O<}g%6hPtgJHYy+s_|< zrLY~k{7%+=o`BNSjWf+ZMxIpPn!DwN@%7A?yML+cNW5aWIQy9DgLAjaZ>rVB&UqEZ z+3=SA`>HbDi5DM#P0~!~ijd+wZg4u@>WYxq)jc_rd|7t=E*3gIDf3BKf>W8wG|`x! zCby3|Za%4PHebMkd$HebM^Ce-!t;!aHX7*Nh>bcfHUHkG|9(Q8Yn--jeK5=9YxFFO zw2fBxxFS!UeJqr+Bi#FOQ z`BAitu3csKtkj2G@j-9DW#`PY{IaKXQlIh8;+*I0dpi$&ICtH9L(4~FhMe0c9^_Qs zZj5}J{rTFxUc1#EXY~Zue44cXzQCHbOP7l5R6V*T?bC|vwRNm-FHW+!zV(ya`Y%_f zt}T<}BdX{L&HiFLc+$>V&*L z%^Y!d>t757nRCBCpCI~?^~}z0l^5z&pI5KGxog^9*GX?ybIwX-KDJ8bX7z?YPuPXc znIl|Z)psPM`plSb@pXTxO~=n!?;@naVmbKL z%X*`&INoROJS5gMsfJ^+T4Mdx)iuA(A{TBv@-<;K7pZ59kv*kV~cYoC{ zxVt*RXssb;fm6B0RAPyXz=)?Fd+Mbo0>-u%aT3JeZud6#-V zomStk<63m2y(T)prc!kO+XuDRUOm%)$8^D}C3VKeO_>+oUlbN*JDz1&r+y$o^}Bdz z-(2(jJKID4f15Ykid8$Mu^_LgEA@|h)b-}@*SGGe#ou7+E4{(EX3H7210Qc~dwk+? z)s>~^q%JMud$dDlMWuFlcI;`x&+C))nYY$dUecZ

HevnrC%E{$l+#Ur(0IxN&gW z-B|&}2JT+pLe>dh(UhO-Sy06JymwzUyU&l0F0&;zO#0&zdt>Xof=(8PYPLPwy)H|i zm&|W=pKws6XOhVO?r@QRZ{24szkbu=!IMMm8w_O)8gdvWyGC9sUgvApf7tKbi~!je z)<5JgUv@h4>&xqh=VvoKu+e?T<@~^WR{7+4C4I+)PERh*I~H`}J9C7qX$h-zw~Ll> zkFRn^o8T9T;BAjj2rpTFx2;Kad269$_@3-5s{U6vHh7=&5pwzZ=RSXf?YUL6*?m^G zFonspsB8H}Y(3DWp5Z!i;~B1i;%xtet86n;qn5ug7UB-izS_C$obFYo>N6Skg=N<& zPns^)nY_sMnt|j7sn@qo?)1KQ%74E};q{B5G2siEco^gj7XJ8_!{K8y)&GJf%iQN} za=RHBzNGc+jZc&O7yaY=eug!R;%W>7kDm*e-TdNt=Esv~JDFB0>qZqrJ#C}eCs^h#wFl}DGe12HvDb~Ol3%X+uYcKP4N(g*h&UX6v7IXH( zr0h}-+xZo@ziqnz{pINu9uXdW8QWI}PfLELbazQ3m%fIeMe(M{`5%9{rrW%mYyNR2 zU(ZTw#{{m88!jkc@{135XysK&6aBMK^1v%ThKrsl4O&OHb#^U1dfjkd8Ot5+`D;S5 zj;;#`_tO5I7Mt|Yl_Br!qXT|bOT6B6--z4L$$j4FTg0)J8EiTsi%$F#U*@*hS!8R4 zUqNl=&bq9lYZNym39YU1`6{>4N7kV$hg%}`m_whnnU(APu%^T#!5lF!?jI5|eevg7 z)P?*u>#5x5E43LyINRpz-XJRJ_Kg3DY5$fF%KR<~5q$G&9J=qbZ~j(wWva*S`L=>A z^*?z1v}27wt}zbe(7*P2s)(~rvXc*U*s_VILuR+!Fx-Andury#-*zkC?wR#W|M%9v z&AFGPZ}DX86a{5QK+H;+GEDXtOv;Rir6v#a(l$mI|!uLQ!JogMqqm?es>(q4gKXC>3d)0o=p=@BdZ>GTryIj#Ll2{Zqzp4?{`@lI8RE!HSeVw+dslJYgjCT2t} zv|lCCaE`G*acTCXH|1qwW=^e4Vf`%XftxaO_SZ2_ose4L`$uMN-A#dX=Lor)DGC*h zCym_h{;W(nwdQ<|+wUN&t5ftFa{bi5*7hGexoMvAB#k_$1^-3Xi0f}yGeh?1jBkk# zr)|1*j&D|1RAv43W+9KiKN}}%x-RncxV%KfyERxQ$lG9+gIjD+T}*s)^ra&#%(9w} zu`geLzg@cJ8q0=FzBLQ2dYH?3A68{2{j57;l3@BXrQJ%6<*3CfqQtzI)BWNja#_WetmJGXn(e$+SFb?So5mW&xo zX2stW^ZW6{VoiZ$e$g3CIqCIDpQCj9R>()(&i?#w{-#>a>;t{rJwMDjSK42_@JD*_ zy+-@P%aj+bnR5J7ZCB=jt}S1sT6ZiF>c8>l)|-$0o_k~e7P#|dn=LfTVvMSYef33v z=W#=5oqX$*7y5m#7TgWn-?O{ruTiFR!q%0Oi!5y!S62$p53C8go$O-$f9hRbtwpoW zKA%yUBzogg#6EvR-U#8zEtfp(bbLD0q|{iLckgmMub#K(*_-+kcU{X?&z#Y=AXH?J z-qls=6aKi|{T4C*gXXiQBBA4trcMkcNw@#>o=Eiyl2zUIMh%W3a}*Sr^+HgBfN1C@6TQ8NT`FK#?K(`}uL^<{&vMa#E8 zYwJE&@n^m6Jgx#qvb?fR~AOZ<(y_(L#r ze(uD~xlYHH#j7oP$C%JLT82UUMXV5_RS25jS_snqBLT>=NP?)a3Pxm@0qT`B-%6_JeyP78^z+3Oc!0J(_uadBm}Jt&{WS z1Xr~kWtwVq#Z+jin?ferx{UDJiaxy=2Ye4~NV*j-^;y)NaYdQ0_iKro-K)=a=XMu) ze(^fF?jRQrL&8taHW_QXCQ-?2?7PmNcxOFv)#}T^zY^udig+eVgsm{R-Ek(H|L7#f ziA55xS9yfSGp<=SNzQG?ccwK3f?CHnSsr+o{>S~i(P!sfVoP7^9Q*b5)r2)@~F@ta^CU?qlBi= z_^aG$3pU6$+*Im4n6-i9fNj0)jYH*&vhxEDyjp&P<=gv+{jsvj&0DumW+}U%w8E4{ zH+s>5bFsxcOwY*h%+h$R*~infL~6(K^^&Qa-P(;uTg*S5asJ2`mN8M~_0G-zSFVcg zm$p907hTx7wfeP#L88?)kKr#@P?ku&1^>$Md-91AaclrCwlmzuq7 zRs8X5UpcM5c^X;#{k(-iw|d#c-P%FXUsN9pEtN6eKPlB8Rt2zJE zsqDw1YXowFzub|@@m-(x>Be$_8&91@Hf)(}>Jhno)gNxfX{|b`2L9{TFJKi;_#0)w zdi4#LC`Xv%n!_PZiYW(T1V5t)mDZo)bvsu#x=(Xr+j-kP-;rBXeqH7xP*iWu}ccqXyY{P=}Szk^`X2m*}eZ9S{U&gaXP&;6v{ z!V`DW>xtPd<-a*jSpIVjzEaevv7mH8h!<{#sZSg4tCb>nvC8$~CiF20^%*#^TMI;V9t_xB!o5qMo{kJq({ z%km#HuHib^Q|lih^6!7z63z8z&ncW%yUCQABG8kbBC+SC+q+{Gy9{&YXkPkdw*OOP zMr(%t_WGdyv}>viQThDeJev;bW${P-keFS`Y*~Nj|HN)}8|RowPFf9;`|1xJjr*Rc zyRL}KE#&|ED{knf2P{LZ=HJloG&FG zln)$9Ft89)=h$!}RYWhT?P5Gblu$-s{hx0EV*&vXWS~r=lnY_;^Yy{@?PQns3ONqa0b8=jC!?*4I2y;TQ$&6AG=@6K3>8 z2bJxu*@rEed;$u(rdN}xi=G!-pv!evDN;5WzhfMmzH(N9}*E*zJBJEus?y9Pc04E!mPbV zf2(fwiT(UKikE|;l$yj|-C|1k`g&jXQ7)z3hVL>NO4oi^;(m+W>fi4F|8~SJ@7rp% zHv7Pn+kZ|43O#>ll(R=WY|#O~lZKz~yCy|xYcvlOS7vkwrPdM8ajqzBTjR8lJEB|GF}rG)Jww#Q z65fN0e*Be6`LUgO^E%FFJKcP*Yu!F_mLX*R{;DIEA3uFx6HVV?4PaTj<3s{TJH03mZh8 zpCwM~td_~2U?pXzvV&=%{>w?aSD6eJurfqhN7rmp=7{U|JkQOv=##G71g6$6S9UEm zzb2nOyW64lAM@9DJ{|_kp8ro<_A_?TpWsGO^WvNecLlDfjhta`AFp9p;r4*(=lj!c z9&;^s1YQ@|QTHQp?Z3xT=g;Z|{#lnFTAF0rFfpj z!Sbcq5=Z|%xOvh}_f8Eb@Z5`VFDyMq7 z%F`w(NL98Sw`;f&<$eC&a(C%t+hq8bO=?4$>p&(yyyb^D`mqRV!wzU_^DpN-AFXlPYb z^v~Na#wWT#>8;GQj8BPM1$?f*?0LH4rfHd@mHk}>zXMVs3$ky-ojGId$K%dX%U8{I z=>4)q>l*cbeKY&Xa>aB_-7QInt=H4<*zzCya#qPX=Xs?DlUUcfP%OkwuIGv7v(G7I0_$Z|G% z)uW2LFOUD=(Bl!wF}!xyX~jR?ln>nQ(SH`LvEgjkUZdgnW+7L^@|$AU446_+y;^JZ z)!oUV^z#lDN#U83zr0DhbTsUf0OQ&nEIPca^+dM+cw(BnXwru-b?nv`c71zX*qPKE z{!1aEa$(I1zl>=-xtfd{PMkI<+Wzm=nkA3rW6hk7gnHbq_tSQ?>a+H!n3L@m$v3OA zj8A6&2J6)D=W;>wuRUlEO?)@$-m=?k*oDuuxjesjXo=bt#x*?xy0OmM45e>BKax2! z?FQ4cr~C|So=sGgtFgHv87A>~RgUoVmrs(8Z zv(~BKP+>0R<&H{ATqSa}TCTrp)-ZN@iVysOQRpAkjvpo11-W6yI?%3C#Vr zuf42jRZP;$BPt6`Rv7%aV56?>=cuj6klk=lYtoI67hg?(es$NkK^gUH+!{OefLbJZYbeM3SOaH=g}l8$`v89MI$3{!=eV))+RAlZP4=1 zfD4NfTw9sMSarFgMAm2|1TI`)y5&Gt$Sc=8t}xK*+zVaY8mYD3A(iCdHRO8E?H+IuBPtD^qohrm* zY08v-Oyl>r;=BmvFhK_4u(&zw4j~N8YG&JHmDbJ^-g7xx_#?Mits2i04#S%^eIM2| zw!fEenQnggyJ7qKmZobTSai9Y4K$9{8stUy1Hae;of=M|IOtII`q|nS!~1d$^0*W9_ikjWL&;xVaxi=o4y|& z3eT;{KNtBxcgE_lhW?3~uGx}Q=dryU%)VWw~j{2oldD57<-_YPWXewB&_S&h&4MmH1BV6lF zeq9!ywfWt;AKd*8rUFd|OjX~91s3}mH4*|haEWh-diOB$aWii& z`wq}jMn^T#P)F}{r)yhNlD>Uaitw~PcwL#{j`>H)RE_s?K^wT#*$%9dirv@NzP+w`d)?)I zx7k_N1Z;>`)(gt7sZ_1s@ow(R50?TrEL(K#cW`lA>nWCH_b0b!{a>oTw#Kl)F_zQn zQlaWG&S_behbO0;dwy}D+{?``X5?pS3;SE`=e6MexU9szw2)N;v~)K$<{@kF$LEI= zkMl76%9Tyulk@qX^$f<8DCR>Ob}_G>vxK|v@JBs)y#&_BAC)2m?VY%v&3<*g`ia%S z-%b3BCp>DgOn>=kJ9A&p&iy`ID*a>A zuHM)t@p}tyJ`O*1V8=byTUE+3#e$~`!YuwR7TNNMc|#RPSo%bXn@#^cS^@#|q~geyfu-pZj3*clVRLN$iU@NOdylgfK1= z=v<-TdEn=@8)0s0Y4PO(&;I>5$g(EyAlGeG-*Y=9)%^Yj2QsbdIKX;*7dQK+zbrwg zpH7aSHrZ!!evAF}!1-bG9l1*%%s;R$-7V?*Use&WFxi7#a<}aocZzYY5s*pi+1a0R zdl}!7{bIhCzv?WuF0Q`${zliae(SAy>+H*e_j5YcGpzRB;1p(B{U>>nWBTgew$E$T zw@99Q|8`wYjfwyHQ#&`ZirllhVruKP;Hq-CLwxx=jfjC?HbkJ%f6|(-Qk`i8GK~k+n0xyvL=X1SG?xGcqT|Y z>%hsV4;-Bf=T#oHuz2x-`{uwwvB$0^JC!FgvuO9|_bg0mSzYjPedfPOhmXAEaA7~N-8J*;9EB4S zp7KrJJ4Lm_zMRT$W&gF~jbiNH&$A7TKRn{BpRyqr`+DR zTxIqrNdxhdD_Q=i99!eB&U=p8=EXywiaj^9yH}d~m7B26zI94$q2z_Q2|Htozu8}S zSYE$|J*n#GHUEmR`bPg8-Z|#8S_}@nac>Ws&~zp#>00_ere}|N4=0*^IU?A<(r(5l z=O({+lh;*3fp_OVXqj#HDt)=^Uy(J3STE;(lc_iKw7r*ca>047vkpSH1^+7lo%EW! z!cR1ne^%3u2u-VVXZHNOdX@1E!+~A1z9@-pHdjkr=$O8{Ec|D1V*VMuiYW;!l{PND zuYb0@JfLT1`SQ=SoIB;xmPMax#Wb^`9=SAajIQWCe9+|0%F2$DS0=rwH{asClr>`E z0(-S5#)maBxWW<>wqAPpOV82v-i{OJB>&G~`J5}+`S;7>WCoAqM$hW~R@-Lf+^kn$ znSb}ZLdC+99f<-CGS|KwGkIfp_*2)}rR-VvX07SVK6Ihs!obMGp|NU zd+=QnKCi?1j_p`)Cbz=ZfBU`aMZ)G3|67voIy>`>aD)8mttk<%31U7yE#HER@+Uq> z2tPX0$&$rxp+&(vEq9wZ<$$-wZQQ3{abB)Uy>6oxb=B;{_x~TSI&p=`-n{y0^11v& z2e@k2N{C4HZ0=ImWNiANqvpE${sAKknZy6rEZ14>-thEGnEw6vujO%jwL5l;$X(nx z^+@{Ol|nYmG_+;rsBa>x)QEJI7)i!;c zX*+N9EWUN2{AQfM6zN-hn-UJ*T_&1v(;%K>wc-}>p6o+e%^&Vvs<_H+Q=YS8W#2`o zX{_7I870|FwteRbQ-}T6A8uU{DVDZ~`E*snjHt9{< z6S%*RH#276Wba?x5oQ4kVsx%8UABDEo3(1ri&rIEUORfqfA^BZ-7i?gRLvLFJuH}G z>3CsPvumb9-}HGFHyL-8JvLy|o|5z?Z}B(LK; zu35C}+IrWo49`^KJN(bPKTLWfG3S+VbYSMx3(k{j2zkV|@rN2Eu(xG_6FRPrRqG@MU#61r_s*ds&Y}@kSPnP}tf`6>sOfISW z60PmFMs~0;#-;C4=BP3M_T|v4XZnZjCa3syzxaPr3J85DyLE-Mb@b+z`)4o=Jei5?BNZ^psE~hur zE6mt8vM)GxjYn<$^aS43hfCkHWJPS9pMRik4TA>vu{50-?>}0{wO1DIp7xpd#_#UP zZN<+I&2O5e@I)=XV(x*N-oKA*h-kBRw{7rvnsW2L+m_;Ow_R=)3$Q(N>p6Z<#^iSQZjhbs2aDMCBd8-U(Jh&OlE@R>=c%i{8x%Nf>mJqR=riI&9f2`RM%rBYt zkT-8xF+Kb}!@Oszz*FnRr8ho zaMP5=c81+rFSHYGI;pSy^j%<{aaQRk*Mg?$CE*Nyx)wLizDtfg_%HnygIM~#p4?+s z)|+pWRT9~-f~Vnz%|ExrzmB>j&x_X1KK62L-PThZz3<;%!QhBO1}l;{5CDp3u_^t`@!NTv502YB5v1 z_M*?7UM5G?x6Tz`d3*BJ8SM&Tmt=3SmTpJ*b^c*-`H_u$IIONy&j8JJzVrhcF+!|Eev)LrFjgOsNCule`v zeXi!`y>#cxKmE?8o2>TKt@sunTXuiprTT;4ULF4V>*`H0#cVclpF2ITIz1)d79WY- zW0?85+k{Ey&?YB|gvOVdFIIa>1Pbw5iY@ZpR2yTdH}3yfb)$B4Zm90}*rC=rE(|7FM)x&`s*5od^ ztG$+0+kcTAPk6y0Hr^N7x%vw$8~26kKH2@tcggy*&H#MJS-@W4I z>sGXWC4bmbv%_~$ zn18CJO|MKxa^V`r^ygDm?7AJlMfdD_BFdEhGDp2id?O26mGE20%RZIXz$nta`)FQkkbI_g@4uu4 zB31X+Dlwe-8x_08KWn!5$yuI;{hLc!yJCNBs7cB$UXl@Fu(oTM=ClzX06XLDG+ zn`?T7BS+ZcApN4(m9JZ)vbd*x3wZ9k=!?On8C+BUd1=0zwNkjLa9`nfqy@n<*9>(;HXy0*5kM(+SiJd?xbxYgPmv&vU9OprU_yKjR; z-&~O@|4FrR+xHjp*F3u(m}K3mb2wUQ>bD7^^_p|NLfAaao~xeMIbbs58w=y=32HOl zlpQZ*?VHN}J5Oxx#H}ATZvOl)-N-<{wmN)*MzuZDv2yi>$eq{3Uy9CNzdrk>bX@xR zsy>e6)r-&ba9@--W4d(xQ=i`!6TBJLOnR8F_NC#V$$?g%?rE892^G&b9-FkmWd5Ef z@4cm_ee1A(7}4CAbm9P~&WY@%h0Ld z?#kD$%)Z$iYH)oL7^aBbYCm8q*5o;Bsb1ma=_bN6uYY{!b3Tue z`}E8{A5E^?d4HF^3gy#y?ChMtVEvN0+;ah!revFS3rAR&QvB|f?5?6)h1TqBX??UP z;I7fVV|9O9*7Th`Ct=>|INy2UTN#}OZT{=~4!1`e+rAdQIQhz)uM9r9H`JnY#eOX{ z)7iGwVjlYi{hf09Ybz9UWYkjr2egI0{h4Ty=+_*&#A0R!ms=u#`GrH{B zc=bR#|Hdw@xT)N} zQS+bp1YN$o@Cy4nb0x2L&)K=xXk^TtRuti4$n0{|C(EPqa66O1l&ghj)`ckthiv}# z=Zm+K@66p>)2dh^I%+hZF-6MeH3;8*XqQ#?^Hunfhd*wzocp8_7Q|z`X``9o;dOF; zn^j))?`oKwhe|z#5i&V$Nv8iu3 zYoYbv^dZl^57ta)I+%Jxvf}wf^-9lgxqZ_ek8qwc+QqGWb^AQ4teGmB|3Xt{Slr&t zq^Ji2_=KK&``Nva3mRoEl zcgHqf*W^3TgEy}`8@-uB_FaYkgL>BoIzA^tzWk83H+?Z_`SBg9#r$`+-&agqar5e% zCU?(Cmj6W=)=5|Ws@|*nV7nZ{Yh#}_n|nLvnrxeD_+Mx5yqdBn{7X)Kv~)YM>_Gad zM5Q?g4yrA`RQ_foOPGUwIg>IEv$jk184vaiyRvpPi*8zF`B;9k!Qq4j=h#o5R?twi za7~H=4NIKr`hWT1ku4h@7fs4M^OA|B+W${)<@49GJzsv@KWW#sy*D&})l@_l{(QyH z5`9nf=%lI5R>uqv9iILDzX{Kp3qgln-Xw&-l=IG)3_Boq^xVd?@3?Fg_I~PLFJ|i-9Y^6IFDqHSI`V`gqyyyCtZ!tIR=6EYSmS#V`!aM0o=VXnD zuL_r|`dGHTw*JTvW+CX~FB9J=9f>KhJG6JNZP)>>QXQcP#RKQqzP%Hi9sm0D&P}y8%Y$TO z`mRp?I5WKbm*Tvu^DS?Ph_dt7hFSO72nw#ba5LL~=HsioVtn^BUsag5thp)7UC`ol zQOuv-T_S3i)Hsfrc20^85~;kGFkgGl^V^ED-A{fW>9yLB!uRD^{!-S2i3@`MXQ!NM zEmFC1d|u=ItNGg&|KwngGL3>b9Hxc8!39(X4*H^%q|MJhGKR?nUti{wq&h7Ocs>8Qrp5 zc;W=PgIQKQ3LB2>biOMul%62U7FDcnBP_V(l=L>K3s>az792IW<6ks6{lvt3&eK{| z9tOPKzai|-y9L5^3TvdLUx-`jl|SD2QAX)%4}W85eRlR&@eNG9Dh7cTm%KWf8fS7y zv1i?Ldj2+W`Sz;fEe)?jR{2IRUej?t=kK??zwPYrJ8w)>KeFb5KhItLg$bg?30E1n zocXmy&*8OmqD14h-JNYRVsqbQM7e&sDpPNGL37vD;zxQC({E`oP3Ntb?!WkG-44nA zn~}znYY%8K+^W5y`bI$_ol*T$M|_d#f&HF4T5m>fDbe8In`~X1^txP4F*o(X$7}Pu z9ki;JABYr7JSn|KN$}*KZ2O8Ao4IB+PKnH957Yh@vhT}+s_7e6Ja}m9_`J6M?CF*-j-XYke|mG~`uS#8-fJ4HoEwqFCiZNZS$^)Lv>n^$mL5F#@%RlVADv?{ zw%vBwrZ4vg?~|y@)>Jc0&Jbp6E)!ec&doE;?l`aR+EvrONpF~-+j#ev#f;kPE!&Lj z_3PVKERMP=-t;w}VaFd!&*!h3O6Qm}H%w)z^_;6YS9ixGu|o^a9^P~;LQ|yseQoex zwwGFKSq=)7t2Z^5D}Ig4Jhx^MXN1U>TY@Z+6K6f#x3@{~iPgE1m+kD+HpjAlU-T}y z$?%MMe3M=D!B=}D{>3~vGrRfog3UV{rcIEYosbY)Y4PkySiWfSn#9=wVcRE`gjR99 zw>|bLaq`RrLxtX#f%+Q&t21f_5DO=NrSDEF1)d9?qt;>2@8MtYCA*83Ozi^&dmHet|CxxbF# zScy2Bu+r^U+2zmwc^tSVztzX+wQ*FF;2TwuHH)5Ymf|?T^LX_Vs^5?%e*X?z@UQU4k!|^L+L_mLri6`d^e+TP>>LYN7&T>GHShe_7iH9B370 z)%IR8{`_{;`h9TqNtNoj=2Air0W&Bl-NsVX}^Ac=0Iy)jl zIQuHENWsI3#jJ}TpE=7g>$=Ni2^Z-Ne*8-=NAH!9EsZ$9UCwtkHTIXbN9o2hT4GX1 zxK>7#7(^Vr;CL|0p^TYbXoE&Zsc!edLy>&TlKws1#oOqsvGz3ELcfO+{l5Esm@co^ z+0nR7?UuM%K*QC(!mIj^Eid=#Bnn@Q?AyyA9h+J!6);EOMi=+)+X;s`)*R$J(3+DK zVcOR*@j`1On+{jhU2nw*3;x7*?e#a#$YyIiyvX0$e=o|)gTtvV?afDq?;(fSOcQ?D z8cayGzR+-$anA<(nej#9kKZwWb9HXtb^N`7%c}!DOxkV<7o7SkXRHXF^hTTWn~}ES z;SGr{JVzsW*%AUTylS1woWi(z`I*D#-YT|RP5bil%)~y0sRi- zU<#Y@XkxG;_l{nxeOH5TDz27dJCkhMwAxTh*^hZ=rJNIAH3w6L7>2|B|Xvh)%A8n)PS29b2n zP5<9k3eVr`!W-rId^5v>t&^LsWpeg9axw^;74~*dPJ3CqIKec8g<0fl%_Fy-bz#dt zDr6)c?Rz+-+Cl_0_p8kn1v-9cVS=k;Hy5i8SD45ejf}tpi<}O2HHm@Fq|k^6ys*fL zvAao>RhugcG%dVg(E`x4u_#xV$d(lW2VSke@i4Gv$<_V8mbl*ve?HCNulvh47avWQ zHO+hJ5ZV3Tw`kS#Maxe49?bG+7JGH;k#O##U3M>SC2=j;ICYlsgdh&C=FmUSmr3n- zqwimJ^!zKEKim1_Ge2skgzsH`S$|%l@ET65YgW3k@eK9xwP}+cZ01@M^nRjO(V3e4 zS!ux=q%1BpEpPOCtjW}{%QP_I`DdQV8@8W3zPRqI>vcU3^Nza6%+DUD++VuAb2U1% zY7&q6flZb*pK@iK>rNW_JUaGRFHc?L^flpkalOo1QeM`s!VWV}Trv53C)+JjPb%}F zYrqO#hNSYzaVkAQ8>E63q%x;%IdsO@e3y&r!)7h>|6!H4Gw;4^U-ywCDg5SH?q|2dO8#zaTCq1FJ!kDrSA8mox^A};w2yyl*~tZ4E^XC*n-+9a zE$?OLxF-iZmnnv%?OS8SINAy;4o+1-;LXL<^@{D zJfC(?ZSI%0#b>fIery4qSCDXR>-?)#?{=klZ~ZXY|J7oyu(zeT-;Qa0s@y9s%_Pry zKxPHosws(?8s8?%Wj4pFrT@taXTBYL^q^>V%S>*Yay9i^E)i#!$Z0?3F!q0^?W1ID z#1oegV}H)<GY{Pw4eI8XF?ktZ(_X zAt{*4xr^o0XW`9#v0q;aE`K-k@7cTe9&~T&O^Mpoc&72W*!(+hCQtQBNMkqZiHU6L zd%Hl>J?igFv3YY_tmfoBF*+6XXP8EbnK!%W>*jJuH07U+?3dOGxWOJDeaWj zGn-%B@cx%xT{~U-ZfL^ic;iz-0Wv#I?sk|tkAI!p-mU+;AO7YpWapT>I$x&rlfHbG zs;yv{rL_fOJSb_-1)zk z%zJxkX5X%|&pTW=&6As~Pp+SIuiV;Qcs+;MZqV5W5)G4nzdk7TZ~lgWvSryE6IL%@ z?m5%#oyCjiB1SH!+WA@K!xS|pTs^Yc|8Vb~C%>irO1Q#S*nrmb?5Xz(V%E42`yoi^ zPQ;R**&g@jOnv?Ew>g8bH=EnH=0_8s>CP8_&f??1qP}%O(L=5uey!Rkmlw?WReNep z((UC>C(l`OOI2u^V!2G-NAcKyaiz->N{_o}|9o{y=I1)kZOxC@?27&(lgzMTmiU#e z_nO%2>TC_xp8iKTuXBs~|&p2UGf~fq0scEzQ|1qvfJ6LVn*t*;}_HZ>n&p(A1H)Rqm z9(R6wyZ&19KR=^SXZZ6ZCU02&WK+)1MS{mVxK*s4dat^>GtTp-p@@U_JI2!o47ca3 zEn*Fu;=$FTec}IEpU>$tcO0L{Iq}7JKW+C1PN_|y8(vL~lvKJ@ymi6-*AEpkZU#RO z*wDp%K`L>!SjTPW*zS~f%A4yF(`HRiJ`wAYx@@1t> zx-4sZkH`K}$hfJQz&ojd^T#gVgtNO}?GY5^h!kDpaJ*N>nD0Q=Plow%oNJnt9SY;` z7ZgtG(auj_PcP}vA{2=nt^qU=g`FCDMn`=8qO-R4TtQMU%VK4uZ zHU1(Izi(>(5=x1lSSIJZfc4o!ca^@wa*xC|6qpMf$WpxVLU88Q`(2kjXEokt*A9@A zJd&_0W#Lm{*N>C!&wFtFxS-T1rXf`5`7HXRK;Qh%^b3=2uIbv+;`wB9RQ{3kHs-cd zQ)cgIK2dh!f#r7DfV9wR{`+BMNKc3Z}$X}*1>72+*kJa|8&*`pRDj--Kl=FnQa+4Fs zE;*%>{&tp~eLpx4{E(M?Gr86EPoVJmJD(ohJh{(f*Ef$$;l@g1O^F0A#%zUmo~z^k z32ZNEbZivbX&q2pQnFaLe>Kl>fr-g8TAL5XTyb3Z;|152X?g3P8>%cmrFzf7P$})m zyQx#c?bj6+hc&9c-K=uq2>;7lyB3Aa@G!c#`PBM{YiAl3+{@;XG3Isje%s@o{Um(1 zl*Q`4y|VvwyS7UUl{YR{zjY+tf5#FP&p?m0(Lo8Hj5$J{FP9dn=*<+K`pQT7`~D|W z4sRBT5R=T=z{UCR@6U_(C$pcgGtg<06n!~;w_lOJpZ8zwKfm=Pl?shN>LggLtzW*# z*Iq5qozJ4Ckyqw|agpCDx#W!=lXuUPSzkRb=ictw3A?}l+4A#E<>LB{rf##gPP6*^ z>HI$f)2}aGZ)ffNw$J>}@BZI1HZkX;5B6%D+OSB)^<>q%D3gWfn2$2PIvtZ~uI%qCF)-o2lbm{f@T#Huko@VejSk z)$EuWvU`cknZ_jzqNt^h(p8VxaWOHSm z?OEO}FMF?>RxZ8%&%jhQr(Py`i^Ih{wZeUWW!_(UH2J#CmfaKG8>(v7H^+Q-X#(zL<1iLAFk(GoyDhqtw42 zS{rs>U4K7%hRcDl`yOnD#(UKhjvBmqZIixd?cL};7TM~nn>@`teXn0OaugE@aQY3qWqiI@vQT`0`k27bm>3&JqY^hm(Z=oBzjo7v$ zS$jk_m`t+T{>6Gt%Yr)D^4x?4^W}AdH_T5EUG)0@SI|;YmE{@+8(c-4*upH@BL7`l zIBmm`FTc4br_NtIn$XI^Cw5x(Pn=g&@_l(5KNq}5q0QP6z;jV_0ZUG8)Iv$9zhR9)0I zyT4d9f;H8)%pp*H?IS(WH9y3IG$bV$g=;oi{blnlUE{|6{rS&%e~#5Vy!J2RcUZmS zX6+ki&u^7hFQi_~yByuzy)pK6c8ld_F0pky-Ha`-uWddPy0NZ5$?lRYTSd|DFS7+) z%R7tKc0NC~)x?%@g&D`5)LR?da&5H2s~t}H%$YQ0zTN+4hMAvFTF2`vPCURB9>%b( zcfppu-)v2PKl%P(m)HvBNu@f;d|G*yty5m?lAH7;XWgz(?60CWXyx|Lv}u|K8q+@d zI_m2oF`ex_Q@!Jhe!e>Dyfy!`sqXHpyV6)=qfwPd8pS*7ddj zy0$EgJI*}LJ~iU6@EWyME6yIwT<*0s=VDM~qh;;g2Q~(Od-c~pDW7UD%jU5nTeH*{j{?Xq_uiF>Q7Iitifq9SIo^{`vuJ_td)imLt|(WJY6uPRny_kh{E@d`mDm3J ztTE3eJnK%-$A7`y&hD|zt}JH``qutDyUxLzH)tYDaNWIo#lqp&H<^py+@H4EIEKGW zhd)|Iy7tB7j?ClLKFnf%S3FoRe-bXW*f8q}R}<&;+>5*R`;>xIQ)t7gWOdQ4 z^4#m~1CO6uFhS^R=Lg%Z>lV&$PwluOAN!hXOO@8`{l9H@ZCmy*t>0~WG*?etK>MXR z1)V20r5*WE+ZF36w8P-QA-QBnD(XUUjZ@3m8sLWspTYexoOlxC! zEc>c=!5*_$L})B=3EwbREbPJyh6uHJCO@Bis(T$FuqCZOUh})Be#6)I>wa+a@BeJQ zcHQ=Kx>x(cb^EMe?>VvWSnz>YiyLBd4|Cp*6G{j@(76_LEaBczo?kq_lv2M+C$c^> z@VUG0=*a|o7t_OsHmND={_)__yf`(4d3rO?;>V9xfOdCgfBYS{ap}5cKTq48H~&(- zvBmewsg%nbeSDW(Pp&QODQr8Mv~iz->L-s|4AV}B$A`TA5%a=WxoIkYxyat6&tIeF z^t&Dpb7RQuQe#%A>btnwyj+NN+6SFt2Vu4IT&|{PcmMt>ef4a-(qFwxk7}g$1l`l5eMrurT5v0EFnM$qxD-pPHTYKpvn9ZrOKJ$lKs zb(ebG$z0B>XJ2hzx07$Oh9GcF9-WxnQU~~idFqU?8#*tRW8nWzD??L&xgHQKYE3_?LPAst>QKk)e_mT zOL(!~O~r!0#y2;L3Hj{%q-f(KvA9h7@Q3{_@?NQzm&?pD;|OB#YkRkE%_n{~E+atCBrfcjwa)cbrU&Ed z@-0`b51o0fY`X4>(}QQz4=g#jNvif+@>A9N_)SvodDkA*^lkZNoSgCFtzZ7vtZuvP zyx7zC4zM}9K0ZF{k3my}zzLQaM^c=wZRI|;EWV6$#`Dwy|7pi2-MsN?IxnY`PfFj_ zz1%s)RT`J}>Q73Ne1ADB=MqoMzN)x~>mC{|ugF=VT9&A|OmXWm-K!6-ZMt>toY}`H z*6nMLi|*Tde`)wX-XC#`5?hu`72?!M&i}a5T+*+-kVj(ip%||UyQteiR^R30byXw+ zR*OcgWcBqpqf_yC_39mWMe8*Se!jZj&Th4CfZ;Sl#bu1A&lo56Ir0=2bZ$zEUO(wkylLqbqm}yi=T0i` z=6KeV_H~EEh12=6|M=EFe8so=&q>C_ElHnk6YgCLF|Xgp(8$%CS^Y}G?Xm=8%-1cDBZ1hqAQ>dY*UZMn68fQD)t9@L`Bg$~4aGcAb{;{%=%l z{-gu9u3CSvOj~!kfIUm-n}b13V$`m>q~EXlC8o2aJ(5`4r&#dpY1f2J8E*gf?%dm1 z)_z{tfOU1^)0l-bKCff>Lweip9VT-eDm{&vC;nSG&DbWB zb25|h-mAq-&aVG9OKoEEG<&KoqitXiS<8El+3AGL8!gkNUw(8ynf>bePRZnV(F?Zw zu5EmOzI)ru6Gl%`79B`gA@1IHaa~fAr^jBw_3S{;L|buXM>ZE6tfYx#ZyW&D?TlkD7F> z`@~teX%W-G=lzerca(kI!Ie1m``irS*1pwp@)GSDe8q|zR>@BFo&V~h$?G?_oE1#X z9vd0jKGczGc&V^w&rOvjYx(cBr@H&?`>xRBTRnN_iU$wZGZt_qZW5b0DP2Tu=J7Mu z*6-`P7!)iMf@&h~9_!HIJJ0MJXwdrQvfJOB)jm&-Cl*Go)VOq<=diAVRQUQ2UZ>;? z_N#BppVq~lS}^&+<%jO4z;|Yu7dU3C+$Fc{OXAT9Key)#~T= zMrVAK#V4Tm(o|GaU~<*$`m)nf~n(3cESYCNE-Q?QVAn0WO{-jS)f;YlutWzvL>RR~F^1sO0 zUuVL%Tr-Uj5qIcLeb}iJ z?t0e0PeyCMvMX>}C@Cs_@4l9j?ygQ-k1M)o<{Hk9t2>kx{rla;Z+6G;3eUgNqB38{ zM?HG8QT&>woGcUDX>;Zp|NZxowcPJOcb8aD%0=D7*CxDjJTI?gv^nPEgseH6o+Vrm zs46(dwO4!6Oo2(ZAC(;5#b0G{<~(@pmO0Ucj&<#yBz0ij}{X9t`eE}yXMwT?wRMO{uL3txH~cHM9mhw{t_eFnC2y<1mhp7X`ceBb+P?j!B6b?cT$%zxdrX2a*o zdo#Z;aQ_hTX5PGI{fp0NE*DdnmthvV({^3x=RSeZ+vnV++NQF*UB50rZ>EsA@lgYT zD3$l`S(iOiFE21+`&!0U#_qnv+9Am^UM;nKrRCFA>&zvO=Qyu&H?eKMxu>?EyxBVQ z=>J=XW;Ds~Zj@-cAR3wYeDa-%jXIoODIF_zt@+>@#UiLxRxZE&$1nZU-%swks2k(c z?YYeR7vJWeDtSFijvwnYJS>~MpKps+hUL63N55~AShDKXo0B&WU!HOEl)LytR_pZ@ zet{J=_olU3blPpduzupMIr&!`C!~i4e&2U`jfsj|SlD~F+Tx=t*QsAGaPeN@<)qbG zD9+m=9X9LBu>{pu78{$hB5k_wd|oP{cwMsKYW@DzoXXeZwryN1nxJCqc3HacaYsn+ zor6EiEI2Q!m4E##F)K^Pw}n4GAx9&mD>i)3UEjd?8ip%(?RHF_r?;tN&4hz-9X6{| z)U_Q1mK488ywtFzSWaSc{pDqo7ERy!^6|Y(g4dlKdrvM32tOMrJ85^1@U&8n1eL#Y7e9*rYO`x;oL_0j z|C3cKS`MG82-@Ym=kGn=(!!Oh`z2;CEbDRI-ts>6;^z;)?tV^5o+rxmhBb0}+vLtQ zRttG-k8S8y>(o1`xU>9udR&JIckQPY={Ig#UY>b-;=#U28|*f!)|^-s7$I8FpVr?I z9=ZRX*aVNpzw3E_u3|~~T~T?sP`_!4;VwDlH*brS$`o~2?#s`d^uAZ(_1+0w8y*&% zaMeD+B`qmnwX$wQLNvp{JKq+h=hRrpy^M+8CEZ<@^=j42qpJ?6P2YHjP3tLBQ22>G z+nnDVQe5iOvtljp?bUID)AILD%(dMxW8x;Ia>MrAJG&jqy!Jg`6Sd`p?W|&U-99(h z{T1cLLY~1dXX$R7tSu4tHT?bE5*MbIkLDzOOqj6g+zq+3#ml-D_1gV#2)QgirO&T_ zwc7stU|G8#ol6eoY@Ezoq_s<(8qhl9NB0tY-%MrABMT+n8Mto2$ZfaPPit9&eSyR_g3> zJ1wtss^d4KNMW1zuZg~g1pc*c*tSk@&8`Vbo9kXlO69!0)ikB-(XL7tsVi4`tUX<= z1;xBd-$_q=mtn@;_3v|A)J;vU&o?d#KJa|W^k{Eu$lnJH{UwdzVmE)@%=;GT>#-uE z&&X%{JbT6Nt!`iYXS&`#y=2|ITfw`H^onH)6}BI)|6#IBuO@hku%@kTp-1MOMO#z< zcNH{s4jAvc4<|HzTs?BUy)q(cY76L_)s! z+uO+eI^6Yl?M~zC*EV$K%O?bfhi^W<-DHEw@+)>hT;?2iHG6`pH zKhU=C%*-=w4qFDdbf?di(R*T4LPM%$Fs_1RZ_CT=h$J6-Nb5pXV zC!e^+m9)+6Re|!vOOM}&ZA+W7#`1_>RN(~Q>h-g9Z(eTNX7rZzYjg0ES#^0Y^>)YB zUu-jrz9w;Xp0aaLZ(GZqHGXX&lUUxHE_n6p^{R7EUSF4+mLC;no z{*0UUQb=-Aa_ppnrJ)~H?(CTQRodt3)K%`=3}^E;Tg)p7_CC({>$t_#t$SaEO0J!= z*2-^Pc$`z$_qosYI{Z0}Z$ueQ2y1m0Ta}pof6Kyamfs&Mzuk7NGQ8l~1rZDBAd6)cF~KYG&g7duerER%-f|Pv9ND>(Z3%$!Op+hx3;TB z70y$wyptTOeKy5P^3%3k6Rdt6Pc>b(-$3c^!prafuzs}E?$_>ICzBkVeCNTEb*tX2 zS(jAcaj)9#>A4Q=o43Nl)wa9#MZA2)Vifb}sK(9Cw@;*U-@fa0pA#2Z)3)yMq05rn zm8KWG{?_Jk?XCQ^V}AwidF=BSYwFr}VU=u#U&Qh}kLwCo4@$K3AKlUw9@07A++~@m ztgQLH#d=Cj^OmeB+Y@~=%wqD1%Q+L+9u@cnc1&Otjjqi3(!Gi=r|Vp)=8q5MM!ufhhHF>85B2^XHD$g)rfiDsoS0iO zR||Z%>)gCN$Dey^j#-WPTzi(rt(TPQHqX`Hl~KG{w_WjWX`g-4vMmJ<^A=xy_U~-z z%e7tK)YdvYwN3CjS~BPFmPvna>%Pv8?VoBs!!N(@Y23ud{h42-J60W>^!Mv)p2GPe zZAZNOm5Vc#&RH(nHY-o8qe;16bp;#0?c$!iME9G06B>2|RhBPlW#vry7;inR=;f{T zmKRp7N$Om0yQfj?@qu;6UfktaH+$+`hsdqZ36LuBxCu=KQ z5nJn!oZ!>m^op-rbh^ADkHFQ33wAvVkCy(_ecw_;$~!NKZOfl7nbM!4%v(=Z#C)e<9StMRl8IoK5|MaWt#}?lGSoq{(o6O4nDVk9k<=#Io z2(6ASUcdSNA({U_cD&=d+B@IM@PldKHnvMu8@eq7Cwc3~6$boUpw)5hUbS_{>Kj?n z%AukD+rHiRuemmXZ;{EgJ4eKhs!rZ?RWv34#+8rON2iwUzsVYVy}Gmgz@II*aukhD z&HtRZ_R3WqX92dXqj_>Omt9~Dxya0!>w4ql_FuMQ>P?DucV*^IeLYqG#{ESe^*64n zC@#Aw`he-*yF>rDbpLD5o%F#_R{ky<%j(Bz3LUD_`u6+c%MZqwS*-r?vTxh5X-9l6 z{AJu)bN6c#d%&KWiyz`OWSy{Y7kM))GO{tq-)@H|0lcZ zcyIri`h<_~LCe$>hXE(lH{bi%AN$aB(a>D4%EY$K zhXm9MlHFprx&N|WuJI(%f{`cvYonQ@=X`akZ&m4uR?a)!6&Be#xO{a{cV4sMmhI}y zd%Mz}ZoA#Dyhd~J{KFqQPR}%DEU!0++P_z8gW>lOb>64H)brkF@aJ$E94`3#u2R`r z+iS(i?l$|9864UZn=}8KI)3f9YcKe^KWCM2@7<)cIlSvss=h3KYkI6}Yx^CiSK(>f z++JlybUDlP7RJmvx1>MI$wuO3?V;GcAO?*7kH{_z!>m^>}E{!`q!Md#*9E*9;3H^R4@={c5t z`}x*-iPIw9Ua{>nBlTW>Uy<&*=Tk@yZ!tsf*RHu6H>&Y`vdWA;{OI?E8$PZ=H~f@V zt<*XBdvoz2qcsf~_l+(n|NWvn>D>9cizkFkKi%Uoa5-W*VXs`s*Z8uaP)^s_*XLZ> zrR-+SJs>SnxPpx*%J!z>>SGbNmQ3t7wR#$|`cdT4>a1`*1FgM%pU)=PPL{d3Zd;J- zBats>owR4IyK}^a;Yqtx^rU1h!8@^Ke$f_!F4w9B9hx+4`6Tb(-zw!gpW~GDZrcdn zHAVWO>6^>dpSyUxvVS|NrP0BH$ep!|MBf!Dt92Jt$1!vA$CAhi_r9*FnBShFCtGf`iMFzQ4b{U{~R0n=SvRB(1)a z9QlcDMk0IAWuJVXl^Q$#s<)R-VP0!OO_8xr{v$0pPXYXS9_1{h%GX4^J?w3T$HS>)Rmwl(x=gc&6yBul%E3z!SzT>X!m26Yjt-R^WtR^G}&wC}H9VDAH|L2D@ zYB%R>df53cAb#W4J$;I6Qo>!QSJ@nG4t~PDUV4(zEpI)Uve~L@2Ywl(9BT|+H79JNtNQ2DDJ5_FQ!G3yjaG@}8uH~bs9enLe8l0(JU``E zTfgBo&3Rl#dk;tMO8?O3QpeY%pmj1U`|u?hb<>S=I(qNVW$XB({34da?e#vdLV5WX zw*|LfznPwU^uPL|pD6*)zF*1zY+rQg_`~<7*I1>y=6;?nP{O^P%`Za6voEAPuKad+ z*b*Tf@8bCjm24l*UJ!hoWA!6_SKWtM!b!3$`?oelv#9Izsk8-us!eiJYfNBWv^y;4 zGy5U0%b$hYrp()P%IQt_KfmIWFN@b&-9PqV-{vzxIw==*iw`|&IXdyr3Xjh`UECSh zx7KtvJ@~xVg5j0m-g9fTrrest6{&dIcGb4MhjnB+-%Z$a^qA*0vFCFO3l2T^U6al6&{0 zZ=%IKpGsQpN*}|ytCLDN9VaYOs6C^*@O$I?+28!uD1DN+Y5A4GytH_S*N18@FP)N; zOq%N&XYBi&;JDvge$o1qE?qn4b_QQnT7U6!>yj3&HFhTxw$zD5DM`o6&k0>~;p4PI z;}^9r&K^BqE9sg$QCT|v|Ni~<>t^uQE;@H^=048H_p1+kx=nd@;FW&eta~?AUHGCr zFHYK^Vs-Zp&kpYsiTqQ%7b)kwDev2Mvc%axp)>#PZD9>Z!L5dMt^2+%*<<%u?Eq)@ zVYdqBFZWmT<|(Q=E3y2!eZ^Uq1XDki`R!QaF}qX^6n1vQX8hwM&ES_Tk4u) zjlS%0_mNAC2SXO1?l@mA8ad@ELW)H1Q~hO|V0mvQkr1_qI&)w?z|d_8l3v+pv;yqEXPL$1Y6dZBgl z3-9>?kGO4L56HK!?_ZNxDS1ED`FH$5wk7kr_4uj-4P*kN?K}&g9thR(7W?jX^^kYz zve>;@zuzvJsr{n(+xil(eZPN9efRgl%y+fy3QKj@PL$faF?arkXQy{Rs$;E=p_=UMwXGfYk&T1AGa~C@F z`b~MSf=6ijx7|wfHgrh*`*Jg9OdHyQCGcKm*Jy+48M=yjMc3=OHd35tzOCRZPHphCr z)Z7F(4ki9Nu_cikhoBF*_9EsXB}6??*JT54;1 zPmA+h%oWx$*ARwBxzp!;ea|)XwbwhgqC=17JKaCRyC!)%C>`lHgyvS8cfTW#j$e4GSOFvqt>siw$gF)I4d|CC%l&0<4-_tu{ou)vsHh z6<+pR?cuCG{T;%lE&K_W8{*CUBK`zFVCV|f-Ng0OYPQzAwAhtv&ox+E8r0_eR!QG} zSpL)p-pSU-vSpbkMy*f{IXcT}>bqap*56|OeeBY#bs<-eC@$@~Z@pz^%mHr+|JVl) zT8<_*%3O!koUYRM-Y=Z%$>$d#v-hNL4rlm%_a}yuzW)X8ztTJQ)%Qxs^BEGd z*{14RAQkt;-tMlNweH@-348voW}YqE;XF6TW|eVLp}x%`o{oR{s(b(J@%F2qx4TYe z&ISt|_4RyDO`Sz#T;tOB=dfIx?aZDMdp%`yTxgSm*2;G_timfdZeEe~@VvE^lg?um zuq&4fddGe!w|U2M<7AKX~xqMc#jE b2N;xgs{d}#P`Spyz`)??>gTe~DWM4fJeV&W literal 0 HcmV?d00001 diff --git a/files/images/firmware/octax.png b/files/images/firmware/octax.png new file mode 100644 index 0000000000000000000000000000000000000000..12ec5a2a2dd6e4c1909025088dd090a5f70dae12 GIT binary patch literal 33230 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 literal 0 HcmV?d00001 diff --git a/files/images/firmware/octo_off.png b/files/images/firmware/octo_off.png new file mode 100644 index 0000000000000000000000000000000000000000..f5bbcbc21f0dbca71fe27f161b678f12c26b01c3 GIT binary patch literal 45119 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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 BL*W1b literal 0 HcmV?d00001 diff --git a/files/images/firmware/octo_on.png b/files/images/firmware/octo_on.png new file mode 100644 index 0000000000000000000000000000000000000000..6ff00e838bbfae635831db06aecc62dc40373c15 GIT binary patch literal 104867 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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򯬞WERlos#QguA(SbMNx5%LYLK9sX(Trw`75 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 literal 0 HcmV?d00001 diff --git a/files/images/firmware/octx.png b/files/images/firmware/octx.png new file mode 100644 index 0000000000000000000000000000000000000000..e2390939732f8351263af3e4a4861a5672ac52bc GIT binary patch literal 25838 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 literal 0 HcmV?d00001 diff --git a/files/images/firmware/plane.png b/files/images/firmware/plane.png new file mode 100644 index 0000000000000000000000000000000000000000..bfe646787a8c4509696c00ac32cdf5adf067913f GIT binary patch literal 5604 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 literal 0 HcmV?d00001 diff --git a/files/images/firmware/plane_off.png b/files/images/firmware/plane_off.png new file mode 100644 index 0000000000000000000000000000000000000000..59b54674ab1d905d76a6e2b8fa4d8c4f853e7a4b GIT binary patch literal 23873 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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�PV*|l=S%D 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

%F~u)*3uL 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 literal 0 HcmV?d00001 diff --git a/files/images/firmware/quad_T_off.png b/files/images/firmware/quad_T_off.png new file mode 100644 index 0000000000000000000000000000000000000000..df89eb1bc280485a50c4aefac54dca74677d2b03 GIT binary patch literal 36228 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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 literal 0 HcmV?d00001 diff --git a/files/images/firmware/quad_T_on.png b/files/images/firmware/quad_T_on.png new file mode 100644 index 0000000000000000000000000000000000000000..933c7bbb75eeff1617f721ff5a3a139a59e874eb GIT binary patch literal 74315 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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�PV*|l=S%D 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 aRL{&%C->8OmX22?$X}kWelF{r5}E)#7jGK? literal 0 HcmV?d00001 diff --git a/files/images/firmware/quad_on.png b/files/images/firmware/quad_on.png new file mode 100644 index 0000000000000000000000000000000000000000..ef296bbd75eb6611888b91296ed5a8274d334cc4 GIT binary patch literal 64898 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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 literal 0 HcmV?d00001 diff --git a/files/images/firmware/quadplus.png b/files/images/firmware/quadplus.png new file mode 100644 index 0000000000000000000000000000000000000000..350b76f24dbc1df7ef32b239b7e34176b649e2ae GIT binary patch literal 18387 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 z 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 literal 0 HcmV?d00001 diff --git a/files/images/firmware/quadx.png b/files/images/firmware/quadx.png new file mode 100644 index 0000000000000000000000000000000000000000..a935e874329bd6b663b7fb4f5146b9731694aec7 GIT binary patch literal 18122 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%0DJlH0tKR-9Of6~!hXBKq#95`yA2wIW9Tnc9{k3x0 zx>GBpj+JbB&HqEgx~6wweesPgJPpM9*dYNQ*-{4HE=j)&;3mXqhx<&|8_Pu|$ z&i-$P`L{69nO8*)sYSh5a{f%vi$w>k@)!19w6t_QlBTqE(XGl)dqD%~iN%-iAMA8o z^WsapRb|=jLi<;1C(G^o?LS#pqu;V=+qHYL7u}hJKX3XZUTM14Ry;M)q&oh>%lyc` zsn>Gfhu!samx}(tKezj2R{m%Ag&IF9YC|0Sj!yfi_`G&urpWZw+c!3y`1$d>*~T8j zEgN^#_$sbUyYOUckk(d1g^FIOV-xyM>afo)lQD~ppVCQ1c9<6DwPC+I@Hw z&WRk_l(6Z?qvK`uH!r<^o3p1*-Qe`H1ml8Z4zg!1Y-^CX)7YN+xzV$$f~CobRb+Bh0b-&y4o}GTQU+e1CO!(|-;>mW?Nm`<}U8a_jG->oY1I?8sd! zGg)|YvZ~tg#^ukmb}V#T^I6qn%QeXz(4BDqp8fN?Yya`QG+J@Zz zG5x}Og|BHL4}X5G5Sr(-V)=JH<~3DWcK3FhOj*p?Ei!y(S!oVf?O~@3*J%@1cgCdB zZw;Z&vHiZsVs^GOBq-Tg+-qT5S?_fG?f>?3@_+v)9pw-_!Eoi^A+C(CzjxQU&o_VN zc;&&JPO~c~tTS3Sw11jZsdRjI_Qs~hB`-r)ema==bnB5dvK4km>K*%5$~kLZq{{i`ub-?Cv-nw^)Ahvu;ZN zwoYyLwF$^`z1(eb&}Qpjd(T(ChkOq6U)}PrX)bT}ggG7+5kG=+%?~8~u%ogIUe;PA~HJAL{pQLO!zf4U3*Y@yh zcB}hDmq^>0p1H{DWVO}x$g``dMzQRk``LYV)eATOdEuWew>;_RT|b#?dnSBaGPSHl zlt0pO#eqe^XV=C##+aO061Tjk_0#$g!4LEQ6djQd%54o>@}%Z&78ZWb za>%k)X?5<5H8&zsSXX8J`f%HSp41`Egm71$qb-vUu${Ot%YBu!eZu~pz%C785AC%a z+?TR%{eAR#;|Z=Bdw;)^+&qRx(FTFBtEQY(4Q)*ggew|iA5fKc^@?G*ZuX(-x+Jpg>gkXin7fJm{`N-e#_2X z{(V$OoqZ$U$`u(678`E$9nk07!K5$zud{#6f-2^af?l_<1y$=0aql`1&=rD&KLF^S~caG^Si}ix&H*T{9ION^KXom{-*03ky_VuX@h<8E)5;;+3^-tho|fQ z%2?j$5T?DH|Aoz?XZkj_)9WXBW#-_ohoJnxa!yZWOedw7KJ}_}bfhRkR{w!}cjn(G%7_qIhS5=;}546AnpjYRc!T z33;%(YuT0q_piRQv#_}P%UEmPh67(JUnis|n%w7W(YX^h?Q-AMV+Bh#NT_D06t1YP zj!{i^doIS6yynfjj3umTA7i6$Z<%psyO3AcyZecfhc{oeN-Li@bwTKJnG+X9xr^*X z&YYTdE^4)q_@0{>jCMQnP;2JT#7sp zGl^MM|Hr!}sqeh@^(}d^`)m4^C5JzUm?Vn6e6jugy=%w3_VO)nT<@d(A#szHdt+IJ zrSs2Hc5*Fz-H|DAQ$*y5L*$kRr!r%c<@EH| zCi}Ndh#Lb-@ot6M=qW=+k=~XNzMZqJ~5x~_n&9K+_Y4<*j9i+J5|cb=v$!q z{>FeS=MxTgf0^l9dRo<-r(<(d% z;+Xz_ciEp86g`?+Z@IalJ5B0Z8B3ePMW;i->K9(-S1wtZ+@B&GWiWY(Rf_X3Vf7vM zElQn54176%YMU3<^a>q!T7GUNL(;UM-U11hOuLAQ`y4n{m%qyTd3m=?)XEC&f=%bO zE}AEA+U40eJ$~V`t=HFrc9ebRPe?q#H1U)$OVBs&gXW4EAzT4#CWNhwb6{D>>%ZFU zK96ee(t>v@*nc)W_^UmMW8M+9N2OtZFC-W3_HcF%TXQ8ZbcI)8Lee~WU(-X1OwQTv z+Oesc6F2C%nU+Rw2{QEeKlzyL#fwO+OeuxRi4GpF?SY`gMg zk`eF1U(8eXC~CcK*=2R--`XXMWql6XG@s=)y}eks=+7_L$?bYB7yWJ>Y6xK0Sjux= zUh{I}Ua|bH=%qf+2D4X7-COkGhUPB@_rey|SFfJ#_49nrxS~gF{s*<71^2m}B>JrC zPIRibFp9D0@Tfe#u;8wK3~%S1p!N2+&=Y<5_B;PZF3IsZc*9eCjTF>1wMJ=X&Te}C9{PhGQVid)1qCEME8 zDZ8424`#Q`w%T|rAZDwt#l$X6i4c=fqp&v5q z^2**WUV24zioi40`*AA9{d`tJD?_fB2W)iYd+?Jx>4DD-elD4LRW|qIW|_rArM}Ji z!OmN{og?uiL&%Go;`-$&j(b>_&r)Fg6}V)NKwCgTl8qwI28IO1Bexf==9qnGzvOIX zN!Q)a8oc8lKiCwOx-#U;BwOFtk}G|aYEIU~oqu*uY`M`)Ta)rl@;)acECgSDkT`7g z>#5fri=J6c?p$XVTduH{=S+}wnCQ?tYwIZ`ot*P`#C&68vy8X&p9r*Hy2Y_Y`R)7u zJtt4`CN^~Pb2ErJ<(GM`n5MOK(}Hc&9DRFF2JPEqC}Qn#N~OK<`1vgRuKiw&7HiYb zYU~X*;`p5IC4QcnBeU^>7;E1|=8$P3Kbzi*W}RpbQf(1U-sBjbw(`=!={I;zsI%M; zyTx!Q&`c)tG;boqe@34_9>-r6DY7*4pOsFVz*Bsq;>>L3r;9hAm)T;^;w!x*j=i*1 z)Ghz)T(1)j4GKP%`E5TL7U~K-TI4d7l{aGPiSG`##Z=f@tvM219k2+J zN1lp~cp}<#bwzzmc=1M`I_CdZIF;Dt^Gd1|1Xb+^TC<9$En+J_?Rc?!SIL-9e2hMaAQ1L)ENsfk#YNtuAoZhq-Q-kFMvN z7HR$A>88fbJ5T8K`IVg6$?Y?Dr&slfo*=yzekIRh0k7i@?X$1U5`Vk>!jxb9j0f{A zZftA4*)QIteP!)-&NI8_)I9ExDR^`$vsNz1HFl*r&r(Zm!Rz5^squRXHarwtvrI`Y zC}iu;(q>*Bok^>76xVQRma=M`ov-LHcLht0zir8anZ{{1KWlG~^E+;p!dNe*X6~C= zcXT`7`-gsg-y=Tk`Set>&3HkAKl#uFTD7*vWQe>&9=AH)_q6P1vHv9b>?jbdVHm)>S@_%|eH?38VIs&Mbh?0Y^tUb@8;h(f(JpKN^9z4kr6 zk#x@+!#aEi|z4`R>)+s4A*UHz{aeFmOxpx{oeLL@PRKVsr4>s!$92R$O|1q2to#=RNTEBR=gh=_3*;T^&OiGhZ*Q@GU*SA6s*CO><29d`Sdewa#*KJAHID0_khtjPjaTx{en>@IT=5F|~ z=+Y;p_I-9g(nG(y{=a%~dZ^X4rVrV^C;!w*Ssd^`_J!F4jf(geu zf#4~BJT`C3sQ9thgYn;*I`uVC=?OvX;x|hqQxhE>L)2z(*yZOe#MhDPxWv-sQsPy9 z+v_iFwccg_dy~Gu{eOQwf2g6?q`eP4U2lAMU6_2ySIkpK%;g-vVT!id*$HnBb1XC6 zv+wT(tq-Mt8$<+J?!0d~+Ii40NRfAClLFh8lRskO51d?}v(9&_QiOz8?2eUrl}C2& z$@^aGv3}b$wU3r6xrdvZS*Faf&~SJ7U|V%>1$&Z}agZ;zw;<}2Qt%=V-(@il9RZZ;1)`|IS7()J!)UyrviWZO68yZ2Qk$W%fO)LwHKp;imiZ zHJptD49~_*afr}WW!q)HfB&izG1I2VZaQGWv{2+(TdMS(nAe}T>PkmiKGXmmjIc8E z?ctLK8`u0&+@~VgWqz~x{^70fCu;rYSvsYb@wuVu*@t!NYmBsa$88esY3E=1R^@ie z=Yns^MOJ^0G5^?;5Ktg^$ZOs%qYXcc9T@M}B@0i|`p%@rzo+iyj^`UDr73<@y||ZI zThYKY&@dwL!1F|IGO(GT4{Np9C7U#AY`pkS@w zOYDxW`wjLz@v@sZKQgYy(j``X?_cw^PD}MV87}HQy)|iJ3#&9^i{Xl0ej8K@?`+L4 z{jv8)dg3B|7VSN6JMVo^cpz$LezSQ+a&cRSquijhk`opNV_Tuo~NnG!>JjaS+R=`Yi06hCuFT4>^tTcN+bp0L_a2)!h4wsg|BlO?$< zd{Z7aWaO@V-X_ZQXSvDA=^MJ1UFogWG`)Per}ezEI+M+0F6P1IL)O1D7 ziQZdzJw9xo(+l0qgZB^KUmbGg zSITpNvV%>Wv7e4C%2qz{gQ;%AiY2eCww7IUe7ow<67AU1b4NQhOoi8dV4Od_>nC%a zZNS2Sdu&0o^<=->BxN?gn!LB)X{w-n&8dTEo%5x&m-g`AF5j@v;W+EbeH?1C=G!%IqB zy`S%!?EYm!TuAjF?kyjeFL!?O@_DS^(w!nAftT;DT4*=h$YFCrb&Ju-1se;FEZ)b9D0LQK9$=xZo&oG|Y@(DL-&@`i(Cx@2_twaAoI2O!nW<-Hnbt2`a?*3{d)^zbi@t6vjon>cf8*!2*tc_* z{C_pQHEP|NQ~M_BwjAyL=e4IZMt0_gGNsQaR3~5TTyQZ&qs?p21zoY&kGlJ%%05q; zsXU#B?K1Zjo*63^uyFS%|8%rWmdrm;sUjgV?V<0d`XJl-MO$5)Cp%5Mwm$S$ahTV2 z8TZC%-)3H&Vik!t^G+826H=mX zdPC%+&8z;ie2Kz8S0$g5SB;lXntLSC_1DBp^EM|jx!>Kh!*dn$nYP7o913$AICjmx zSey`}G`m@+r0(AAROg^h&dzC{EZ=4RnsDsM)%d#`Uhn33H8IbA>I!-P2Td9k##@&3 zvwVn8EWWt<2(Q0kOK4Wu|GKcwIHQIy|M_+nXU%Qg%^BM2$G#qPs@W8+MxNgEvpQdc zrtx+&D;@4uJ@vOqo^!I~j8-$F<^Wdbjm=AHvLA#WR{J*HYfpjd(q|!aBUe0La!C5# z>hi@h)0A3Tol5V>*OzS%HY&?KC%|knuU7f?F;=C+$ETkWR@%$9Pgx_G=j-pywf`Jm zKAp?^f5Mk~zVquJ?A{e9e5h-oOx(Q4HQhg?o`~jUe~jec!L)gE<)(vwH$0E0 ztzLNWX59R>+(NUB%IAcc%%0Ar)S6Tu@P$8hx&CUW<=f_M-kH}r#Z$IR+sE}%-7*0& zlX*M7nI{*ka4%ZBqHIx&?$->lQ&rspF8X?Z@9DkV9c81|F5Yx7=ljJg>@4T^WoU6r zP2IKg+Wyqr2NF_$emd7?+7n`Jq|x4U{3-L22Q8JV*AB0`esR_NB_U#SdThTgcJ9A= zP5q|H%~fyj#Q%?aeQKhWWXs1>*DtxZ&%E+_)0_*AF?vJmbaYNL(vpIo8}cMR(Z(e~xoe zvD!DENH%K8W~GQJF*z(%U@P-nsS_YE|LUK{OPjBSZ+2NZ-Pq)}#+1%!RnF$6OEb!w zg0%Y%EvRKsj|3(vSxY=f9XmJuR4To|`%Gj90_tt1{D?_8jy&6spdUyK-08 z1J@eaprE>}pH7b--rAn>BOqcy@`dm2*H$dG;y!rtK}XZ(9U-BTCtVITIb4!{Z+G|6 z#IDm!mtPz^s~fe(&hGq!*h@^`*}rS1avl0%W2Jb#-S?n3r|(~$P{xD5!!wpBuol== zGxr5XMDCftvbo{?+plHc4;~C!rjX$Fa&D8xr}K+UG`_8PGV5I*+xCL%lY>90R7V`l zyxEnNzV5F6zZsn=tlwF`tCwnVG<^K{;h=h;Scq7!_>CvO&tAB5vTkM7>jbHFw`=9k zUTWjscxjjF<#+cF-;DpvYNZzw|F_{u^#YSge!02tRs}4o(AdR!bVtlL{pB;R>|Q*x z?ZNq9m;1jRH09Gg8GX-2Zfk7=XXpz`RhgQO5grvH-0|vt#UA$A>zk- zf9f5#<&@;Pq z?d$N^B~#x$Te$S3_LT#FU6i#m3^tY|tz(~k?y`WR$(pZhbN*YDUum9nH9XqtwNcj= zzX?;{RqjyVvE8FV_)4+i#Ns`_`!#x3RV{ITo_;)VyTR+5D=XtP>%+<~Wqswmn&}fY z?eUB?^KQSDknCNPAQLw?>_Kax;8_vCTRmUDjO}yWdd`8@YxCv9^0#+pmhG>2a&hk4){7^& z7#=e`W_;}Q!sFhu<-yN=^rbD@o4r^zdUP+`s(tB#Api14>4WK_-D?iyo7&{hlI{0& z-DT?$Y9Qe=yZh*?$A8z)sx6*Yb6f0dZGv5s(qq>z7dm9V27B#apJn}h$-Kb3RoAbX z#hS2NKUk?*d8ftZto03*J#2zUxNjUO+xPwOT#r{B_Bncv&Vq}VJ?LmNbnN|Cwexo<+sgwZq3tWZtnv;EGKcrawOl>|Fj_NclctRH#1wRCq2K<$?W41ka{86$Tj!& zBevta7w-AA_cs4pr;ASFMvZGOP1^8CQI}!PlE3dtvX^r$OcyPgm3DAdR%PR~eXq9P zz7?_3O{itfulZXPR(#qM_`iR7$Q3)=+0|>C#Hv`$7~{Ve0VlC_PSqs8Kc3TV7ERsKaL?BS~)eG(aL6;Zy zPRqJ{nMY>+@|zu3AL%%mcdD-S|ClsA>&S(>E-fbV9do|3y_r9ID|7xUcjJp}ows#z z=WN>gPjuO;hi_-pU+|6mTW&QuG)h?P!HU`Si%)8wY2Gq5;#r9QqfNh$USIHUnoRJ= z9pN_~2{*-maa?%QAaJe0s+C>*e7k#B*B2@7y#D)GWUG?{k6riruX0Yto$9(dezwt( zzjdV7ie5kYe4#Ga(>son3fk9y6!wX^AiUZrv}@Jj>tEdG-ZEm;(qjm8{T$lL$oGx2 zdA(P*u|YBiH^bJA5?s1dA8&Z)$1?o}&x=(L-PQ}Z{QfAg=Gdy&qMDzquAID{pZQ5_ zZsd||sjQS|r)oYtov~!y$*UK*Ut2L%y(kcV{pEf7?xgDn8{5MEhMP^Z_ES8?I`KAF zWvg`7lbtJ_rt)scl8i4}Dj-mEc1l;B<7%`0Gg+>(p8H}g(KYupXWZp^%StzOa)mrR zGx59Qe;;eLr<()YN&>v94>37-IP9AiwfmKN__`S5)z*d$^ItDISf#%-NVZ+?%7q)E zlaGWyDD*v zRp0H?MHf=dl3zR6*6N*F6c+oJWA^;=+&5pg^R$J?uFRSrmd=!^RDbY#A24(z}9>EYDJN$Nc&0eEt|IN{4?L(FUw*q@f4(!QOmg}H+Gr-%;xR!;_~O4=v#$MJ z9&$+YYIZLdG)u?+dO9Tjnk|<+Z2EL_>rIv z-;ns=<8rzslI%@gPd%m^F)H3YCjMea{7UuNEgN<%T`|qW%B|B4a+sl zoc{NTiK~6DUht}E-dXEq!OvsntUP7&m_vKbwnNJc{ofa5JpL$q)OI)fs|&Wvqg@o{ z-p|Wk{G>&ry+LzaXY4Ra43Z7?9&9uL;f+=hN^=&yR3vc_`q$O!F{xi{7$Q-K4 z)b#$MPe|xZhY0mrVN3Baa^5)Sae}bR=Y1A`bxGmzWyt1lb_;+FNoKx#sf~;;Dv>VOc;ODnzSKonPsVGxn zD-Y(vuh-72w0i!G`f{Km`@(@0P4&Mn`nhH)^ZWg-Jj`?FNR6+${vz>>i>lfLLVpQ{ z@A3QK!Zhd4)1%WDJAKaR6aOopA!%GPVb%F*>=SicN`qcqw_-NmwB^;d1__xT*BbrG z4jbmrKf!%!kBymO_y$SItM>dmH9a=InxY9ZKgrt*!Mp=jBL(iOFd#Ciyj@>4B?R?qU!*l<9og=a5 z$f|{HwRhhnf8gg{UQ_gF=YciV6;66m(~q;QzGad4^7~t!3E>+X`R0D})xT6KmXR61 zJN`zOeLZjI(o+^wl0Sct<4xYdafrX~#{R|qR;vvvuc{qsNE5bGXfoqiRW@xN%_l)XDr#KCf&U+TzkCvPCXdZu<`=aD`bg#f7 z0lqJ9>a=eBy&~{$cD{yd*k6J9^Uhv%(r8g&TeX367u(#9CF|9leK@?g30c1r-R2iv zzD2;x^uCGJa^csX%r``CZxIl3+`?<{Cw}+yft`~hzi*F?sIUTJnPy| zgFw?#!O6@M9TJ@)YFS-&z0SCL05tz&c~M#6g}p%vN6H2(r}g|7F0OwluXL7^qXX#} zYVc{%kOk@F99r!Zf#n2h_|kO+#UKBfco?2uf0aEW_hBUi0|SGntDnm{r-UW|kudwK literal 0 HcmV?d00001 diff --git a/files/images/firmware/rover.png b/files/images/firmware/rover.png new file mode 100644 index 0000000000000000000000000000000000000000..2bffc8e36103f94ad952e0685debf0a2dcc8906c GIT binary patch literal 13576 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

BXacg5d|qf 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 FngF5Z!-oI> literal 0 HcmV?d00001 diff --git a/files/images/firmware/rover_off.png b/files/images/firmware/rover_off.png new file mode 100644 index 0000000000000000000000000000000000000000..24e91f6dae67b552a30c9e6c7aa5f90bbf57c083 GIT binary patch literal 30490 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D z)AOqf92giLmegJRr=!1Fs==DAA@|=R)pslzaoh_^zjvo?;&<4}u;Asb@XrOHuyI{D zVdu@8PoF%w;dR6*I`LF^?Z5Ox@dv{H=KQR)`SbnjgME)w8jWHb-C2G-ICSQV&r+H5 zlQ>(F?mX*v|FfO@{~y`QN=H1Cc1CE4JPs5p>~opb^Vw*rQm4}-&7-Q9{-->;uk)MP z?!GC*hAcbA>WR85Vw0J_d8-RVlpJ{Uoq^%g?)-ySG&qj}HTE=evN)dL5KdIQ z)xnt56`|b6AwIM9hvGpG7NKqxg_9j3flA&JO+5^QxN*)_l1-a!&&`e3ua#^+9GA!W47@5h1D7SxBBgz zj~g6#A;E5ZB*#GS*kPxQ7CM}hlTU9{TEnyYnAC=_HO#v^zb2pGSk5BU=z4(DjHTR3 zAyLlJBf=-b?}o<;1sN3+!CRc>oXjnOht!oOukhZYwoCBm5s4%t!}bUd9p!66{lfYJ z)g8`9%vFRsosHCYPGIufxFqC~&?UD^c|poAbym(c@sLuUeDYRG_9k}ADLM+;Ct9D( zeRBAT@e}DMil3sn<|a85F8LAsNF(S}mY3vHfu|-<*-~d1IfgEt6?AvS!Vp2z{wSxl z3%3QW4{To{Y*ISQ@@%u1r}xsei>6+d$`H@^p1J--$u7aWQ|0`oUkJZ+`lb7e=`WbS zl=JYmi8deaNY{{@Ex|64E?F+IeumF7$;;i6$3qOv4PVcAK9hfDerSZ&Hmw@biKn=x zdQDZEDy^j-vU1h3RrgkLhkgz{9n!xtF1U7`Tc~mHe>d_u9`{m@QFl-8KgT-vdGO8PyUV$j zi}~7GeO;%wDtoE)!rd*_s-Zv4yNvdDMa_T;rjSw=362#t!}?6!99TGea2*X~{}xO}JIWWUw(uB9K| z@NwJ8Z7a7+Zg_fw?e@BDx!Y zH{DKew)C;PC-y$^D*0L%`>^WL*SWJd&pz~a#qIU)%-&_bYrix9jLCe>d6CA&7Y?6r zeh~QdqCNNgsRr5i*VOqt`!}Xte?weiF{Ks~WZOrc( z-HVJrV}4-!iS4KT59iN|Z@uqaulzsdf7Sns49go-8Pl0N8yy>?nSTGMs!`nEXK!^o z_1mVKZykFU>~s`$>~C7z^z`6b#f%egCahKb{(Q!{iRUu;S_A4{T)V)Y_$;yea2=0& zYkO;Wn|)tFM}*Wx!|A5w7w~uqa%k{cmrdoEZ^s;PjneQ^$Wq(XB zE%MCOh`AA-Io>jsdRptu@^bdw|MT{9`=hy!xF1)G&(J>+TTr?1+@UY6%f(je3F%l( zbMWc#vzYS1Q9x^jSdZ!_;d0eJuF6BQhtiewFPdHKxZxb5CFl3aL(8{n(wm8UOe9?^Mp05k-A*loR+-^iPE^P#l9&$H9T$q+0Ijz(^k*ZKKu5}=2N#P zn9q4X|NmQ|LqZQHZCl#r9j+@I@oev!EXz$cg_XCt9*eSSw}r8-vDwkJO)K}R|LV8l z)7RDQRjcyNZj3v4s_EcX#_ZSJpLO=5U*2G_JbEWM>JG<72+!miM zT7N_1PQ_E{_WV=(XWp5zW##H4J5$c5T}pfT?4IttXufHyrazm`m&bea))wCTVO!pQ z{pNaGfBIRC+q;{$IqzJ&-)6_2)a577owc?PSrYOkt)mB z$?2cY_spF-x3*62=bePxi?&riPd;})i$DMUE`gGVmt6mMKeygveJhIR>@!u2w#o?{vP3ODqSM8(!-MR7pPJPya z@&%tS-f{oV*4ljj-^8!|{LZZXGy6}s@wUC5XJKb)`N+QL@5?{SozJJ7SDPpPZ_&Tg z>%_(M>wa8)ef`|U85b8$|1^E_{@j|Se_tJVExG>ou|vn?_MNOSHjMic_WSL@@;l|S z?-$?a_kU8OP_OYnCJ0cuf2ZUNk) zykcnBCFkerS0onb8|oS8mi(gxAE>@kzC9Y*9_;nVCR2HP_2c;J0mlh?bx|XHp zl_+C#L`pK;oPyG#9B}xgBKS5nLIJD?0@se>Z@4s0-jAtDDw zFGvQbw$zGD9NIuK5N+V30Er=+irfM#=c3falKi5O{QMj{NGe10pPZc)G{Q6UQu51- zHEs0KRU@JrVNj||Vo9nUC@Jb1nClu?gculG8Jbubnra&uTNxN283Iv>W`=KSNn%Q3 zNg^?(pr}PRCqE@Kt&%8H5Gqm4@b$Iw%quQQ%u7!7bg`?*Ezrx%OtG>sFflSQGcnXn zGfqv`O|&#I(6ul#GSIb5GcqXR;-Vn2s5ljr3vHEP*$`g7KoTc}v;pU4 ztHfkbL1UK;N~@_UHu@-{2xmd`fUJTj$i$35;zAiiJ8nD5Gg9;LC3uKYU{$ycDb7zT zDNig)bxcpqDKF^x5>#FiFxU%DR%m>WD65O*MdFLAfl-G304eX=0BU1WUI9N zqTIw1yUg6g^i=(VymT9VgdoCB8+a{b<(!|BU*wygl4@scqmNA(t1eGx=K#pqnq6^_ zyOV;atFxJ*rJ0$ok)9#4F-Yo=%mLM7R{lkqsd*)d;Jj^UqmLnmu08@(R^*g|)teg` z7#JAn8-hrvR%B^(t&#Y(B1@xdMd%F8%Pg@og4%{AjHC-x*+K#}xF9h()y~jHA6*Dt zbwFlCYEFbpW^QU;ab|v=oiV7c1ZzTNOCl|hzux*veDpzgaeV}XmAl3 zP!MIK!37BiBFWLsqfNH`El zjs_Qz0R>Su8eEWYAd(ynE+PX8qHHv{AmKnHIT~C<1{6fuXmCNofk<*RxQGlWh_cb( zf`kK+qqrn9U2O`PQ;36`hAj(FA3la`Ql6ZrQ3$fQTH7~_hsa(n4PRIY2 zD+2?ALb6AYF9SoBDg#49GXulV{|pQbFBuq04Hy_+B``2p&0t^<&z}^3)Qy3`NX65| zF{I+wo4b{JLLYxW@G)A5_fr2NjY%s#XR&)N-Qhb+LyBXn%0&%N)mlMGr)EnfFV{}C zg@KEMJheQHTtA+j6R_X@T2#&V!t=Jj?^J)YtDgV4^8eE0jBnMCZ!EIB-JN~S$mq>6CEzJRyX>FIs>N|r`UtaMx#T6!Zn z@!Pwi&acuQi%Ne8{AS^ZZ<^X4%gdtLxM|*k?pYpto(OgN&i2v?Y_grocW%AFVm` zY9X;IVu^2rHWhlv^G?&!?dRJ6ud9~niCjNN;|0~ApI@r7uKPXmy~Ui^UsIE9_oe$M zyR6CI!*!j%zgz$R`#!hV?8LA0_NsC=8XvF6&#kZj&wnoWcm405GWY9T&$#tG^O$WL z;gEE1&$$-UTlY6Q{w`}zx6j|7-=C2iw(xKLlQqXrM0Uk({C;)S)Fa2`AA2z$YG&a+ zQRtK!zvp_4_Qrbq&eT&CpI5Q-dBp6Acr=?^b=}p>f7WFl{>SIp$|&mh@9yoKZGL`! zcLKR$GzuRubcTIXxR_&hv!zog{p=(btxfKn|K_n@yS(-Pexc7* zF&irH+jXkXIkCn`;k(9V29>|vSL8UqUTk?a&GDXENbz$o8MB_I$%z*B*Va#7yXxwn z%B#iaCVo!(oYu!6@Q0<_y~V-piNvbByQ+N>Y8#(;-rMtveYVQI8}9oort3ZRXgT@m z=|8oIuO&M2oMHlOYg{>mR__&$*NK)k_o~TRWZpTImr35vDe3Dhm9WHZZ({4?*H@K( zvlNi~lAy>dylV5gNo#)}_t>*!>h|@!ikBbZo9^wj^_^{>it2dr+{E)yS zc1dC3rkCH!GtN)s4YI%VxM|+zbk8?cy((d0e2gng>)!r|*yd+{_;&c_Pm-IP*?ZV)<(&NtNvr@3x()t`$;#}@3-%~I^(y>w%t>XXvykCzdQf>hQz^Qt&Qg! zA1EJm;!+J+K3}nL-!=7FX1BsXub1j3!Xn62QFwslJ<7i3l zo=vH$QMU6gpUPkgxi!;as?I~734S^U=bbq<>8OzYsVOY4`Q?r(%zk}AE%t`eg;uWW z->c+bO|qPNKJ{AGgmcW%hrej-E$qFsZQ~-bweFi7rsVEs)LT)1e4dC%*Bw2Di{}m> z3Or{Yz2;Acg!!T4VpsFuO3eQy9$Rzomiz60&!ju&zn!)tVc(qP)!$TpTWq{h92LKy z>|n%R>1vUH&~*OL6$%>{{j1-Y^k%2aubk;eq;^d?yRY_*@Q(d;;(Alos`>t@yvq7n zb>Ci(N7Lh9h|l5M_22LOefuo|FZJ!y_r48FX%aXo_wjk}52k(}9;Ha9s+4_e;?<2V z{;-~?@uX(&2}L&7?zI2^l!W=becrrx-?#q6+Y?9FBR8|;+_C7~&gXee!bxb&l)Q$u z2UpZL9^sbuwE1t-xi!o3eaZv=-4|Y8o624Px9S^bQvCUe<-ZPZiShXV?~S6ute;iM z7d{DP=Kud?d{s#2SVHBk4^fS$ukE@P`}&%YwAq<|d;%v8D-1fX{-3vhqAj1&r(jZ zsbYK(cX^o*JMR>Ws*+W;PE{L(KDnmEt86nlJvH1br)J^jZq9=#txC7Imrs{)u}j+E z&hm3{%|dr?pMQQlpHk+|aFO;F)Hdw&;aQ}rHgW!9ha=A!7}noZer2@$r>RP_drPC= ziZ$u0?w=LfT{^wuPGO7=1H+N*9~_<=-0pfdO;zKZrV^rBGHq_}+7}n^-VA1BU?|GF z9p<^=)Kv9@UKd$TTi)F@pD$>u={t#PMuvuRKl@mrwR5cx&r2{oad%?G+*rSD%WU*7 zo>FFDV0a(9B6<2=?+t$@eQRE?x^dG|-D_)AH!?9OL}p#}nd(1j8|O5YF!MVK(c3(- z73CP27$%s6u3mad-E+5L#H5I?JN&lItC%xclA&S2hE2T3Wwetw@~PKwYV7|sZ_CSr zla8#~s2BV3hKpYk14GlXc`9?Oyl&Wgo>GsP6cOooJYD_e@ns*>85kNF! zS#_G$QBQ6LhYO)A9GXM}&bdb98dx(haP0FE_1wU;_HU|?rT`a%L&coK%7+q8pLwFf z%Ak;=6+TTpkd=E<0&CEZ`45>GCe-y^n3^UPD{;+#!XxjeB3u>Ee&1d%WdGmkk+{_N zHxqw+K7Vfh=C}6$r(`6b>9dPUV(fMOdf(s5^O2_2-LFT4Vzw|mXur?zac8Udqkem@ zKcTlj&#x={H)reXYxAPFY+_ZPqp-1M+hfTmRH$3_58$&dzC`o^F+@5{X1Q4 z-qls7>+WvR++Kfi{hoFfZTEfuydKG%T_LVJX-CDzISkjBMP)YGUt4=w*z{Nsi>%)C zA0Nv)b)&p;ZaO8sjjA$Psm`Y0yJvsgqZ#Z==GMPFx?xXo=Kr^z$5_QZa#kfznQb<; zqGn@4J(qWav2p7E{QG`QqOVv^SIt=FH`OBcx=u~`PMHVJ?USkx&Z(T1b9Rp2MWNlM z*(&RzbT1nHn>*jbM(Nn%hnJQ<{d`mT^oi@b%fyprn+dJod8~3d3q#`8q}C(i@sobs z%DyC5x6k^j-O4S`!zymydf)fUW1Ta5=TW9<6}8*_ABoC7-LdDZ7-yJ<(3+>GRsF6k zElE2wfjOi9OjB9njkzZ#sdoNcUH$FEbKOXz^!Ll>l=+swR{OYWwaTpAa-VY#c>Zy zgVkZJpPe=wSr%v8xi!mcO|1K(tHPaMJqpO$6F;K;D`Ru+?jwJ$?)#ha-`2)# z-}l7kXKT~5SLh{%EaUMNZ}{=2@WM=on-X)UFZcevC9!$)-;JAWY%_^8rSoH7znfe64mT->K;Iw^OzL@nPYY zT?}@=eYW{^UM#+{Z?BobuD|8}Gx)Of;}5=zNwMGer|8|i>w#5__ev%oNt{(68?3_2 zu*oEQ+Gn?)$=93bF1>qmpYOIDo@^7_>QndYA8~%GwE2DA%H-Yd@I}2(y?*V!Yb}{*?5%>p1Rs-_s(Lc!@mD^w*Donr+@l-{pSBIr3>Y%*Syi6-8N^9^}=?! z2^Bv@O(Gq3{dQ1)d1r-rnRoG@Cyuvf8YZV?KREEFzUo~}=<5Z-+fHuQp;>!Z|y{BxlBvSEj|YBP`F(d;9LWUX~K4(|c*vearTL zzgsR8UmKdw@l`NnvYO29HMdG<+k~y%b!1|>$Cg8@>TbWiopYgP4pZVDV++SWUSKXF%bSA@+S^TAEe5PwF9}iHS zCfcyg-R;|!;|;o1?a4D@tMhED%X_Aj{SEbvSe|9cGkc9| zQ|l5bqlly}hAh{FpKe=Sb@o<5{EXkVKOC)<@prUHv;ey!uP@_GuMUPCMTCz2)5`-f8n}z3)ArrYp1i&X(8G<|jU`T$o&Y zJX`7Z*HTT1)RdX`itc<(B+x;y*~H9-mP6O;_ki-y&RqQ zv)vp2ZF$WreQMfN$zS^)3w^$BT{?~B^zWs85#D;P7Tl|LuAP&|>YBUjRf+EIgxD4J zM1bB?yFiMvMMzB0S)K-E2U|FZAVo43x*xU2Si{^qUW zzrQ`c@$2Tg{QG)ut73h(i0MzN_$BG+zoEiKBB01Aa^bcJ+o1PrCkq$eu}E*cTCA1+ zzdHB!t(?7A?$n2^Z*$@P(0?{5?}EoI@!4y|uaq516MT2Es2f0)|TI!7O|Tz zU1~zc{EVATZM}b9ZS=~q-dNJ9<|Ur;|FYSXNBn=A^6teXU0if-{$_QSnKRFEJ)d8< z=zg2wt#oOh_+2HdwqLfij$7)LxoGL}wK+H6)MtOsyV<{d-mCC?hb7iH>{{nuV;>(O zZn!nFVWW_?^~Iq7O{M3Wa+ZnC+@AMThFR!a>2li;-`TCY8;h!P`*zRIUhloX6@7!up`m1nW`plU^$+h!;e$TjYq4}v+uw9t`g8Ow- znX5k}y!$s#cWuDlwj;)0BR73@h+QYXVeP+p8D?flE5f|umaaZt|Fd=X_x#u`_W$R+ z*k$@p#(#F{j;y6F+b1(I{5ia?`t`=B&1x}k8@{G&&rsXAc3N@4?kT5RIECV8C|$gD zKI`fh+v`@X>6yFhR{r~2k$yN*c3pV<#2wDn2i9D8*~Yu+fBCyJcmG-V-M=nhf9n44 zm&Xfa{k4NrY@;T2`|e-SZCn2COwxHz+W@obb=Bpai`}x47Ik;sGD)6YCiC;RnZ=!5 zebHIxPyYPc^tUyyJmGZ7wDSubKUtQ)ope5x^P!CH{|~#>W^H@%>dW-QrH*D98qxW> zCHD-OI@Tt;KhN2-ApZUJ`1NmpYIN>gJ3D>z2Jfuu{Opx#-Kt62;U06gJ3NlbKEC;$ zzFFJJW2?k29C@;Bq0s!DvYO>fSHi*8V5t5BgQPJ#v!W{pHK#Dn_@J;+s=89@+PIPwXqD zi^uoo$KTv!dX&NC`-SGB+VAoLeXnm{OR0^%y|F3qmcF)zRsBA-33G#9?}&W#^@~d9 zHOCKY@@`L_<&k~e;`Ucj?L&ok-0v$#H|I~iv3mNR|HtK&4}SXU@a46BG{2q0~ z%afCh?p&McdF|tNmm6HSZkFUQ{Et}s_310~f_1v$S6<(`mb2Aqkw?#i?=h!7ZdVsN zJiaObv7TL^S0_`u!-Z9m%l1sdU$Zmmf27-@y+v;^RrYA za=l=!_;_^F*0ilhx~5u)?wPQ1^{xHe!@m8#`Sj4Ib5FaEo(k*PH$A!Y%f}zWMgQ{o z&MKS5uJ#jO8o%E!saHzITmR4I`KkLi&%bPUaFX!CX0Z=js^l*&TdK5i&4%ZnQqNUI zC4RgR(HUQNaHGqsO-8JT-CI`2=C3j@%FnjledpTtChM^GAKz}Do7y+QjB}dIk8`mp zuT^zz(z=Te#b5id_w%;RpYjSUwXa4$tyU22-De)f_%vbL>$OoQuVqL5u!yR)t61$J z*japk!sDWgN8bof+*G<@j`)JB=2lH!cN>$MRi!gx=RP=RHRbckV?{Z))jswZTeNZ5 zzusx}G-M~=S{>(r^@rWWZ;9_ZazZt5LQI+StrZ*R_=nl+T4ZpXT{asNZMn^N}kj)^=p|HQZR-8%`%H?P+< zt(&ni=(@nxd6O6X`WBtOdtcyb=^INL6Ay3x|M$53|GWJCKJ#+(%!t}0wkFPP9%}*u{q{`upY}F<>+0R- zdxdg!56{`O%e3^h*Pi!wosQZ|GB?-7&3m@yz;FNa6N}3NHu+YCJu3GJckB4O$Tsxx zq_V{c*LS`So#&Zg1S*J?+H%`(`0Yr@f!t z_qPa4>YXL@{#XBzyStme{>%-09iDcoP$$IV_2cR+$>&{CE0s-bBZ?T>?&(GUzj)N@ zt>9!)yUjgzx1^fts(zMTMJ)Vy?$E7`@QE{Of#ffAz{+6r$mEnKzc$MC$;x~4WbNH^zRYvWt_stw&tGi2{ph##w1|jm zY3;-}%e%GvWoK{xoBj5pXt>9o`X1wl+)~n7#n*0r+FAcGM@ONbL-yTX^&6d6o%y}i z1etE{mOlOdHtXJ}i(}@w&8moSysBq4`%={jvpxD7<7}VL4QlNYN?BBMwm#bD! z`pTD5fAhvhRd3^l3pX~YN;LPsmk@k&Bzx1#FyZ4z?=W%)ckB#kj z{{AzxtP{y%O;X+WWznB(*WBxS-z%Py^!}44J4Y)#DnVE${h@{SW&x3Fu6MSropa!C z>DqP7>_We-{@10+-k%%PIZ4RaSe5Ux5%V^Yp062yKfj5yJ02%H=jOYhPO~(f4AHso zcWK|+TwA}_pjAKj$N9A1e>d2_-ci4QGyAbeKUDg6ZaVmCZ$8Jhe_LGFgs&;MH^Fa? z#>P_VPWP7=SfhO`q+UB(m7K7&-aO%SUy~E7P_^@p`u#`r!cXnLcj5Nk=O1n#Xe^pH zMN{~jw#kE3?pdj9um9edu|DnW6PMcew)ye;%f)ZB@qYT3Bi8+O#m@JU#d;GBtG3Mf zur2NJ=kuOEWwwU1-z03#4qNAO?)MBsXX!O@Lj4|>dQZ#W3OM#E>c4M3OI?4V^M}d* z=I&o)a^PFWx8w46RsWPF3w=HI)cpB*_s@s>Z>s;Pf4Tp7)T0;WwR7($?O7jRS6avD zp3LcM^37FjHP4|&=6iQGu(qyUA~zdVxyH!WHcJERA^6psRx%HjGOJcVlsc!S*^DeVBl&-$LVd0VV`Kkv$9a*tk z<=SfXjTc)_?q!h9j_vogTdOwj@=c@8_rIo}x6NG@GvV9OwASd!Tdz&;4fF_0O8tGb zif2{$@^IFUrw`p#%rX=<`p$l`hu?e6?Cld?|G4|~(!ROX>uN8a-v7V)+SWgJ-dMg9 zT63oR>2uw}0_*M%66dR*J^g%kuJ-%&y=pVIUGm(Nw_tv4*uC%yVQt|X?k$^|-}ZeB zn#-Ery!CHV`JA;;>Q)@U9N)yrPM;pXjYZuu{W$aY z)4wa82<}_c@S)&aPx(8YkAJ_OtTdOkj!t@7Q~ymvH_USO(QegSykRESgs<-C%-daK z^f2C%>-mj`*}GJqSKN5>@yXdN-`OmuD<9ON#Z{K&Ui8vW9D)7zaw4CJc*oLAjb3gssoUXczIpJMQ z`TncFgwhX*dOtjL(o)Zi!|vbB?wy-6C-13SqsXKZ!KrL(b#>LrY4QCWx|8dF2tg@O%+Fr`P@9WGKRxkc z+1o#rq0&}`&sQAz7h4@7(S6sU{KbQJ&-*=#9Ir-y{hjeStv+sjvHJ7HAwoLye|*(A z#WpqW{^^@j-+q-n{OhZbd;heIX5H|kmeWq9txb9L>QflQ=U(%F+aqu9zW!>V%B#P( z6CO$b{!u(Q;5CcQWTBoD_e-seWYo$LH4$CqF&%t0djvo70~257d1ww7KYaET2E= z$HIG!H`c5_a((W^ziCh9i{jYNJk4DFJooal8c)WD57$_{3zyxUK5yc;%*Sna_P#&V zsv1`{^T!Wt$2)3a)38jz{^))?enMU)2AN4yX|!=Q&_}pxwTb)Q%5TIn$0$_V>E;d8^Ee^7~UQUWj#uN#4!=XxH3tw?q0-~Y z{bqaRa_+BCj1P0Tu_gcg``2@qv#!ovdsyFYdRfictmwyKNk=uZH_EN&oYKp?>E@f{ zcatO5?{kS}R2JJ_x@=OcgXN~!`0 ztLy#nZqk`Wes4F-|IYaKVAc27o150fuGi_A@i(z~+2@KW6}OCkRaQ0K3NqWM#rS;6 z)y&N5mBj*8dw3V~Zri?fq0Thj)wh>h{r_w7_xt6N+pk|93tRu@-|wGV%uTZrZqC}I zZ}a}`YTfIH7H->eQ#H!}!s?q{X1{9=)^u*0GC92Y2mjyL6`{BGt_&_Nv&jidPTBph z{I~4l*zZ*W|N3M<{XA!5e6jxK`aS9foYQ0qymRV)dM>)2tyKCZLw&_(!C3vdt>tgG z3jKe-qbFdq=_S33PURChgKu8mwEsdM_mAiEEgbt6>&9^@RB&EL_A6= zd$)LQc*3+nzexLdg7~8Ar>0M5-d>u0jkig)B0NTMV}D&^_|u6Y3vPUTeJiwY`S+=B z7>{_Z$kE+>EK1?ltM{(bKJzrbzH--Vd|VT6rhWIA(AR5acVDZkotW9!tYY_fif*b) zljzZXwZFf;y`9cE#kYQKz`^^>X_tLI%Zuix>4;~{wc1qbtlv33n`xT8y|}YL#L;JV z=BGc#dLLq~m=_TFlR5i-w8``r--R25{inRX*OsuO_J8Oq3*mKsQI&fW9Qz6cBKq&1 zkrevxA8jqZuqq9dFQ9>L$4ff&T86rrT0(v&C9CW zE~@75S(o!pJi6ubs~FoK3tU!b7hgKLN&eIvwT;Q{Kfk-npJZqV*!uea-?&H4x6aKi z-F9TzS(Sauo>uOO4>}wDjpcaNueE#kIo*CA>_7Ey!qWn)n0IqRM82JWKey)P&y9Pd z*GBuI#UGvK7P0YCy$e~ z4+!b(zI7Vnj<-EvlF%D1!Y=Y1}H z-L&z)d-l@u*NNU&%WQ4lR!vH6J&n}Ao;+M7UwVCu6M%mAyFJ&z6+ud+!n)q{KP_VKu0QWTPySmep8oUBy4zf`+tk+HKi2bc`|)#gqL0qMzA_-t?!H6p z#>a=xChnB`#P<5oAJ6F$H@2RhAHMc=bfV?+TMgS(`s3dOJ}^G7^8CfT>UG=e@2}pN z%pmmqaQ~l5+5guz6kl`Ash_$3_vK?@H*@m#hko4=yS;D5`){pZd-yYEww<+0UC}G` zqnL5prFB=tO9Lw9=6|oQj7|AkasSx7lh3yqmif-A_?@-e?(u1Ej$OLZe=6r5^W9U& znt8uVbn@Ei%ROx_J$JgijpdxDy6W?axRQ;FG~n`r--c~*jM?6dQ)O)@mZy&k3S zw4B~G!!A~MPSVMn^S9mjbb#^SzID2`55LZe{~z~?!{I{2OosKL>z}RBd4IL{@#kF` zr7u-Pr)+yaJ@N3Ly@lJRhVQ8p`TdVgNXK92!%BnYzWRI5EM9l__q(YXu_y9$ubj89 zX?e#l>yl|({kmkruiu4ya(iE@?R4<^RdW3D!oBwEKOcO?!_b(@I`eDQ*NTEowu&$A zoSePC{&ud=W7$`UoX^%etDL)BWI5Z+^7iM7>ECue%gVg|SL)9D@ZI~0Qg599y+r@p zoZ4l3ejC@n6IgR0>g=q}lOJwxoxFCYad8>rt%SEPTJO*44$Qx$aq%tdw+|6Nf7kx5 zEN)M}TyFnAW>I+Q@qPci?2db?e->q9nZJd9+l$W)jraE5Qnyx_S6Y^*zW2oMZSMW~ zdKdn2PL~xaOODxJx8`Wq)6!3wKbM%URt;PG>|JTjr5R_>`F|cZ)B zH0K}hOMbK=q;HOa{;$tgrdcOAr`$9tS6`rN5%%J&?rw(J+Y6!t!|UFe|K0hz>e%-x z^E(Rfudm)JR2}m?Hz`$2_n9^~$81UCzm;<@Z?%1QL9zVpuHM2;hFkK4wY_yTZejMK_(Vc|U-%}msjL%< zSAP|}@qG8+%Doen*D_?*yq)<~#kW>--;qOFyUlae-hK{`f4U}i`>(`p&*F8yWt3c5 zab(-;)-P_AM>y*HuFtt1{M3g(r%6?P##yV6*##+Uql9*s_P_sr%vS4SZmhs=2HlNa z|C!F*THq+OzwGDtb$iV=o`3g#r~9JoQ$MX;{l9l-O(dwDc=-F9&HwhS;yw26zWu)Y zyMOC-e$_Ad{y9wJcT(>4a+MYA&-x|`-Tk+>?Cp}+^4}ST(-Nzc<4!FRxl~b(Ws@I8tMiyj1Lp z-w&he`_4E0{8YLBpBA%&hwaBDF5CML6lEXb$XtJJ<(%5;YpbT-+i>sEyZ5&Oc%>gr z+~N4=(|10Z32WtSAN_v2yXekj)!z%Fw$4#qX8HAB)z3Yz?|Dx(wo&1{w&&-+xQ=ff z`M10$#-2XMUGnG054{6vXZPrR)UUrk?MdZR(enLQmwN9x|8DMP!R0R&$LxPqts6Ow zQDMuHxxXH9-~5yM6V^|zcyOy<9?-uu^Y)!gTaFAr8lJQB3i_lpgdm$du8XHLbmiklIun^>ER z7}M64=XY+rR6CWr7|&>v`(g<+8kr4Z{jYy;_;j{L-fVkf8LvfwUblT&ROd- zJ9uo#5$ri~YKQNdwtkPYq|_(1XJ#$!yvS3&-}IMU`tCgclsBF(n}k>Ix1W3N+LyYM z%IjJ8u)p@1`*-6{=FXp=*{jQMv0A)3mvGNADs~3{7K6-2iGGXq?^QpF&7B*uEoXz> z)k{k^?Uyz=!5~m^Zt2Nw`IBFi#xA`hwYqiY@2}j?{^k1A#0}POf{7}Y8)utN zUt5-|ns-evP`f%H{P?3k=^-1+Huu&_Ef;?!z5aA(if#P8V!Pt)s{DDEsv^^;b04ew zm40pMXTD3PlBU?-es^U~_i-i;<;>};u1{ENXZ8ALb4S_THZvay`8DPFn-8t^d;I45 z9Pb%FxBg#q=Ll#-ZD;@HyFO;w$E{1JWqg&&6{}dv%Ze^tHj0K+m-pDXG`W`uE zw}jK>e!@O)Z57-2*Jk@xzTLIfWm9SPp8kDvyf;Sf&XeUlYor>tVsamsDBrU>&U-gf zgx0jAe0je|_u{kzoZPQ(ZgO7~R(Igv-D_T34lX+Wa>21nR?=$z_X=w7eSG|cY0pM~ zHind&>u#?(Y#F7tEc0?fE!XRX|6@)&-MF#xKEK87(&|eI%~x}`mE4=K^|k&!jg6QIVvB7C}f~CHPx6L%2i4iM<*qELy?cn}!LGc@B!<*ZsuUBrLSAS{?%juX}qs!aY z-gi!HnwId?_o}lF`?u;^k@AgYOY`oXIVsO_IeuEjS5uWRhDX`g>;G22weQpp-;myv z&}b)>d*5zF=hXY3mK|r!>}I;Y{yghUpKWbn$IrzyFce*17rnDxP26+KM*k1jO>|e> zUA5Ji(e2)sT?*gbV8sCOqlj`7NNZS8- zZZBjVf0DQOT2L9!wCGPh`|Im(Ry|vZ|?GrcqSi)2m2>rD(C%9+>K@ABF8C5t^d+qAupZ;s~KN z6$ZNvHg<_jv_27hdV@ZLiu==3Z<<}KoKB}qS$|-k!ojZRPB!he4$SNg(&-o0O-@j~ zvWHd3Jg?*Z_cfn(O>OotJw4q!W|PIf`?C$5AN~3|Cz@f>;cHvE%dhR&8hwA+i=deI zFQvA8JhyAhudw%e&+jN5EOI@@wf5Rlo>igKD`NdSFJ9ZV`*~hx=_@armnogo4BcJmA#ymZBx^CkpvEI^aPm}vo|Nh>VQPRxzsXC1P>1q8PM;KI=$8O)% z{yf_{E&HKs_H?yZLa|%3y>&vPlB8pQm#vzn{39>k;@hEVxsz}* z{C#_`u71TC@A@b+RYfjXW#jxq?+$FsFTb~QO{8|=&7hw)@il_?>t5at-?rw>(I+QG zcvuDc%I<0%>PnSGxjbAe(XRqDy%7?qYo-qb> z6S*HRm%q80VZxcRyVG*23%ib-vA7;EXQi{=uCE1R5v~`6b&e&lw!~Qc{&Ftm&yhKQ zr*7n*9Kq-?;Z~{i;@>A0TmIJW?^EB%r7pC_Vbj)MckEto*L%osw(&iKLPt)(&fD(g z^0^bsZ0~uxad6$27i3~!SYlNLUzrbHj}9h?S(J|0BLHTB*TW+S2DFU=i0uJj76aNI z0WcSAHG&uljsS0-0Q(<7AOZo*A`lW-g98x=U=}ze9xVPZ&k(mm?dFH$zm|fo81r=X Kb6Mw<&;$UsM0?}_ literal 0 HcmV?d00001 diff --git a/files/images/firmware/rover_on.png b/files/images/firmware/rover_on.png new file mode 100644 index 0000000000000000000000000000000000000000..13123caeb0c05810819f996fb3ec2301fe7d5098 GIT binary patch literal 59171 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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 N22WQ%mvv4FO#twu5xD>W literal 0 HcmV?d00001 diff --git a/files/images/firmware/triy.png b/files/images/firmware/triy.png new file mode 100644 index 0000000000000000000000000000000000000000..16654b3c5a2560d3cb80a8982e2166e6bf66529d GIT binary patch literal 15037 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&4mJh`hRWK$QU(SF&H|6fVg?3oVGw3ym^DX& zfq_A?#5JNMI6tkVJh3R1!7(L2DOJHUH!(dmC^a#qvhZZ84FiLfm#2$kNX4x;b2)25 zuHO8AKK9wUSt*;^CuH0RbZEZX;8mNvbkh!#sI|AF#cO{5+nSegb30o4|j3AvljoSD1(&v|2&J%vT;oGEHEJ?rkDS67+I zXT^?je`_kGaPIjXiP#FgW}PyFRe zqNc|+HMiE)b~_8rd)V}Sc}lK@!6HRNt<`zgpMB!2Ok1V2?4zO3jf<-+Gh{AQY-l>> z&=$+%;}@Kwmt@q-eAmEU?(MYrH*-$RR*Y!Bp|FSXU4YBOoc(#bu7{MLkp9LN!78p1 ze?sB{_h+`W&Fi{)>FXTBdw|&HSnD z7sKyOmPfRH+_0EZ7%(Y0-S~&ajG2!ws4u&zqE{vwvnNAljn|cp6Ed1YPf0%w+^*wS zHM#qW@$IO}<`spt&O+-qciX&~Qlq~5`|I^Z+;5^HVig*9Oo?{tzLfLGLP|J0+v>)x zyZ>hF=M>k{iz_R;c_ieoLI0ZHA<4cIQ zW+`935$T$D%=fJ+Yu-;T4si*sA4mQcze~JxecepW(`M$~DnZSrYP*gdy2CX6n!uI& zeoHnQTxojxH0U;We}P-Y)Xl{iXeDDdX=&U2V-mtNuEc zL`THzYI>a)X;GkDI{75y-7h7q3Mbd9#M>Jg+`nG^XPHXy`3>Erk$f*r{spKW6YBW< zWbdtH;dH&bS9Ag`o&>1fzNlyUr?@ei>%U*X|L-e*AOE@V$nF=V|CU?KJ$tH@W#`e- z%6;B-c`BS?H]HU7V>t2U_qPvNe_&7bGyxb-Q^WG|Y+s^>9#$C278&!=cr8-{n6 zZ)sEeJTpm5eCtP*l~7xgw&B|P>p@!l-}!ERWBc;9%=1IR;fC+E!Dc?wj;>u26BYPpOJHfh zg?&l+8}1h-MXjhxa9gHku&r_bxtGp~xxCvFL`_+H%XfD4>`M9@w{v})~G0vbZ(8d*sZyI0{6M)d*Xff z?p);f%2#7ok|(#?vR8ZlU*%w`wmFu(XhyYdc`@Ux%{x6sm5(=xPWSOhH23+uDp&Dw zmC(J1Y7s~8wB9bbuHNgFznNp^oc)?7O@c%hp49C&|I{AF)7E`U%1BIe(S`}LPbL~J zjS%0tP=D^E?6~jm*%}`uY{iXrRlW=6 zD@$jU?dzU9<8{E!t*M`0N1xq)|HK3~#$O8}P4j+M#DCZ~zj)y*|2-Z;H^lVV!Z$nK z3v!!(S(CGTl6y&fYH(xWS%`=66Fx!AQm;j3m?$-)2D+SMM+l@sUBJa4qV_VTi) zALgh2+u6f??P}-6mTyyo-Aj*dJ9ngjrS{<3?`(F8XC5LiqwrsZ|Jg~8jTU!_tt~0)e|0|RzgEg84l&)UW^BDDpZtz;)aFqMD-n)h znqIxIEsJ~RY_Cmk1OK-*eW_-yvNQiW|L_Kui-&mj=<7aTbTsbPO*NO_%2N6-%RXiZ zZD-ljw&8i8)v2A@vobES{QIqI*XsXZ{eIhYTnEGOJ*!yYo zbbV!tr91)mUn*m zA=9qOdFDab)#G`ycbrHd*I%oQ}vWo^Ee3Z1c z<@byII|^dw%KVJE?!~mfqxi(;L4X zJU{zw*fGx5+I4nDy=ot3>}uOs!nxNhaL2q!XV=VI(tG5NYmLdxBV7;XzPmqV*8$&O z$)%TT8rHQ=o3Fg^W?T2wRL-n(&5p;GOKEEe_%587)1LA!>-vq$(X~!D?Xzy)-u;&; zckRQZscRBj(srwyS@OqowX3F(p_iSivYMi*6RdKSYTIbZ(r>dtPP1KLl`5U>a?7-1iYgF>4zc10MTf2O|^)=x| zY%dKr=j1MZ@QNoQQhC;jdu)-No!ZTngpyh zI((8T+$HgILY_pQxk=;Xz)PX^tF5%#`UZnOZSItU2!aa zWzhPmQ(Z+BGJ;DNafC_E%}F+$9gxTQy|DdlrpcyLbp zExfQ$P|o{x7k`G-jU0)*N&dk{{xAA0ux8Dg>1EqaPEt6s7KKVb&U<`SV!txCU1aP@_7x(zHYH(SCHhQ)@0M$8 zciZsoR(Y~nBIl;$hJ@a-lj>{MzT7!;vX|85m&Q3W)C0{{9urRSbaRr9xx2|jRKClg z$DJom&quX>Ge`fNyOmPH(#KRgUPKsJWggdh+U_;E`1I#X3&qw1z5C`7cJSM2^`%*? zd6gTO&M&#c9sTFN&BY7*Qd$4cT(j%a!HVQON4=#pFRz;TLdLSLUhjZ~oZ*zI??1M$ z*|ub^^)ctii6<3m*t%v;*k(&R}F*EgFmFUDI>q1|lrEZDK3R}}y=2l19h1_b|`tbPc+W8v;?>)}*+}Qsp zFY-g^?m1HDA611;VThQNtly&}?Nrz^DW_VJZ@q-&y9d8Z8Ke30oB0#8zMp-x`{Mo` z&Ue4B@IGm^ao<sO@*^i~RWi!e1AJ5t)cqe)K<#!2%Yo2&Not@rac2|5ShkJ7J zPtK&o>Gks4ui~ffzwudoSypZsv%lPY+w}#%678#lgr>H}?C^RlxbETP z&-49GmfuVNdgu7>rji9dFCBPhGVW}7*%jgP{O{L{1v2cBk@a2EBRYlGKIX)$9xV;{AR7T4IBIGqKzZoMjZ z*^*VSxBKR)iana!SH*F*%+mi?{nY>IsaXGs5w3r4zpcKXQ2+l+(#~Bk|1NHhI-Ra# zmuVilR&nvkEX7y%zcS9OPG#o0%Hy)3>&>Ku?OpM{-r-j)X6|?0wXp8P!9I4;S)RY% z?kWnbPW~J!)G5~O&pG3i%M>pE#2c@bZ*YUK{d6SAr z8Kc`j*KEkjzI*?zNwADg@7voq_HVndTzIfrQO=lK{M~x>=p3e{7S|loMJN0SkdA&D z7dZdH`P|OK(bFbL|2P-Ee@fNnRf`-KU0wH1m*;q6vQJ}l-Q_H2leuy`R7xcv{)eY1bvZ?k_NIwzeOxW<0YN!@qKd#*Whoi$KT z_TbO|;b3*`)NKXt#kwguUCr7R@1M=GKlyj-nl&qK>hSASY~M(ys)64n3K*XH|+wXUy7{!&rnTsz^@#!m)I z+RYUYpIM#ve&b8UH$r{>TaQL<*t12d!XR;C#zLX^1yOy@GnN!pExRkYyz}9O8+Vq7 zMb2&(Vx5(|@0UWSmu92~b8DRQ#5*r_jukGoSsr3~D|N5dD{jdf!4_vWb~YV<_3@m6 zW96E=j$W}6FP`kJxA_yC#r@9G{@8r|S3mwQ)BUrM-_k|s^Q?DMPHiw>kl+9HwNPfFh87H=<}F?)2}c1)Yh&s2uJi)~Y9gPPagl34nzW$|MDmiQ8Yd3?;V~0CLbUe3gPt<5kQN3)t z(rcoPVYRK}gsmw%zs=wlTRSDiddbI)b+Mt@xhD(!J5FY&R`xBpwyx`=yUQFd90JI>mv9nqBI3tZ}7*3=HH(*-O5&NedzPmPtrF03hgnz-@P_T zq9s;{Nh0~M{OTi#R}Ewh<=DMySwd1-mG8mcVt|g^toaCxi=ZSk<0X!XfeGFYER%T z*7$xwtI#6Fz`bY9`yjor-nR#LNnfw4oa}VFAjx1^MB*`>wCR_V_V)Ij`?N)7b$fNn zr@T|`E*lo9wqNY>l=*c;E3#;-oaHNZ!%9Q1`~|h4(Xap6wf^5VahoO2lH{e@mwZ+q zaTNMGi*K!vb5%vMOXR8LA1_E5rSYYFC|~jWTK2Ab-M8~=pI-J}5)m1$>Uw?Swg>Yn zuDsCtwaT^EJ0{1WNmSRe=e(I#_u;m9*P{8hdq3>|67lo>l;cjuSL5w1r~mwOKknGw zBe$GOg;g6xBUSl=^2EyLD@GiaIcu_Gc3ToIc%r()I32lI>G(R^!?B3w0%Y&i}}J-gu7&eXlp;i`|! zB!jmJckS=7mzS^L{XXHh`|p2?R6E7Q^&U*Sw3S^q%=q{}r>QQjI{Rm+S59__e%rKg zNzu86A`|v4UN@FVP1}5`?H9vZv13awsa@TobkXYZisgrTm!6nsC;fa*^1rMnOZ>F$ z^Ujp|eqN?`eNpFKhC4@sR((zW>atvv>!8%LCzeZ#@;tM{^b)5zpL(Be|0!svMA3h< zw{?2^&A<0IJ$+vHJ~cP#UB6lX>3Pwm&n}*SQLF0}c&1D3-OS{C9>$+_iXRcXi{;Y@Vma5`B&dj4R0sk_D=T6?A zsWV+8dHZj-3x|#No##8Rb2a7S#dRk%r*As9C~?avCC*P@qhH4bW+<0#nb|E>e(lHq z#K?Kd&9$QcAE&+3uD^M+%vZS!!F5fc;Cdhpg`M7@W>zeCzo*UJRp6~j8dR^UH?l;picJubOzx)4uL(k+x zjAdPsrMntGT4gWX;cRR_>)-a+peer{j^Cfk-bCtRoe3>?D`($I3X>&%KgTjN1NRb7<}!oblxlR^snZGpYEa5otQ@%Oh{pQ+U;(2GY?cY_I;$Cz9?Jc`^ZZG`3h+kT1t=_l9$Q_${3{u3xt|!dhp61{0RA&-# zny-BQ!@9qBSl%UX3Hf6*HR|4m;*~z8n-?8DkWu>SMbqhw=p&b7cI3Ud7I|t%#{LY| zTkGdpdCi}ZW}PnJBCW!3_3f?M+S|9Dt4xc|<_~{y-u^`I7mE{rqfh?6wx{>Lo#uD3 z0QKf=92R1*2^m$uls(@d${g%gO@I^#pS)OruP;} zy_;BK{db2(yoA+_IPzQF?Svn*2wH0I|2*3pdU> zBV;WXrNyPA8?>h5=Hl2bKR%psxSw!9EG%E_*rdlsH$U#|yI&X@JA=otqq$VrHSp%c z376I6wy&DyD)+YJWQ)kJRSyoCGCNluanOsr%pbQtaiSdi*Y^MBmRnCLZ}*%fD6_Zj z_THrWJN9;w`yK{u(o6F!*ry&jWA(nw`NEQ?-#+8(lU(5~#eIAC}p7h+|YTfS6&1!ZB?XpfKP5ftN*kNchL8bZI{N?>=_uo`^hQ5ipw*2>T z-BowXEZ;s-*>vIL<*mNVKs)$HZ>;R8eGUHtgud>q+u6A# zdY{4Df^R3pb#3P@zUsJKWsCC~w$|wkSvGZNC)&O~ zeYs&-DCPD* zJ1^BxTl@9P+_yQm61U3~{MUH+c|}uq`N>6(+xM)WJJV(1WajI)rHta@cCC!uv}xUs zCu>)>Rc5cbr=w=LW*xuWg|oZn|IJ>XwAHnB+7IJ5kG%47brrI^-K-Oy7-0OTTy>#qDMMa|%~#*q-!5}szxuUceOiCnrr-T%b38+j%<#Rl zQAFp|!H7-Eo%et2+5YXzi6YhVLQ`?wyC(7*IuCv2^IY(^jXBO#B4>x{&fin>Z+%wY z{F}3gId4u@@@j2=?*I4ZF9|l#;dsBxz_<3&{%v=K?Rx)wSYu>X_+{&xC)dAy`H>ve z6ZQ3Qf$5^jKd$ee^mS3T)t2r(U0=?;tl2YJ-Id9-xmse%C6|xcQ5BO|%4E%hr~CLMKJWjU^DN2KbXvaDXQ7jt zW*^_YUS4Io`cd5zr@%fgO@o=IVy4#5&{=zVk(B;RHS4#FN=qkQ{p{^!bW`rWxXvey zO%c;JFm^uu7Z@EhJLqi1PcD{~%g?7YGMBjTT> z`0A&r|5v15^s821{c39P=ZMnT$BO2DTK=-kP%qP`P*`VM{mx=`^V-X6rMfC|&uJ9b ztnz(e{^aGktA|@&E!eYoYVqgtEEDgER=2g6_Zj_oQ!zVSkbljWBa2&jC9G~WZ51zk z7sChs+OQo-}+t96FAD(wCmn78_s=!Gr)C=!$T@zK%3%EbM7m$pr* z(Tkciw?8ZXgv$5#yNxFuxzXQkb7<%LE1h|fXJ)<#U6*y;r`P=5uZ5dd?I^HQGkDmT zIy*Y%d#KsQ1&MB=+Ik`DzX!cubyIEUJR#THyDKw~|5;)1w?evH(AAEi>Q7?#|LASC z@3R+aoUptzcSqCzvk%Qq{`BXX?`Yh1=5KV;4{a{W!g}F4oTQ`p@~ij>?mF zcjWVZ?Ojl@MTMjP&en~A8*jB;J9_v2=>GWw&pdKjmFIlGohf@3*rrS=l;7U6 zJN(#f)4GqX>u(?0XTbYs>*vom*UFo=gbQd2)c^icQoAKO>lu?<>5^0Im;L=WcJkNW zT5(JBomj5g%jFSY8S;`Y1uV;2t3B(l_1!7KSEv6rSNz^HA@LQzYedN2Z^qMg^t!h- zI8PA$HhYo}SIqB>t8;nJ&N~!zD&cutz$sr*-lF_@LQA#(zPfQ{Z;j8BBfp)GMsL_v zY$3kB|A%X8;pXY4AL@5lYxsCww`^(H@QG)AdPN`p} zy)*vL>D+x2s$VV>v%HnKf`wIVzJ=lM1xHuyZaBW_l4i%-CsJ3U!aAFBr6NQ2uKhRh zceqj7LcvSc|K0{|T9LboudL{e_ZE&*S9j%Q&06^CO|c!H7~iCVsb;LbOYi)iS@!;z z+Qgsvz8l#|Q&4|Rt72jX4j@?vn$iD11>$~@x9v923nYsPM$@N#i{74pB zcUo=PtM=-YUh_}!I}>aqo81=2Ou8hyc47AMWjFkuiOENA+&cBES_n&I{eNri==T?T zrW!^lXdKN-a@tw{@alg3?|V*EZLT}{ceY{L!e^y@3yYafv0W11?ecnFZ*NfkA_p;B z)kM7qj}M3&Z7UD6?fA+fcW(WoclQ^G%rbFX+_&^D3uQD>Kt)yBId#^SP_H;?C!KU$4;0!!h!wbJ+@ng^&Mzo&8AR z`}>Z-=SF&Y`yW5rX5l969_e8I|Ic*U+^(x(>pdPSUGG-=aM)&3+~tLPkE`FAI(JcI zDaZTRE0%@vbKXz#|Fg|^^1OSmCTo~no*f_|$x~1KdZZ-uwParYtu5QE_P2-W|w0^J5IcPbnQW8;Vj3t)w3f`32mQuneqGjq~}2!w^!eL`cE?LMe*)AVaFa7 zco~%+ymwdn!sq;T885E7zOiFlp=0U$;Qr}Nr>A%=kV-RsfBp5&j;n4v->djl#{5Xr zTokb3zsy;M=-s=Uzm`Ahli*h`-!1N%GvONx|I&n3-@v-X)6#D&o&P6swg0=*JhD0& zX1k}JSNhBqn{~oKzR&&GyMi*|mpQi6CzZ1OuL)P3WqLw)$fB)RJD?FF|;lJ2Z zk79Zz?%~s8xgMywETgh}FXzdO?IQpDYRfmdzB&>f!;zUYQQ=+Q^~m}b!%MnL-t?@t%Nb<1bjt4f)xRG9EA{0tEc^e<*|2=$zZJ7{gnFCrB}F&8 zUT2!2vO#xlHFNuwRsJFefAtji1hMK9*TCGnPKqxo2_p?X6i01y&_K zP^)sT`t6>3aMvPp^LW*X7bZw4Rl^{DK^VQ#9cklSmb3S;WnR9}Ck4Gv0lkIIi z&wuh1nR~DK6?5{DS`}z;^6kOBt=ao_JhKi{?7YUWrf?ixO z-@kp1zU1HH^#Ab1bIii#bB#|OKO(E+C|)8IyP?WNrqu1-wzHxV(&t+al^#!>b6<3zk)slOzOx>nxABPVo~V>x!gNnt5abpS0IL;Q#$QOT?bp#G z)HhNRat<3N&0bg_++C`?qfuvOv*_w~j~v_Es$!GNZa&@Oy!QW-T<&+32NkQ+<(K?! zubnBNW8ie>$cBj84UZj{nisy&-+b);DXvTY78w^Gt$U$+$11wU;GO(76UPk)P812B z-VyQFGA!w8>=wS$Kl<5bKbdux|Mc=H+;58;1B&zV-^E8na*J=!{3)Jsr?gh=ojeP7 zkAnF`zmA9J_3Qh0H*6GHt>@LXj(57~G?(fvvj5}ie6@GBTI4_8?tg0U&iWAlzrTg^ z+JCbjWKzE9tFm!Z=egAUoPAnZcELIee2*C)|F@_;<8Ar>Iptxddvf2O{;RFItM6&G z_k(|q8xDAs2*3Q_<+I1|UQ()J)c^kfQAdwvElp!_Uw^-B{SEo={kyyBA6_pMy<^WI zCXtx8NNKsr%w_YwK6{qka!_FPyG2Lu$EPOE=k?i9 zFQ8-4bk}8(`N0nHFZb@7?UVl6GV9&D`Ds7idrim^U}$1(yX5QRvg?lhznS+7G$X|i z|7}iS+|kMD-tybsDYQ?m1U@PzHsE$xfW1V8x4$RXwtV?Hq{@-qK#$vgH82bnrw zt4#ve!ta8NvcU>oOrQPZ<+|mUs!wb6i+^5jC+AVz`!lxQKbTFKU2r=?M8LVDNs>qV z+m-}(c{S|+KRbhs0oSrJ&_XZRdNa^MFZg;h$|VjYC_WZz$au2UFa2mM_piU-x9Unq zuFZekc;EJ$jhS8gKga#+y-yZBc*o2kW+8DZ^<-qoggU4F|8D3lKl|wZvD)wrZW~Wl zrf=WMn*G1ZAb(BPTE^wNi@AIm6e1SfZ<_jYUdX-s_IVliH#M=GcB+y3@j9mKHfIuJ zQUn8d`5MSqpapbrUmawksf0qr4pxK(%A%6n8F(fr{n~VTWu;uT+-dK*bq_juzO$%x z^RfTGczXY=!qo>H1br?aiDme^bVsD=vz5ClrT$me^aY>#n!Rk>S#d6wlFPzBj|&+` zOba&S|9*qzS8e(3Z(HNdwT~~q74|v)^v`h7Jk5rL#)zP>yX#^nzMbF|9pYTEUT;Cj z8{Q4C%I04D{%=y2@XeIV|^ukqPy3-Z>TD)Kn}V}8h^Fi_B|nCHhk z>{mXj7Wcz6J&AF7sA>NR{sJ-WF zU9IZ&70>=AuJ*4>%hvwf+N1bWLG>ozwt}pvh#h}+RZb5VeDD65fkTYr@*1h_7OD@= zfqK32KNmfnaM!NOyYS%ebII|Auipf;_P4w?SDo4BEL67q_EBTWq!@-K(@l5x*D}_c zUZ1R-w=P5Ax3q)&+i5p@-u!L+oGIy*P_=CCC9xU)SFg4?tX`Cr%l@w{$j$MGb^ZJU zePL%E-#hB1xz=vD?^Jenib>hmiJ5Dzt^eP*yOaB3j)2ac)`{+!0p|DreC{**tvoyW zmk7VmN^kWg8-$Bwvld31?PRE(wW{Ow4%e@0x986axO!nOstZj{D?Z&H`#3$jy!?ZH{rva-k4~)BwLPp?cl7^zowgg- zI#@dwEA!}?*_WSuw5i(6%u7Ff>-U$_0&OzAb|w7?N%rjvRx*upWh$F6!8-ip|NE=X z-QVk;t|9*E`rdDSFC`z}Tk~#0b+P+Nt=$>1b4#)de@zMgG&eLx$NQmDpU(!Q!bIGoL>Kp8I-|Sv_>OM#o0{Ch zerHPe{5toiX4{h;K4QK+C%K}(Br;cj>7KTwAusO%zvyCD#fSun?$FIyXYBv3wGG-5 z!s_*|=FO3uZ@=HCvwN=Cq5Al3%+l`V++kNW+micEZ(Cpa_DbL_)jNNC*p^1!`Rcit z>0(ntW1?QzlQ7rf-5Q;r=P&QSwtT7f`dg}s`5c!xS8?6>6q8r@_rrem<=6I9z0$Cq zwbk{Sq6>EuYn$R)#pKT0YIEF@M0I!guDjuEys1eq(qj4LTau?1lv$RGyQkkcI(7BV zjENJRwlJ_{vp6u8c?#t1$%x&Xp&IstX_9KN)v2A`YqZ36OI&SuxM*tw%a?apy58*d4t2GL+l^4_uqdMtZ{y&`9?1W@eTS~JHMJw zUUML0QE7at@NMY}%P0Nrp4OhwsIvIldi|%&7V{@L{Z7bf>erEg&uBe^uPu|^& zxu~%8#*uiVBbyZ>6n4fOv{_yv%bT!TJzv)^{m;)>PnEFy8@J@mcow>r>En}ccE4P? zkG}oap~rBL$&-mULTX1?q4p*}zmw(LmS{ctqOy0-sbdTFJ=m@qIZcy4CGgTckEk36 z|AvIdBg;d~Z>nhV3v<3bzPoN!`0G2@CT*$y_$l^NvFxmkpSG*coW_~DWn#2o>u-rL zUd0H7jhS3h+SBv0rmYQ<$eTZJ-PV?#r#TXD4xTRZF!%A>Q~yXtax?GrmomnJI&C? z>mC%8_ODuXd#mY_Pi{_}n={P{Wp3AB&~8X*bUCQYExvy3%NHLlo@(z*X`IG$y8ZRm zV(sjUO`R*No;+5$r}F6jwoL8|&I%CG++3lO^V~?znfci zrT2f1i7w#J&iJi0J+N!Wvue$_Lyn7Tocf$M7jfI)6JK)N`(m&{gaYFOz4J@-XFJ=< zEmwZf-1f6b=KihM{HA%Y0;JzX{(jo~E!=Le%c`%gTw%J^>8Ewyte-#U^sCzWe`jz< z>vo@i_C)KfN%TswzyEh0ez#%j&-}dFYrjf4#8|jh8199*`fR>sZlUWO_<2syo*>CR zcQ*Z6v#j#4i1xy+CEh#iZhUNrHE$|hDR66%l&JBJP|tu_hyNZ=-Q=ydtmS*iDW=)I z>zEEQIs1P+*0$g&=ZeR{xm?|sUnz*M{siqOykGF|{YZGhRyhX>um7!<&kib`9Fx4s>0+otL_){Pudk0@?0XZ$ zyV=U`+SN^>icVdUMYwO}`beYxz%QOEG_3`Mz2F|MSIehAU=& zS$HVR{aJWy#=18%m#H0pv9wEO(uN;x{8Bpk$L7vAxis(8=bJuaZSFI5{n*Y4k)4NmtHzz2oV9V;|39&|sQ$IeRzi_|v^u~n7 zg^Mp4_?m6MAX>(3eOht0^!JrpCQ0f01|P!m}?%D?}t@XxiUVu73Atho{E5 z0EyI6{rh)>^j2@$Z0aKV*X!}ed5U`<-<0?Hx3x}V-NQ8>w;N5L6!|!4Q*v#Se_*=i zOu2&W$=mcp7wrZ`t8+EmZPVu3I|3=DclK2Md;K>$O-ni?eRGzKeE;{7TSj6xo?f~B z+%Iz7_v@FG3Y9l%dDtgTkM*GU zi|hOL_ZNnLaHtN_Y47@d^mT2l*R`2uC%-u`hz#6nEscVpQWs=Juh8o+U_ZDPX4J5%*!fV zd3c&#urbraN#--(d8XW)GP(VfO1VwGv*gkBHHwSf>+S50FEn1m!zayh*`!c>(wqf( zZ0D+%pOcHsYAf3GBm8K_cAI32`1-Z+|6i5Qo~6E5rf`DJ(kh$iS(lHv+A{A=sc4Y6 zX0X83^xh`BXQ%vU-dD}3c)w745p(d`e#_#^i;hUYP!!Oa;PAv^>GEeHJF0YEmcL!N zc=E#b*ITdu{+fExZ?9c?kNfkcztLX=IK(`3!Yox6?)|;eFxKXiE4OTOsjBq6^v|M& z8||9c84BI9Uom@Gzv6!`P%X-LH>U9A5s|di)IindTE@Q%AC{dBscqCb@s9QPt_TCe zQ0`aHa$iUu=4QFu&VR2V@7me;&F-Bt2SN@$nEUhRm&accQwpd2GW{&CzV_bT!?G&g zpHIF|U(M&az&U24D!Z7Nhr_Jdp^rbln<~94IwWH@*Ds~)_tQIY9<;FCX7k!~*16}B_cfL1 zUr<(vP&l}D&4fg|n%`ea?!G!XTU%;L$m|MJ??*~yB}oChVy)gU>tZ{-$Znph`wf0{O7|bKA53xOUs+Y^bR_SvWJNZlQL@^p=^NHWv;jxrQwa zov`<{m6yAv{nKlqhEcL&Vje+3qJ>tRlR|B}6%?cYcrKpH(%5vf^V?5r`^#=c%!@lk zkFHJYFEcCLsO8#y_z=^{^Nlz9r&_xPXdU=}?$ov0PRCwb`n^mt`=Xt5Z`p#6=B`QV zv0K)~^{jEa$eNqC@AC{EFM+v?;Q~#pZWA&BWiozt-pnbQwRY*}ir=BmUm{O8?fQA> z*RF=SeRH>a@w7%bZeVbE-5_ws%=Yera|~ALF2A>_ihZ_7RA{T z!N_rqLqsG!pD_=Rq&u@*n#<_A^?43{6o%SKE%UTi|CpK=sw|@OK z-?BevMR^xp%{)0VAW3a!Qi#Td)g4nlZ;3U&dCO+Gi(Yc^@(x$F*DKk?mr7Oa6b;ql z&M_0;qgh%P8y$RCadNhl?t*)=Q6d!yZp)T+9IDa_OE=8f-I&lg(S38)ouuh4yW{R$ zOsih<$2gxtSo8CTrucCIxHrraud85tq*PGq8_U>LNC*&%$Tz|Inw6CidMTSn< zR&X!Ef5JERq|>|&35|=EE!fz#yE=GUUe>f~?i2iKf(QQ_?Py?VV%-(|EVx(n?W~!b za*8)wgdB2p+FGzG{PT?#vF$qZ4i~tHHzYJ>1e95p3%`H+;E?OV0;|g9`}OWDbXup% zd39&9O{`O?a(xAB6tlwyhx&z6_rzZ|Onh4XXW{qPOxq&5#5=FNsY(BlGP^U=Y~`-l z=->y_rXN_uB%os;kg;@q5BJrnk$f*-h+P%9x0+jHx3$T(g?1-iRL3j1Y4>QFO+0&I zV|)F)Y3o*Gc4ZW0zYErj2{|>RXwQaE>RX$c4|?;lyx1hcUrex7Op#c zrEE*vtryQXYMS*2iydO!*|bYCC#ZMTwh0?EYgXmjzP8#Y$G{;b;na2G|6HTkqZ>A{ qgLYL?KA1&tT&yAG@qcauhWyV?OQlx}FJ@q1VDNPHb6Mw<&;$UqQXk3y literal 0 HcmV?d00001 diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 43423d7a50..8ac89950fa 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -262,8 +262,9 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/AdvParameterList.ui \ src/ui/configuration/ArduRoverPidConfig.ui \ src/ui/configuration/terminalconsole.ui \ - src/ui/configuration/SerialSettingsDialog.ui - + src/ui/configuration/SerialSettingsDialog.ui \ + src/ui/configuration/ApmFirmwareConfig.ui \ + src/ui/configuration/ApmFirmwareStatus.ui INCLUDEPATH += src \ src/ui \ src/ui/linechart \ @@ -453,7 +454,9 @@ HEADERS += src/MG.h \ src/ui/configuration/console.h \ src/ui/configuration/SerialSettingsDialog.h \ src/ui/configuration/terminalconsole.h \ - src/ui/configuration/ApmHighlighter.h + src/ui/configuration/ApmHighlighter.h \ + src/ui/configuration/ApmFirmwareConfig.h \ + src/ui/configuration/ApmFirmwareStatus.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -662,7 +665,9 @@ SOURCES += src/main.cc \ src/ui/configuration/terminalconsole.cpp \ src/ui/configuration/console.cpp \ src/ui/configuration/SerialSettingsDialog.cc \ - src/ui/configuration/ApmHighlighter.cc + src/ui/configuration/ApmHighlighter.cc \ + src/ui/configuration/ApmFirmwareConfig.cc \ + src/ui/configuration/ApmFirmwareStatus.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 2b356c0f28..8dc316a96a 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -119,6 +119,43 @@ files/images/devices/cameraGimalRoll1.png files/images/devices/cameraGimalYaw.png files/images/devices/Shutter.png + files/images/firmware/apmcopter.png + files/images/firmware/apmplane.png + files/images/firmware/apmrover.png + files/images/firmware/FW icons 2013+logos.ai + files/images/firmware/heli.png + files/images/firmware/heli_off.png + files/images/firmware/heli_on.png + files/images/firmware/hexa_off.png + files/images/firmware/hexa_on.png + files/images/firmware/hexaplus.png + files/images/firmware/hexax.png + files/images/firmware/hexay.png + files/images/firmware/octaplus.png + files/images/firmware/octax.png + files/images/firmware/octo_off.png + files/images/firmware/octo_on.png + files/images/firmware/octx.png + files/images/firmware/plane.png + files/images/firmware/plane_off.png + files/images/firmware/plane_on.png + files/images/firmware/quad_off.png + files/images/firmware/quad_on.png + files/images/firmware/quad_T_off.png + files/images/firmware/quad_T_on.png + files/images/firmware/quadplus.png + files/images/firmware/quadx.png + files/images/firmware/quady.png + files/images/firmware/rover.png + files/images/firmware/rover_off.png + files/images/firmware/rover_on.png + files/images/firmware/Tir_off.png + files/images/firmware/Tir_on.png + files/images/firmware/triy.png + files/images/firmware/X8.png + files/images/firmware/X8_on.png + files/images/firmware/Y6_off.png + files/images/firmware/Y6_on.png files/styles/Vera.ttf diff --git a/src/ui/configuration/ApmFirmwareConfig.cc b/src/ui/configuration/ApmFirmwareConfig.cc new file mode 100644 index 0000000000..ba713bbc8e --- /dev/null +++ b/src/ui/configuration/ApmFirmwareConfig.cc @@ -0,0 +1,412 @@ +#include "ApmFirmwareConfig.h" +#include +#include +#include +#include "LinkManager.h" +#include "LinkInterface.h" +#include "qserialport.h" +#include "qserialportinfo.h" +#include "SerialLink.h" +ApmFirmwareConfig::ApmFirmwareConfig(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); + firmwareStatus = 0; + m_betaFirmwareChecked = false; + m_tempFirmwareFile=0; + // + + //QNetworkRequest req(QUrl("https://raw.github.com/diydrones/binary/master/Firmware/firmware2.xml")); + + + + m_networkManager = new QNetworkAccessManager(this); + + connect(ui.roverPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); + connect(ui.planePushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); + connect(ui.copterPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); + connect(ui.hexaPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); + connect(ui.octaQuadPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); + connect(ui.octaPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); + connect(ui.quadPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); + connect(ui.triPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); + connect(ui.y6PushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); + requestFirmwares(false); + connect(ui.betaFirmwareButton,SIGNAL(clicked()),this,SLOT(betaFirmwareButtonClicked())); +} +void ApmFirmwareConfig::requestFirmwares(bool beta) +{ + + if (!beta) + { + QNetworkReply *reply1 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-heli/git-version.txt"))); + QNetworkReply *reply2 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-quad/git-version.txt"))); + QNetworkReply *reply3 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-hexa/git-version.txt"))); + QNetworkReply *reply4 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-octa/git-version.txt"))); + QNetworkReply *reply5 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-octa-quad/git-version.txt"))); + QNetworkReply *reply6 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-tri/git-version.txt"))); + QNetworkReply *reply7 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-y6/git-version.txt"))); + QNetworkReply *reply8 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Plane/stable/apm2/git-version.txt"))); + QNetworkReply *reply9 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Rover/stable/apm2/git-version.txt"))); + + m_buttonToUrlMap[ui.roverPushButton] = "http://firmware.diydrones.com/Rover/stable/apm2/APMrover2.hex"; + m_buttonToUrlMap[ui.planePushButton] = "http://firmware.diydrones.com/Plane/stable/apm2/ArduPlane.hex"; + m_buttonToUrlMap[ui.copterPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-heli/ArduCopter.hex"; + m_buttonToUrlMap[ui.hexaPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-hexa/ArduCopter.hex"; + m_buttonToUrlMap[ui.octaQuadPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-octa-quad/ArduCopter.hex"; + m_buttonToUrlMap[ui.octaPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-octa/ArduCopter.hex"; + m_buttonToUrlMap[ui.quadPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-quad/ArduCopter.hex"; + m_buttonToUrlMap[ui.triPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-tri/ArduCopter.hex"; + m_buttonToUrlMap[ui.y6PushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-y6/ArduCopter.hex"; + + //http://firmware.diydrones.com/Plane/stable/apm2/ArduPlane.hex + connect(reply1,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply1,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply2,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply2,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply3,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply3,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply4,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply4,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply5,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply5,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply6,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply6,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply7,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply7,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply8,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply8,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply9,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply9,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + qDebug() << "Getting Stable firmware..."; + } + else + { + QNetworkReply *reply1 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-heli/git-version.txt"))); + QNetworkReply *reply2 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-quad/git-version.txt"))); + QNetworkReply *reply3 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-hexa/git-version.txt"))); + QNetworkReply *reply4 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-octa/git-version.txt"))); + QNetworkReply *reply5 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-octa-quad/git-version.txt"))); + QNetworkReply *reply6 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-tri/git-version.txt"))); + QNetworkReply *reply7 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-y6/git-version.txt"))); + QNetworkReply *reply8 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Plane/beta/apm2/git-version.txt"))); + QNetworkReply *reply9 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Rover/beta/apm2/git-version.txt"))); + + m_buttonToUrlMap[ui.roverPushButton] = "http://firmware.diydrones.com/Rover/beta/apm2/APMrover2.hex"; + m_buttonToUrlMap[ui.planePushButton] = "http://firmware.diydrones.com/Plane/beta/apm2/ArduPlane.hex"; + m_buttonToUrlMap[ui.copterPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-heli/ArduCopter.hex"; + m_buttonToUrlMap[ui.hexaPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-hexa/ArduCopter.hex"; + m_buttonToUrlMap[ui.octaQuadPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-octa-quad/ArduCopter.hex"; + m_buttonToUrlMap[ui.octaPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-octa/ArduCopter.hex"; + m_buttonToUrlMap[ui.quadPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-quad/ArduCopter.hex"; + m_buttonToUrlMap[ui.triPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-tri/ArduCopter.hex"; + m_buttonToUrlMap[ui.y6PushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-y6/ArduCopter.hex"; + + //http://firmware.diydrones.com/Plane/stable/apm2/ArduPlane.hex + connect(reply1,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply1,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply2,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply2,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply3,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply3,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply4,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply4,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply5,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply5,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply6,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply6,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply7,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply7,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply8,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply8,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply9,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply9,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + qDebug() << "Getting Beta firmware..."; + } +} + +void ApmFirmwareConfig::betaFirmwareButtonClicked() +{ + if (!m_betaFirmwareChecked) + { + m_betaFirmwareChecked = true; + requestFirmwares(true); + } + else + { + m_betaFirmwareChecked = false; + requestFirmwares(false); + } +} +void ApmFirmwareConfig::firmwareProcessFinished(int status) +{ + QProcess *proc = qobject_cast(sender()); + if (!proc) + { + return; + } + //qDebug() << "Error:" << proc->errorString(); + //qDebug() << "Upload finished!" << QString::number(status); + m_tempFirmwareFile->deleteLater(); //This will remove the temporary file. + m_tempFirmwareFile = 0; + +} +void ApmFirmwareConfig::firmwareProcessReadyRead() +{ + QProcess *proc = qobject_cast(sender()); + if (!proc) + { + return; + } + QString error = proc->readAllStandardError() + proc->readAllStandardOutput(); + if (error.contains("Writing")) + { + firmwareStatus->resetProgress(); + } + else if (error.contains("Reading")) + { + firmwareStatus->resetProgress(); + } + if (error.startsWith("#")) + { + firmwareStatus->progressTick(); + } + else + { + firmwareStatus->passMessage(error); + } + qDebug() << "E:" << error; + //qDebug() << "AVR Output:" << proc->readAllStandardOutput(); + //qDebug() << "AVR Output:" << proc->readAllStandardError(); +} + +void ApmFirmwareConfig::downloadFinished() +{ + qDebug() << "Download finished, burning firmware"; + QNetworkReply *reply = qobject_cast(sender()); + if (!reply) + { + return; + } + QByteArray hex = reply->readAll(); + m_tempFirmwareFile = new QTemporaryFile(); + m_tempFirmwareFile->open(); + m_tempFirmwareFile->write(hex); + m_tempFirmwareFile->flush(); + m_tempFirmwareFile->close(); + //tempfirmware.fileName() + QProcess *process = new QProcess(this); + connect(process,SIGNAL(finished(int)),this,SLOT(firmwareProcessFinished(int))); + connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(firmwareProcessReadyRead())); + connect(process,SIGNAL(readyReadStandardError()),this,SLOT(firmwareProcessReadyRead())); + connect(process,SIGNAL(error(QProcess::ProcessError)),this,SLOT(firmwareProcessError(QProcess::ProcessError))); + QList portList = QSerialPortInfo::availablePorts(); + + + foreach (const QSerialPortInfo &info, portList) + { + qDebug() << "PortName : " << info.portName() + << "Description : " << info.description(); + qDebug() << "Manufacturer: " << info.manufacturer(); + + + } + + //info.manufacturer() == "Arduino LLC (www.arduino.cc)" + //info.description() == "%mega2560.name%" + bool foundconnected = false; + QString detectedcomport = "COM4"; + for (int i=0;igetLinks().size();i++) + { + if (LinkManager::instance()->getLinks()[i]->isConnected()) + { + //This is likely the serial link we want. + SerialLink *link = qobject_cast(LinkManager::instance()->getLinks()[i]); + if (!link) + { + qDebug() << "Eror, trying to program over a non serial link. This should not happen"; + return; + } + detectedcomport = link->getPortName(); + link->requestReset(); + foundconnected = true; + link->disconnect(); + link->wait(1000); // Wait 1 second for it to disconnect. + } + } + if (!foundconnected) + { + QMessageBox::information(0,"Error","You must be connected to a MAV over serial link to flash firmware"); + return; + } + qDebug() << "Attempting to reset port"; + + QSerialPort port; + + port.setPortName(detectedcomport); + port.open(QIODevice::ReadWrite); + port.setDataTerminalReady(true); + port.waitForBytesWritten(250); + port.setDataTerminalReady(false); + port.close(); + + firmwareStatus->setStatus("Burning"); +#ifdef Q_OS_WIN + process->start("avrdude/avrdude.exe",QStringList() << "-Cavrdude/avrdude.conf" << "-pm2560" << "-cstk500" << QString("-P").append(detectedcomport) << QString("-Uflash:w:").append(m_tempFirmwareFile->fileName()).append(":i")); +#else + process->start("avrdude",QStringList() << "-Cavrdude/avrdude.conf" << "-pm2560" << "-cstk500" << QString("-P").append(detectedcomport) << QString("-Uflash:w:").append(m_tempFirmwareFile->fileName()).append(":i")); +#endif +} +void ApmFirmwareConfig::firmwareProcessError(QProcess::ProcessError error) +{ + qDebug() << "Error:" << error; +} + +void ApmFirmwareConfig::burnButtonClicked() +{ + QPushButton *senderbtn = qobject_cast(sender()); + if (m_buttonToUrlMap.contains(senderbtn)) + { + qDebug() << "Go download:" << m_buttonToUrlMap[senderbtn]; + QNetworkReply *reply = m_networkManager->get(QNetworkRequest(QUrl(m_buttonToUrlMap[senderbtn]))); + //http://firmware.diydrones.com/Plane/stable/apm2/ArduPlane.hex + connect(reply,SIGNAL(finished()),this,SLOT(downloadFinished())); + + connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + firmwareStatus = new ApmFirmwareStatus(); + firmwareStatus->show(); + firmwareStatus->setStatus("Downloading"); + } +} + +void ApmFirmwareConfig::firmwareListError(QNetworkReply::NetworkError error) +{ + QNetworkReply *reply = qobject_cast(sender()); + qDebug() << "Error!" << reply->errorString(); +} +bool ApmFirmwareConfig::stripVersionFromGitReply(QString url, QString reply,QString type,QString stable,QString *out) +{ + if (url.contains(type) && url.contains("git-version.txt") && url.contains(stable)) + { + QString version = reply.mid(reply.indexOf("APMVERSION:")+12).replace("\n","").replace("\r","").trimmed(); + *out = version; + return true; + } + return false; + +} + +void ApmFirmwareConfig::firmwareListFinished() +{ + QNetworkReply *reply = qobject_cast(sender()); + QString replystr = reply->readAll(); + QString outstr = ""; + if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-heli",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) + { + ui.copterLabel->setText(outstr); + return; + } + if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-quad",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) + { + ui.quadLabel->setText(outstr); + return; + } + if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-hexa",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) + { + ui.hexaLabel->setText(outstr); + return; + } + if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-octa",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) + { + ui.octaLabel->setText(outstr); + return; + } + if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-octa-quad",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) + { + ui.octaQuadLabel->setText(outstr); + return; + } + if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-tri",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) + { + ui.triLabel->setText(outstr); + return; + } + if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-y6",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) + { + ui.y6Label->setText(outstr); + return; + } + if (stripVersionFromGitReply(reply->url().toString(),replystr,"Plane",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) + { + ui.planeLabel->setText(outstr); + return; + } + if (stripVersionFromGitReply(reply->url().toString(),replystr,"Rover",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) + { + ui.roverLabel->setText(outstr); + return; + } + //qDebug() << replystr; + /* + QXmlStreamReader xml(replystr); + while (!xml.atEnd()) + { + if (xml.name() == "options" && xml.isStartElement()) + { + xml.readNext(); + while (xml.name() != "options") + { + if (xml.name() == "Firmware" && xml.isStartElement()) + { + xml.readNext(); + FirmwareDef def; + while (xml.name() != "Firmware") + { + if (xml.name() == "url" && xml.isStartElement()) + { + xml.readNext(); + def.url = xml.text().toString(); + } + else if (xml.name() == "url2560" && xml.isStartElement()) + { + xml.readNext(); + def.url2560 = xml.text().toString(); + } + else if (xml.name() == "url2560-2" && xml.isStartElement()) + { + xml.readNext(); + def.url25602 = xml.text().toString(); + } + else if (xml.name() == "urlpx4" && xml.isStartElement()) + { + xml.readNext(); + def.urlpx4 = xml.text().toString(); + } + else if (xml.name() == "name" && xml.isStartElement()) + { + xml.readNext(); + def.name = xml.text().toString(); + } + else if (xml.name() == "desc" && xml.isStartElement()) + { + xml.readNext(); + def.desc = xml.text().toString(); + } + else if (xml.name() == "format_version" && xml.isStartElement()) + { + xml.readNext(); + def.version = xml.text().toString().toInt(); + } + + xml.readNext(); + } + } + xml.readNext(); + } + } + xml.readNext(); + }*/ +} + +ApmFirmwareConfig::~ApmFirmwareConfig() +{ +} diff --git a/src/ui/configuration/ApmFirmwareConfig.h b/src/ui/configuration/ApmFirmwareConfig.h new file mode 100644 index 0000000000..aca500a3ff --- /dev/null +++ b/src/ui/configuration/ApmFirmwareConfig.h @@ -0,0 +1,55 @@ +#ifndef APMFIRMWARECONFIG_H +#define APMFIRMWARECONFIG_H + +#include +#include +#include +#include +#include +#include +#include +#include "qserialport.h" +#include "ui_ApmFirmwareConfig.h" +#include "ApmFirmwareStatus.h" + +class ApmFirmwareConfig : public QWidget +{ + Q_OBJECT + +public: + explicit ApmFirmwareConfig(QWidget *parent = 0); + ~ApmFirmwareConfig(); +private slots: + void firmwareListFinished(); + void firmwareListError(QNetworkReply::NetworkError error); + void burnButtonClicked(); + void betaFirmwareButtonClicked(); + void downloadFinished(); + void firmwareProcessFinished(int status); + void firmwareProcessReadyRead(); + void firmwareProcessError(QProcess::ProcessError error); +private: + ApmFirmwareStatus *firmwareStatus; + QTemporaryFile *m_tempFirmwareFile; + QNetworkAccessManager *m_networkManager; + void requestFirmwares(bool beta); + bool stripVersionFromGitReply(QString url,QString reply,QString type,QString stable,QString *out); + bool m_betaFirmwareChecked; + QMap m_buttonToUrlMap; + Ui::ApmFirmwareConfig ui; + class FirmwareDef + { + public: + QString url; + QString url2560; + QString url25602; + QString urlpx4; + QString type; + QString name; + QString desc; + int version; + }; + QList m_firmwareList; +}; + +#endif // APMFIRMWARECONFIG_H diff --git a/src/ui/configuration/ApmFirmwareConfig.ui b/src/ui/configuration/ApmFirmwareConfig.ui new file mode 100644 index 0000000000..b6640b6263 --- /dev/null +++ b/src/ui/configuration/ApmFirmwareConfig.ui @@ -0,0 +1,446 @@ + + + ApmFirmwareConfig + + + + 0 + 0 + 958 + 497 + + + + Form + + + + + 10 + 20 + 91 + 31 + + + + <h2>Firmware</h2> + + + + + + 30 + 60 + 801 + 371 + + + + + + + + + + 150 + 150 + + + + + 150 + 150 + + + + + + + + :/files/images/firmware/heli.png:/files/images/firmware/heli.png + + + + 150 + 150 + + + + + + + + ArduCopter vX.XX + + + Qt::AlignCenter + + + + + + + + + + + + 150 + 150 + + + + + 150 + 150 + + + + + + + + :/files/images/firmware/quadplus.png:/files/images/firmware/quadplus.png + + + + 150 + 150 + + + + + + + + ArduCopter vX.XX + + + Qt::AlignCenter + + + + + + + + + + + + 150 + 150 + + + + + 150 + 150 + + + + + + + + :/files/images/firmware/plane.png:/files/images/firmware/plane.png + + + + 150 + 150 + + + + + + + + ArduPlane vX.XX + + + Qt::AlignCenter + + + + + + + + + + + + 150 + 150 + + + + + 150 + 150 + + + + + + + + :/files/images/firmware/triy.png:/files/images/firmware/triy.png + + + + 150 + 150 + + + + + + + + ArduCopter vX.XX + + + Qt::AlignCenter + + + + + + + + + + + + 150 + 150 + + + + + 150 + 150 + + + + + + + + :/files/images/firmware/hexay.png:/files/images/firmware/hexay.png + + + + 150 + 150 + + + + + + + + ArduCopter vX.XX + + + Qt::AlignCenter + + + + + + + + + + + + 150 + 150 + + + + + 150 + 150 + + + + + + + + :/files/images/firmware/rover.png:/files/images/firmware/rover.png + + + + 150 + 150 + + + + + + + + ArduRover vX.XX + + + Qt::AlignCenter + + + + + + + + + + + + 150 + 150 + + + + + 150 + 150 + + + + + + + + :/files/images/firmware/octaplus.png:/files/images/firmware/octaplus.png + + + + 150 + 150 + + + + + + + + ArduCopter vX.XX + + + Qt::AlignCenter + + + + + + + + + + + + 150 + 150 + + + + + 150 + 150 + + + + + + + + :/files/images/firmware/octx.png:/files/images/firmware/octx.png + + + + 150 + 150 + + + + + + + + ArduCopter vX.XX + + + Qt::AlignCenter + + + + + + + + + + + + 150 + 150 + + + + + 150 + 150 + + + + + + + + :/files/images/firmware/hexaplus.png:/files/images/firmware/hexaplus.png + + + + 150 + 150 + + + + + + + + ArduCopter vX.XX + + + Qt::AlignCenter + + + + + + + + + + + 760 + 440 + 91 + 23 + + + + Beta firmwares + + + + + + + + diff --git a/src/ui/configuration/ApmFirmwareStatus.cc b/src/ui/configuration/ApmFirmwareStatus.cc new file mode 100644 index 0000000000..aec009f4ec --- /dev/null +++ b/src/ui/configuration/ApmFirmwareStatus.cc @@ -0,0 +1,30 @@ +#include "ApmFirmwareStatus.h" + + +ApmFirmwareStatus::ApmFirmwareStatus(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); + ui.progressBar->setMaximum(50); +} + +ApmFirmwareStatus::~ApmFirmwareStatus() +{ +} +void ApmFirmwareStatus::passMessage(QString msg) +{ + ui.textBrowser->append(msg); +} +void ApmFirmwareStatus::setStatus(QString message) +{ + ui.label->setText("

" + message + "

"); +} + +void ApmFirmwareStatus::resetProgress() +{ + ui.progressBar->setValue(0); +} + +void ApmFirmwareStatus::progressTick() +{ + ui.progressBar->setValue(ui.progressBar->value()+1); +} diff --git a/src/ui/configuration/ApmFirmwareStatus.h b/src/ui/configuration/ApmFirmwareStatus.h new file mode 100644 index 0000000000..6334692201 --- /dev/null +++ b/src/ui/configuration/ApmFirmwareStatus.h @@ -0,0 +1,23 @@ +#ifndef APMFIRMWARESTATUS_H +#define APMFIRMWARESTATUS_H + +#include +#include "ui_ApmFirmwareStatus.h" + +class ApmFirmwareStatus : public QWidget +{ + Q_OBJECT + +public: + explicit ApmFirmwareStatus(QWidget *parent = 0); + ~ApmFirmwareStatus(); + void passMessage(QString msg); + void setStatus(QString message); + void resetProgress(); + void progressTick(); + +private: + Ui::ApmFirmwareStatus ui; +}; + +#endif // APMFIRMWARESTATUS_H diff --git a/src/ui/configuration/ApmFirmwareStatus.ui b/src/ui/configuration/ApmFirmwareStatus.ui new file mode 100644 index 0000000000..a9a09fc8ed --- /dev/null +++ b/src/ui/configuration/ApmFirmwareStatus.ui @@ -0,0 +1,68 @@ + + + ApmFirmwareStatus + + + + 0 + 0 + 889 + 313 + + + + Form + + + + + 390 + 110 + 75 + 23 + + + + Close + + + + + + 10 + 150 + 871 + 141 + + + + + + + 20 + 20 + 291 + 31 + + + + <h2>Status</h2> + + + + + + 10 + 70 + 851 + 23 + + + + 0 + + + + + + diff --git a/src/ui/configuration/ApmHardwareConfig.cc b/src/ui/configuration/ApmHardwareConfig.cc index 225f6a1f2b..f576e6fa07 100644 --- a/src/ui/configuration/ApmHardwareConfig.cc +++ b/src/ui/configuration/ApmHardwareConfig.cc @@ -60,9 +60,9 @@ ApmHardwareConfig::ApmHardwareConfig(QWidget *parent) : QWidget(parent) connect(ui.frameTypeButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); - QWidget *widget = new QWidget(this); - ui.stackedWidget->addWidget(widget); //Firmware placeholder. - m_buttonToConfigWidgetMap[ui.firmwareButton] = widget; + m_apmFirmwareConfig = new ApmFirmwareConfig(this); + ui.stackedWidget->addWidget(m_apmFirmwareConfig); //Firmware placeholder. + m_buttonToConfigWidgetMap[ui.firmwareButton] = m_apmFirmwareConfig; connect(ui.firmwareButton,SIGNAL(clicked()),this,SLOT(activateStackedWidget())); m_frameConfig = new FrameTypeConfig(this); diff --git a/src/ui/configuration/ApmHardwareConfig.h b/src/ui/configuration/ApmHardwareConfig.h index aea82cde73..8dc6876d2d 100644 --- a/src/ui/configuration/ApmHardwareConfig.h +++ b/src/ui/configuration/ApmHardwareConfig.h @@ -49,6 +49,7 @@ This file is part of the QGROUNDCONTROL project #include "CameraGimbalConfig.h" #include "AntennaTrackerConfig.h" #include "ApmPlaneLevel.h" +#include "ApmFirmwareConfig.h" class ApmHardwareConfig : public QWidget { @@ -63,6 +64,7 @@ private: AccelCalibrationConfig *m_accelConfig; RadioCalibrationConfig *m_radioConfig; + ApmFirmwareConfig *m_apmFirmwareConfig; Radio3DRConfig *m_radio3drConfig; BatteryMonitorConfig *m_batteryConfig; SonarConfig *m_sonarConfig; -- GitLab From 09cc683c2795569cd3abca3563438336855ad7f9 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Mon, 29 Jul 2013 15:29:14 -0400 Subject: [PATCH 097/460] More changes for a better looking and functioning ApmFirmwareConfig screen --- qgroundcontrol.pro | 9 +- src/ui/configuration/ApmFirmwareConfig.cc | 480 ++++++++++++---------- src/ui/configuration/ApmFirmwareConfig.h | 12 +- src/ui/configuration/ApmFirmwareConfig.ui | 67 ++- src/ui/configuration/ApmFirmwareStatus.cc | 30 -- src/ui/configuration/ApmFirmwareStatus.h | 23 -- src/ui/configuration/ApmFirmwareStatus.ui | 68 --- 7 files changed, 342 insertions(+), 347 deletions(-) delete mode 100644 src/ui/configuration/ApmFirmwareStatus.cc delete mode 100644 src/ui/configuration/ApmFirmwareStatus.h delete mode 100644 src/ui/configuration/ApmFirmwareStatus.ui diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 8ac89950fa..ea7265e23f 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -263,8 +263,7 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/ArduRoverPidConfig.ui \ src/ui/configuration/terminalconsole.ui \ src/ui/configuration/SerialSettingsDialog.ui \ - src/ui/configuration/ApmFirmwareConfig.ui \ - src/ui/configuration/ApmFirmwareStatus.ui + src/ui/configuration/ApmFirmwareConfig.ui INCLUDEPATH += src \ src/ui \ src/ui/linechart \ @@ -455,8 +454,7 @@ HEADERS += src/MG.h \ src/ui/configuration/SerialSettingsDialog.h \ src/ui/configuration/terminalconsole.h \ src/ui/configuration/ApmHighlighter.h \ - src/ui/configuration/ApmFirmwareConfig.h \ - src/ui/configuration/ApmFirmwareStatus.h + src/ui/configuration/ApmFirmwareConfig.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -666,8 +664,7 @@ SOURCES += src/main.cc \ src/ui/configuration/console.cpp \ src/ui/configuration/SerialSettingsDialog.cc \ src/ui/configuration/ApmHighlighter.cc \ - src/ui/configuration/ApmFirmwareConfig.cc \ - src/ui/configuration/ApmFirmwareStatus.cc + src/ui/configuration/ApmFirmwareConfig.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/configuration/ApmFirmwareConfig.cc b/src/ui/configuration/ApmFirmwareConfig.cc index ba713bbc8e..ed3b526dab 100644 --- a/src/ui/configuration/ApmFirmwareConfig.cc +++ b/src/ui/configuration/ApmFirmwareConfig.cc @@ -1,16 +1,15 @@ -#include "ApmFirmwareConfig.h" -#include -#include -#include #include "LinkManager.h" #include "LinkInterface.h" #include "qserialport.h" #include "qserialportinfo.h" #include "SerialLink.h" + +#include "ApmFirmwareConfig.h" + ApmFirmwareConfig::ApmFirmwareConfig(QWidget *parent) : QWidget(parent) { ui.setupUi(this); - firmwareStatus = 0; + //firmwareStatus = 0; m_betaFirmwareChecked = false; m_tempFirmwareFile=0; // @@ -30,111 +29,122 @@ ApmFirmwareConfig::ApmFirmwareConfig(QWidget *parent) : QWidget(parent) connect(ui.quadPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); connect(ui.triPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); connect(ui.y6PushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); - requestFirmwares(false); - connect(ui.betaFirmwareButton,SIGNAL(clicked()),this,SLOT(betaFirmwareButtonClicked())); + requestFirmwares(); + connect(ui.betaFirmwareButton,SIGNAL(clicked(bool)),this,SLOT(betaFirmwareButtonClicked(bool))); + + ui.progressBar->setMaximum(100); + ui.progressBar->setValue(0); + ui.progressBar->setVisible(false); + + ui.textBrowser->setVisible(false); + connect(ui.showOutputCheckBox,SIGNAL(clicked(bool)),ui.textBrowser,SLOT(setShown(bool))); } -void ApmFirmwareConfig::requestFirmwares(bool beta) + + +void ApmFirmwareConfig::requestBetaFirmwares() { + m_betaFirmwareChecked = true; + QNetworkReply *reply1 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-heli/git-version.txt"))); + QNetworkReply *reply2 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-quad/git-version.txt"))); + QNetworkReply *reply3 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-hexa/git-version.txt"))); + QNetworkReply *reply4 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-octa/git-version.txt"))); + QNetworkReply *reply5 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-octa-quad/git-version.txt"))); + QNetworkReply *reply6 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-tri/git-version.txt"))); + QNetworkReply *reply7 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-y6/git-version.txt"))); + QNetworkReply *reply8 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Plane/beta/apm2/git-version.txt"))); + QNetworkReply *reply9 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Rover/beta/apm2/git-version.txt"))); - if (!beta) - { - QNetworkReply *reply1 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-heli/git-version.txt"))); - QNetworkReply *reply2 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-quad/git-version.txt"))); - QNetworkReply *reply3 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-hexa/git-version.txt"))); - QNetworkReply *reply4 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-octa/git-version.txt"))); - QNetworkReply *reply5 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-octa-quad/git-version.txt"))); - QNetworkReply *reply6 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-tri/git-version.txt"))); - QNetworkReply *reply7 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-y6/git-version.txt"))); - QNetworkReply *reply8 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Plane/stable/apm2/git-version.txt"))); - QNetworkReply *reply9 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Rover/stable/apm2/git-version.txt"))); - - m_buttonToUrlMap[ui.roverPushButton] = "http://firmware.diydrones.com/Rover/stable/apm2/APMrover2.hex"; - m_buttonToUrlMap[ui.planePushButton] = "http://firmware.diydrones.com/Plane/stable/apm2/ArduPlane.hex"; - m_buttonToUrlMap[ui.copterPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-heli/ArduCopter.hex"; - m_buttonToUrlMap[ui.hexaPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-hexa/ArduCopter.hex"; - m_buttonToUrlMap[ui.octaQuadPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-octa-quad/ArduCopter.hex"; - m_buttonToUrlMap[ui.octaPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-octa/ArduCopter.hex"; - m_buttonToUrlMap[ui.quadPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-quad/ArduCopter.hex"; - m_buttonToUrlMap[ui.triPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-tri/ArduCopter.hex"; - m_buttonToUrlMap[ui.y6PushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-y6/ArduCopter.hex"; + m_buttonToUrlMap[ui.roverPushButton] = "http://firmware.diydrones.com/Rover/beta/apm2/APMrover2.hex"; + m_buttonToUrlMap[ui.planePushButton] = "http://firmware.diydrones.com/Plane/beta/apm2/ArduPlane.hex"; + m_buttonToUrlMap[ui.copterPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-heli/ArduCopter.hex"; + m_buttonToUrlMap[ui.hexaPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-hexa/ArduCopter.hex"; + m_buttonToUrlMap[ui.octaQuadPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-octa-quad/ArduCopter.hex"; + m_buttonToUrlMap[ui.octaPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-octa/ArduCopter.hex"; + m_buttonToUrlMap[ui.quadPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-quad/ArduCopter.hex"; + m_buttonToUrlMap[ui.triPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-tri/ArduCopter.hex"; + m_buttonToUrlMap[ui.y6PushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-y6/ArduCopter.hex"; - //http://firmware.diydrones.com/Plane/stable/apm2/ArduPlane.hex - connect(reply1,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply1,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply2,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply2,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply3,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply3,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply4,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply4,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply5,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply5,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply6,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply6,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply7,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply7,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply8,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply8,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply9,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply9,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - qDebug() << "Getting Stable firmware..."; - } - else - { - QNetworkReply *reply1 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-heli/git-version.txt"))); - QNetworkReply *reply2 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-quad/git-version.txt"))); - QNetworkReply *reply3 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-hexa/git-version.txt"))); - QNetworkReply *reply4 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-octa/git-version.txt"))); - QNetworkReply *reply5 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-octa-quad/git-version.txt"))); - QNetworkReply *reply6 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-tri/git-version.txt"))); - QNetworkReply *reply7 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-y6/git-version.txt"))); - QNetworkReply *reply8 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Plane/beta/apm2/git-version.txt"))); - QNetworkReply *reply9 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Rover/beta/apm2/git-version.txt"))); - - m_buttonToUrlMap[ui.roverPushButton] = "http://firmware.diydrones.com/Rover/beta/apm2/APMrover2.hex"; - m_buttonToUrlMap[ui.planePushButton] = "http://firmware.diydrones.com/Plane/beta/apm2/ArduPlane.hex"; - m_buttonToUrlMap[ui.copterPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-heli/ArduCopter.hex"; - m_buttonToUrlMap[ui.hexaPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-hexa/ArduCopter.hex"; - m_buttonToUrlMap[ui.octaQuadPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-octa-quad/ArduCopter.hex"; - m_buttonToUrlMap[ui.octaPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-octa/ArduCopter.hex"; - m_buttonToUrlMap[ui.quadPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-quad/ArduCopter.hex"; - m_buttonToUrlMap[ui.triPushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-tri/ArduCopter.hex"; - m_buttonToUrlMap[ui.y6PushButton] = "http://firmware.diydrones.com/Copter/beta/apm2-y6/ArduCopter.hex"; + //http://firmware.diydrones.com/Plane/stable/apm2/ArduPlane.hex + connect(reply1,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply1,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply2,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply2,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply3,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply3,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply4,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply4,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply5,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply5,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply6,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply6,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply7,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply7,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply8,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply8,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply9,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply9,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + qDebug() << "Getting Beta firmware..."; +} - //http://firmware.diydrones.com/Plane/stable/apm2/ArduPlane.hex - connect(reply1,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply1,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply2,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply2,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply3,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply3,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply4,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply4,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply5,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply5,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply6,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply6,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply7,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply7,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply8,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply8,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - connect(reply9,SIGNAL(finished()),this,SLOT(firmwareListFinished())); - connect(reply9,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - qDebug() << "Getting Beta firmware..."; - } +void ApmFirmwareConfig::requestFirmwares() +{ + m_betaFirmwareChecked = false; + QNetworkReply *reply1 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-heli/git-version.txt"))); + QNetworkReply *reply2 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-quad/git-version.txt"))); + QNetworkReply *reply3 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-hexa/git-version.txt"))); + QNetworkReply *reply4 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-octa/git-version.txt"))); + QNetworkReply *reply5 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-octa-quad/git-version.txt"))); + QNetworkReply *reply6 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-tri/git-version.txt"))); + QNetworkReply *reply7 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-y6/git-version.txt"))); + QNetworkReply *reply8 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Plane/stable/apm2/git-version.txt"))); + QNetworkReply *reply9 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Rover/stable/apm2/git-version.txt"))); + + m_buttonToUrlMap[ui.roverPushButton] = "http://firmware.diydrones.com/Rover/stable/apm2/APMrover2.hex"; + m_buttonToUrlMap[ui.planePushButton] = "http://firmware.diydrones.com/Plane/stable/apm2/ArduPlane.hex"; + m_buttonToUrlMap[ui.copterPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-heli/ArduCopter.hex"; + m_buttonToUrlMap[ui.hexaPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-hexa/ArduCopter.hex"; + m_buttonToUrlMap[ui.octaQuadPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-octa-quad/ArduCopter.hex"; + m_buttonToUrlMap[ui.octaPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-octa/ArduCopter.hex"; + m_buttonToUrlMap[ui.quadPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-quad/ArduCopter.hex"; + m_buttonToUrlMap[ui.triPushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-tri/ArduCopter.hex"; + m_buttonToUrlMap[ui.y6PushButton] = "http://firmware.diydrones.com/Copter/stable/apm2-y6/ArduCopter.hex"; + + //http://firmware.diydrones.com/Plane/stable/apm2/ArduPlane.hex + connect(reply1,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply1,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply2,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply2,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply3,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply3,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply4,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply4,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply5,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply5,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply6,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply6,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply7,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply7,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply8,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply8,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + connect(reply9,SIGNAL(finished()),this,SLOT(firmwareListFinished())); + connect(reply9,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); + qDebug() << "Getting Stable firmware..."; } -void ApmFirmwareConfig::betaFirmwareButtonClicked() +void ApmFirmwareConfig::betaFirmwareButtonClicked(bool betafirmwareenabled) { - if (!m_betaFirmwareChecked) + if (betafirmwareenabled) { - m_betaFirmwareChecked = true; - requestFirmwares(true); + QMessageBox::information(0,"Warning","Beta firmwares are from the latest trunk. Use at your own risk!!"); + ui.label->setText("

Beta Firmware

"); + ui.betaFirmwareButton->setText("Stable Firmware"); + requestBetaFirmwares(); } else { - m_betaFirmwareChecked = false; - requestFirmwares(false); + ui.label->setText("

Firmware

"); + ui.betaFirmwareButton->setText("Beta Firmware"); + requestFirmwares(); } } void ApmFirmwareConfig::firmwareProcessFinished(int status) @@ -144,7 +154,26 @@ void ApmFirmwareConfig::firmwareProcessFinished(int status) { return; } - //qDebug() << "Error:" << proc->errorString(); + if (status != 0) + { + //Error of some kind + QMessageBox::information(0,"Error","An error has occured during the upload process. See window for details"); + ui.textBrowser->setVisible(true); + ui.showOutputCheckBox->setChecked(true); + ui.textBrowser->setPlainText(ui.textBrowser->toPlainText().append("\n\nERROR!!\n" + proc->errorString())); + QScrollBar *sb = ui.textBrowser->verticalScrollBar(); + if (sb) + { + sb->setValue(sb->maximum()); + } + ui.statusLabel->setText("Error during upload"); + } + else + { + //Ensure we're reading 100% + ui.progressBar->setValue(100); + ui.statusLabel->setText("Upload complete"); + } //qDebug() << "Upload finished!" << QString::number(status); m_tempFirmwareFile->deleteLater(); //This will remove the temporary file. m_tempFirmwareFile = 0; @@ -157,24 +186,38 @@ void ApmFirmwareConfig::firmwareProcessReadyRead() { return; } - QString error = proc->readAllStandardError() + proc->readAllStandardOutput(); - if (error.contains("Writing")) + QString output = proc->readAllStandardError() + proc->readAllStandardOutput(); + if (output.contains("Writing")) { - firmwareStatus->resetProgress(); + //firmwareStatus->resetProgress(); + ui.progressBar->setValue(0); } - else if (error.contains("Reading")) + else if (output.contains("Reading")) { - firmwareStatus->resetProgress(); + ui.progressBar->setValue(50); } - if (error.startsWith("#")) + if (output.startsWith("#")) { - firmwareStatus->progressTick(); + ui.progressBar->setValue(ui.progressBar->value()+1); + + ui.textBrowser->setPlainText(ui.textBrowser->toPlainText().append(output)); + QScrollBar *sb = ui.textBrowser->verticalScrollBar(); + if (sb) + { + sb->setValue(sb->maximum()); + } } else { - firmwareStatus->passMessage(error); + ui.textBrowser->setPlainText(ui.textBrowser->toPlainText().append(output + "\n")); + QScrollBar *sb = ui.textBrowser->verticalScrollBar(); + if (sb) + { + sb->setValue(sb->maximum()); + } } - qDebug() << "E:" << error; + + qDebug() << "E:" << output; //qDebug() << "AVR Output:" << proc->readAllStandardOutput(); //qDebug() << "AVR Output:" << proc->readAllStandardError(); } @@ -213,68 +256,78 @@ void ApmFirmwareConfig::downloadFinished() //info.manufacturer() == "Arduino LLC (www.arduino.cc)" //info.description() == "%mega2560.name%" - bool foundconnected = false; - QString detectedcomport = "COM4"; - for (int i=0;igetLinks().size();i++) - { - if (LinkManager::instance()->getLinks()[i]->isConnected()) - { - //This is likely the serial link we want. - SerialLink *link = qobject_cast(LinkManager::instance()->getLinks()[i]); - if (!link) - { - qDebug() << "Eror, trying to program over a non serial link. This should not happen"; - return; - } - detectedcomport = link->getPortName(); - link->requestReset(); - foundconnected = true; - link->disconnect(); - link->wait(1000); // Wait 1 second for it to disconnect. - } - } - if (!foundconnected) - { - QMessageBox::information(0,"Error","You must be connected to a MAV over serial link to flash firmware"); - return; - } + qDebug() << "Attempting to reset port"; QSerialPort port; - port.setPortName(detectedcomport); + port.setPortName(m_detectedComPort); port.open(QIODevice::ReadWrite); port.setDataTerminalReady(true); port.waitForBytesWritten(250); port.setDataTerminalReady(false); port.close(); - firmwareStatus->setStatus("Burning"); + ui.statusLabel->setText("Burning"); #ifdef Q_OS_WIN - process->start("avrdude/avrdude.exe",QStringList() << "-Cavrdude/avrdude.conf" << "-pm2560" << "-cstk500" << QString("-P").append(detectedcomport) << QString("-Uflash:w:").append(m_tempFirmwareFile->fileName()).append(":i")); + process->start("avrdude/avrdude.exe",QStringList() << "-Cavrdude/avrdude.conf" << "-pm2560" << "-cstk500" << QString("-P").append(m_detectedComPort) << QString("-Uflash:w:").append(m_tempFirmwareFile->fileName()).append(":i")); #else - process->start("avrdude",QStringList() << "-Cavrdude/avrdude.conf" << "-pm2560" << "-cstk500" << QString("-P").append(detectedcomport) << QString("-Uflash:w:").append(m_tempFirmwareFile->fileName()).append(":i")); + process->start("avrdude",QStringList() << "-Cavrdude/avrdude.conf" << "-pm2560" << "-cstk500" << QString("-P").append(m_detectedComPort) << QString("-Uflash:w:").append(m_tempFirmwareFile->fileName()).append(":i")); #endif } void ApmFirmwareConfig::firmwareProcessError(QProcess::ProcessError error) { qDebug() << "Error:" << error; } +void ApmFirmwareConfig::firmwareDownloadProgress(qint64 received,qint64 total) +{ + ui.progressBar->setValue( 100.0 * ((double)received/(double)total)); +} void ApmFirmwareConfig::burnButtonClicked() { QPushButton *senderbtn = qobject_cast(sender()); if (m_buttonToUrlMap.contains(senderbtn)) { + bool foundconnected = false; + for (int i=0;igetLinks().size();i++) + { + if (LinkManager::instance()->getLinks()[i]->isConnected()) + { + //This is likely the serial link we want. + SerialLink *link = qobject_cast(LinkManager::instance()->getLinks()[i]); + if (!link) + { + qDebug() << "Eror, trying to program over a non serial link. This should not happen"; + return; + } + if (!(QMessageBox::question(this,"WARNING","You are about to upload new firmware to your board. This will disconnect you if you are currently connected. Be sure the MAV is on the ground, and connected over USB/Serial link.\n\nDo you wish to proceed?",QMessageBox::Yes,QMessageBox::No) == QMessageBox::Yes)) + { + return; + } + + m_detectedComPort = link->getPortName(); + link->requestReset(); + foundconnected = true; + link->disconnect(); + link->wait(1000); // Wait 1 second for it to disconnect. + } + } + if (!foundconnected) + { + QMessageBox::information(0,"Error","You must be connected to a MAV over serial link to flash firmware. Please connect to a MAV then try again"); + return; + } + qDebug() << "Go download:" << m_buttonToUrlMap[senderbtn]; QNetworkReply *reply = m_networkManager->get(QNetworkRequest(QUrl(m_buttonToUrlMap[senderbtn]))); //http://firmware.diydrones.com/Plane/stable/apm2/ArduPlane.hex connect(reply,SIGNAL(finished()),this,SLOT(downloadFinished())); connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); - firmwareStatus = new ApmFirmwareStatus(); - firmwareStatus->show(); - firmwareStatus->setStatus("Downloading"); + connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(firmwareDownloadProgress(qint64,qint64))); + ui.statusLabel->setText("Downloading"); + ui.progressBar->setVisible(true); } } @@ -302,109 +355,114 @@ void ApmFirmwareConfig::firmwareListFinished() QString outstr = ""; if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-heli",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.copterLabel->setText(outstr); + if (m_betaFirmwareChecked) + { + ui.copterLabel->setText("BETA " + outstr); + } + else + { + ui.copterLabel->setText(outstr); + } return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-quad",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.quadLabel->setText(outstr); + if (m_betaFirmwareChecked) + { + ui.quadLabel->setText("BETA " + outstr); + } + else + { + ui.quadLabel->setText(outstr); + } return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-hexa",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.hexaLabel->setText(outstr); + if (m_betaFirmwareChecked) + { + ui.hexaLabel->setText("BETA " + outstr); + } + else + { + ui.hexaLabel->setText(outstr); + } return; } - if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-octa",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) + if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-octa-quad",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.octaLabel->setText(outstr); + if (m_betaFirmwareChecked) + { + ui.octaQuadLabel->setText("BETA " + outstr); + } + else + { + ui.octaQuadLabel->setText(outstr); + } return; } - if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-octa-quad",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) + if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-octa",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.octaQuadLabel->setText(outstr); + if (m_betaFirmwareChecked) + { + ui.octaLabel->setText("BETA " + outstr); + } + else + { + ui.octaLabel->setText(outstr); + } return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-tri",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.triLabel->setText(outstr); + if (m_betaFirmwareChecked) + { + ui.triLabel->setText("BETA " + outstr); + } + else + { + ui.triLabel->setText(outstr); + } return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-y6",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.y6Label->setText(outstr); + if (m_betaFirmwareChecked) + { + ui.y6Label->setText("BETA " + outstr); + } + else + { + ui.y6Label->setText(outstr); + } return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"Plane",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.planeLabel->setText(outstr); + if (m_betaFirmwareChecked) + { + ui.planeLabel->setText("BETA " + outstr); + } + else + { + ui.planeLabel->setText(outstr); + } return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"Rover",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.roverLabel->setText(outstr); - return; - } - //qDebug() << replystr; - /* - QXmlStreamReader xml(replystr); - while (!xml.atEnd()) - { - if (xml.name() == "options" && xml.isStartElement()) + if (m_betaFirmwareChecked) { - xml.readNext(); - while (xml.name() != "options") - { - if (xml.name() == "Firmware" && xml.isStartElement()) - { - xml.readNext(); - FirmwareDef def; - while (xml.name() != "Firmware") - { - if (xml.name() == "url" && xml.isStartElement()) - { - xml.readNext(); - def.url = xml.text().toString(); - } - else if (xml.name() == "url2560" && xml.isStartElement()) - { - xml.readNext(); - def.url2560 = xml.text().toString(); - } - else if (xml.name() == "url2560-2" && xml.isStartElement()) - { - xml.readNext(); - def.url25602 = xml.text().toString(); - } - else if (xml.name() == "urlpx4" && xml.isStartElement()) - { - xml.readNext(); - def.urlpx4 = xml.text().toString(); - } - else if (xml.name() == "name" && xml.isStartElement()) - { - xml.readNext(); - def.name = xml.text().toString(); - } - else if (xml.name() == "desc" && xml.isStartElement()) - { - xml.readNext(); - def.desc = xml.text().toString(); - } - else if (xml.name() == "format_version" && xml.isStartElement()) - { - xml.readNext(); - def.version = xml.text().toString().toInt(); - } - - xml.readNext(); - } - } - xml.readNext(); - } + ui.roverLabel->setText("BETA " + outstr); + } + else + { + ui.roverLabel->setText(outstr); } - xml.readNext(); - }*/ + return; + } + qDebug() << "Match not found for:" << reply->url(); + qDebug() << "Git version line:" << replystr; } ApmFirmwareConfig::~ApmFirmwareConfig() diff --git a/src/ui/configuration/ApmFirmwareConfig.h b/src/ui/configuration/ApmFirmwareConfig.h index aca500a3ff..bc1bf0964e 100644 --- a/src/ui/configuration/ApmFirmwareConfig.h +++ b/src/ui/configuration/ApmFirmwareConfig.h @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #include "qserialport.h" #include "ui_ApmFirmwareConfig.h" #include "ApmFirmwareStatus.h" @@ -23,16 +26,19 @@ private slots: void firmwareListFinished(); void firmwareListError(QNetworkReply::NetworkError error); void burnButtonClicked(); - void betaFirmwareButtonClicked(); + void betaFirmwareButtonClicked(bool betafirmwareenabled); void downloadFinished(); void firmwareProcessFinished(int status); void firmwareProcessReadyRead(); void firmwareProcessError(QProcess::ProcessError error); + void firmwareDownloadProgress(qint64 received,qint64 total); private: - ApmFirmwareStatus *firmwareStatus; + //ApmFirmwareStatus *firmwareStatus; + QString m_detectedComPort; QTemporaryFile *m_tempFirmwareFile; QNetworkAccessManager *m_networkManager; - void requestFirmwares(bool beta); + void requestFirmwares(); + void requestBetaFirmwares(); bool stripVersionFromGitReply(QString url,QString reply,QString type,QString stable,QString *out); bool m_betaFirmwareChecked; QMap m_buttonToUrlMap; diff --git a/src/ui/configuration/ApmFirmwareConfig.ui b/src/ui/configuration/ApmFirmwareConfig.ui index b6640b6263..b49f8318c8 100644 --- a/src/ui/configuration/ApmFirmwareConfig.ui +++ b/src/ui/configuration/ApmFirmwareConfig.ui @@ -6,8 +6,8 @@ 0 0 - 958 - 497 + 868 + 661 @@ -18,7 +18,7 @@ 10 20 - 91 + 211 31 @@ -428,14 +428,69 @@ - 760 + 700 440 - 91 + 131 23 - Beta firmwares + Beta firmware + + + true + + + false + + + + + + 50 + 470 + 791 + 23 + + + + 24 + + + + + + 60 + 500 + 741 + 151 + + + + + + + 600 + 440 + 101 + 17 + + + + Show Output + + + + + + 60 + 440 + 141 + 21 + + + + Status diff --git a/src/ui/configuration/ApmFirmwareStatus.cc b/src/ui/configuration/ApmFirmwareStatus.cc deleted file mode 100644 index aec009f4ec..0000000000 --- a/src/ui/configuration/ApmFirmwareStatus.cc +++ /dev/null @@ -1,30 +0,0 @@ -#include "ApmFirmwareStatus.h" - - -ApmFirmwareStatus::ApmFirmwareStatus(QWidget *parent) : QWidget(parent) -{ - ui.setupUi(this); - ui.progressBar->setMaximum(50); -} - -ApmFirmwareStatus::~ApmFirmwareStatus() -{ -} -void ApmFirmwareStatus::passMessage(QString msg) -{ - ui.textBrowser->append(msg); -} -void ApmFirmwareStatus::setStatus(QString message) -{ - ui.label->setText("

" + message + "

"); -} - -void ApmFirmwareStatus::resetProgress() -{ - ui.progressBar->setValue(0); -} - -void ApmFirmwareStatus::progressTick() -{ - ui.progressBar->setValue(ui.progressBar->value()+1); -} diff --git a/src/ui/configuration/ApmFirmwareStatus.h b/src/ui/configuration/ApmFirmwareStatus.h deleted file mode 100644 index 6334692201..0000000000 --- a/src/ui/configuration/ApmFirmwareStatus.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef APMFIRMWARESTATUS_H -#define APMFIRMWARESTATUS_H - -#include -#include "ui_ApmFirmwareStatus.h" - -class ApmFirmwareStatus : public QWidget -{ - Q_OBJECT - -public: - explicit ApmFirmwareStatus(QWidget *parent = 0); - ~ApmFirmwareStatus(); - void passMessage(QString msg); - void setStatus(QString message); - void resetProgress(); - void progressTick(); - -private: - Ui::ApmFirmwareStatus ui; -}; - -#endif // APMFIRMWARESTATUS_H diff --git a/src/ui/configuration/ApmFirmwareStatus.ui b/src/ui/configuration/ApmFirmwareStatus.ui deleted file mode 100644 index a9a09fc8ed..0000000000 --- a/src/ui/configuration/ApmFirmwareStatus.ui +++ /dev/null @@ -1,68 +0,0 @@ - - - ApmFirmwareStatus - - - - 0 - 0 - 889 - 313 - - - - Form - - - - - 390 - 110 - 75 - 23 - - - - Close - - - - - - 10 - 150 - 871 - 141 - - - - - - - 20 - 20 - 291 - 31 - - - - <h2>Status</h2> - - - - - - 10 - 70 - 851 - 23 - - - - 0 - - - - - - -- GitLab From 31d632f5be962b460768e7e04c11db47103ef495 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Mon, 29 Jul 2013 16:24:47 -0400 Subject: [PATCH 098/460] Slight change for compile error --- src/ui/configuration/ApmFirmwareConfig.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ui/configuration/ApmFirmwareConfig.h b/src/ui/configuration/ApmFirmwareConfig.h index bc1bf0964e..ae0a533758 100644 --- a/src/ui/configuration/ApmFirmwareConfig.h +++ b/src/ui/configuration/ApmFirmwareConfig.h @@ -11,9 +11,10 @@ #include #include #include +#include + #include "qserialport.h" #include "ui_ApmFirmwareConfig.h" -#include "ApmFirmwareStatus.h" class ApmFirmwareConfig : public QWidget { -- GitLab From d86262ee831797383dc03e748b5b4705001e948a Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Mon, 29 Jul 2013 15:19:10 -0700 Subject: [PATCH 099/460] Fixes firmware flashing on OSX --- src/ui/configuration/ApmFirmwareConfig.cc | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/ui/configuration/ApmFirmwareConfig.cc b/src/ui/configuration/ApmFirmwareConfig.cc index ed3b526dab..e9e996efdf 100644 --- a/src/ui/configuration/ApmFirmwareConfig.cc +++ b/src/ui/configuration/ApmFirmwareConfig.cc @@ -269,11 +269,26 @@ void ApmFirmwareConfig::downloadFinished() port.close(); ui.statusLabel->setText("Burning"); + QString avrdudeExecutable; + QStringList stringList; + #ifdef Q_OS_WIN - process->start("avrdude/avrdude.exe",QStringList() << "-Cavrdude/avrdude.conf" << "-pm2560" << "-cstk500" << QString("-P").append(m_detectedComPort) << QString("-Uflash:w:").append(m_tempFirmwareFile->fileName()).append(":i")); -#else - process->start("avrdude",QStringList() << "-Cavrdude/avrdude.conf" << "-pm2560" << "-cstk500" << QString("-P").append(m_detectedComPort) << QString("-Uflash:w:").append(m_tempFirmwareFile->fileName()).append(":i")); + stringList = QStringList() << "-Cavrdude/avrdude.conf" << "-pm2560" + << "-cstk500" << QString("-P").append(m_detectedComPort) + << QString("-Uflash:w:").append(m_tempFirmwareFile->fileName()).append(":i"); + + avrdudeExecutable = "avrdude/avrdude.exe"; #endif +#ifdef Q_OS_MAC + stringList = QStringList() << "-v" << "-pm2560" + << "-cstk500" << QString("-P/dev/cu.").append(m_detectedComPort) + << QString("-Uflash:w:").append(m_tempFirmwareFile->fileName()).append(":i"); + avrdudeExecutable = "/usr/local/CrossPack-AVR/bin/avrdude"; +#endif + + // Start the Flashing + qDebug() << avrdudeExecutable << stringList; + process->start(avrdudeExecutable,stringList); } void ApmFirmwareConfig::firmwareProcessError(QProcess::ProcessError error) { -- GitLab From d8229281bd12d97a84e92842ab95a70dea4ee298 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Mon, 29 Jul 2013 21:44:43 -0700 Subject: [PATCH 100/460] Terminal Console: Added APM mode to send reset and send the break to enable the CLI on connect --- src/ui/configuration/terminalconsole.cpp | 40 ++++++++++++++++++++++-- src/ui/configuration/terminalconsole.h | 5 +++ src/ui/configuration/terminalconsole.ui | 12 +------ 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/ui/configuration/terminalconsole.cpp b/src/ui/configuration/terminalconsole.cpp index e3d890d7b5..919c646671 100644 --- a/src/ui/configuration/terminalconsole.cpp +++ b/src/ui/configuration/terminalconsole.cpp @@ -50,7 +50,8 @@ This file is part of the APM_PLANNER project TerminalConsole::TerminalConsole(QWidget *parent) : QWidget(parent), - ui(new Ui::TerminalConsole) + ui(new Ui::TerminalConsole), + m_consoleMode(APM) { ui->setupUi(this); @@ -71,6 +72,7 @@ TerminalConsole::TerminalConsole(QWidget *parent) : ui->disconnectButton->setEnabled(false); ui->settingsButton->setEnabled(true); + addBaudComboBoxConfig(); fillPortsInfo(*ui->linkComboBox); @@ -82,12 +84,18 @@ TerminalConsole::TerminalConsole(QWidget *parent) : ui->linkComboBox->setCurrentIndex(0); } - //setUiControls(m_settingsDialog); + addConsoleModesComboBoxConfig(); initConnections(); } void TerminalConsole::addBaudComboBoxConfig() +{ + ui->consoleModeBox->addItem(QLatin1String("APM"), APM); + ui->consoleModeBox->addItem(QLatin1String("PX4"), PX4); +} + +void TerminalConsole::addConsoleModesComboBoxConfig() { ui->baudComboBox->addItem(QLatin1String("115200"), QSerialPort::Baud115200); ui->baudComboBox->addItem(QLatin1String("57600"), QSerialPort::Baud57600); @@ -147,6 +155,8 @@ void TerminalConsole::openSerialPort(const SerialSettings &settings) qDebug() << "Open Terminal Console Serial Port"; writeSettings(); // Save last successful connection + sendResetCommand(); + } else { m_serial->close(); QMessageBox::critical(this, tr("Error"), m_serial->errorString()); @@ -170,6 +180,15 @@ void TerminalConsole::closeSerialPort() m_statusBar->showMessage(tr("Disconnected")); } +void TerminalConsole::sendResetCommand() +{ + if (m_serial->isOpen()) { + m_serial->setDataTerminalReady(true); + m_serial->waitForBytesWritten(250); + m_serial->setDataTerminalReady(false); + } +} + void TerminalConsole::writeData(const QByteArray &data) { // qDebug() << "writeData:" << data; @@ -181,6 +200,23 @@ void TerminalConsole::readData() QByteArray data = m_serial->readAll(); // qDebug() << "readData:" << data; m_console->putData(data); + + switch(m_consoleMode) + { + case APM: // APM + // On reset, send the break sequence and display help + if (data.contains("ENTER 3")) { + m_serial->write("\r\r\r"); + m_serial->waitForBytesWritten(10); + m_serial->write("HELP\r"); + } + break; + case PX4: + // Do nothing + default: + qDebug() << "Mode not yet implemented"; + } + } void TerminalConsole::handleError(QSerialPort::SerialPortError error) diff --git a/src/ui/configuration/terminalconsole.h b/src/ui/configuration/terminalconsole.h index 5c8a91182b..85a5643946 100644 --- a/src/ui/configuration/terminalconsole.h +++ b/src/ui/configuration/terminalconsole.h @@ -54,6 +54,8 @@ class TerminalConsole : public QWidget { Q_OBJECT +public: + enum ConsoleMode { APM, PX4 }; public: explicit TerminalConsole(QWidget *parent = 0); ~TerminalConsole(); @@ -64,6 +66,7 @@ private slots: void closeSerialPort(); void writeData(const QByteArray &data); void readData(); + void sendResetCommand(); void handleError(QSerialPort::SerialPortError error); @@ -75,6 +78,7 @@ private: void initConnections(); void addBaudComboBoxConfig(); void fillPortsInfo(QComboBox &comboxBox); + void addConsoleModesComboBoxConfig(); void writeSettings(); void loadSettings(); @@ -87,6 +91,7 @@ private: SettingsDialog *m_settingsDialog; QSerialPort *m_serial; SerialSettings m_settings; + ConsoleMode m_consoleMode; }; #endif // TERMINALCONSOLE_H diff --git a/src/ui/configuration/terminalconsole.ui b/src/ui/configuration/terminalconsole.ui index 1ee9ec87cc..455cfc1e7a 100644 --- a/src/ui/configuration/terminalconsole.ui +++ b/src/ui/configuration/terminalconsole.ui @@ -126,7 +126,7 @@ - + 0 @@ -139,16 +139,6 @@ 0 - - - APM - - - - - PX4 - - -- GitLab From 8b79008342954914d1a1063f13a0ef48bed32a06 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Mon, 29 Jul 2013 21:47:41 -0400 Subject: [PATCH 101/460] Changes for proper min/max values of radio calibration --- .../configuration/RadioCalibrationConfig.cc | 2 + src/ui/designer/QGCRadioChannelDisplay.cpp | 50 +++++++++---------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/ui/configuration/RadioCalibrationConfig.cc b/src/ui/configuration/RadioCalibrationConfig.cc index a3ce3b6121..e08ccc0702 100644 --- a/src/ui/configuration/RadioCalibrationConfig.cc +++ b/src/ui/configuration/RadioCalibrationConfig.cc @@ -175,6 +175,7 @@ void RadioCalibrationConfig::calibrateButtonClicked() ui.radio5Widget->showMinMax(); ui.radio6Widget->showMinMax(); ui.radio7Widget->showMinMax(); + ui.throttleWidget->showMinMax(); ui.radio8Widget->showMinMax(); QMessageBox::information(0,"Information","Click OK, then move all sticks to their extreme positions, watching the min/max values to ensure you get the most range from your controller. This includes all switches"); } @@ -189,6 +190,7 @@ void RadioCalibrationConfig::calibrateButtonClicked() ui.yawWidget->hideMinMax(); ui.radio5Widget->hideMinMax(); ui.radio6Widget->hideMinMax(); + ui.throttleWidget->hideMinMax(); ui.radio7Widget->hideMinMax(); ui.radio8Widget->hideMinMax(); QString statusstr; diff --git a/src/ui/designer/QGCRadioChannelDisplay.cpp b/src/ui/designer/QGCRadioChannelDisplay.cpp index 148965eb61..1b10dc824c 100644 --- a/src/ui/designer/QGCRadioChannelDisplay.cpp +++ b/src/ui/designer/QGCRadioChannelDisplay.cpp @@ -43,18 +43,18 @@ void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) painter.setPen(QColor::fromRgb(50,255,50)); //m_value - m_min / m_max - m_min - if (!m_showMinMax) - { - int newval = (height()-2-(painter.fontMetrics().height() * 2)) * ((float)(currval - m_min) / ((m_max-m_min)+1)); - int newvaly = (height()-2-(painter.fontMetrics().height() * 2)) - newval; - painter.drawRect(1,newvaly,width()-3,((height()-2) - newvaly - (painter.fontMetrics().height() * 2))); - } - else - { - int newval = (height()-2-(painter.fontMetrics().height() * 2)) * ((float)(currval / 3001.0)); + //if (!m_showMinMax) + //{ + // int newval = (height()-2-(painter.fontMetrics().height() * 2)) * ((float)(currval - m_min) / ((m_max-m_min)+1)); + // int newvaly = (height()-2-(painter.fontMetrics().height() * 2)) - newval; + // painter.drawRect(1,newvaly,width()-3,((height()-2) - newvaly - (painter.fontMetrics().height() * 2))); + //} + //else + //{ + int newval = (height()-2-(painter.fontMetrics().height() * 2)) * ((float)((currval - 800.0) / 1401)); int newvaly = (height()-2-(painter.fontMetrics().height() * 2)) - newval; painter.drawRect(1,newvaly,width()-3,((height()-2) - newvaly - (painter.fontMetrics().height() * 2))); - } + //} QString valstr = QString::number(m_value); painter.setPen(QColor::fromRgb(255,255,255)); @@ -64,8 +64,8 @@ void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) { painter.setBrush(Qt::NoBrush); painter.setPen(QColor::fromRgb(255,0,0)); - int maxyval = (height()-3 - (painter.fontMetrics().height() * 2)) - (((height()-3-(painter.fontMetrics().height() * 2)) * ((float)m_max / 3000.0))); - int minyval = (height()-3 - (painter.fontMetrics().height() * 2)) - (((height()-3-(painter.fontMetrics().height() * 2)) * ((float)m_min / 3000.0))); + int maxyval = (height()-3 - (painter.fontMetrics().height() * 2)) - (((height()-3-(painter.fontMetrics().height() * 2)) * ((float)(m_max - 800) / 1400.0))); + int minyval = (height()-3 - (painter.fontMetrics().height() * 2)) - (((height()-3-(painter.fontMetrics().height() * 2)) * ((float)(m_min - 800) / 1400.0))); painter.drawRect(2,maxyval,width()-3,minyval - maxyval); QString minstr = QString::number(m_min); painter.drawText((width() / 2.0) - (painter.fontMetrics().width("min")/2.0),minyval,"min"); @@ -83,14 +83,14 @@ void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) painter.drawRect(0,0,width()-1,(height()-1) - (painter.fontMetrics().height() * 2)); painter.setBrush(Qt::SolidPattern); painter.setPen(QColor::fromRgb(50,255,50)); - if (!m_showMinMax) - { - painter.drawRect(1,1,(width()-3) * ((float)(currval-m_min) / (m_max-m_min)),(height()-3) - (painter.fontMetrics().height() * 2)); - } - else - { - painter.drawRect(1,1,(width()-3) * ((float)currval / 3000.0),(height()-3) - (painter.fontMetrics().height() * 2)); - } + //if (!m_showMinMax) + //{ + // painter.drawRect(1,1,(width()-3) * ((float)(currval-m_min) / (m_max-m_min)),(height()-3) - (painter.fontMetrics().height() * 2)); + //} + //else + //{ + painter.drawRect(1,1,(width()-3) * ((float)(currval-800.0) / 1400.0),(height()-3) - (painter.fontMetrics().height() * 2)); + //} painter.setPen(QColor::fromRgb(255,255,255)); QString valstr = QString::number(m_value); painter.drawText((width()/2.0) - (painter.fontMetrics().width(m_name)/2.0),((height()-3) - (painter.fontMetrics().height()*1)),m_name); @@ -99,15 +99,15 @@ void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) { painter.setBrush(Qt::NoBrush); painter.setPen(QColor::fromRgb(255,0,0)); - painter.drawRect(width() * ((float)m_min / 3000.0),2,((width()-1) * ((float)m_max / 3000.0)) - (width() * ((float)m_min / 3000.0)),(height()-5) - (painter.fontMetrics().height() * 2)); + painter.drawRect(width() * ((float)(m_min - 800.0) / 1400.0),2,((width()-1) * ((float)(m_max-800.0) / 1400.0)) - (width() * ((float)(m_min-800.0) / 1400.0)),(height()-5) - (painter.fontMetrics().height() * 2)); QString minstr = QString::number(m_min); - painter.drawText((width() * ((float)m_min / 3000.0)) - (painter.fontMetrics().width("min")/2.0),((height()-3) - (painter.fontMetrics().height()*1)),"min"); - painter.drawText((width() * ((float)m_min / 3000.0)) - (painter.fontMetrics().width(minstr)/2.0),((height()-3) - (painter.fontMetrics().height() * 0)),minstr); + painter.drawText((width() * ((float)(m_min-800.0) / 1400.0)) - (painter.fontMetrics().width("min")/2.0),((height()-3) - (painter.fontMetrics().height()*1)),"min"); + painter.drawText((width() * ((float)(m_min-800.0) / 1400.0)) - (painter.fontMetrics().width(minstr)/2.0),((height()-3) - (painter.fontMetrics().height() * 0)),minstr); QString maxstr = QString::number(m_max); - painter.drawText((width() * ((float)m_max / 3000.0)) - (painter.fontMetrics().width("max")/2.0),((height()-3) - (painter.fontMetrics().height()*1)),"max"); - painter.drawText((width() * ((float)m_max / 3000.0)) - (painter.fontMetrics().width(maxstr)/2.0),((height()-3) - (painter.fontMetrics().height() * 0)),maxstr); + painter.drawText((width() * ((float)(m_max-800.0) / 1400.0)) - (painter.fontMetrics().width("max")/2.0),((height()-3) - (painter.fontMetrics().height()*1)),"max"); + painter.drawText((width() * ((float)(m_max-800.0) / 1400.0)) - (painter.fontMetrics().width(maxstr)/2.0),((height()-3) - (painter.fontMetrics().height() * 0)),maxstr); } } } -- GitLab From 3de60b73e3fa6df2a79b84b3d5f11219e38f83c1 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Mon, 29 Jul 2013 22:36:41 -0400 Subject: [PATCH 102/460] More changes for ApmFirmware, to better identify when Beta is selected --- src/ui/configuration/ApmFirmwareConfig.cc | 68 ++++++++++++++++++----- src/ui/configuration/ApmFirmwareConfig.h | 9 ++- src/ui/configuration/ApmFirmwareConfig.ui | 25 +++++++-- 3 files changed, 80 insertions(+), 22 deletions(-) diff --git a/src/ui/configuration/ApmFirmwareConfig.cc b/src/ui/configuration/ApmFirmwareConfig.cc index e9e996efdf..a7ecbe74bc 100644 --- a/src/ui/configuration/ApmFirmwareConfig.cc +++ b/src/ui/configuration/ApmFirmwareConfig.cc @@ -1,3 +1,5 @@ +#include + #include "LinkManager.h" #include "LinkInterface.h" #include "qserialport.h" @@ -29,21 +31,60 @@ ApmFirmwareConfig::ApmFirmwareConfig(QWidget *parent) : QWidget(parent) connect(ui.quadPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); connect(ui.triPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); connect(ui.y6PushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); - requestFirmwares(); + QTimer::singleShot(500,this,SLOT(requestFirmwares())); connect(ui.betaFirmwareButton,SIGNAL(clicked(bool)),this,SLOT(betaFirmwareButtonClicked(bool))); ui.progressBar->setMaximum(100); ui.progressBar->setValue(0); - ui.progressBar->setVisible(false); ui.textBrowser->setVisible(false); connect(ui.showOutputCheckBox,SIGNAL(clicked(bool)),ui.textBrowser,SLOT(setShown(bool))); + + addBetaLabel(ui.roverPushButton); + addBetaLabel(ui.planePushButton); + addBetaLabel(ui.copterPushButton); + addBetaLabel(ui.quadPushButton); + addBetaLabel(ui.hexaPushButton); + addBetaLabel(ui.octaQuadPushButton); + addBetaLabel(ui.octaPushButton); + addBetaLabel(ui.triPushButton); + addBetaLabel(ui.y6PushButton); + +} +void ApmFirmwareConfig::hideBetaLabels() +{ + for (int i=0;ihide(); + } + ui.warningLabel->hide(); } +void ApmFirmwareConfig::showBetaLabels() +{ + for (int i=0;ishow(); + } + ui.warningLabel->show(); +} + +void ApmFirmwareConfig::addBetaLabel(QWidget *parent) +{ + + QLabel *label = new QLabel(parent); + QVBoxLayout *layout = new QVBoxLayout(); + parent->setLayout(layout); + label->setAlignment(Qt::AlignRight | Qt::AlignBottom); + label->setText("

BETA

"); + layout->addWidget(label); + m_betaButtonLabelList.append(label); +} void ApmFirmwareConfig::requestBetaFirmwares() { m_betaFirmwareChecked = true; + showBetaLabels(); QNetworkReply *reply1 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-heli/git-version.txt"))); QNetworkReply *reply2 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-quad/git-version.txt"))); QNetworkReply *reply3 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/beta/apm2-hexa/git-version.txt"))); @@ -89,6 +130,7 @@ void ApmFirmwareConfig::requestBetaFirmwares() void ApmFirmwareConfig::requestFirmwares() { m_betaFirmwareChecked = false; + hideBetaLabels(); QNetworkReply *reply1 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-heli/git-version.txt"))); QNetworkReply *reply2 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-quad/git-version.txt"))); QNetworkReply *reply3 = m_networkManager->get(QNetworkRequest(QUrl("http://firmware.diydrones.com/Copter/stable/apm2-hexa/git-version.txt"))); @@ -135,15 +177,14 @@ void ApmFirmwareConfig::betaFirmwareButtonClicked(bool betafirmwareenabled) { if (betafirmwareenabled) { - QMessageBox::information(0,"Warning","Beta firmwares are from the latest trunk. Use at your own risk!!"); - ui.label->setText("

Beta Firmware

"); - ui.betaFirmwareButton->setText("Stable Firmware"); + ui.label->setText(tr("

Beta Firmware

")); + ui.betaFirmwareButton->setText(tr("Stable Firmware")); requestBetaFirmwares(); } else { - ui.label->setText("

Firmware

"); - ui.betaFirmwareButton->setText("Beta Firmware"); + ui.label->setText(tr("

Firmware

")); + ui.betaFirmwareButton->setText(tr("Beta Firmware")); requestFirmwares(); } } @@ -157,7 +198,7 @@ void ApmFirmwareConfig::firmwareProcessFinished(int status) if (status != 0) { //Error of some kind - QMessageBox::information(0,"Error","An error has occured during the upload process. See window for details"); + QMessageBox::information(0,tr("Error"),tr("An error has occured during the upload process. See window for details")); ui.textBrowser->setVisible(true); ui.showOutputCheckBox->setChecked(true); ui.textBrowser->setPlainText(ui.textBrowser->toPlainText().append("\n\nERROR!!\n" + proc->errorString())); @@ -166,13 +207,13 @@ void ApmFirmwareConfig::firmwareProcessFinished(int status) { sb->setValue(sb->maximum()); } - ui.statusLabel->setText("Error during upload"); + ui.statusLabel->setText(tr("Error during upload")); } else { //Ensure we're reading 100% ui.progressBar->setValue(100); - ui.statusLabel->setText("Upload complete"); + ui.statusLabel->setText(tr("Upload complete")); } //qDebug() << "Upload finished!" << QString::number(status); m_tempFirmwareFile->deleteLater(); //This will remove the temporary file. @@ -268,10 +309,10 @@ void ApmFirmwareConfig::downloadFinished() port.setDataTerminalReady(false); port.close(); - ui.statusLabel->setText("Burning"); QString avrdudeExecutable; QStringList stringList; + ui.statusLabel->setText(tr("Flashing")); #ifdef Q_OS_WIN stringList = QStringList() << "-Cavrdude/avrdude.conf" << "-pm2560" << "-cstk500" << QString("-P").append(m_detectedComPort) @@ -316,7 +357,7 @@ void ApmFirmwareConfig::burnButtonClicked() qDebug() << "Eror, trying to program over a non serial link. This should not happen"; return; } - if (!(QMessageBox::question(this,"WARNING","You are about to upload new firmware to your board. This will disconnect you if you are currently connected. Be sure the MAV is on the ground, and connected over USB/Serial link.\n\nDo you wish to proceed?",QMessageBox::Yes,QMessageBox::No) == QMessageBox::Yes)) + if (!(QMessageBox::question(this,tr("WARNING"),tr("You are about to upload new firmware to your board. This will disconnect you if you are currently connected. Be sure the MAV is on the ground, and connected over USB/Serial link.\n\nDo you wish to proceed?"),QMessageBox::Yes,QMessageBox::No) == QMessageBox::Yes)) { return; } @@ -330,7 +371,7 @@ void ApmFirmwareConfig::burnButtonClicked() } if (!foundconnected) { - QMessageBox::information(0,"Error","You must be connected to a MAV over serial link to flash firmware. Please connect to a MAV then try again"); + QMessageBox::information(0,tr("Error"),tr("You must be connected to a MAV over serial link to flash firmware. Please connect to a MAV then try again")); return; } @@ -342,7 +383,6 @@ void ApmFirmwareConfig::burnButtonClicked() connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(firmwareListError(QNetworkReply::NetworkError))); connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(firmwareDownloadProgress(qint64,qint64))); ui.statusLabel->setText("Downloading"); - ui.progressBar->setVisible(true); } } diff --git a/src/ui/configuration/ApmFirmwareConfig.h b/src/ui/configuration/ApmFirmwareConfig.h index ae0a533758..9db7d32930 100644 --- a/src/ui/configuration/ApmFirmwareConfig.h +++ b/src/ui/configuration/ApmFirmwareConfig.h @@ -33,13 +33,18 @@ private slots: void firmwareProcessReadyRead(); void firmwareProcessError(QProcess::ProcessError error); void firmwareDownloadProgress(qint64 received,qint64 total); + void requestFirmwares(); + void requestBetaFirmwares(); + private: + void addBetaLabel(QWidget *parent); + void hideBetaLabels(); + void showBetaLabels(); //ApmFirmwareStatus *firmwareStatus; QString m_detectedComPort; QTemporaryFile *m_tempFirmwareFile; QNetworkAccessManager *m_networkManager; - void requestFirmwares(); - void requestBetaFirmwares(); + QList m_betaButtonLabelList; bool stripVersionFromGitReply(QString url,QString reply,QString type,QString stable,QString *out); bool m_betaFirmwareChecked; QMap m_buttonToUrlMap; diff --git a/src/ui/configuration/ApmFirmwareConfig.ui b/src/ui/configuration/ApmFirmwareConfig.ui index b49f8318c8..7f4096f4db 100644 --- a/src/ui/configuration/ApmFirmwareConfig.ui +++ b/src/ui/configuration/ApmFirmwareConfig.ui @@ -7,7 +7,7 @@ 0 0 868 - 661 + 684 @@ -448,7 +448,7 @@ 50 - 470 + 490 791 23 @@ -461,7 +461,7 @@ 60 - 500 + 520 741 151 @@ -470,8 +470,8 @@ - 600 - 440 + 710 + 470 101 17 @@ -483,7 +483,7 @@ - 60 + 30 440 141 21 @@ -493,6 +493,19 @@ Status + + + + 180 + 440 + 491 + 16 + + + + <h3><font color=#FFAA00>WARNING: Only install BETA firmware if you are an experienced tester.</font></h3> + + -- GitLab From f28cb0223e358ba413272ceaf309a55b4724be18 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 30 Jul 2013 06:28:03 -0400 Subject: [PATCH 103/460] Change for duplicate header file --- qgroundcontrol.pro | 1 - 1 file changed, 1 deletion(-) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index ea7265e23f..6776f73aa8 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -380,7 +380,6 @@ HEADERS += src/MG.h \ src/ui/QGCMAVLinkInspector.h \ src/ui/MAVLinkDecoder.h \ src/ui/WaypointViewOnlyView.h \ - src/ui/WaypointViewOnlyView.h \ src/ui/WaypointEditableView.h \ src/ui/UnconnectedUASInfoWidget.h \ src/ui/QGCRGBDView.h \ -- GitLab From 55f7245cbab98cdd7990eabc59ad631b315a10fe Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 30 Jul 2013 06:33:59 -0400 Subject: [PATCH 104/460] Change for "burn" to "flash" for firmware config flashing --- src/ui/configuration/ApmFirmwareConfig.cc | 22 +++++++++++----------- src/ui/configuration/ApmFirmwareConfig.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ui/configuration/ApmFirmwareConfig.cc b/src/ui/configuration/ApmFirmwareConfig.cc index a7ecbe74bc..4b63192a51 100644 --- a/src/ui/configuration/ApmFirmwareConfig.cc +++ b/src/ui/configuration/ApmFirmwareConfig.cc @@ -22,15 +22,15 @@ ApmFirmwareConfig::ApmFirmwareConfig(QWidget *parent) : QWidget(parent) m_networkManager = new QNetworkAccessManager(this); - connect(ui.roverPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); - connect(ui.planePushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); - connect(ui.copterPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); - connect(ui.hexaPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); - connect(ui.octaQuadPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); - connect(ui.octaPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); - connect(ui.quadPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); - connect(ui.triPushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); - connect(ui.y6PushButton,SIGNAL(clicked()),this,SLOT(burnButtonClicked())); + connect(ui.roverPushButton,SIGNAL(clicked()),this,SLOT(flashButtonClicked())); + connect(ui.planePushButton,SIGNAL(clicked()),this,SLOT(flashButtonClicked())); + connect(ui.copterPushButton,SIGNAL(clicked()),this,SLOT(flashButtonClicked())); + connect(ui.hexaPushButton,SIGNAL(clicked()),this,SLOT(flashButtonClicked())); + connect(ui.octaQuadPushButton,SIGNAL(clicked()),this,SLOT(flashButtonClicked())); + connect(ui.octaPushButton,SIGNAL(clicked()),this,SLOT(flashButtonClicked())); + connect(ui.quadPushButton,SIGNAL(clicked()),this,SLOT(flashButtonClicked())); + connect(ui.triPushButton,SIGNAL(clicked()),this,SLOT(flashButtonClicked())); + connect(ui.y6PushButton,SIGNAL(clicked()),this,SLOT(flashButtonClicked())); QTimer::singleShot(500,this,SLOT(requestFirmwares())); connect(ui.betaFirmwareButton,SIGNAL(clicked(bool)),this,SLOT(betaFirmwareButtonClicked(bool))); @@ -265,7 +265,7 @@ void ApmFirmwareConfig::firmwareProcessReadyRead() void ApmFirmwareConfig::downloadFinished() { - qDebug() << "Download finished, burning firmware"; + qDebug() << "Download finished, flashing firmware"; QNetworkReply *reply = qobject_cast(sender()); if (!reply) { @@ -340,7 +340,7 @@ void ApmFirmwareConfig::firmwareDownloadProgress(qint64 received,qint64 total) ui.progressBar->setValue( 100.0 * ((double)received/(double)total)); } -void ApmFirmwareConfig::burnButtonClicked() +void ApmFirmwareConfig::flashButtonClicked() { QPushButton *senderbtn = qobject_cast(sender()); if (m_buttonToUrlMap.contains(senderbtn)) diff --git a/src/ui/configuration/ApmFirmwareConfig.h b/src/ui/configuration/ApmFirmwareConfig.h index 9db7d32930..51c8fdb786 100644 --- a/src/ui/configuration/ApmFirmwareConfig.h +++ b/src/ui/configuration/ApmFirmwareConfig.h @@ -26,7 +26,7 @@ public: private slots: void firmwareListFinished(); void firmwareListError(QNetworkReply::NetworkError error); - void burnButtonClicked(); + void flashButtonClicked(); void betaFirmwareButtonClicked(bool betafirmwareenabled); void downloadFinished(); void firmwareProcessFinished(int status); -- GitLab From 78c4673f5b7aa05754d08a9f77d58ceafdf98a5f Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Tue, 30 Jul 2013 08:19:48 -0700 Subject: [PATCH 105/460] Fixes component alignments and small improvements to Firmware View --- src/ui/configuration/ApmFirmwareConfig.cc | 81 +++-------------------- src/ui/configuration/ApmFirmwareConfig.ui | 10 +-- 2 files changed, 14 insertions(+), 77 deletions(-) diff --git a/src/ui/configuration/ApmFirmwareConfig.cc b/src/ui/configuration/ApmFirmwareConfig.cc index 4b63192a51..400b8a029e 100644 --- a/src/ui/configuration/ApmFirmwareConfig.cc +++ b/src/ui/configuration/ApmFirmwareConfig.cc @@ -410,110 +410,47 @@ void ApmFirmwareConfig::firmwareListFinished() QString outstr = ""; if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-heli",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - if (m_betaFirmwareChecked) - { - ui.copterLabel->setText("BETA " + outstr); - } - else - { - ui.copterLabel->setText(outstr); - } + ui.copterLabel->setText(outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-quad",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - if (m_betaFirmwareChecked) - { - ui.quadLabel->setText("BETA " + outstr); - } - else - { - ui.quadLabel->setText(outstr); - } + ui.quadLabel->setText(outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-hexa",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - if (m_betaFirmwareChecked) - { - ui.hexaLabel->setText("BETA " + outstr); - } - else - { - ui.hexaLabel->setText(outstr); - } + ui.hexaLabel->setText(outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-octa-quad",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - if (m_betaFirmwareChecked) - { - ui.octaQuadLabel->setText("BETA " + outstr); - } - else - { - ui.octaQuadLabel->setText(outstr); - } + ui.octaQuadLabel->setText(outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-octa",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - if (m_betaFirmwareChecked) - { - ui.octaLabel->setText("BETA " + outstr); - } - else - { - ui.octaLabel->setText(outstr); - } + ui.octaLabel->setText(outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-tri",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - if (m_betaFirmwareChecked) - { - ui.triLabel->setText("BETA " + outstr); - } - else - { - ui.triLabel->setText(outstr); - } + ui.triLabel->setText(outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-y6",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - if (m_betaFirmwareChecked) - { - ui.y6Label->setText("BETA " + outstr); - } - else - { - ui.y6Label->setText(outstr); - } + ui.y6Label->setText(outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"Plane",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - if (m_betaFirmwareChecked) - { - ui.planeLabel->setText("BETA " + outstr); - } - else - { - ui.planeLabel->setText(outstr); - } + ui.planeLabel->setText(outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"Rover",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - if (m_betaFirmwareChecked) - { - ui.roverLabel->setText("BETA " + outstr); - } - else - { - ui.roverLabel->setText(outstr); - } + ui.roverLabel->setText(outstr); return; } qDebug() << "Match not found for:" << reply->url(); diff --git a/src/ui/configuration/ApmFirmwareConfig.ui b/src/ui/configuration/ApmFirmwareConfig.ui index 7f4096f4db..4350d71e9c 100644 --- a/src/ui/configuration/ApmFirmwareConfig.ui +++ b/src/ui/configuration/ApmFirmwareConfig.ui @@ -447,9 +447,9 @@ - 50 + 30 490 - 791 + 801 23 @@ -460,9 +460,9 @@ - 60 + 30 520 - 741 + 801 151 @@ -503,7 +503,7 @@ - <h3><font color=#FFAA00>WARNING: Only install BETA firmware if you are an experienced tester.</font></h3> + <html><head/><body><p><span style=" font-size:large; font-weight:600; color:#e90000;">WARNING:</span><span style=" font-size:large; font-weight:600; color:#ffaa00;"> Only install BETA firmware if you are an experienced tester.</span></p></body></html> -- GitLab From 09452414f7115e47e2a21d9e5911a8b472a7343c Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 30 Jul 2013 09:34:03 -0700 Subject: [PATCH 106/460] eliminate refs to nonexistent toolbar files --- qgroundcontrol.pri | 6 ------ qgroundcontrol.pro | 12 +----------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/qgroundcontrol.pri b/qgroundcontrol.pri index fdf608780b..1ba7dbdbe6 100644 --- a/qgroundcontrol.pri +++ b/qgroundcontrol.pri @@ -73,12 +73,6 @@ macx|macx-g++42|macx-g++|macx-llvm: { QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/components/ QMAKE_POST_LINK += && cp -rf $$BASEDIR/qml/components/*.qml $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/components - QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/resources - QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/resources/qgroundcontrol - QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/resources/qgroundcontrol/toolbar - QMAKE_POST_LINK += && cp -rf $$BASEDIR/qml/resources/qgroundcontrol/toolbar/*.png $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/resources/qgroundcontrol/toolbar - - # Fix library paths inside executable QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qgroundcontrol QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qgroundcontrol diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index e3030dc99e..83a962cc38 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -804,17 +804,7 @@ OTHER_FILES += \ OTHER_FILES += \ qml/ApmToolBar.qml \ qml/components/Button.qml \ - qml/components/TextButton.qml \ - qml/resources/qgroundcontrol/toolbar/connect.png \ - qml/resources/qgroundcontrol/toolbar/flightplanner.png \ - qml/resources/qgroundcontrol/toolbar/helpwizard.png \ - qml/resources/qgroundcontrol/toolbar/softwareconfig.png \ - qml/resources/qgroundcontrol/toolbar/terminal.png \ - qml/resources/qgroundcontrol/toolbar/simulation.png \ - qml/resources/qgroundcontrol/toolbar/hardwareconfig.png \ - qml/resources/qgroundcontrol/toolbar/flightdata.png \ - qml/resources/qgroundcontrol/toolbar/disconnect.png \ - qml/resources/qgroundcontrol/toolbar/donate.png \ + qml/components/TextButton.qml #qmlcomponents.path += $${DESTDIR}$${TARGET}/components -- GitLab From f2cbf7bc613e2a39c87943b7cb93962d3629416b Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 30 Jul 2013 09:13:30 -0400 Subject: [PATCH 107/460] Simplified Serial port selection window --- src/ui/CommConfigurationWindow.cc | 13 +- src/ui/CommSettings.ui | 180 +++---- src/ui/SerialConfigurationWindow.cc | 3 + src/ui/SerialSettings.ui | 727 ++++++++++++++++------------ 4 files changed, 518 insertions(+), 405 deletions(-) diff --git a/src/ui/CommConfigurationWindow.cc b/src/ui/CommConfigurationWindow.cc index de6c8715d5..20754dbcdc 100644 --- a/src/ui/CommConfigurationWindow.cc +++ b/src/ui/CommConfigurationWindow.cc @@ -68,11 +68,18 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn ui.connectionType->setEnabled(false); ui.linkType->setEnabled(false); ui.protocolGroupBox->setVisible(false); + ui.protocolTypeGroupBox->setVisible(false); // Connect UI element visibility to checkbox - connect(ui.advancedOptionsCheckBox, SIGNAL(clicked(bool)), ui.connectionType, SLOT(setEnabled(bool))); - connect(ui.advancedOptionsCheckBox, SIGNAL(clicked(bool)), ui.linkType, SLOT(setEnabled(bool))); - connect(ui.advancedOptionsCheckBox, SIGNAL(clicked(bool)), ui.protocolGroupBox, SLOT(setVisible(bool))); + //connect(ui.advancedOptionsCheckBox, SIGNAL(clicked(bool)), ui.connectionType, SLOT(setEnabled(bool))); + //connect(ui.advancedOptionsCheckBox, SIGNAL(clicked(bool)), ui.linkType, SLOT(setEnabled(bool))); + //connect(ui.advancedOptionsCheckBox, SIGNAL(clicked(bool)), ui.protocolGroupBox, SLOT(setVisible(bool))); + ui.advancedOptionsCheckBox->setVisible(false); + //connect(ui.advCheckBox,SIGNAL(clicked(bool)),ui.advancedOptionsCheckBox,SLOT(setChecked(bool))); + connect(ui.advCheckBox,SIGNAL(clicked(bool)),ui.protocolTypeGroupBox,SLOT(setVisible(bool))); + connect(ui.advCheckBox, SIGNAL(clicked(bool)), ui.connectionType, SLOT(setEnabled(bool))); + connect(ui.advCheckBox, SIGNAL(clicked(bool)), ui.linkType, SLOT(setEnabled(bool))); + connect(ui.advCheckBox, SIGNAL(clicked(bool)), ui.protocolGroupBox, SLOT(setVisible(bool))); // add link types ui.linkType->addItem(tr("Serial"), QGC_LINK_SERIAL); diff --git a/src/ui/CommSettings.ui b/src/ui/CommSettings.ui index 91f0ad49dd..735340383e 100644 --- a/src/ui/CommSettings.ui +++ b/src/ui/CommSettings.ui @@ -6,76 +6,15 @@ 0 0 - 413 - 373 + 770 + 563 Form - - - 6 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 5 - 5 - - - - - - - - - - Link Type - - - - - - - - - - Protocol - - - - - - - -1 - - - - - - - Advanced Options - - - - - - - - - Qt::Horizontal - - - - + + Link @@ -97,8 +36,8 @@ 0 0 - 393 - 76 + 748 + 97 @@ -107,7 +46,65 @@ - + + + + Show Advanced Protocol Options + + + + + + + GroupBox + + + + + + + + Link Type + + + + + + + + + + -1 + + + + + + + Advanced Options + + + + + + + Protocol + + + + + + + + + + + + Qt::Horizontal + + + + Protocol @@ -129,8 +126,8 @@ 0 0 - 393 - 76 + 748 + 96 @@ -139,20 +136,20 @@
- - - - - 0 - 0 - + + + + Qt::Vertical - - Disconnected + + + 20 + 40 + - + - + 12 @@ -189,6 +186,19 @@ + + + + + 0 + 0 + + + + Disconnected + + + @@ -214,6 +224,14 @@ Close the configuration window + line + linkGroupBox + protocolGroupBox + connectionStatusLabel + advCheckBox + protocolTypeGroupBox + label_5 + verticalSpacer diff --git a/src/ui/SerialConfigurationWindow.cc b/src/ui/SerialConfigurationWindow.cc index 72974c7c14..9d26613979 100644 --- a/src/ui/SerialConfigurationWindow.cc +++ b/src/ui/SerialConfigurationWindow.cc @@ -129,6 +129,9 @@ SerialConfigurationWindow::SerialConfigurationWindow(LinkInterface* link, QWidge connect(ui.parEven, SIGNAL(toggled(bool)), this, SLOT(setParityEven(bool))); connect(ui.dataBitsSpinBox, SIGNAL(valueChanged(int)), this->link, SLOT(setDataBits(int))); connect(ui.stopBitsSpinBox, SIGNAL(valueChanged(int)), this->link, SLOT(setStopBits(int))); + connect(ui.advCheckBox,SIGNAL(clicked(bool)),ui.advGroupBox,SLOT(setShown(bool))); + ui.advCheckBox->setChecked(false); + ui.advGroupBox->setVisible(false); //connect(this->link, SIGNAL(connected(bool)), this, SLOT()); ui.portName->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow); diff --git a/src/ui/SerialSettings.ui b/src/ui/SerialSettings.ui index 6056720009..fd96720ec6 100644 --- a/src/ui/SerialSettings.ui +++ b/src/ui/SerialSettings.ui @@ -6,379 +6,464 @@ 0 0 - 304 - 283 + 546 + 457 Form - - - 6 - - - - - Serial Port - - - - - - - The serial port to which the system is connected. All ports listed here should work. - - - The serial port to which the system is connected. All ports listed here should work. - - - The serial port to which the system is connected. All ports listed here should work. - - - true - - - QComboBox::AdjustToContents - - - - - - - - - - - - Baud Rate - - - - - - - The data transmission rate. If unsure 57600 and 115200 are very common rates. - - - The data transmission rate. If unsure 57600 and 115200 are very common rates. - - - The data transmission rate. If unsure 57600 and 115200 are very common rates. - - - false - - - QComboBox::AdjustToContents - - - - 50 - - - - - 75 - - - - - 110 - - - - - 134 - - - - - 150 - - - - - 200 - - - - - 300 - - - - - 600 - - - - - 1200 - - - - - 1800 - - - - - 2400 - - - - - 4800 - - - - - 9600 - - - - - 14400 - - - - - 19200 - - - - - 38400 - - - - - 56000 - - - - - 57600 - - - - - 76800 - - - - - 115200 - - + + + - - 128000 - - - - - 230400 - - - - - 256000 - - - - - 460800 - - - - - 921600 - + + + Serial Port + + - - - - - - Flow Control - - - - - - - Activate / deactivate hardware flow control. Commonly deactivated - - - Activate / deactivate hardware flow control. Commonly deactivated - - - Activate / deactivate hardware flow control. Commonly deactivated - - - Active - - - - - - - Parity - - - - - - + - Set the parity. In most cases no parity (None) is used. + The serial port to which the system is connected. All ports listed here should work. - Set the parity. In most cases no parity (None) is used. + The serial port to which the system is connected. All ports listed here should work. - Set the parity. In most cases no parity (None) is used. - - - None + The serial port to which the system is connected. All ports listed here should work. - + true + + QComboBox::AdjustToContents + + + + + + - - - Set the parity. In most cases no parity (None) is used. + + + Qt::Horizontal - - Set the parity. In most cases no parity (None) is used. - - - Set the parity. In most cases no parity (None) is used. + + + 40 + 20 + + + + + + + + + - Odd + Baud Rate - + - Set the parity. In most cases no parity (None) is used. + The data transmission rate. If unsure 57600 and 115200 are very common rates. - Set the parity. In most cases no parity (None) is used. + The data transmission rate. If unsure 57600 and 115200 are very common rates. - Set the parity. In most cases no parity (None) is used. + The data transmission rate. If unsure 57600 and 115200 are very common rates. - - Even + + false + + + QComboBox::AdjustToContents + + + 50 + + + + + 75 + + + + + 110 + + + + + 134 + + + + + 150 + + + + + 200 + + + + + 300 + + + + + 600 + + + + + 1200 + + + + + 1800 + + + + + 2400 + + + + + 4800 + + + + + 9600 + + + + + 14400 + + + + + 19200 + + + + + 38400 + + + + + 56000 + + + + + 57600 + + + + + 76800 + + + + + 115200 + + + + + 128000 + + + + + 230400 + + + + + 256000 + + + + + 460800 + + + + + 921600 + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + - - - - - 0 - 0 - - - - - 0 - 0 - - - - Number of data bits per symbol. This is almost always 8. - - - Number of data bits per symbol. This is almost always 8. - - - Number of data bits per symbol. This is almost always 8. - - - 5 - - - 8 - - - 5 - - - - - + + - Stop bits + Show Advanced Port Settings - - - - - 0 - 0 - - - - Number of stop bits per symbol. This is almost always 2. - - - Number of stop bits per symbol. This is almost always 2. - - - Number of stop bits per symbol. This is almost always 2. - - - true - - - false - - - 1 - - - 2 - - - 2 - - + + + + + + Advanced + + + + + + + + Flow Control + + + + + + + Activate / deactivate hardware flow control. Commonly deactivated + + + Activate / deactivate hardware flow control. Commonly deactivated + + + Activate / deactivate hardware flow control. Commonly deactivated + + + Active + + + + + + + + + + + Parity + + + + + + + + + Set the parity. In most cases no parity (None) is used. + + + Set the parity. In most cases no parity (None) is used. + + + Set the parity. In most cases no parity (None) is used. + + + None + + + true + + + + + + + Set the parity. In most cases no parity (None) is used. + + + Set the parity. In most cases no parity (None) is used. + + + Set the parity. In most cases no parity (None) is used. + + + Odd + + + + + + + Set the parity. In most cases no parity (None) is used. + + + Set the parity. In most cases no parity (None) is used. + + + Set the parity. In most cases no parity (None) is used. + + + Even + + + + + + + + + + + + + Data bits + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Number of data bits per symbol. This is almost always 8. + + + Number of data bits per symbol. This is almost always 8. + + + Number of data bits per symbol. This is almost always 8. + + + 5 + + + 8 + + + 5 + + + + + + + + + + + Stop bits + + + + + + + + 0 + 0 + + + + Number of stop bits per symbol. This is almost always 2. + + + Number of stop bits per symbol. This is almost always 2. + + + Number of stop bits per symbol. This is almost always 2. + + + true + + + false + + + 1 + + + 2 + + + 2 + + + + + + + horizontalLayoutWidget + horizontalLayoutWidget_2 + horizontalLayoutWidget_4 + portlabel_5 + horizontalLayoutWidget_3 + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - + Qt::Vertical - 0 - 0 + 20 + 40 - - - - Data bits - - - -- GitLab From 6733692c2517f330652ae9f8c3a8a3924da91c5c Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 30 Jul 2013 13:49:27 -0400 Subject: [PATCH 108/460] Fix for potential race condition where UI is not finished configuring when parameters start coming in --- src/ui/configuration/AP2ConfigWidget.cc | 4 ++++ src/ui/configuration/AP2ConfigWidget.h | 1 + src/ui/configuration/AccelCalibrationConfig.cc | 3 +-- src/ui/configuration/AdvParameterList.cc | 2 +- src/ui/configuration/AdvancedParamConfig.cc | 1 + src/ui/configuration/AirspeedConfig.cc | 1 + src/ui/configuration/ApmPlaneLevel.cc | 1 + src/ui/configuration/ArduCopterPidConfig.cc | 1 + src/ui/configuration/ArduPlanePidConfig.cc | 2 +- src/ui/configuration/ArduRoverPidConfig.cc | 2 +- src/ui/configuration/BatteryMonitorConfig.cc | 2 +- src/ui/configuration/CameraGimbalConfig.cc | 2 +- src/ui/configuration/CompassConfig.cc | 1 + src/ui/configuration/FailSafeConfig.cc | 1 + src/ui/configuration/FlightModeConfig.cc | 1 + src/ui/configuration/FrameTypeConfig.cc | 1 + src/ui/configuration/OpticalFlowConfig.cc | 1 + src/ui/configuration/OsdConfig.cc | 2 ++ src/ui/configuration/RadioCalibrationConfig.cc | 2 ++ src/ui/configuration/SonarConfig.cc | 2 ++ src/ui/configuration/StandardParamConfig.cc | 1 + 21 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/ui/configuration/AP2ConfigWidget.cc b/src/ui/configuration/AP2ConfigWidget.cc index 08eb44f215..3ce8751b72 100644 --- a/src/ui/configuration/AP2ConfigWidget.cc +++ b/src/ui/configuration/AP2ConfigWidget.cc @@ -4,9 +4,13 @@ AP2ConfigWidget::AP2ConfigWidget(QWidget *parent) : QWidget(parent) { m_uas = 0; +} +void AP2ConfigWidget::initConnections() +{ connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); activeUASSet(UASManager::instance()->getActiveUAS()); } + void AP2ConfigWidget::activeUASSet(UASInterface *uas) { if (m_uas) diff --git a/src/ui/configuration/AP2ConfigWidget.h b/src/ui/configuration/AP2ConfigWidget.h index 69e9f6f7fb..b8a397dd24 100644 --- a/src/ui/configuration/AP2ConfigWidget.h +++ b/src/ui/configuration/AP2ConfigWidget.h @@ -12,6 +12,7 @@ public: protected: UASInterface *m_uas; void showNullMAVErrorMessageBox(); + void initConnections(); signals: public slots: diff --git a/src/ui/configuration/AccelCalibrationConfig.cc b/src/ui/configuration/AccelCalibrationConfig.cc index 945ba5e2e0..a92702482a 100644 --- a/src/ui/configuration/AccelCalibrationConfig.cc +++ b/src/ui/configuration/AccelCalibrationConfig.cc @@ -6,9 +6,8 @@ AccelCalibrationConfig::AccelCalibrationConfig(QWidget *parent) : AP2ConfigWidge ui.setupUi(this); connect(ui.calibrateAccelButton,SIGNAL(clicked()),this,SLOT(calibrateButtonClicked())); - connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUASSet(UASInterface*))); - activeUASSet(UASManager::instance()->getActiveUAS()); m_accelAckCount=0; + initConnections(); } AccelCalibrationConfig::~AccelCalibrationConfig() diff --git a/src/ui/configuration/AdvParameterList.cc b/src/ui/configuration/AdvParameterList.cc index 971f290e61..24a5bc384e 100644 --- a/src/ui/configuration/AdvParameterList.cc +++ b/src/ui/configuration/AdvParameterList.cc @@ -11,7 +11,7 @@ AdvParameterList::AdvParameterList(QWidget *parent) : AP2ConfigWidget(parent) ui.tableWidget->setColumnWidth(1,100); ui.tableWidget->setColumnWidth(2,200); ui.tableWidget->setColumnWidth(3,800); - + initConnections(); } AdvParameterList::~AdvParameterList() diff --git a/src/ui/configuration/AdvancedParamConfig.cc b/src/ui/configuration/AdvancedParamConfig.cc index 8410b6a002..3475da4d1d 100644 --- a/src/ui/configuration/AdvancedParamConfig.cc +++ b/src/ui/configuration/AdvancedParamConfig.cc @@ -4,6 +4,7 @@ AdvancedParamConfig::AdvancedParamConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); + initConnections(); } AdvancedParamConfig::~AdvancedParamConfig() diff --git a/src/ui/configuration/AirspeedConfig.cc b/src/ui/configuration/AirspeedConfig.cc index b5c91f33b7..27699996b1 100644 --- a/src/ui/configuration/AirspeedConfig.cc +++ b/src/ui/configuration/AirspeedConfig.cc @@ -6,6 +6,7 @@ AirspeedConfig::AirspeedConfig(QWidget *parent) : AP2ConfigWidget(parent) ui.setupUi(this); connect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(enableCheckBoxClicked(bool))); connect(ui.useAirspeedCheckBox,SIGNAL(toggled(bool)),this,SLOT(useCheckBoxClicked(bool))); + initConnections(); } AirspeedConfig::~AirspeedConfig() diff --git a/src/ui/configuration/ApmPlaneLevel.cc b/src/ui/configuration/ApmPlaneLevel.cc index c93193055f..49b1b20f5e 100644 --- a/src/ui/configuration/ApmPlaneLevel.cc +++ b/src/ui/configuration/ApmPlaneLevel.cc @@ -6,6 +6,7 @@ ApmPlaneLevel::ApmPlaneLevel(QWidget *parent) : AP2ConfigWidget(parent) ui.setupUi(this); connect(ui.levelPushButton,SIGNAL(clicked()),this,SLOT(levelClicked())); connect(ui.manualLevelCheckBox,SIGNAL(toggled(bool)),this,SLOT(manualCheckBoxToggled(bool))); + initConnections(); } ApmPlaneLevel::~ApmPlaneLevel() diff --git a/src/ui/configuration/ArduCopterPidConfig.cc b/src/ui/configuration/ArduCopterPidConfig.cc index bd0924323b..ad7211ed39 100644 --- a/src/ui/configuration/ArduCopterPidConfig.cc +++ b/src/ui/configuration/ArduCopterPidConfig.cc @@ -107,6 +107,7 @@ ArduCopterPidConfig::ArduCopterPidConfig(QWidget *parent) : AP2ConfigWidget(pare ui.ch7OptComboBox->addItem(m_ch78ValueToTextList[i].second); ui.ch8OptComboBox->addItem(m_ch78ValueToTextList[i].second); } + initConnections(); } ArduCopterPidConfig::~ArduCopterPidConfig() diff --git a/src/ui/configuration/ArduPlanePidConfig.cc b/src/ui/configuration/ArduPlanePidConfig.cc index 4cfa5efa6e..157c2db387 100644 --- a/src/ui/configuration/ArduPlanePidConfig.cc +++ b/src/ui/configuration/ArduPlanePidConfig.cc @@ -58,7 +58,7 @@ ArduPlanePidConfig::ArduPlanePidConfig(QWidget *parent) : AP2ConfigWidget(parent connect(ui.writePushButton,SIGNAL(clicked()),this,SLOT(writeButtonClicked())); connect(ui.refreshPushButton,SIGNAL(clicked()),this,SLOT(refreshButtonClicked())); - + initConnections(); } ArduPlanePidConfig::~ArduPlanePidConfig() diff --git a/src/ui/configuration/ArduRoverPidConfig.cc b/src/ui/configuration/ArduRoverPidConfig.cc index f9d9034e67..e84d79943c 100644 --- a/src/ui/configuration/ArduRoverPidConfig.cc +++ b/src/ui/configuration/ArduRoverPidConfig.cc @@ -39,7 +39,7 @@ ArduRoverPidConfig::ArduRoverPidConfig(QWidget *parent) : AP2ConfigWidget(parent connect(ui.writePushButton,SIGNAL(clicked()),this,SLOT(writeButtonClicked())); connect(ui.refreshPushButton,SIGNAL(clicked()),this,SLOT(refreshButtonClicked())); - + initConnections(); } ArduRoverPidConfig::~ArduRoverPidConfig() diff --git a/src/ui/configuration/BatteryMonitorConfig.cc b/src/ui/configuration/BatteryMonitorConfig.cc index 6e56877884..68692aa62b 100644 --- a/src/ui/configuration/BatteryMonitorConfig.cc +++ b/src/ui/configuration/BatteryMonitorConfig.cc @@ -31,7 +31,7 @@ BatteryMonitorConfig::BatteryMonitorConfig(QWidget *parent) : AP2ConfigWidget(pa connect(ui.battCapacityLineEdit,SIGNAL(editingFinished()),this,SLOT(batteryCapacitySet())); - + initConnections(); } void BatteryMonitorConfig::activeUASSet(UASInterface *uas) { diff --git a/src/ui/configuration/CameraGimbalConfig.cc b/src/ui/configuration/CameraGimbalConfig.cc index 724dd4bc1d..6b14b1a466 100644 --- a/src/ui/configuration/CameraGimbalConfig.cc +++ b/src/ui/configuration/CameraGimbalConfig.cc @@ -106,7 +106,7 @@ CameraGimbalConfig::CameraGimbalConfig(QWidget *parent) : AP2ConfigWidget(parent connect(ui.neutralXSpinBox,SIGNAL(editingFinished()),this,SLOT(updateNeutralAngles())); connect(ui.neutralYSpinBox,SIGNAL(editingFinished()),this,SLOT(updateNeutralAngles())); connect(ui.neutralZSpinBox,SIGNAL(editingFinished()),this,SLOT(updateNeutralAngles())); - + initConnections(); } void CameraGimbalConfig::updateRetractAngles() diff --git a/src/ui/configuration/CompassConfig.cc b/src/ui/configuration/CompassConfig.cc index d0cbcc7ada..610d354ed6 100644 --- a/src/ui/configuration/CompassConfig.cc +++ b/src/ui/configuration/CompassConfig.cc @@ -39,6 +39,7 @@ CompassConfig::CompassConfig(QWidget *parent) : AP2ConfigWidget(parent) ui.orientationComboBox->addItem("ROTATION_PITCH_90"); ui.orientationComboBox->addItem("ROTATION_PITCH_270"); ui.orientationComboBox->addItem("ROTATION_MAX"); + initConnections(); } CompassConfig::~CompassConfig() { diff --git a/src/ui/configuration/FailSafeConfig.cc b/src/ui/configuration/FailSafeConfig.cc index 0e0d45e3dd..66e1c10475 100644 --- a/src/ui/configuration/FailSafeConfig.cc +++ b/src/ui/configuration/FailSafeConfig.cc @@ -82,6 +82,7 @@ FailSafeConfig::FailSafeConfig(QWidget *parent) : AP2ConfigWidget(parent) connect(ui.throttleCheckBox,SIGNAL(clicked(bool)),this,SLOT(throttleChecked(bool))); connect(ui.throttlePwmSpinBox,SIGNAL(editingFinished()),this,SLOT(throttlePwmChanged())); connect(ui.throttleFailSafeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(throttleFailSafeChanged(int))); + initConnections(); } void FailSafeConfig::gcsChecked(bool checked) { diff --git a/src/ui/configuration/FlightModeConfig.cc b/src/ui/configuration/FlightModeConfig.cc index d5acd58176..114c88857a 100644 --- a/src/ui/configuration/FlightModeConfig.cc +++ b/src/ui/configuration/FlightModeConfig.cc @@ -5,6 +5,7 @@ FlightModeConfig::FlightModeConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); connect(ui.savePushButton,SIGNAL(clicked()),this,SLOT(saveButtonClicked())); + initConnections(); } FlightModeConfig::~FlightModeConfig() diff --git a/src/ui/configuration/FrameTypeConfig.cc b/src/ui/configuration/FrameTypeConfig.cc index 7ee5abad3d..8c123c69fb 100644 --- a/src/ui/configuration/FrameTypeConfig.cc +++ b/src/ui/configuration/FrameTypeConfig.cc @@ -44,6 +44,7 @@ FrameTypeConfig::FrameTypeConfig(QWidget *parent) : AP2ConfigWidget(parent) connect(ui.plusRadioButton,SIGNAL(clicked()),this,SLOT(plusFrameSelected())); connect(ui.xRadioButton,SIGNAL(clicked()),this,SLOT(xFrameSelected())); connect(ui.vRadioButton,SIGNAL(clicked()),this,SLOT(vFrameSelected())); + initConnections(); } FrameTypeConfig::~FrameTypeConfig() diff --git a/src/ui/configuration/OpticalFlowConfig.cc b/src/ui/configuration/OpticalFlowConfig.cc index cc0404a06d..3e8bdb8b78 100644 --- a/src/ui/configuration/OpticalFlowConfig.cc +++ b/src/ui/configuration/OpticalFlowConfig.cc @@ -5,6 +5,7 @@ OpticalFlowConfig::OpticalFlowConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); connect(ui.enableCheckBox,SIGNAL(clicked(bool)),this,SLOT(enableCheckBoxClicked(bool))); + initConnections(); } OpticalFlowConfig::~OpticalFlowConfig() diff --git a/src/ui/configuration/OsdConfig.cc b/src/ui/configuration/OsdConfig.cc index 25f5cd376d..e3280a9c86 100644 --- a/src/ui/configuration/OsdConfig.cc +++ b/src/ui/configuration/OsdConfig.cc @@ -5,6 +5,8 @@ OsdConfig::OsdConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); connect(ui.enablePushButton,SIGNAL(clicked()),this,SLOT(enableButtonClicked())); + initConnections(); + } OsdConfig::~OsdConfig() diff --git a/src/ui/configuration/RadioCalibrationConfig.cc b/src/ui/configuration/RadioCalibrationConfig.cc index e08ccc0702..eb9db6fca9 100644 --- a/src/ui/configuration/RadioCalibrationConfig.cc +++ b/src/ui/configuration/RadioCalibrationConfig.cc @@ -76,6 +76,8 @@ RadioCalibrationConfig::RadioCalibrationConfig(QWidget *parent) : AP2ConfigWidge rcMax << 1900.0 << 1900.0 << 1900.0 << 1900.0 << 1900.0 << 1900.0 << 1900.0 << 1900.0; rcTrim << 1500.0 << 1500.0 << 1500.0 << 1500.0 << 1500.0 << 1500.0 << 1500.0 << 1500.0; rcValue << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0; + + initConnections(); } RadioCalibrationConfig::~RadioCalibrationConfig() diff --git a/src/ui/configuration/SonarConfig.cc b/src/ui/configuration/SonarConfig.cc index 586a7f9ab5..fb8c4687b0 100644 --- a/src/ui/configuration/SonarConfig.cc +++ b/src/ui/configuration/SonarConfig.cc @@ -10,6 +10,8 @@ SonarConfig::SonarConfig(QWidget *parent) : AP2ConfigWidget(parent) ui.sonarTypeComboBox->addItem("HRLV"); connect(ui.enableCheckBox,SIGNAL(toggled(bool)),this,SLOT(checkBoxToggled(bool))); connect(ui.sonarTypeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(sonarTypeChanged(int))); + + initConnections(); } SonarConfig::~SonarConfig() diff --git a/src/ui/configuration/StandardParamConfig.cc b/src/ui/configuration/StandardParamConfig.cc index c9ebb4acf9..caa49ccde4 100644 --- a/src/ui/configuration/StandardParamConfig.cc +++ b/src/ui/configuration/StandardParamConfig.cc @@ -3,6 +3,7 @@ StandardParamConfig::StandardParamConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); + initConnections(); } StandardParamConfig::~StandardParamConfig() { -- GitLab From 15708fb779958c6b3a140839ca2bb7176a5e0ce8 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 30 Jul 2013 14:48:55 -0400 Subject: [PATCH 109/460] Fix for QuickView being unable to add items. Bug introduced with the new multi-column changes --- src/ui/uas/UASQuickView.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ui/uas/UASQuickView.cc b/src/ui/uas/UASQuickView.cc index 23e3fcc2d4..f557c77985 100644 --- a/src/ui/uas/UASQuickView.cc +++ b/src/ui/uas/UASQuickView.cc @@ -143,6 +143,8 @@ void UASQuickView::valueEnabled(QString value) uasPropertyValueMap[value] = 0; } saveSettings(); + item->show(); + sortItems(m_columnCount); } void UASQuickView::sortItems(int columncount) @@ -165,7 +167,7 @@ void UASQuickView::sortItems(int columncount) //Create a vertical layout for every intended column for (int i=0;iaddItem(layout); m_verticalLayoutList.append(layout); } -- GitLab From d35a7cd792d60a08c925772dc3130bc5b0472c14 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 30 Jul 2013 14:57:00 -0400 Subject: [PATCH 110/460] Change for console mode, allows for console window and qDebug() output in release mode --- qgroundcontrol.pro | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 6776f73aa8..70501c5990 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -20,7 +20,8 @@ # Qt configuration CONFIG += qt \ - thread + thread \ + console # serialport QT += network \ -- GitLab From 41c179400897775de610e0047cf4b31bb3830bc5 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 30 Jul 2013 15:13:30 -0400 Subject: [PATCH 111/460] Change so firmware information requests happen 10 seconds after startup instead of 0.5seconds, to avoid a race condition --- src/ui/configuration/ApmFirmwareConfig.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/configuration/ApmFirmwareConfig.cc b/src/ui/configuration/ApmFirmwareConfig.cc index 400b8a029e..40da2c7605 100644 --- a/src/ui/configuration/ApmFirmwareConfig.cc +++ b/src/ui/configuration/ApmFirmwareConfig.cc @@ -31,7 +31,7 @@ ApmFirmwareConfig::ApmFirmwareConfig(QWidget *parent) : QWidget(parent) connect(ui.quadPushButton,SIGNAL(clicked()),this,SLOT(flashButtonClicked())); connect(ui.triPushButton,SIGNAL(clicked()),this,SLOT(flashButtonClicked())); connect(ui.y6PushButton,SIGNAL(clicked()),this,SLOT(flashButtonClicked())); - QTimer::singleShot(500,this,SLOT(requestFirmwares())); + QTimer::singleShot(10000,this,SLOT(requestFirmwares())); connect(ui.betaFirmwareButton,SIGNAL(clicked(bool)),this,SLOT(betaFirmwareButtonClicked(bool))); ui.progressBar->setMaximum(100); -- GitLab From 64bb126e20ec2d5240f96b2b2ba7ed40cd7d0638 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 30 Jul 2013 12:52:38 -0700 Subject: [PATCH 112/460] Start adjusting config UI Start move to single column layout for advanced parameters; Fix crashing bug in PrimaryFlightDisplay when uas is removed and then re-added; workaround compiler warning in GeneralBlockPanelKernel, --- .../Core/products/GeneralBlockPanelKernel.h | 5 +- src/ui/PrimaryFlightDisplay.cc | 3 + src/ui/QGCConfigView.cc | 48 ++++++++------- src/ui/QGCPX4VehicleConfig.cc | 60 +++++++------------ src/ui/QGCPX4VehicleConfig.ui | 55 +++++------------ 5 files changed, 66 insertions(+), 105 deletions(-) diff --git a/libs/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/libs/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h index 2116dcc740..e0344e62a2 100644 --- a/libs/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h +++ b/libs/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h @@ -88,7 +88,7 @@ void computeProductBlockingSizes(std::ptrdiff_t& k, std::ptrdiff_t& m, std::ptrd // at the register level. For vectorization purpose, these small vertical panels are unpacked, // e.g., each coefficient is replicated to fit a packet. This small vertical panel has to // stay in L1 cache. - std::ptrdiff_t l1, l2; + std::ptrdiff_t l1, l2, initial_n; typedef gebp_traits Traits; enum { @@ -98,11 +98,12 @@ void computeProductBlockingSizes(std::ptrdiff_t& k, std::ptrdiff_t& m, std::ptrd mr_mask = (0xffffffff/mr)*mr }; + initial_n = n; manage_caching_sizes(GetAction, &l1, &l2); k = std::min(k, l1/kdiv); std::ptrdiff_t _m = k>0 ? l2/(4 * sizeof(LhsScalar) * k) : 0; if(_m diff --git a/src/ui/PrimaryFlightDisplay.cc b/src/ui/PrimaryFlightDisplay.cc index a68acdf545..d0070d2292 100644 --- a/src/ui/PrimaryFlightDisplay.cc +++ b/src/ui/PrimaryFlightDisplay.cc @@ -293,6 +293,9 @@ void PrimaryFlightDisplay::forgetUAS(UASInterface* uas) */ void PrimaryFlightDisplay::setActiveUAS(UASInterface* uas) { + if (uas == this->uas) + return; //no need to rewire + // Disconnect the previous one (if any) forgetUAS(this->uas); diff --git a/src/ui/QGCConfigView.cc b/src/ui/QGCConfigView.cc index b33e6e664b..ff88f313a0 100644 --- a/src/ui/QGCConfigView.cc +++ b/src/ui/QGCConfigView.cc @@ -14,12 +14,9 @@ QGCConfigView::QGCConfigView(QWidget *parent) : connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(activeUASChanged(UASInterface*))); - if (ui->waitingLabel) { - ui->gridLayout->removeWidget(ui->waitingLabel); - delete ui->waitingLabel; - ui->waitingLabel = NULL; - } - ui->gridLayout->addWidget(new QGCPX4VehicleConfig()); + //don't show a configuration widget if no vehicle is connected + //show a placeholder informational widget instead + } QGCConfigView::~QGCConfigView() @@ -32,26 +29,31 @@ void QGCConfigView::activeUASChanged(UASInterface* uas) if (currUAS == uas) return; - if (ui->waitingLabel) { - ui->gridLayout->removeWidget(ui->waitingLabel); - delete ui->waitingLabel; - ui->waitingLabel = NULL; - } - - if (currUAS && currUAS->getAutopilotType() != uas->getAutopilotType()) { - foreach (QObject* obj, ui->gridLayout->children()) { - QWidget* w = dynamic_cast(obj); - if (w) { - ui->gridLayout->removeWidget(w); + //remove all child widgets since they could contain stale data + //for example, when we switch from one PX4 UAS to another UAS + foreach (QObject* obj, ui->gridLayout->children()) { + QWidget* w = dynamic_cast(obj); + if (w) { + ui->gridLayout->removeWidget(w); + if (obj != ui->waitingLabel) delete obj; - } } } - switch (uas->getAutopilotType()) { - case MAV_AUTOPILOT_PX4: - ui->gridLayout->addWidget(new QGCPX4VehicleConfig()); - default: - ui->gridLayout->addWidget(new QGCVehicleConfig()); + if (NULL != uas) { + ui->gridLayout->removeWidget(ui->waitingLabel); + + switch (uas->getAutopilotType()) { + case MAV_AUTOPILOT_PX4: + ui->gridLayout->addWidget(new QGCPX4VehicleConfig()); + break; + default: + ui->gridLayout->addWidget(new QGCVehicleConfig()); + } } + else { + //restore waiting label if we no longer have a connection + ui->gridLayout->addWidget(ui->waitingLabel); + } + } diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index a0c01d0f5e..b61a81a151 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -18,6 +18,12 @@ #include "QGCToolWidget.h" #include "ui_QGCPX4VehicleConfig.h" + +#define WIDGET_INDEX_RC 0 +#define WIDGET_INDEX_SENSOR_CAL 1 +#define WIDGET_INDEX_GENERAL_CONFIG 2 +#define WIDGET_INDEX_ADV_CONFIG 3 + QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : QWidget(parent), mav(NULL), @@ -107,22 +113,23 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : } void QGCPX4VehicleConfig::rcMenuButtonClicked() { - ui->stackedWidget->setCurrentIndex(0); + //TODO eg ui->stackedWidget->findChild("rcConfig"); + ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_RC); } void QGCPX4VehicleConfig::sensorMenuButtonClicked() { - ui->stackedWidget->setCurrentIndex(1); + ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_SENSOR_CAL); } void QGCPX4VehicleConfig::generalMenuButtonClicked() { - ui->stackedWidget->setCurrentIndex(ui->stackedWidget->count()-2); + ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_GENERAL_CONFIG); } void QGCPX4VehicleConfig::advancedMenuButtonClicked() { - ui->stackedWidget->setCurrentIndex(ui->stackedWidget->count()-1); + ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_ADV_CONFIG); } QGCPX4VehicleConfig::~QGCPX4VehicleConfig() @@ -288,7 +295,7 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) foreach (QString file,vehicledir.entryList(QDir::Files | QDir::NoDotAndDotDot)) { if (file.toLower().endsWith(".qgw")) { - QWidget* parent = left?ui->advancedLeftContents:ui->advancedRightContents; + QWidget* parent = ui->advanceColumnContents; tool = new QGCToolWidget("", parent); if (tool->loadSettings(vehicledir.absoluteFilePath(file), false)) { @@ -297,16 +304,8 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) box->setTitle(tool->objectName()); box->setLayout(new QVBoxLayout(box)); box->layout()->addWidget(tool); - if (left) - { - left = false; - ui->advancedLeftLayout->addWidget(box); - } - else - { - left = true; - ui->advancedRightLayout->addWidget(box); - } + ui->advancedColumnLayout->addWidget(box); + } else { delete tool; } @@ -808,8 +807,9 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) } - // Do nothing if system is the same - if (mav == active) return; + // Do nothing if UAS is already visible + if (mav == active) + return; if (mav) { @@ -829,11 +829,7 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) { child->deleteLater(); } - foreach(QWidget* child, ui->advancedLeftContents->findChildren()) - { - child->deleteLater(); - } - foreach(QWidget* child, ui->advancedRightContents->findChildren()) + foreach(QWidget* child, ui->advanceColumnContents->findChildren()) { child->deleteLater(); } @@ -1184,15 +1180,7 @@ void QGCPX4VehicleConfig::parameterChanged(int uas, int component, QString param if (!found) { //New param type, create a QGroupBox for it. - QWidget* parent; - if (ui->advancedLeftLayout->count() > ui->advancedRightLayout->count()) - { - parent = ui->advancedRightContents; - } - else - { - parent = ui->advancedLeftContents; - } + QWidget* parent = ui->advanceColumnContents; // Create the tool, attaching it to the QGroupBox QGCToolWidget *tool = new QGCToolWidget("", parent); @@ -1214,16 +1202,8 @@ void QGCPX4VehicleConfig::parameterChanged(int uas, int component, QString param libParamToWidgetMap.insert(parameterName,tool); toolWidgets.append(tool); + ui->advancedColumnLayout->addWidget(box); - // Make sure we have similar number of widgets on each side. - if (ui->advancedLeftLayout->count() > ui->advancedRightLayout->count()) - { - ui->advancedRightLayout->addWidget(box); - } - else - { - ui->advancedLeftLayout->addWidget(box); - } toolToBoxMap[tool] = box; } } diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 883dfd72ff..6535f127ca 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -7,7 +7,7 @@ 0 0 1256 - 711 + 783 @@ -43,7 +43,7 @@ 0 0 133 - 691 + 757 @@ -889,7 +889,7 @@ Config <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p></body></html> @@ -906,8 +906,8 @@ p, li { white-space: pre-wrap; } 0 0 - 530 - 574 + 26 + 26 @@ -981,8 +981,8 @@ p, li { white-space: pre-wrap; } 0 0 - 525 - 523 + 16 + 16 @@ -1018,8 +1018,8 @@ p, li { white-space: pre-wrap; } 0 0 - 524 - 523 + 16 + 16 @@ -1065,10 +1065,10 @@ p, li { white-space: pre-wrap; } - + - + Load Platform Defaults @@ -1092,13 +1092,13 @@ p, li { white-space: pre-wrap; } true - + 0 0 - 525 - 523 + 928 + 562 @@ -1106,7 +1106,7 @@ p, li { white-space: pre-wrap; } 0 - + @@ -1124,31 +1124,6 @@ p, li { white-space: pre-wrap; } 0 - - - - true - - - - - 0 - 0 - 524 - 523 - - - - - 0 - - - - - - - - -- GitLab From 0ab6baea4216e04a0af68de5102dfa5ba9b3402f Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 30 Jul 2013 16:55:02 -0700 Subject: [PATCH 113/460] wip new advanced configuration layout --- src/ui/QGCPX4VehicleConfig.cc | 12 +- src/ui/QGCPX4VehicleConfig.ui | 393 +++++++++++++++++++++------------- 2 files changed, 248 insertions(+), 157 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index b61a81a151..f609a78416 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -315,7 +315,7 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) // Load tabs for general configuration foreach (QString dir,generaldir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { - QPushButton *button = new QPushButton(ui->scrollAreaWidgetContents_3); + QPushButton *button = new QPushButton(ui->leftNavScrollAreaWidgetContents); connect(button,SIGNAL(clicked()),this,SLOT(menuButtonClicked())); ui->navBarLayout->insertWidget(2,button); button->setMinimumHeight(75); @@ -359,7 +359,7 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) // Load additional tabs for vehicle specific configuration foreach (QString dir,vehicledir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { - QPushButton *button = new QPushButton(ui->scrollAreaWidgetContents_3); + QPushButton *button = new QPushButton(ui->leftNavScrollAreaWidgetContents); connect(button,SIGNAL(clicked()),this,SLOT(menuButtonClicked())); ui->navBarLayout->insertWidget(2,button); @@ -1362,14 +1362,14 @@ void QGCPX4VehicleConfig::parameterChanged(int uas, int component, QString param void QGCPX4VehicleConfig::updateStatus(const QString& str) { - ui->statusLabel->setText(str); - ui->statusLabel->setStyleSheet(""); + ui->advancedStatusLabel->setText(str); + ui->advancedStatusLabel->setStyleSheet(""); } void QGCPX4VehicleConfig::updateError(const QString& str) { - ui->statusLabel->setText(str); - ui->statusLabel->setStyleSheet(QString("QLabel { margin: 0px 2px; font: 14px; color: %1; background-color: %2; }").arg(QGC::colorDarkWhite.name()).arg(QGC::colorMagenta.name())); + ui->advancedStatusLabel->setText(str); + ui->advancedStatusLabel->setStyleSheet(QString("QLabel { margin: 0px 2px; font: 14px; color: %1; background-color: %2; }").arg(QGC::colorDarkWhite.name()).arg(QGC::colorMagenta.name())); } void QGCPX4VehicleConfig::updateMinMax() { diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 6535f127ca..47f84377ba 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -21,7 +21,7 @@ - + 135 @@ -37,7 +37,7 @@ true - + 0 @@ -138,12 +138,19 @@ Config - 3 + 0 - + + + + 16 + 75 + true + + RC Calibration @@ -873,9 +880,16 @@ Config + + + 16 + 75 + true + + - + Sensor Calibration @@ -889,8 +903,8 @@ Config <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p></body></html> +</style></head><body style=" font-family:'Lucida Grande'; font-size:16pt; font-weight:600; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400;"><br /></p></body></html> @@ -906,8 +920,8 @@ p, li { white-space: pre-wrap; } 0 0 - 26 - 26 + 520 + 700 @@ -925,9 +939,16 @@ p, li { white-space: pre-wrap; } + + + 16 + 75 + true + + - + General Config @@ -953,6 +974,13 @@ p, li { white-space: pre-wrap; } + + + 13 + 50 + false + + Load Platform Defaults @@ -981,8 +1009,8 @@ p, li { white-space: pre-wrap; } 0 0 - 16 - 16 + 514 + 637 @@ -1018,8 +1046,8 @@ p, li { white-space: pre-wrap; } 0 0 - 16 - 16 + 513 + 637 @@ -1043,9 +1071,16 @@ p, li { white-space: pre-wrap; } - + + + + 16 + 75 + true + + - Advanced Config + Advanced Configuration @@ -1079,9 +1114,15 @@ p, li { white-space: pre-wrap; } - + + + + 3 + 1 + + - Configuration + Onboard Configuration @@ -1097,8 +1138,8 @@ p, li { white-space: pre-wrap; } 0 0 - 928 - 562 + 587 + 569 @@ -1112,153 +1153,203 @@ p, li { white-space: pre-wrap; } + + + + + + false + + + Load parameters currently in non-permanent memory of aircraft. + + + + + + Refresh + + + + + + + false + + + Copy parameters from permanent memory to non-permanent current memory of aircraft. DOES NOT update the parameters in this view, click refresh after copying them to get them. + + + + + + + + + Read ROM + + + + + + + false + + + Copy current parameters in non-permanent memory of the aircraft to permanent memory. Transmit your parameters first to write these. + + + + + + Write ROM + + + + + + + false + + + Save parameters in this view to a file on this computer. + + + + + + Save to File + + + + + - + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + + 2 + 0 + + + + + 329 + 0 + + - Configuration + Changes Pending - - - 0 + + + + 10 + 30 + 381 + 601 + - + + + 0 + + + + + + + + false + + + Set current parameters in non-permanent onboard memory. + + + + + + Commit to UAS + + + + + + + false + + + Set current parameters in non-permanent onboard memory. + + + + + + Clear + + + + + + + false + + + Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them. + + + + + + Load from File + + + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + - - - - - - - - - - No pending changes - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - false - - - Copy current parameters in non-permanent memory of the aircraft to permanent memory. Transmit your parameters first to write these. - - - - - - Write (ROM) - - - - - - - false - - - Set current parameters in non-permanent onboard memory. - - - - - - Set (UAS) - - - - - - - false - - - Copy parameters from permanent memory to non-permanent current memory of aircraft. DOES NOT update the parameters in this view, click refresh after copying them to get them. - - - - - - - - - Read (ROM) - - - - - - - false - - - Load parameters currently in non-permanent memory of aircraft. - - - - - - Get (UAS) - - - - - - - false - - - Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them. - - - - - - Load (File) - - - - - - - false - - - Save parameters in this view to a file on this computer. - - - - + + - Save (File) + Status - - + + -- GitLab From dc8f2ec7045b73e335981f84d7535da215340010 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 30 Jul 2013 21:07:49 -0400 Subject: [PATCH 114/460] Changed to increase spacing between QML toolbar items to make text more readable --- qml/ApmToolBar.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qml/ApmToolBar.qml b/qml/ApmToolBar.qml index 234e421952..7e5d297eea 100644 --- a/qml/ApmToolBar.qml +++ b/qml/ApmToolBar.qml @@ -44,7 +44,7 @@ Rectangle { Row { anchors.left: parent.left - spacing: 2 + spacing: 10 Rectangle { // Spacer width: 5 -- GitLab From 0abdb7626e3da47f0f276f640d4de561516c3a4a Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 30 Jul 2013 21:08:09 -0400 Subject: [PATCH 115/460] Reordered InfoView tabs, so Messages is at the end --- src/ui/QGCTabbedInfoView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/QGCTabbedInfoView.cpp b/src/ui/QGCTabbedInfoView.cpp index e319471386..42095760e0 100644 --- a/src/ui/QGCTabbedInfoView.cpp +++ b/src/ui/QGCTabbedInfoView.cpp @@ -7,10 +7,10 @@ QGCTabbedInfoView::QGCTabbedInfoView(QWidget *parent) : QWidget(parent) actionsWidget = new UASActionsWidget(this); quickView = new UASQuickView(this); rawView = new UASRawStatusView(this); - ui.tabWidget->addTab(messageView,"Messages"); ui.tabWidget->addTab(quickView,"Quick"); ui.tabWidget->addTab(actionsWidget,"Actions"); ui.tabWidget->addTab(rawView,"Status"); + ui.tabWidget->addTab(messageView,"Messages"); } void QGCTabbedInfoView::addSource(MAVLinkDecoder *decoder) { -- GitLab From 2ecd72d0f66e663c4ebc9e5f6381db5d6fd5ae15 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 30 Jul 2013 21:08:32 -0400 Subject: [PATCH 116/460] Removed "BETA" tag from firmware button images until they can be done properly --- src/ui/configuration/ApmFirmwareConfig.cc | 27 +++++++++++------------ src/ui/configuration/ApmFirmwareConfig.h | 1 - 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/ui/configuration/ApmFirmwareConfig.cc b/src/ui/configuration/ApmFirmwareConfig.cc index 40da2c7605..4ef8950d59 100644 --- a/src/ui/configuration/ApmFirmwareConfig.cc +++ b/src/ui/configuration/ApmFirmwareConfig.cc @@ -40,7 +40,7 @@ ApmFirmwareConfig::ApmFirmwareConfig(QWidget *parent) : QWidget(parent) ui.textBrowser->setVisible(false); connect(ui.showOutputCheckBox,SIGNAL(clicked(bool)),ui.textBrowser,SLOT(setShown(bool))); - addBetaLabel(ui.roverPushButton); + /*addBetaLabel(ui.roverPushButton); addBetaLabel(ui.planePushButton); addBetaLabel(ui.copterPushButton); addBetaLabel(ui.quadPushButton); @@ -48,7 +48,7 @@ ApmFirmwareConfig::ApmFirmwareConfig(QWidget *parent) : QWidget(parent) addBetaLabel(ui.octaQuadPushButton); addBetaLabel(ui.octaPushButton); addBetaLabel(ui.triPushButton); - addBetaLabel(ui.y6PushButton); + addBetaLabel(ui.y6PushButton);*/ } void ApmFirmwareConfig::hideBetaLabels() @@ -71,7 +71,6 @@ void ApmFirmwareConfig::showBetaLabels() void ApmFirmwareConfig::addBetaLabel(QWidget *parent) { - QLabel *label = new QLabel(parent); QVBoxLayout *layout = new QVBoxLayout(); parent->setLayout(layout); @@ -410,51 +409,51 @@ void ApmFirmwareConfig::firmwareListFinished() QString outstr = ""; if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-heli",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.copterLabel->setText(outstr); + ui.copterLabel->setText((m_betaFirmwareChecked ? "BETA " : "") + outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-quad",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.quadLabel->setText(outstr); + ui.quadLabel->setText((m_betaFirmwareChecked ? "BETA " : "") + outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-hexa",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.hexaLabel->setText(outstr); + ui.hexaLabel->setText((m_betaFirmwareChecked ? "BETA " : "") + outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-octa-quad",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.octaQuadLabel->setText(outstr); + ui.octaQuadLabel->setText((m_betaFirmwareChecked ? "BETA " : "") + outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-octa",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.octaLabel->setText(outstr); + ui.octaLabel->setText((m_betaFirmwareChecked ? "BETA " : "") + outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-tri",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.triLabel->setText(outstr); + ui.triLabel->setText((m_betaFirmwareChecked ? "BETA " : "") + outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"apm2-y6",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.y6Label->setText(outstr); + ui.y6Label->setText((m_betaFirmwareChecked ? "BETA " : "") + outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"Plane",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.planeLabel->setText(outstr); + ui.planeLabel->setText((m_betaFirmwareChecked ? "BETA " : "") + outstr); return; } if (stripVersionFromGitReply(reply->url().toString(),replystr,"Rover",(m_betaFirmwareChecked ? "beta" : "stable"),&outstr)) { - ui.roverLabel->setText(outstr); + ui.roverLabel->setText((m_betaFirmwareChecked ? "BETA " : "") + outstr); return; } - qDebug() << "Match not found for:" << reply->url(); - qDebug() << "Git version line:" << replystr; + //qDebug() << "Match not found for:" << reply->url(); + //qDebug() << "Git version line:" << replystr; } ApmFirmwareConfig::~ApmFirmwareConfig() diff --git a/src/ui/configuration/ApmFirmwareConfig.h b/src/ui/configuration/ApmFirmwareConfig.h index 51c8fdb786..07c1fa9b15 100644 --- a/src/ui/configuration/ApmFirmwareConfig.h +++ b/src/ui/configuration/ApmFirmwareConfig.h @@ -35,7 +35,6 @@ private slots: void firmwareDownloadProgress(qint64 received,qint64 total); void requestFirmwares(); void requestBetaFirmwares(); - private: void addBetaLabel(QWidget *parent); void hideBetaLabels(); -- GitLab From 4dbb954de8c7257c32a49801c46d60191c24fd8b Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 30 Jul 2013 21:09:04 -0400 Subject: [PATCH 117/460] Fix for accelerometer config failure leading to inability to recalibrate. Also changing screen will void calibration and require recalibration. --- .../configuration/AccelCalibrationConfig.cc | 34 +++++++++++++++++-- src/ui/configuration/AccelCalibrationConfig.h | 2 ++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/ui/configuration/AccelCalibrationConfig.cc b/src/ui/configuration/AccelCalibrationConfig.cc index a92702482a..f552580d1f 100644 --- a/src/ui/configuration/AccelCalibrationConfig.cc +++ b/src/ui/configuration/AccelCalibrationConfig.cc @@ -57,9 +57,29 @@ void AccelCalibrationConfig::calibrateButtonClicked() { m_uas->executeCommandAck(m_accelAckCount++,true); ui.calibrateAccelButton->setText("Calibrate\nAccelerometer"); + if (m_accelAckCount > 8) + { + //We've clicked too many times! Reset. + for (int i=0;i<8;i++) + { + m_uas->executeCommandAck(i,true); + } + m_accelAckCount = 0; + } } } +void AccelCalibrationConfig::hideEvent(QHideEvent *evt) +{ + if (!m_uas || !m_accelAckCount) + { + return; + } + for (int i=m_accelAckCount;i<8;i++) + { + m_uas->executeCommandAck(i,true); //Clear out extra commands. + } +} void AccelCalibrationConfig::uasTextMessageReceived(int uasid, int componentid, int severity, QString text) { //command received: " Severity 1 @@ -70,7 +90,7 @@ void AccelCalibrationConfig::uasTextMessageReceived(int uasid, int componentid, if (m_accelAckCount == 0) { //Calibration Sucessful\r" - ui.calibrateAccelButton->setText("Any\nKey"); + ui.calibrateAccelButton->setText("Continue"); m_accelAckCount++; } if (m_accelAckCount == 7) @@ -86,11 +106,21 @@ void AccelCalibrationConfig::uasTextMessageReceived(int uasid, int componentid, { m_accelAckCount = 0; } + else if (text.contains("Calibration") && text.contains("FAILED")) //Failure + { + m_accelAckCount = 0; + } ui.outputLabel->setText(ui.outputLabel->text() + "\n" + text); } else { - ui.outputLabel->setText(text); + ui.outputLabel->setText(text.replace("press any key","click Continue below")); + if (!this->isVisible()) + { + //Clear out! + m_uas->executeCommandAck(m_accelAckCount++,true); + ui.calibrateAccelButton->setText("Calibrate\nAccelerometer"); + } } } diff --git a/src/ui/configuration/AccelCalibrationConfig.h b/src/ui/configuration/AccelCalibrationConfig.h index ef6f6e1a17..1526562534 100644 --- a/src/ui/configuration/AccelCalibrationConfig.h +++ b/src/ui/configuration/AccelCalibrationConfig.h @@ -14,6 +14,8 @@ class AccelCalibrationConfig : public AP2ConfigWidget public: explicit AccelCalibrationConfig(QWidget *parent = 0); ~AccelCalibrationConfig(); +protected: + void hideEvent(QHideEvent *evt); private slots: void activeUASSet(UASInterface *uas); void calibrateButtonClicked(); -- GitLab From 8797ecd5b4355104f4631fe43da0b477f480d9d2 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 30 Jul 2013 21:09:42 -0400 Subject: [PATCH 118/460] Changed "Adv Parameter List" to "Full Parameter List" --- src/ui/configuration/ApmSoftwareConfig.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/configuration/ApmSoftwareConfig.ui b/src/ui/configuration/ApmSoftwareConfig.ui index c29e3b6ff7..c9b04f30d0 100644 --- a/src/ui/configuration/ApmSoftwareConfig.ui +++ b/src/ui/configuration/ApmSoftwareConfig.ui @@ -132,7 +132,7 @@ - Adv Parameter List + Full Parameter List false -- GitLab From 3a5e2815bc2a19ab00bb6cd18947b09c7a58efba Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 30 Jul 2013 18:11:07 -0700 Subject: [PATCH 119/460] Fixes for displaying RC Ch5-Ch8 --- src/ui/QGCPX4VehicleConfig.cc | 222 +++++++++++++++++----------------- src/ui/QGCPX4VehicleConfig.h | 5 +- 2 files changed, 114 insertions(+), 113 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index f609a78416..787262f11b 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -1374,7 +1374,8 @@ void QGCPX4VehicleConfig::updateError(const QString& str) void QGCPX4VehicleConfig::updateMinMax() { // Order is: roll, pitch, yaw, throttle, mode sw, aux 1-3 - /*ui->rollWidget->setMin(rcMin[0]); + /* + *ui->rollWidget->setMin(rcMin[0]); ui->rollWidget->setMax(rcMax[0]); ui->pitchWidget->setMin(rcMin[1]); ui->pitchWidget->setMax(rcMax[1]); @@ -1389,7 +1390,8 @@ void QGCPX4VehicleConfig::updateMinMax() ui->radio7Widget->setMin(rcMin[6]); ui->radio7Widget->setMax(rcMax[6]); ui->radio8Widget->setMin(rcMin[7]); - ui->radio8Widget->setMax(rcMax[7]);*/ + ui->radio8Widget->setMax(rcMax[7]); +*/ } void QGCPX4VehicleConfig::setRCType(int type) @@ -1414,143 +1416,141 @@ void QGCPX4VehicleConfig::checktimeOuts() } } + +void QGCPX4VehicleConfig::updateRcWidgetValues() +{ + switch (rc_mode) { + case RC_MODE_1: + ui->rollWidget->setValue(rcValue[0]); + ui->throttleWidget->setValue(rcValue[1]); + ui->yawWidget->setValue(rcValue[2]); + ui->pitchWidget->setValue(rcValue[3]); + + ui->rollWidget->setMin(rcMin[0]); + ui->rollWidget->setMax(rcMax[0]); + ui->throttleWidget->setMin(rcMin[1]); + ui->throttleWidget->setMax(rcMax[1]); + ui->yawWidget->setMin(rcMin[2]); + ui->yawWidget->setMax(rcMax[2]); + ui->pitchWidget->setMin(rcMin[3]); + ui->pitchWidget->setMax(rcMax[3]); + break; + + case RC_MODE_2: + ui->rollWidget->setValue(rcValue[0]); + ui->pitchWidget->setValue(rcValue[1]); + ui->yawWidget->setValue(rcValue[2]); + ui->throttleWidget->setValue(rcValue[3]); + + ui->rollWidget->setMin(rcMin[0]); + ui->rollWidget->setMax(rcMax[0]); + ui->pitchWidget->setMin(rcMin[1]); + ui->pitchWidget->setMax(rcMax[1]); + ui->yawWidget->setMin(rcMin[2]); + ui->yawWidget->setMax(rcMax[2]); + ui->throttleWidget->setMin(rcMin[3]); + ui->throttleWidget->setMax(rcMax[3]); + break; + + case RC_MODE_3: + ui->yawWidget->setValue(rcValue[0]); + ui->throttleWidget->setValue(rcValue[1]); + ui->rollWidget->setValue(rcValue[2]); + ui->pitchWidget->setValue(rcValue[3]); + + ui->yawWidget->setMin(rcMin[0]); + ui->yawWidget->setMax(rcMax[0]); + ui->throttleWidget->setMin(rcMin[1]); + ui->throttleWidget->setMax(rcMax[1]); + ui->rollWidget->setMin(rcMin[2]); + ui->rollWidget->setMax(rcMax[2]); + ui->pitchWidget->setMin(rcMin[3]); + ui->pitchWidget->setMax(rcMax[3]); + break; + + case RC_MODE_4: + ui->yawWidget->setValue(rcValue[0]); + ui->pitchWidget->setValue(rcValue[1]); + ui->rollWidget->setValue(rcValue[2]); + ui->throttleWidget->setValue(rcValue[3]); + + ui->yawWidget->setMin(rcMin[0]); + ui->yawWidget->setMax(rcMax[0]); + ui->pitchWidget->setMin(rcMin[1]); + ui->pitchWidget->setMax(rcMax[1]); + ui->rollWidget->setMin(rcMin[2]); + ui->rollWidget->setMax(rcMax[2]); + ui->throttleWidget->setMin(rcMin[3]); + ui->throttleWidget->setMax(rcMax[3]); + break; + + case RC_MODE_NONE: + ui->rollWidget->setValue(rcValue[0]); + ui->pitchWidget->setValue(rcValue[1]); + ui->throttleWidget->setValue(rcValue[2]); + ui->yawWidget->setValue(rcValue[3]); + + ui->rollWidget->setMin(800); + ui->rollWidget->setMax(2200); + ui->pitchWidget->setMin(800); + ui->pitchWidget->setMax(2200); + ui->throttleWidget->setMin(800); + ui->throttleWidget->setMax(2200); + ui->yawWidget->setMin(800); + ui->yawWidget->setMax(2200); + break; + } + + + ui->radio5Widget->setMin(rcMin[4]); + ui->radio5Widget->setMax(rcMax[4]); + ui->radio5Widget->setValue(rcValue[4]); + + ui->radio6Widget->setMin(rcMin[5]); + ui->radio6Widget->setMax(rcMax[5]); + ui->radio6Widget->setValue(rcValue[5]); + + ui->radio7Widget->setMin(rcMin[6]); + ui->radio7Widget->setMax(rcMax[6]); + ui->radio7Widget->setValue(rcValue[6]); + + ui->radio8Widget->setMin(rcMin[7]); + ui->radio8Widget->setMax(rcMax[7]); + ui->radio8Widget->setValue(rcValue[7]); + +} + void QGCPX4VehicleConfig::updateView() { if (changed) { - if (rc_mode == RC_MODE_1) - { - //ui->rollSlider->setValue(rcRoll * 50 + 50); - //ui->pitchSlider->setValue(rcThrottle * 100); - //ui->yawSlider->setValue(rcYaw * 50 + 50); - //ui->throttleSlider->setValue(rcPitch * 50 + 50); - ui->rollWidget->setValue(rcValue[0]); - ui->throttleWidget->setValue(rcValue[1]); - ui->yawWidget->setValue(rcValue[2]); - ui->pitchWidget->setValue(rcValue[3]); - - ui->rollWidget->setMin(rcMin[0]); - ui->rollWidget->setMax(rcMax[0]); - ui->throttleWidget->setMin(rcMin[1]); - ui->throttleWidget->setMax(rcMax[1]); - ui->yawWidget->setMin(rcMin[2]); - ui->yawWidget->setMax(rcMax[2]); - ui->pitchWidget->setMin(rcMin[3]); - ui->pitchWidget->setMax(rcMax[3]); - } - else if (rc_mode == RC_MODE_2) - { - //ui->rollSlider->setValue(rcRoll * 50 + 50); - //ui->pitchSlider->setValue(rcPitch * 50 + 50); - //ui->yawSlider->setValue(rcYaw * 50 + 50); - //ui->throttleSlider->setValue(rcThrottle * 100); - ui->rollWidget->setValue(rcValue[0]); - ui->pitchWidget->setValue(rcValue[1]); - ui->yawWidget->setValue(rcValue[2]); - ui->throttleWidget->setValue(rcValue[3]); - - ui->rollWidget->setMin(rcMin[0]); - ui->rollWidget->setMax(rcMax[0]); - ui->pitchWidget->setMin(rcMin[1]); - ui->pitchWidget->setMax(rcMax[1]); - ui->yawWidget->setMin(rcMin[2]); - ui->yawWidget->setMax(rcMax[2]); - ui->throttleWidget->setMin(rcMin[3]); - ui->throttleWidget->setMax(rcMax[3]); - } - else if (rc_mode == RC_MODE_3) - { - //ui->rollSlider->setValue(rcYaw * 50 + 50); - //ui->pitchSlider->setValue(rcThrottle * 100); - //ui->yawSlider->setValue(rcRoll * 50 + 50); - //ui->throttleSlider->setValue(rcPitch * 50 + 50); - ui->yawWidget->setValue(rcValue[0]); - ui->throttleWidget->setValue(rcValue[1]); - ui->rollWidget->setValue(rcValue[2]); - ui->pitchWidget->setValue(rcValue[3]); - - ui->yawWidget->setMin(rcMin[0]); - ui->yawWidget->setMax(rcMax[0]); - ui->throttleWidget->setMin(rcMin[1]); - ui->throttleWidget->setMax(rcMax[1]); - ui->rollWidget->setMin(rcMin[2]); - ui->rollWidget->setMax(rcMax[2]); - ui->pitchWidget->setMin(rcMin[3]); - ui->pitchWidget->setMax(rcMax[3]); - } - else if (rc_mode == RC_MODE_4) - { - //ui->rollSlider->setValue(rcYaw * 50 + 50); - //ui->pitchSlider->setValue(rcPitch * 50 + 50); - //ui->yawSlider->setValue(rcRoll * 50 + 50); - //ui->throttleSlider->setValue(rcThrottle * 100); - ui->yawWidget->setValue(rcValue[0]); - ui->pitchWidget->setValue(rcValue[1]); - ui->rollWidget->setValue(rcValue[2]); - ui->throttleWidget->setValue(rcValue[3]); - - ui->yawWidget->setMin(rcMin[0]); - ui->yawWidget->setMax(rcMax[0]); - ui->pitchWidget->setMin(rcMin[1]); - ui->pitchWidget->setMax(rcMax[1]); - ui->rollWidget->setMin(rcMin[2]); - ui->rollWidget->setMax(rcMax[2]); - ui->throttleWidget->setMin(rcMin[3]); - ui->throttleWidget->setMax(rcMax[3]); - } - else if (rc_mode == RC_MODE_NONE) - { - ui->rollWidget->setValue(rcValue[0]); - ui->pitchWidget->setValue(rcValue[1]); - ui->throttleWidget->setValue(rcValue[2]); - ui->yawWidget->setValue(rcValue[3]); - - ui->rollWidget->setMin(800); - ui->rollWidget->setMax(2200); - ui->pitchWidget->setMin(800); - ui->pitchWidget->setMax(2200); - ui->throttleWidget->setMin(800); - ui->throttleWidget->setMax(2200); - ui->yawWidget->setMin(800); - ui->yawWidget->setMax(2200); - } + updateRcWidgetValues(); + //update the channel labels ui->chanLabel->setText(QString("%1/%2").arg(rcValue[rcMapping[0]]).arg(rcRoll, 5, 'f', 2, QChar(' '))); ui->chanLabel_2->setText(QString("%1/%2").arg(rcValue[rcMapping[1]]).arg(rcPitch, 5, 'f', 2, QChar(' '))); ui->chanLabel_3->setText(QString("%1/%2").arg(rcValue[rcMapping[2]]).arg(rcYaw, 5, 'f', 2, QChar(' '))); ui->chanLabel_4->setText(QString("%1/%2").arg(rcValue[rcMapping[3]]).arg(rcThrottle, 5, 'f', 2, QChar(' '))); - - - //ui->modeSwitchSlider->setValue(rcMode * 50 + 50); - ui->chanLabel_5->setText(QString("%1/%2").arg(rcValue[rcMapping[4]]).arg(rcMode, 5, 'f', 2, QChar(' '))); - if (rcValue[rcMapping[4] != UINT16_MAX]) { - ui->radio5Widget->setValue(rcValue[4]); - ui->chanLabel_5->setText(QString("%1/%2").arg(rcValue[rcMapping[5]]).arg(rcAux1, 5, 'f', 2, QChar(' '))); + ui->chanLabel_5->setText(QString("%1/%2").arg(rcValue[rcMapping[4]]).arg(rcMode, 5, 'f', 2, QChar(' '))); } else { ui->chanLabel_5->setText(tr("---")); } if (rcValue[rcMapping[5]] != UINT16_MAX) { - //ui->aux1Slider->setValue(rcAux1 * 50 + 50); - ui->radio6Widget->setValue(rcValue[5]); ui->chanLabel_6->setText(QString("%1/%2").arg(rcValue[rcMapping[5]]).arg(rcAux1, 5, 'f', 2, QChar(' '))); } else { ui->chanLabel_6->setText(tr("---")); } if (rcValue[rcMapping[6]] != UINT16_MAX) { - //ui->aux2Slider->setValue(rcAux2 * 50 + 50); - ui->radio7Widget->setValue(rcValue[6]); ui->chanLabel_7->setText(QString("%1/%2").arg(rcValue[rcMapping[6]]).arg(rcAux2, 5, 'f', 2, QChar(' '))); } else { ui->chanLabel_7->setText(tr("---")); } if (rcValue[rcMapping[7]] != UINT16_MAX) { - //ui->aux3Slider->setValue(rcAux3 * 50 + 50); - ui->radio8Widget->setValue(rcValue[7]); ui->chanLabel_8->setText(QString("%1/%2").arg(rcValue[rcMapping[7]]).arg(rcAux3, 5, 'f', 2, QChar(' '))); } else { ui->chanLabel_8->setText(tr("---")); diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index 4ed7e00698..360d481213 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -56,6 +56,7 @@ public slots: void setRCModeIndex(int newRcMode); /** Render the data updated */ void updateView(); + void updateRcWidgetValues(); void updateMinMax(); @@ -176,8 +177,8 @@ protected: float rcThrottle; ///< PPM input channel used as throttle control input float rcMode; ///< PPM input channel used as mode switch control input float rcAux1; ///< PPM input channel used as aux 1 input - float rcAux2; ///< PPM input channel used as aux 1 input - float rcAux3; ///< PPM input channel used as aux 1 input + float rcAux2; ///< PPM input channel used as aux 2 input + float rcAux3; ///< PPM input channel used as aux 3 input bool rcCalChanged; ///< Set if the calibration changes (and needs to be written) bool changed; ///< Set if any of the input data changed QTimer updateTimer; ///< Controls update intervals -- GitLab From 4034178a1b1ab87bb729a39536763b8f30c4e57f Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sun, 21 Jul 2013 14:16:03 -0700 Subject: [PATCH 120/460] Workaround google maps breakage Add map type selector menu; use Bing maps by default; zoom to a more human scale on Go Home --- src/ui/map/QGCMapToolBar.cc | 60 +++++++++++++++++++++++++++++++------ src/ui/map/QGCMapToolBar.h | 4 +++ src/ui/map/QGCMapWidget.cc | 7 +++++ 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/ui/map/QGCMapToolBar.cc b/src/ui/map/QGCMapToolBar.cc index eebc1f75ee..067544bcd2 100644 --- a/src/ui/map/QGCMapToolBar.cc +++ b/src/ui/map/QGCMapToolBar.cc @@ -7,8 +7,10 @@ QGCMapToolBar::QGCMapToolBar(QWidget *parent) : ui(new Ui::QGCMapToolBar), map(NULL), optionsMenu(this), + mapTypesMenu(this), trailPlotMenu(this), updateTimesMenu(this), + mapTypesGroup(new QActionGroup(this)), trailSettingsGroup(new QActionGroup(this)), updateTimesGroup(new QActionGroup(this)) { @@ -45,21 +47,43 @@ void QGCMapToolBar::setMap(QGCMapWidget* map) // Set exclusive items trailSettingsGroup->setExclusive(true); updateTimesGroup->setExclusive(true); - + mapTypesGroup->setExclusive(true); // Build up menu trailPlotMenu.setTitle(tr("&Add trail dot every..")); updateTimesMenu.setTitle(tr("&Limit map view update rate to..")); + mapTypesMenu.setTitle(tr("&Map type")); - // FIXME MARK CURRENT VALUES IN MENU - QAction* action = trailPlotMenu.addAction(tr("No trail"), this, SLOT(setUAVTrailTime())); - action->setData(-1); + + //setup the mapTypesMenu + QAction* action; + action = mapTypesMenu.addAction(tr("Bing Hybrid"),this,SLOT(setMapType())); + action->setData(MapType::BingHybrid); + action->setCheckable(true); + mapTypesGroup->addAction(action); + + action = mapTypesMenu.addAction(tr("Google Hybrid"),this,SLOT(setMapType())); + action->setData(MapType::GoogleHybrid); + action->setCheckable(true); + mapTypesGroup->addAction(action); + + action = mapTypesMenu.addAction(tr("OpenStreetMap"),this,SLOT(setMapType())); + action->setData(MapType::OpenStreetMap); action->setCheckable(true); - trailSettingsGroup->addAction(action); + mapTypesGroup->addAction(action); + //TODO check current item + optionsMenu.addMenu(&mapTypesMenu); + + + // FIXME MARK CURRENT VALUES IN MENU + QAction *defaultTrailAction = trailPlotMenu.addAction(tr("No trail"), this, SLOT(setUAVTrailTime())); + defaultTrailAction->setData(-1); + defaultTrailAction->setCheckable(true); + trailSettingsGroup->addAction(defaultTrailAction); for (int i = 0; i < uavTrailTimeCount; ++i) { - QAction* action = trailPlotMenu.addAction(tr("%1 second%2").arg(uavTrailTimeList[i]).arg((uavTrailTimeList[i] > 1) ? "s" : ""), this, SLOT(setUAVTrailTime())); + action = trailPlotMenu.addAction(tr("%1 second%2").arg(uavTrailTimeList[i]).arg((uavTrailTimeList[i] > 1) ? "s" : ""), this, SLOT(setUAVTrailTime())); action->setData(uavTrailTimeList[i]); action->setCheckable(true); trailSettingsGroup->addAction(action); @@ -71,7 +95,7 @@ void QGCMapToolBar::setMap(QGCMapWidget* map) } for (int i = 0; i < uavTrailDistanceCount; ++i) { - QAction* action = trailPlotMenu.addAction(tr("%1 meter%2").arg(uavTrailDistanceList[i]).arg((uavTrailDistanceList[i] > 1) ? "s" : ""), this, SLOT(setUAVTrailDistance())); + action = trailPlotMenu.addAction(tr("%1 meter%2").arg(uavTrailDistanceList[i]).arg((uavTrailDistanceList[i] > 1) ? "s" : ""), this, SLOT(setUAVTrailDistance())); action->setData(uavTrailDistanceList[i]); action->setCheckable(true); trailSettingsGroup->addAction(action); @@ -85,7 +109,7 @@ void QGCMapToolBar::setMap(QGCMapWidget* map) // Set no trail checked if no action is checked yet if (!trailSettingsGroup->checkedAction()) { - action->setChecked(true); + defaultTrailAction->setChecked(true); } optionsMenu.addMenu(&trailPlotMenu); @@ -119,7 +143,6 @@ void QGCMapToolBar::setMap(QGCMapWidget* map) } optionsMenu.addMenu(&updateTimesMenu); - ui->optionsButton->setMenu(&optionsMenu); } } @@ -175,6 +198,23 @@ void QGCMapToolBar::setUpdateInterval() } } +void QGCMapToolBar::setMapType() +{ + QObject* sender = QObject::sender(); + QAction* action = qobject_cast(sender); + + if (action) + { + bool ok; + int mapType = action->data().toInt(&ok); + if (ok) + { + map->SetMapType((MapType::Types)mapType); + ui->posLabel->setText(tr("Map type: %1").arg(mapType)); + } + } +} + void QGCMapToolBar::tileLoadStart() { ui->posLabel->setText(tr("Starting to load tiles..")); @@ -201,10 +241,12 @@ void QGCMapToolBar::tileLoadProgress(int progress) } } + QGCMapToolBar::~QGCMapToolBar() { delete ui; delete trailSettingsGroup; delete updateTimesGroup; + delete mapTypesGroup; // FIXME Delete all actions } diff --git a/src/ui/map/QGCMapToolBar.h b/src/ui/map/QGCMapToolBar.h index a7e75f220f..b03d2b9fdb 100644 --- a/src/ui/map/QGCMapToolBar.h +++ b/src/ui/map/QGCMapToolBar.h @@ -28,6 +28,7 @@ public slots: void setUAVTrailTime(); void setUAVTrailDistance(); void setUpdateInterval(); + void setMapType(); private: Ui::QGCMapToolBar *ui; @@ -37,8 +38,11 @@ protected: QMenu optionsMenu; QMenu trailPlotMenu; QMenu updateTimesMenu; + QMenu mapTypesMenu; + QActionGroup* trailSettingsGroup; QActionGroup* updateTimesGroup; + QActionGroup* mapTypesGroup; }; #endif // QGCMAPTOOLBAR_H diff --git a/src/ui/map/QGCMapWidget.cc b/src/ui/map/QGCMapWidget.cc index d52994aae9..87d1a7f1c0 100644 --- a/src/ui/map/QGCMapWidget.cc +++ b/src/ui/map/QGCMapWidget.cc @@ -30,6 +30,12 @@ QGCMapWidget::QGCMapWidget(QWidget *parent) : defaultGuidedAlt = -1; loadSettings(false); + //handy for debugging: + //this->SetShowTileGridLines(true); + + //default appears to be Google Hybrid, and is broken currently + this->SetMapType(MapType::BingHybrid); + this->setContextMenuPolicy(Qt::ActionsContextMenu); QAction *guidedaction = new QAction(this); @@ -511,6 +517,7 @@ void QGCMapWidget::updateHomePosition(double latitude, double longitude, double void QGCMapWidget::goHome() { SetCurrentPosition(Home->Coord()); + SetZoom(18); //zoom to "large RC park" size } /** -- GitLab From eb59fcb59f47cc2f3df6fcc9c5bd5f4c80037b6a Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Tue, 30 Jul 2013 21:52:18 -0400 Subject: [PATCH 121/460] Fix for saving and reloading QuickView column count --- src/ui/uas/UASQuickView.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/uas/UASQuickView.cc b/src/ui/uas/UASQuickView.cc index f557c77985..40039dd305 100644 --- a/src/ui/uas/UASQuickView.cc +++ b/src/ui/uas/UASQuickView.cc @@ -106,6 +106,7 @@ void UASQuickView::saveSettings() void UASQuickView::loadSettings() { QSettings settings; + m_columnCount = settings.value("UAS_QUICK_VIEW_COLUMNS",1).toInt(); int size = settings.beginReadArray("UAS_QUICK_VIEW_ITEMS"); for (int i=0;i Date: Tue, 30 Jul 2013 19:27:24 -0700 Subject: [PATCH 122/460] improve visiblity of RC channel indicators --- src/ui/designer/QGCRadioChannelDisplay.cpp | 127 ++++++++++++--------- src/ui/designer/QGCRadioChannelDisplay.h | 2 + 2 files changed, 77 insertions(+), 52 deletions(-) diff --git a/src/ui/designer/QGCRadioChannelDisplay.cpp b/src/ui/designer/QGCRadioChannelDisplay.cpp index 148965eb61..12620cb610 100644 --- a/src/ui/designer/QGCRadioChannelDisplay.cpp +++ b/src/ui/designer/QGCRadioChannelDisplay.cpp @@ -1,6 +1,7 @@ #include "QGCRadioChannelDisplay.h" #include QGCRadioChannelDisplay::QGCRadioChannelDisplay(QWidget *parent) : QWidget(parent) + { m_showMinMax = false; m_min = 0; @@ -8,6 +9,10 @@ QGCRadioChannelDisplay::QGCRadioChannelDisplay(QWidget *parent) : QWidget(parent m_value = 1500; m_orientation = Qt::Vertical; m_name = "Yaw"; + + m_fillBrush = QBrush(Qt::green, Qt::SolidPattern); + + } void QGCRadioChannelDisplay::setName(QString name) { @@ -26,81 +31,99 @@ void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) //1500 is the middle, static servo value. QPainter painter(this); - int currval = m_value; - if (currval > m_max) - { - currval = m_max; + int fontHeight = painter.fontMetrics().height(); + int twiceFontHeight = fontHeight * 2; + + painter.setBrush(Qt::Dense4Pattern); + painter.setPen(QColor::fromRgb(128,128,64)); + + int curVal = m_value; + if (curVal > m_max) { + curVal = m_max; } - if (currval < m_min) - { - currval = m_min; + if (curVal < m_min) { + curVal = m_min; } if (m_orientation == Qt::Vertical) { - painter.drawRect(0,0,width()-1,(height()-1) - (painter.fontMetrics().height() * 2)); - painter.setBrush(Qt::SolidPattern); + //draw border + painter.drawRect(0,0,width()-1,(height()-1) - twiceFontHeight); painter.setPen(QColor::fromRgb(50,255,50)); - //m_value - m_min / m_max - m_min + painter.setBrush(Qt::SolidPattern); - if (!m_showMinMax) - { - int newval = (height()-2-(painter.fontMetrics().height() * 2)) * ((float)(currval - m_min) / ((m_max-m_min)+1)); - int newvaly = (height()-2-(painter.fontMetrics().height() * 2)) - newval; - painter.drawRect(1,newvaly,width()-3,((height()-2) - newvaly - (painter.fontMetrics().height() * 2))); - } - else - { - int newval = (height()-2-(painter.fontMetrics().height() * 2)) * ((float)(currval / 3001.0)); - int newvaly = (height()-2-(painter.fontMetrics().height() * 2)) - newval; - painter.drawRect(1,newvaly,width()-3,((height()-2) - newvaly - (painter.fontMetrics().height() * 2))); + //draw the text value of the widget, and its label + QString valStr = QString::number(m_value); + painter.setPen(QColor::fromRgb(255,255,255)); + painter.drawText((width()/2.0) - (painter.fontMetrics().width(m_name)/2.0),((height()-3) - (fontHeight*1)),m_name); + painter.drawText((width()/2.0) - (painter.fontMetrics().width(valStr)/2.0),((height()-3) - (fontHeight * 0)),valStr); + + + painter.setPen(QColor::fromRgb(128,128,64)); + painter.setBrush(m_fillBrush); + + if (!m_showMinMax) { + //draw just the value + int newval = (height()-2-twiceFontHeight) * ((float)(curVal - m_min) / ((m_max-m_min)+1)); + int yVal = (height()-2-twiceFontHeight) - newval; + painter.drawRect(1,yVal,width()-3,((height()-2) - yVal - twiceFontHeight)); } + else { + //draw the value + int newval = (height()-2-twiceFontHeight) * ((float)(curVal / 3001.0)); + int yVal = (height()-2-twiceFontHeight) - newval; + painter.drawRect(1,yVal,width()-3,((height()-2) - yVal - twiceFontHeight)); - QString valstr = QString::number(m_value); - painter.setPen(QColor::fromRgb(255,255,255)); - painter.drawText((width()/2.0) - (painter.fontMetrics().width(m_name)/2.0),((height()-3) - (painter.fontMetrics().height()*1)),m_name); - painter.drawText((width()/2.0) - (painter.fontMetrics().width(valstr)/2.0),((height()-3) - (painter.fontMetrics().height() * 0)),valstr); - if (m_showMinMax) - { - painter.setBrush(Qt::NoBrush); + //draw min max indicator bars painter.setPen(QColor::fromRgb(255,0,0)); - int maxyval = (height()-3 - (painter.fontMetrics().height() * 2)) - (((height()-3-(painter.fontMetrics().height() * 2)) * ((float)m_max / 3000.0))); - int minyval = (height()-3 - (painter.fontMetrics().height() * 2)) - (((height()-3-(painter.fontMetrics().height() * 2)) * ((float)m_min / 3000.0))); - painter.drawRect(2,maxyval,width()-3,minyval - maxyval); + painter.setBrush(Qt::NoBrush); + + int yMax = (height()-3 - twiceFontHeight) - (((height()-3-twiceFontHeight) * ((float)m_max / 3000.0))); + int yMin = (height()-3 - twiceFontHeight) - (((height()-3-twiceFontHeight) * ((float)m_min / 3000.0))); + painter.drawRect(2,yMax,width()-3,yMin - yMax); + + //draw min and max labels QString minstr = QString::number(m_min); - painter.drawText((width() / 2.0) - (painter.fontMetrics().width("min")/2.0),minyval,"min"); - painter.drawText((width() / 2.0) - (painter.fontMetrics().width(minstr)/2.0),minyval + painter.fontMetrics().height(),minstr); + painter.drawText((width() / 2.0) - (painter.fontMetrics().width("min")/2.0),yMin,"min"); + painter.drawText((width() / 2.0) - (painter.fontMetrics().width(minstr)/2.0),yMin + fontHeight,minstr); QString maxstr = QString::number(m_max); - painter.drawText((width() / 2.0) - (painter.fontMetrics().width("max")/2.0),maxyval,"max"); - painter.drawText((width() / 2.0) - (painter.fontMetrics().width(maxstr)/2.0),maxyval + painter.fontMetrics().height(),maxstr); + painter.drawText((width() / 2.0) - (painter.fontMetrics().width("max")/2.0),yMax,"max"); + painter.drawText((width() / 2.0) - (painter.fontMetrics().width(maxstr)/2.0),yMax + fontHeight,maxstr); - //painter.drawRect(width() * ,2,((width()-1) * ((float)m_max / 3000.0)) - (width() * ((float)m_min / 3000.0)),(height()-5) - (painter.fontMetrics().height() * 2)); } } - else + else //horizontal orientation { - painter.drawRect(0,0,width()-1,(height()-1) - (painter.fontMetrics().height() * 2)); - painter.setBrush(Qt::SolidPattern); + //draw the value + painter.drawRect(0,0,width()-1,(height()-1) - twiceFontHeight); painter.setPen(QColor::fromRgb(50,255,50)); - if (!m_showMinMax) - { - painter.drawRect(1,1,(width()-3) * ((float)(currval-m_min) / (m_max-m_min)),(height()-3) - (painter.fontMetrics().height() * 2)); - } - else - { - painter.drawRect(1,1,(width()-3) * ((float)currval / 3000.0),(height()-3) - (painter.fontMetrics().height() * 2)); - } + painter.setBrush(m_fillBrush); + + //draw the value string painter.setPen(QColor::fromRgb(255,255,255)); QString valstr = QString::number(m_value); - painter.drawText((width()/2.0) - (painter.fontMetrics().width(m_name)/2.0),((height()-3) - (painter.fontMetrics().height()*1)),m_name); - painter.drawText((width()/2.0) - (painter.fontMetrics().width(valstr)/2.0),((height()-3) - (painter.fontMetrics().height() * 0)),valstr); - if (m_showMinMax) - { + painter.drawText((width()/2.0) - (painter.fontMetrics().width(m_name)/2.0),((height()-3) - (fontHeight*1)),m_name); + painter.drawText((width()/2.0) - (painter.fontMetrics().width(valstr)/2.0),((height()-3) - (fontHeight * 0)),valstr); + + + painter.setPen(QColor::fromRgb(0,128,0)); + painter.setBrush(m_fillBrush); + + if (!m_showMinMax) { + //draw just the value + painter.drawRect(1,1,(width()-3) * ((float)(curVal-m_min) / (m_max-m_min)),(height()-3) - twiceFontHeight); + } + else { + //draw the value + painter.drawRect(1,1,(width()-3) * ((float)curVal / 3000.0),(height()-3) - twiceFontHeight); + + //draw the min and max bars painter.setBrush(Qt::NoBrush); painter.setPen(QColor::fromRgb(255,0,0)); - painter.drawRect(width() * ((float)m_min / 3000.0),2,((width()-1) * ((float)m_max / 3000.0)) - (width() * ((float)m_min / 3000.0)),(height()-5) - (painter.fontMetrics().height() * 2)); + painter.drawRect(width() * ((float)m_min / 3000.0),2,((width()-1) * ((float)m_max / 3000.0)) - (width() * ((float)m_min / 3000.0)),(height()-5) - twiceFontHeight); + //draw the min and max strings QString minstr = QString::number(m_min); painter.drawText((width() * ((float)m_min / 3000.0)) - (painter.fontMetrics().width("min")/2.0),((height()-3) - (painter.fontMetrics().height()*1)),"min"); painter.drawText((width() * ((float)m_min / 3000.0)) - (painter.fontMetrics().width(minstr)/2.0),((height()-3) - (painter.fontMetrics().height() * 0)),minstr); diff --git a/src/ui/designer/QGCRadioChannelDisplay.h b/src/ui/designer/QGCRadioChannelDisplay.h index be8958a23a..93abcff7a2 100644 --- a/src/ui/designer/QGCRadioChannelDisplay.h +++ b/src/ui/designer/QGCRadioChannelDisplay.h @@ -27,6 +27,8 @@ private: int m_max; bool m_showMinMax; QString m_name; + QBrush m_fillBrush; + signals: public slots: -- GitLab From e5198b1e73e22ff9ccff6cea28de71822774d7e8 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 30 Jul 2013 21:14:01 -0700 Subject: [PATCH 123/460] Gradients for RC indicators --- src/ui/designer/QGCRadioChannelDisplay.cpp | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/ui/designer/QGCRadioChannelDisplay.cpp b/src/ui/designer/QGCRadioChannelDisplay.cpp index 12620cb610..a0e4e458d4 100644 --- a/src/ui/designer/QGCRadioChannelDisplay.cpp +++ b/src/ui/designer/QGCRadioChannelDisplay.cpp @@ -1,7 +1,6 @@ #include "QGCRadioChannelDisplay.h" #include QGCRadioChannelDisplay::QGCRadioChannelDisplay(QWidget *parent) : QWidget(parent) - { m_showMinMax = false; m_min = 0; @@ -13,6 +12,8 @@ QGCRadioChannelDisplay::QGCRadioChannelDisplay(QWidget *parent) : QWidget(parent m_fillBrush = QBrush(Qt::green, Qt::SolidPattern); + + } void QGCRadioChannelDisplay::setName(QString name) { @@ -25,12 +26,16 @@ void QGCRadioChannelDisplay::setOrientation(Qt::Orientation orient) m_orientation = orient; update(); } + void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) { //Values range from 0-3000. //1500 is the middle, static servo value. QPainter painter(this); + + + int fontHeight = painter.fontMetrics().height(); int twiceFontHeight = fontHeight * 2; @@ -47,6 +52,11 @@ void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) if (m_orientation == Qt::Vertical) { + QLinearGradient gradientBrush(0, 0, this->width(), this->height()); + gradientBrush.setColorAt(1.0,QColor::fromRgb(0,128,0)); + gradientBrush.setColorAt(0.5,QColor::fromRgb(0,200,0)); + gradientBrush.setColorAt(0.0, QColor::fromRgb(64,255,0)); + //draw border painter.drawRect(0,0,width()-1,(height()-1) - twiceFontHeight); painter.setPen(QColor::fromRgb(50,255,50)); @@ -58,9 +68,8 @@ void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) painter.drawText((width()/2.0) - (painter.fontMetrics().width(m_name)/2.0),((height()-3) - (fontHeight*1)),m_name); painter.drawText((width()/2.0) - (painter.fontMetrics().width(valStr)/2.0),((height()-3) - (fontHeight * 0)),valStr); - painter.setPen(QColor::fromRgb(128,128,64)); - painter.setBrush(m_fillBrush); + painter.setBrush(gradientBrush); if (!m_showMinMax) { //draw just the value @@ -95,10 +104,15 @@ void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) } else //horizontal orientation { + QLinearGradient hGradientBrush(0, 0, this->width(), this->height()); + hGradientBrush.setColorAt(0.0,QColor::fromRgb(0,128,0)); + hGradientBrush.setColorAt(0.5,QColor::fromRgb(0,200,0)); + hGradientBrush.setColorAt(1.0, QColor::fromRgb(64,255,0)); + //draw the value painter.drawRect(0,0,width()-1,(height()-1) - twiceFontHeight); painter.setPen(QColor::fromRgb(50,255,50)); - painter.setBrush(m_fillBrush); + painter.setBrush(hGradientBrush); //draw the value string painter.setPen(QColor::fromRgb(255,255,255)); @@ -108,7 +122,7 @@ void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) painter.setPen(QColor::fromRgb(0,128,0)); - painter.setBrush(m_fillBrush); + painter.setBrush(hGradientBrush); if (!m_showMinMax) { //draw just the value -- GitLab From bca2c3692e959e160f65084512818f65b531ea66 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 30 Jul 2013 21:23:14 -0700 Subject: [PATCH 124/460] Fix waiting label display --- src/ui/QGCConfigView.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ui/QGCConfigView.cc b/src/ui/QGCConfigView.cc index ff88f313a0..fb8f519b73 100644 --- a/src/ui/QGCConfigView.cc +++ b/src/ui/QGCConfigView.cc @@ -34,14 +34,16 @@ void QGCConfigView::activeUASChanged(UASInterface* uas) foreach (QObject* obj, ui->gridLayout->children()) { QWidget* w = dynamic_cast(obj); if (w) { - ui->gridLayout->removeWidget(w); - if (obj != ui->waitingLabel) + if (obj != ui->waitingLabel) { + ui->gridLayout->removeWidget(w); delete obj; + } } } if (NULL != uas) { ui->gridLayout->removeWidget(ui->waitingLabel); + ui->waitingLabel->setVisible(false); switch (uas->getAutopilotType()) { case MAV_AUTOPILOT_PX4: @@ -49,11 +51,13 @@ void QGCConfigView::activeUASChanged(UASInterface* uas) break; default: ui->gridLayout->addWidget(new QGCVehicleConfig()); + break; } } else { //restore waiting label if we no longer have a connection ui->gridLayout->addWidget(ui->waitingLabel); + ui->waitingLabel->setVisible(true); } } -- GitLab From 00b6d2fc2ec67bf2432391ea5b79d71a9177f124 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 30 Jul 2013 22:03:27 -0700 Subject: [PATCH 125/460] wip new RC layout --- src/ui/QGCPX4VehicleConfig.ui | 1236 +++++++++++++++------------------ 1 file changed, 554 insertions(+), 682 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 47f84377ba..b28fcfe666 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -157,700 +157,165 @@ Config - - - - - Advanced - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Advanced - - - - - - - - false - - - false - - - - Select transmitter model - - - - - - - - true - - - - Mode 1 - - - - - Mode 2 - - - - - Mode 3 - - - - - Mode 4 - - - - - - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - Invert - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Yaw / Rudder - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Invert - - - - - - - Invert - - - - - - - false - - - 1 - - - 8 - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - Pitch / Elevator - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - Aux 2 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - Invert - - - - - - - false - - - 1 - - - 8 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Throttle - - - - - - - Invert - - - - - - - false - - - 1 - - - 8 - - - - - - - false - - - 1 - - - 8 - - - - - - - Mode Switch - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - false - - - 1 - - - 8 - - - - - - - false - - - 1 - - - 8 - - - - - - - Aux 1 - - - - - - - false - - - 1 - - - 8 - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - Aux 3 - - - - - - - Invert - - - - - - - false - - - 1 - - - 8 - - - - - - - Invert - - - - - - - Invert - - - - - - - Roll / Ailerons - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - QLayout::SetMinAndMaxSize - - - - - - - - 250 - 40 - - - - - 250 - 40 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 50 - 200 - - - - - 50 - 200 - - - - - - - - Qt::Horizontal - - - - 250 - 20 - - - - - - - - - 50 - 200 - - - - - 50 - 200 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 250 - 40 - - - - - 250 - 40 - - - - - - - - - 250 - 40 - - - - - 250 - 40 - - - - - - - - - 250 - 40 - - - - - 250 - 40 - - - - - - - - - 250 - 40 - - - - - 250 - 40 - - - - - - - + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + - - - - - - 250 - 40 - - - - - 250 - 40 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + - - - - Qt::Horizontal + + + + + 1 + 0 + - - QSizePolicy::Preferred + + + 50 + 200 + - + - 40 - 20 + 50 + 200 - + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 50 + 200 + + + + + 50 + 200 + + + + + + + + Start Calibration + + - + - + - Start Calibration + Show advanced RC settings - + Qt::Horizontal @@ -864,6 +329,413 @@ Config + + + + Advanced + + + + + + + + false + + + false + + + + Select transmitter model + + + + + + + + true + + + + Mode 1 + + + + + Mode 2 + + + + + Mode 3 + + + + + Mode 4 + + + + + + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Invert + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Yaw / Rudder + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Invert + + + + + + + Invert + + + + + + + false + + + 1 + + + 8 + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Pitch / Elevator + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Aux 2 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Invert + + + + + + + false + + + 1 + + + 8 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Throttle + + + + + + + Invert + + + + + + + false + + + 1 + + + 8 + + + + + + + false + + + 1 + + + 8 + + + + + + + Mode Switch + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + false + + + 1 + + + 8 + + + + + + + false + + + 1 + + + 8 + + + + + + + Aux 1 + + + + + + + false + + + 1 + + + 8 + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Aux 3 + + + + + + + Invert + + + + + + + false + + + 1 + + + 8 + + + + + + + Invert + + + + + + + Invert + + + + + + + Roll / Ailerons + + + + + + + + @@ -920,8 +792,8 @@ p, li { white-space: pre-wrap; } 0 0 - 520 - 700 + 26 + 26 @@ -1009,8 +881,8 @@ p, li { white-space: pre-wrap; } 0 0 - 514 - 637 + 16 + 16 @@ -1046,8 +918,8 @@ p, li { white-space: pre-wrap; } 0 0 - 513 - 637 + 16 + 16 @@ -1138,8 +1010,8 @@ p, li { white-space: pre-wrap; } 0 0 - 587 - 569 + 16 + 16 -- GitLab From d8efa558d2c6b10a8429d1deaef176c21b2ddfcb Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 31 Jul 2013 07:29:27 -0400 Subject: [PATCH 126/460] Addition of Armed/Disarmed indicator on ApmToolbar --- qml/ApmToolBar.qml | 27 +++++++++++++++++++++++++++ src/ui/apmtoolbar.cpp | 21 ++++++++++++++++++++- src/ui/apmtoolbar.h | 6 ++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/qml/ApmToolBar.qml b/qml/ApmToolBar.qml index 7e5d297eea..6065598aed 100644 --- a/qml/ApmToolBar.qml +++ b/qml/ApmToolBar.qml @@ -9,12 +9,25 @@ Rectangle { property alias linkNameLabel: linkDevice.label property alias baudrateLabel: baudrate.label property bool connected: false + property bool armed: false + property string armedstr: "Disarmed" width: toolbar.width height: 72 color: "black" border.color: "black" + onArmedChanged: { + if (armed) { + armedText.text = "Armed" + armedText.color = "Red" + } + else { + armedText.text = "Disarmed" + armedText.color = "Green" + } + } + onConnectedChanged: { if (connected){ console.log("APM Tool BAR QML: connected") @@ -97,6 +110,20 @@ Rectangle { image: "./resources/apmplanner/toolbar/terminal.png" onClicked: globalObj.triggerTerminalView() } + Rectangle { + width:150 + height: parent.height + Text { + id: armedText; + anchors.fill: parent + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.pixelSize: 20 + color: "green" + text: "Disarmed" + } + color:"black" + } Rectangle { // Spacer width: 5 diff --git a/src/ui/apmtoolbar.cpp b/src/ui/apmtoolbar.cpp index 42e85ddc91..2f4595cc64 100644 --- a/src/ui/apmtoolbar.cpp +++ b/src/ui/apmtoolbar.cpp @@ -7,7 +7,7 @@ #include "apmtoolbar.h" APMToolBar::APMToolBar(QWidget *parent): - QDeclarativeView(parent) + QDeclarativeView(parent), m_uas(0) { // Configure our QML object setSource(QUrl::fromLocalFile("qml/ApmToolBar.qml")); @@ -21,6 +21,25 @@ APMToolBar::APMToolBar(QWidget *parent): } setConnection(false); + + connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUasSet(UASInterface*))); + activeUasSet(UASManager::instance()->getActiveUAS()); +} +void APMToolBar::activeUasSet(UASInterface *uas) +{ + if (!uas) + { + return; + } + if (m_uas) + { + disconnect(m_uas,SIGNAL(armingChanged(bool)),this,SLOT(armingChanged(bool))); + } + connect(uas,SIGNAL(armingChanged(bool)),this,SLOT(armingChanged(bool))); +} +void APMToolBar::armingChanged(bool armed) +{ + this->rootObject()->setProperty("armed",armed); } void APMToolBar::setFlightViewAction(QAction *action) diff --git a/src/ui/apmtoolbar.h b/src/ui/apmtoolbar.h index d4e48212e5..9d5608d975 100644 --- a/src/ui/apmtoolbar.h +++ b/src/ui/apmtoolbar.h @@ -3,6 +3,7 @@ #include #include +#include "UASInterface.h" class LinkInterface; @@ -32,6 +33,8 @@ signals: void MAVConnected(bool connected); public slots: + void armingChanged(bool armed); + void activeUasSet(UASInterface *uas); void selectFlightView(); void selectFlightPlanView(); void selectHardwareView(); @@ -44,6 +47,9 @@ public slots: void setConnection(bool connection); void updateLinkDisplay(LinkInterface *newLink); + +private: + UASInterface *m_uas; }; #endif // APMTOOLBAR_H -- GitLab From 44af0a9320be29bedf205a15c23a8c53f4ac5a4e Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 31 Jul 2013 07:29:48 -0400 Subject: [PATCH 127/460] Changed RadioCalibration to have solid green boxes rather than green outlines --- src/ui/designer/QGCRadioChannelDisplay.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/designer/QGCRadioChannelDisplay.cpp b/src/ui/designer/QGCRadioChannelDisplay.cpp index 1b10dc824c..22a5e5cb3e 100644 --- a/src/ui/designer/QGCRadioChannelDisplay.cpp +++ b/src/ui/designer/QGCRadioChannelDisplay.cpp @@ -39,7 +39,7 @@ void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) if (m_orientation == Qt::Vertical) { painter.drawRect(0,0,width()-1,(height()-1) - (painter.fontMetrics().height() * 2)); - painter.setBrush(Qt::SolidPattern); + painter.setBrush(QBrush(QColor::fromRgb(50,255,50),Qt::SolidPattern)); painter.setPen(QColor::fromRgb(50,255,50)); //m_value - m_min / m_max - m_min @@ -81,7 +81,7 @@ void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) else { painter.drawRect(0,0,width()-1,(height()-1) - (painter.fontMetrics().height() * 2)); - painter.setBrush(Qt::SolidPattern); + painter.setBrush(QBrush(QColor::fromRgb(50,255,50),Qt::SolidPattern)); painter.setPen(QColor::fromRgb(50,255,50)); //if (!m_showMinMax) //{ -- GitLab From b38630b395ed4f24df697f66239dd08c203c10e7 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 31 Jul 2013 07:30:10 -0400 Subject: [PATCH 128/460] Added 250ms delay between sending data requests to increase probability of it working. --- src/uas/ArduPilotMegaMAV.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/uas/ArduPilotMegaMAV.cc b/src/uas/ArduPilotMegaMAV.cc index c3c34c5e85..cb972df4e8 100644 --- a/src/uas/ArduPilotMegaMAV.cc +++ b/src/uas/ArduPilotMegaMAV.cc @@ -53,11 +53,17 @@ ArduPilotMegaMAV::ArduPilotMegaMAV(MAVLinkProtocol* mavlink, int id) : void ArduPilotMegaMAV::sendTxRequests() { enableExtendedSystemStatusTransmission(2); + QGC::SLEEP::msleep(250); enablePositionTransmission(3); + QGC::SLEEP::msleep(250); enableExtra1Transmission(10); + QGC::SLEEP::msleep(250); enableExtra2Transmission(10); + QGC::SLEEP::msleep(250); enableExtra3Transmission(2); + QGC::SLEEP::msleep(250); enableRawSensorDataTransmission(2); + QGC::SLEEP::msleep(250); enableRCChannelDataTransmission(2); } -- GitLab From 365a330c83475ddd6075328a78499244f27bd269 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 31 Jul 2013 09:43:39 -0400 Subject: [PATCH 129/460] Fix for Standard and Advanced param views not displaying or accepting edits properly --- src/ui/configuration/AdvancedParamConfig.cc | 34 ++++++++- src/ui/configuration/AdvancedParamConfig.h | 2 + src/ui/configuration/ApmSoftwareConfig.cc | 43 +++++++----- src/ui/configuration/ParamWidget.cc | 76 ++++++++++++++++++--- src/ui/configuration/ParamWidget.h | 11 ++- src/ui/configuration/ParamWidget.ui | 3 + src/ui/configuration/StandardParamConfig.cc | 35 +++++++++- src/ui/configuration/StandardParamConfig.h | 2 + 8 files changed, 174 insertions(+), 32 deletions(-) diff --git a/src/ui/configuration/AdvancedParamConfig.cc b/src/ui/configuration/AdvancedParamConfig.cc index 3475da4d1d..98f0c1c62e 100644 --- a/src/ui/configuration/AdvancedParamConfig.cc +++ b/src/ui/configuration/AdvancedParamConfig.cc @@ -12,7 +12,9 @@ AdvancedParamConfig::~AdvancedParamConfig() } void AdvancedParamConfig::addRange(QString title,QString description,QString param,double min,double max) { - ParamWidget *widget = new ParamWidget(ui.scrollAreaWidgetContents); + ParamWidget *widget = new ParamWidget(param,ui.scrollAreaWidgetContents); + connect(widget,SIGNAL(doubleValueChanged(QString,double)),this,SLOT(doubleValueChanged(QString,double))); + connect(widget,SIGNAL(intValueChanged(QString,int)),this,SLOT(intValueChanged(QString,int))); m_paramToWidgetMap[param] = widget; widget->setupDouble(title + "(" + param + ")",description,0,min,max); ui.verticalLayout->addWidget(widget); @@ -21,7 +23,9 @@ void AdvancedParamConfig::addRange(QString title,QString description,QString par void AdvancedParamConfig::addCombo(QString title,QString description,QString param,QList > valuelist) { - ParamWidget *widget = new ParamWidget(ui.scrollAreaWidgetContents); + ParamWidget *widget = new ParamWidget(param,ui.scrollAreaWidgetContents); + connect(widget,SIGNAL(doubleValueChanged(QString,double)),this,SLOT(doubleValueChanged(QString,double))); + connect(widget,SIGNAL(intValueChanged(QString,int)),this,SLOT(intValueChanged(QString,int))); m_paramToWidgetMap[param] = widget; widget->setupCombo(title + "(" + param + ")",description,valuelist); ui.verticalLayout->addWidget(widget); @@ -31,6 +35,30 @@ void AdvancedParamConfig::parameterChanged(int uas, int component, QString param { if (m_paramToWidgetMap.contains(parameterName)) { - m_paramToWidgetMap[parameterName]->setValue(value.toDouble()); + if (value.type() == QVariant::Double) + { + m_paramToWidgetMap[parameterName]->setValue(value.toDouble()); + } + else + { + m_paramToWidgetMap[parameterName]->setValue(value.toInt()); + } } } +void AdvancedParamConfig::doubleValueChanged(QString param,double value) +{ + if (!m_uas) + { + this->showNullMAVErrorMessageBox(); + } + m_uas->getParamManager()->setParameter(1,param,value); +} + +void AdvancedParamConfig::intValueChanged(QString param,int value) +{ + if (!m_uas) + { + this->showNullMAVErrorMessageBox(); + } + m_uas->getParamManager()->setParameter(1,param,value); +} diff --git a/src/ui/configuration/AdvancedParamConfig.h b/src/ui/configuration/AdvancedParamConfig.h index 6d52ede4cd..07e55d61d1 100644 --- a/src/ui/configuration/AdvancedParamConfig.h +++ b/src/ui/configuration/AdvancedParamConfig.h @@ -16,6 +16,8 @@ public: void addCombo(QString title,QString description,QString param,QList > valuelist); private slots: void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void doubleValueChanged(QString param,double value); + void intValueChanged(QString param,int value); private: QMap m_paramToWidgetMap; Ui::AdvancedParamConfig ui; diff --git a/src/ui/configuration/ApmSoftwareConfig.cc b/src/ui/configuration/ApmSoftwareConfig.cc index fabc49139b..a5308dab76 100644 --- a/src/ui/configuration/ApmSoftwareConfig.cc +++ b/src/ui/configuration/ApmSoftwareConfig.cc @@ -85,23 +85,27 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) ui.advancedParamButton->setVisible(true); ui.advParamListButton->setVisible(true); + QString compare = ""; if (uas->getSystemType() == MAV_TYPE_FIXED_WING) { ui.arduPlanePidButton->setVisible(true); ui.arduCopterPidButton->setVisible(false); ui.arduRoverPidButton->setVisible(false); + compare = "ArduPlane"; } else if (uas->getSystemType() == MAV_TYPE_QUADROTOR) { ui.arduCopterPidButton->setVisible(true); ui.arduPlanePidButton->setVisible(false); ui.arduRoverPidButton->setVisible(false); + compare = "ArduCopter"; } else if (uas->getSystemType() == MAV_TYPE_GROUND_ROVER) { ui.arduRoverPidButton->setVisible(true); ui.arduCopterPidButton->setVisible(false); ui.arduPlanePidButton->setVisible(false); + compare = "APMRover2"; } @@ -138,6 +142,7 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) { parametersname = xml.attributes().value("name").toString(); } + QVariantMap genset; QVariantMap advset; @@ -301,24 +306,25 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) { valuelist.append(QPair(i.key().toInt(),i.value())); } - if (tab == "Standard") - { - m_standardParamConfig->addCombo(humanname,docs,name,valuelist); - } - else if (tab == "Advanced") + if (compare == parametersname) { - m_advancedParamConfig->addCombo(humanname,docs,name,valuelist); + if (tab == "Standard") + { + m_standardParamConfig->addCombo(humanname,docs,name,valuelist); + } + else if (tab == "Advanced") + { + m_advancedParamConfig->addCombo(humanname,docs,name,valuelist); + } + m_advParameterList->setParameterMetaData(name,humanname,docs); } - m_advParameterList->setParameterMetaData(name,humanname,docs); } else if (fieldmap.size() > 0) { float min = 0; - float max = 100; + float max = 65535; if (fieldmap.contains("Range")) { - float min = 0; - float max = 0; //Some range fields list "0-10" and some list "0 10". Handle both. if (fieldmap["Range"].split(" ").size() > 1) { @@ -331,15 +337,18 @@ void ApmSoftwareConfig::activeUASSet(UASInterface *uas) max = fieldmap["Range"].split("-")[1].trimmed().toFloat(); } } - if (tab == "Standard") - { - m_standardParamConfig->addRange(humanname,docs,name,min,max); - } - else if (tab == "Advanced") + if (compare == parametersname) { - m_advancedParamConfig->addRange(humanname,docs,name,max,min); + if (tab == "Standard") + { + m_standardParamConfig->addRange(humanname,docs,name,min,max); + } + else if (tab == "Advanced") + { + m_advancedParamConfig->addRange(humanname,docs,name,min,max); + } + m_advParameterList->setParameterMetaData(name,humanname,docs); } - m_advParameterList->setParameterMetaData(name,humanname,docs); } } diff --git a/src/ui/configuration/ParamWidget.cc b/src/ui/configuration/ParamWidget.cc index 93b3bfd264..b9fb03c726 100644 --- a/src/ui/configuration/ParamWidget.cc +++ b/src/ui/configuration/ParamWidget.cc @@ -1,9 +1,45 @@ #include "ParamWidget.h" - -ParamWidget::ParamWidget(QWidget *parent) : QWidget(parent) +ParamWidget::ParamWidget(QString param,QWidget *parent) : QWidget(parent) { ui.setupUi(this); + m_param = param; + + connect(ui.doubleSpinBox,SIGNAL(editingFinished()),this,SLOT(doubleSpinEditFinished())); + connect(ui.intSpinBox,SIGNAL(editingFinished()),this,SLOT(intSpinEditFinished())); + connect(ui.valueComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboIndexChanged(int))); + connect(ui.valueSlider,SIGNAL(sliderReleased()),this,SLOT(valueSliderReleased())); +} +void ParamWidget::doubleSpinEditFinished() +{ + ui.valueSlider->setValue(((ui.doubleSpinBox->value() - m_min) / (m_max - m_min)) * 100.0); + emit doubleValueChanged(m_param,ui.doubleSpinBox->value()); +} + +void ParamWidget::intSpinEditFinished() +{ + ui.valueSlider->setValue(((ui.intSpinBox->value() - m_min) / (m_max - m_min)) * 100.0); + emit intValueChanged(m_param,ui.intSpinBox->value()); +} + +void ParamWidget::comboIndexChanged(int index) +{ + emit intValueChanged(m_param,m_valueList[index].first); +} + +void ParamWidget::valueSliderReleased() +{ + //Set the spin box, and emit a signal. + if (type == INT) + { + ui.intSpinBox->setValue(((ui.valueSlider->value() / 100.0) * (m_max - m_min)) + m_min); + emit intValueChanged(m_param,ui.intSpinBox->value()); + } + else if (type == DOUBLE) + { + ui.doubleSpinBox->setValue(((ui.valueSlider->value() / 100.0) * (m_max - m_min)) + m_min); + emit doubleValueChanged(m_param,ui.doubleSpinBox->value()); + } } ParamWidget::~ParamWidget() @@ -19,8 +55,18 @@ void ParamWidget::setupInt(QString title,QString description,int value,int min,i ui.valueSlider->show(); ui.intSpinBox->show(); ui.doubleSpinBox->hide(); - m_min = min; - m_max = max; + if (min == 0 && max == 0) + { + m_min = 0; + m_max = 65535; + } + else + { + m_min = min; + m_max = max; + } + ui.intSpinBox->setMinimum(m_min); + ui.intSpinBox->setMaximum(m_max); } void ParamWidget::setupDouble(QString title,QString description,double value,double min,double max) @@ -32,8 +78,18 @@ void ParamWidget::setupDouble(QString title,QString description,double value,dou ui.valueSlider->show(); ui.intSpinBox->hide(); ui.doubleSpinBox->show(); - m_min = min; - m_max = max; + if (min == 0 && max == 0) + { + m_min = 0; + m_max = 65535; + } + else + { + m_min = min; + m_max = max; + } + ui.doubleSpinBox->setMinimum(m_min); + ui.doubleSpinBox->setMaximum(m_max); } void ParamWidget::setupCombo(QString title,QString description,QList > list) @@ -47,10 +103,12 @@ void ParamWidget::setupCombo(QString title,QString description,QListhide(); m_valueList = list; ui.valueComboBox->clear(); + disconnect(ui.valueComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboIndexChanged(int))); for (int i=0;iaddItem(m_valueList[i].second); } + connect(ui.valueComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboIndexChanged(int))); } void ParamWidget::setValue(double value) @@ -58,12 +116,12 @@ void ParamWidget::setValue(double value) if (type == INT) { ui.intSpinBox->setValue(value); - ui.valueSlider->setValue(((value + m_min) / (m_max + m_min)) * 100.0); + ui.valueSlider->setValue(((value - m_min) / (m_max - m_min)) * 100.0); } else if (type == DOUBLE) { ui.doubleSpinBox->setValue(value); - ui.valueSlider->setValue(((value + m_min) / (m_max + m_min)) * 100.0); + ui.valueSlider->setValue(((value - m_min) / (m_max - m_min)) * 100.0); } else if (type == COMBO) { @@ -71,7 +129,9 @@ void ParamWidget::setValue(double value) { if ((int)value == m_valueList[i].first) { + disconnect(ui.valueComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboIndexChanged(int))); ui.valueComboBox->setCurrentIndex(i); + connect(ui.valueComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboIndexChanged(int))); return; } } diff --git a/src/ui/configuration/ParamWidget.h b/src/ui/configuration/ParamWidget.h index aa375d2967..68a3efbf4c 100644 --- a/src/ui/configuration/ParamWidget.h +++ b/src/ui/configuration/ParamWidget.h @@ -9,13 +9,22 @@ class ParamWidget : public QWidget Q_OBJECT public: - explicit ParamWidget(QWidget *parent = 0); + explicit ParamWidget(QString param,QWidget *parent = 0); ~ParamWidget(); void setupInt(QString title,QString description,int value,int min,int max); void setupDouble(QString title,QString description,double value,double min,double max); void setupCombo(QString title,QString description,QList > list); void setValue(double value); +signals: + void doubleValueChanged(QString param,double value); + void intValueChanged(QString param,int value); +private slots: + void doubleSpinEditFinished(); + void intSpinEditFinished(); + void comboIndexChanged(int index); + void valueSliderReleased(); private: + QString m_param; enum VIEWTYPE { INT, diff --git a/src/ui/configuration/ParamWidget.ui b/src/ui/configuration/ParamWidget.ui index ddf4653b8f..8e396cb6fe 100644 --- a/src/ui/configuration/ParamWidget.ui +++ b/src/ui/configuration/ParamWidget.ui @@ -46,6 +46,9 @@ 100 + + 0 + Qt::Horizontal diff --git a/src/ui/configuration/StandardParamConfig.cc b/src/ui/configuration/StandardParamConfig.cc index caa49ccde4..0f43a92250 100644 --- a/src/ui/configuration/StandardParamConfig.cc +++ b/src/ui/configuration/StandardParamConfig.cc @@ -10,7 +10,9 @@ StandardParamConfig::~StandardParamConfig() } void StandardParamConfig::addRange(QString title,QString description,QString param,double min,double max) { - ParamWidget *widget = new ParamWidget(ui.scrollAreaWidgetContents); + ParamWidget *widget = new ParamWidget(param,ui.scrollAreaWidgetContents); + connect(widget,SIGNAL(doubleValueChanged(QString,double)),this,SLOT(doubleValueChanged(QString,double))); + connect(widget,SIGNAL(intValueChanged(QString,int)),this,SLOT(intValueChanged(QString,int))); paramToWidgetMap[param] = widget; widget->setupDouble(title + "(" + param + ")",description,0,min,max); ui.verticalLayout->addWidget(widget); @@ -19,7 +21,9 @@ void StandardParamConfig::addRange(QString title,QString description,QString par void StandardParamConfig::addCombo(QString title,QString description,QString param,QList > valuelist) { - ParamWidget *widget = new ParamWidget(ui.scrollAreaWidgetContents); + ParamWidget *widget = new ParamWidget(param,ui.scrollAreaWidgetContents); + connect(widget,SIGNAL(doubleValueChanged(QString,double)),this,SLOT(doubleValueChanged(QString,double))); + connect(widget,SIGNAL(intValueChanged(QString,int)),this,SLOT(intValueChanged(QString,int))); paramToWidgetMap[param] = widget; widget->setupCombo(title + "(" + param + ")",description,valuelist); ui.verticalLayout->addWidget(widget); @@ -29,6 +33,31 @@ void StandardParamConfig::parameterChanged(int uas, int component, QString param { if (paramToWidgetMap.contains(parameterName)) { - paramToWidgetMap[parameterName]->setValue(value.toDouble()); + if (value.type() == QVariant::Double) + { + paramToWidgetMap[parameterName]->setValue(value.toDouble()); + } + else + { + paramToWidgetMap[parameterName]->setValue(value.toInt()); + } } } +void StandardParamConfig::doubleValueChanged(QString param,double value) +{ + if (!m_uas) + { + this->showNullMAVErrorMessageBox(); + } + m_uas->getParamManager()->setParameter(1,param,value); +} + +void StandardParamConfig::intValueChanged(QString param,int value) +{ + if (!m_uas) + { + this->showNullMAVErrorMessageBox(); + } + m_uas->getParamManager()->setParameter(1,param,value); +} + diff --git a/src/ui/configuration/StandardParamConfig.h b/src/ui/configuration/StandardParamConfig.h index b2fbc04f48..b098d7d05e 100644 --- a/src/ui/configuration/StandardParamConfig.h +++ b/src/ui/configuration/StandardParamConfig.h @@ -16,6 +16,8 @@ public: void addCombo(QString title,QString description,QString param,QList > valuelist); private slots: void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void doubleValueChanged(QString param,double value); + void intValueChanged(QString param,int value); private: QMap paramToWidgetMap; Ui::StandardParamConfig ui; -- GitLab From ca053bd048f0167d1547376b789580e91d91a457 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 31 Jul 2013 10:16:57 -0400 Subject: [PATCH 130/460] Addition of pitch/roll/yaw P value locking in ArduCopter Pid Config --- src/ui/configuration/ArduCopterPidConfig.cc | 24 +++++++++++++++++++++ src/ui/configuration/ArduCopterPidConfig.h | 3 +++ 2 files changed, 27 insertions(+) diff --git a/src/ui/configuration/ArduCopterPidConfig.cc b/src/ui/configuration/ArduCopterPidConfig.cc index ad7211ed39..7d5f274cbd 100644 --- a/src/ui/configuration/ArduCopterPidConfig.cc +++ b/src/ui/configuration/ArduCopterPidConfig.cc @@ -3,6 +3,11 @@ ArduCopterPidConfig::ArduCopterPidConfig(QWidget *parent) : AP2ConfigWidget(parent) { ui.setupUi(this); + m_pitchRollLocked = false; + connect(ui.checkBox,SIGNAL(clicked(bool)),this,SLOT(lockCheckBoxClicked(bool))); + connect(ui.stabilPitchPSpinBox,SIGNAL(valueChanged(double)),this,SLOT(stabilLockedChanged(double))); + connect(ui.stabilRollPSpinBox,SIGNAL(valueChanged(double)),this,SLOT(stabilLockedChanged(double))); + connect(ui.stabilYawPSpinBox,SIGNAL(valueChanged(double)),this,SLOT(stabilLockedChanged(double))); m_nameToBoxMap["STB_RLL_P"] = ui.stabilPitchPSpinBox; m_nameToBoxMap["STB_PIT_P"] = ui.stabilRollPSpinBox; m_nameToBoxMap["STB_YAW_P"] = ui.stabilYawPSpinBox; @@ -109,6 +114,25 @@ ArduCopterPidConfig::ArduCopterPidConfig(QWidget *parent) : AP2ConfigWidget(pare } initConnections(); } +void ArduCopterPidConfig::lockCheckBoxClicked(bool checked) +{ + m_pitchRollLocked = checked; +} +void ArduCopterPidConfig::stabilLockedChanged(double value) +{ + if (m_pitchRollLocked) + { + disconnect(ui.stabilPitchPSpinBox,SIGNAL(valueChanged(double)),this,SLOT(stabilLockedChanged(double))); + disconnect(ui.stabilRollPSpinBox,SIGNAL(valueChanged(double)),this,SLOT(stabilLockedChanged(double))); + disconnect(ui.stabilYawPSpinBox,SIGNAL(valueChanged(double)),this,SLOT(stabilLockedChanged(double))); + ui.stabilPitchPSpinBox->setValue(value); + ui.stabilRollPSpinBox->setValue(value); + ui.stabilYawPSpinBox->setValue(value); + connect(ui.stabilPitchPSpinBox,SIGNAL(valueChanged(double)),this,SLOT(stabilLockedChanged(double))); + connect(ui.stabilRollPSpinBox,SIGNAL(valueChanged(double)),this,SLOT(stabilLockedChanged(double))); + connect(ui.stabilYawPSpinBox,SIGNAL(valueChanged(double)),this,SLOT(stabilLockedChanged(double))); + } +} ArduCopterPidConfig::~ArduCopterPidConfig() { diff --git a/src/ui/configuration/ArduCopterPidConfig.h b/src/ui/configuration/ArduCopterPidConfig.h index bc3ac3a693..d8a1360b88 100644 --- a/src/ui/configuration/ArduCopterPidConfig.h +++ b/src/ui/configuration/ArduCopterPidConfig.h @@ -17,7 +17,10 @@ private slots: void writeButtonClicked(); void refreshButtonClicked(); void parameterChanged(int uas, int component, QString parameterName, QVariant value); + void lockCheckBoxClicked(bool checked); + void stabilLockedChanged(double value); private: + bool m_pitchRollLocked; QList > m_ch6ValueToTextList; QList > m_ch78ValueToTextList; QMap m_nameToBoxMap; -- GitLab From b57635c000506515706240b7c45027fb061918b9 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 31 Jul 2013 11:53:09 -0400 Subject: [PATCH 131/460] Changed name in UI from Adv Parameter List to Full Parameter List --- src/ui/configuration/AdvParameterList.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/configuration/AdvParameterList.ui b/src/ui/configuration/AdvParameterList.ui index 9b9d40849b..3b18893d27 100644 --- a/src/ui/configuration/AdvParameterList.ui +++ b/src/ui/configuration/AdvParameterList.ui @@ -17,7 +17,7 @@ - <h2>Advanced Parameter List</h2> + <h2>Full Parameter List</h2> -- GitLab From 174962a14974a3e9ca3c6d8095382e0ec81ce52e Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 31 Jul 2013 10:03:25 -0700 Subject: [PATCH 132/460] Fixing rc calibration and realtime display --- src/ui/QGCPX4VehicleConfig.cc | 619 +++++++++------------ src/ui/QGCPX4VehicleConfig.h | 4 +- src/ui/QGCPX4VehicleConfig.ui | 365 ++++++------ src/ui/designer/QGCRadioChannelDisplay.cpp | 30 +- src/ui/designer/QGCRadioChannelDisplay.h | 2 + 5 files changed, 477 insertions(+), 543 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 787262f11b..3ea93d914b 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -24,6 +24,10 @@ #define WIDGET_INDEX_GENERAL_CONFIG 2 #define WIDGET_INDEX_ADV_CONFIG 3 + +#define MIN_PWM_VAL 800 +#define MAX_PWM_VAL 2200 + QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : QWidget(parent), mav(NULL), @@ -36,7 +40,7 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : rcAux1(0.0f), rcAux2(0.0f), rcAux3(0.0f), - changed(true), + dataModelChanged(true), rc_mode(RC_MODE_NONE), calibrationEnabled(false), ui(new Ui::QGCPX4VehicleConfig) @@ -66,7 +70,9 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(ui->generalMenuButton,SIGNAL(clicked()),this,SLOT(generalMenuButtonClicked())); connect(ui->advancedMenuButton,SIGNAL(clicked()),this,SLOT(advancedMenuButtonClicked())); - ui->rcModeComboBox->setCurrentIndex((int)rc_mode - 1); + + int selectedRcModeIdx = (RC_MODE_NONE != rc_mode) ? (int)(rc_mode -1) : -1; + ui->rcModeComboBox->setCurrentIndex(selectedRcModeIdx); ui->rcCalibrationButton->setCheckable(true); connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool))); @@ -74,32 +80,35 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(ui->rcModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setRCModeIndex(int))); //connect(ui->setTrimButton, SIGNAL(clicked()), this, SLOT(setTrimPositions())); - /* Connect RC mapping assignments */ - connect(ui->rollSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setRollChan(int))); - connect(ui->pitchSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setPitchChan(int))); - connect(ui->yawSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setYawChan(int))); - connect(ui->throttleSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setThrottleChan(int))); - connect(ui->modeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setModeChan(int))); - connect(ui->aux1SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux1Chan(int))); - connect(ui->aux2SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux2Chan(int))); - connect(ui->aux3SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux3Chan(int))); - - // Connect RC reverse assignments - connect(ui->invertCheckBox, SIGNAL(clicked(bool)), this, SLOT(setRollInverted(bool))); - connect(ui->invertCheckBox_2, SIGNAL(clicked(bool)), this, SLOT(setPitchInverted(bool))); - connect(ui->invertCheckBox_3, SIGNAL(clicked(bool)), this, SLOT(setYawInverted(bool))); - connect(ui->invertCheckBox_4, SIGNAL(clicked(bool)), this, SLOT(setThrottleInverted(bool))); - connect(ui->invertCheckBox_5, SIGNAL(clicked(bool)), this, SLOT(setModeInverted(bool))); - connect(ui->invertCheckBox_6, SIGNAL(clicked(bool)), this, SLOT(setAux1Inverted(bool))); - connect(ui->invertCheckBox_7, SIGNAL(clicked(bool)), this, SLOT(setAux2Inverted(bool))); - connect(ui->invertCheckBox_8, SIGNAL(clicked(bool)), this, SLOT(setAux3Inverted(bool))); + + + //TODO the following methods are not yet implemented + +// Connect RC mapping assignments +// connect(ui->rollSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setRollChan(int))); +// connect(ui->pitchSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setPitchChan(int))); +// connect(ui->yawSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setYawChan(int))); +// connect(ui->throttleSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setThrottleChan(int))); +// connect(ui->modeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setModeChan(int))); +// connect(ui->aux1SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux1Chan(int))); +// connect(ui->aux2SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux2Chan(int))); +// connect(ui->aux3SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux3Chan(int))); + +// // Connect RC reverse assignments +// connect(ui->invertCheckBox, SIGNAL(clicked(bool)), this, SLOT(setRollInverted(bool))); +// connect(ui->invertCheckBox_2, SIGNAL(clicked(bool)), this, SLOT(setPitchInverted(bool))); +// connect(ui->invertCheckBox_3, SIGNAL(clicked(bool)), this, SLOT(setYawInverted(bool))); +// connect(ui->invertCheckBox_4, SIGNAL(clicked(bool)), this, SLOT(setThrottleInverted(bool))); +// connect(ui->invertCheckBox_5, SIGNAL(clicked(bool)), this, SLOT(setModeInverted(bool))); +// connect(ui->invertCheckBox_6, SIGNAL(clicked(bool)), this, SLOT(setAux1Inverted(bool))); +// connect(ui->invertCheckBox_7, SIGNAL(clicked(bool)), this, SLOT(setAux2Inverted(bool))); +// connect(ui->invertCheckBox_8, SIGNAL(clicked(bool)), this, SLOT(setAux3Inverted(bool))); connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); setActiveUAS(UASManager::instance()->getActiveUAS()); - for (unsigned int i = 0; i < chanMax; i++) - { + for (unsigned int i = 0; i < chanMax; i++) { rcValue[i] = UINT16_MAX; rcMapping[i] = i; } @@ -139,10 +148,10 @@ QGCPX4VehicleConfig::~QGCPX4VehicleConfig() void QGCPX4VehicleConfig::setRCModeIndex(int newRcMode) { - if (newRcMode > 0 && newRcMode < 6) - { - //rc_mode = (enum RC_MODE) (newRcMode+1); - changed = true; + newRcMode += 1; //promote from an index to a mode enum + if (newRcMode > 0 && newRcMode < 5) { + rc_mode = (enum RC_MODE) (newRcMode); + dataModelChanged = true; } } @@ -172,7 +181,6 @@ void QGCPX4VehicleConfig::setTrimPositions() } else { - // Reject QMessageBox msgBox; msgBox.setText(tr("Throttle Stick Trim Position Invalid")); @@ -202,7 +210,6 @@ void QGCPX4VehicleConfig::startCalibrationRC() { QMessageBox::information(0,"Warning!","You are about to start radio calibration.\nPlease ensure all motor power is disconnected AND all props are removed from the vehicle.\nAlso ensure transmitter and reciever are powered and connected\n\nClick OK to confirm"); QMessageBox::information(0,"Information","Click OK, then move all sticks to their extreme positions, watching the min/max values to ensure you get the most range from your controller. This includes all switches"); - ui->rcTypeComboBox->setEnabled(false); ui->rcCalibrationButton->setText(tr("Stop RC Calibration")); resetCalibrationRC(); calibrationEnabled = true; @@ -220,8 +227,8 @@ void QGCPX4VehicleConfig::stopCalibrationRC() { QMessageBox::information(0,"Trims","Ensure all sticks are centeres and throttle is in the downmost position, click OK to continue"); calibrationEnabled = false; - ui->rcTypeComboBox->setEnabled(true); ui->rcCalibrationButton->setText(tr("Start RC Calibration")); + ui->rollWidget->hideMinMax(); ui->pitchWidget->hideMinMax(); ui->yawWidget->hideMinMax(); @@ -230,6 +237,7 @@ void QGCPX4VehicleConfig::stopCalibrationRC() ui->radio6Widget->hideMinMax(); ui->radio7Widget->hideMinMax(); ui->radio8Widget->hideMinMax(); + QString statusstr; statusstr = "Below you will find the detected radio calibration information that will be sent to the autopilot\n"; statusstr += "Normal values are around 1100 to 1900, with disconnected channels reading very close to 1500\n\n"; @@ -237,7 +245,7 @@ void QGCPX4VehicleConfig::stopCalibrationRC() statusstr += "--------------------\n"; for (int i=0;i<8;i++) { - statusstr += QString::number(i) + "\t" + QString::number(rcMin[i]) + "\t" + QString::number(rcValue[i]) + "\t" + QString::number(rcMax[i]) + "\n"; + statusstr += QString::number(i) +"\t"+ QString::number(rcMin[i]) +"\t"+ QString::number(rcValue[i]) +"\t"+ QString::number(rcMax[i]) +"\n"; } QMessageBox::information(0,"Status",statusstr); } @@ -1009,13 +1017,10 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) // Update calibration data if (calibrationEnabled) { - if (val < rcMin[chan]) - { + if (val < rcMin[chan]) { rcMin[chan] = val; } - - if (val > rcMax[chan]) - { + if (val > rcMax[chan]) { rcMax[chan] = val; } } @@ -1026,12 +1031,10 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) // Normalized value float normalized; - if (val >= rcTrim[chan]) - { + if (val >= rcTrim[chan]) { normalized = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]); } - else - { + else { normalized = -(rcTrim[chan] - val)/(rcTrim[chan] - rcMin[chan]); } @@ -1040,23 +1043,16 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) // Invert normalized = (rcRev[chan]) ? -1.0f*normalized : normalized; - if (chan == rcMapping[0]) - { - // ROLL + if (chan == rcMapping[0]) { rcRoll = normalized; } - if (chan == rcMapping[1]) - { - // PITCH + else if (chan == rcMapping[1]) { rcPitch = normalized; } - if (chan == rcMapping[2]) - { + else if (chan == rcMapping[2]) { rcYaw = normalized; } - if (chan == rcMapping[3]) - { - // THROTTLE + else if (chan == rcMapping[3]) { if (rcRev[chan]) { rcThrottle = 1.0f + normalized; } else { @@ -1065,28 +1061,20 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) rcThrottle = qBound(0.0f, rcThrottle, 1.0f); } - if (chan == rcMapping[4]) - { - // MODE SWITCH - rcMode = normalized; + else if (chan == rcMapping[4]) { + rcMode = normalized;// MODE SWITCH } - if (chan == rcMapping[5]) - { - // AUX1 - rcAux1 = normalized; + else if (chan == rcMapping[5]) { + rcAux1 = normalized; // AUX1 } - if (chan == rcMapping[6]) - { - // AUX2 - rcAux2 = normalized; + else if (chan == rcMapping[6]) { + rcAux2 = normalized;// AUX2 } - if (chan == rcMapping[7]) - { - // AUX3 - rcAux3 = normalized; + else if (chan == rcMapping[7]) { + rcAux3 = normalized; // AUX3 } - changed = true; + dataModelChanged = true; //qDebug() << "RC CHAN:" << chan << "PPM:" << val << "NORMALIZED:" << normalized; } @@ -1124,52 +1112,182 @@ void QGCPX4VehicleConfig::updateInvertedCheckboxes(int index) } } +void QGCPX4VehicleConfig::handleRcParameterChange(QString parameterName, QVariant value) +{ + if (parameterName.startsWith("RC_")) { + if (parameterName.startsWith("RC_MAP_")) { + //RC Mapping radio channels to meaning + // Order is: roll, pitch, yaw, throttle, mode sw, aux 1-3 + + int intValue = value.toInt() - 1; + if (parameterName.startsWith("RC_MAP_ROLL")) { + rcMapping[0] = intValue; + ui->rollSpinBox->setValue(rcMapping[0]+1); + ui->rollSpinBox->setEnabled(true); + } + else if (parameterName.startsWith("RC_MAP_PITCH")) { + rcMapping[1] = intValue; + ui->pitchSpinBox->setValue(rcMapping[1]+1); + ui->pitchSpinBox->setEnabled(true); + } + else if (parameterName.startsWith("RC_MAP_YAW")) { + rcMapping[2] = intValue; + ui->yawSpinBox->setValue(rcMapping[2]+1); + ui->yawSpinBox->setEnabled(true); + } + else if (parameterName.startsWith("RC_MAP_THROTTLE")) { + rcMapping[3] = intValue; + ui->throttleSpinBox->setValue(rcMapping[3]+1); + ui->throttleSpinBox->setEnabled(true); + } + else if (parameterName.startsWith("RC_MAP_MODE_SW")) { + rcMapping[4] = intValue; + ui->modeSpinBox->setValue(rcMapping[4]+1); + ui->modeSpinBox->setEnabled(true); + } + else if (parameterName.startsWith("RC_MAP_AUX1")) { + rcMapping[5] = intValue; + ui->aux1SpinBox->setValue(rcMapping[5]+1); + ui->aux1SpinBox->setEnabled(true); + } + else if (parameterName.startsWith("RC_MAP_AUX2")) { + rcMapping[6] = intValue; + ui->aux2SpinBox->setValue(rcMapping[6]+1); + ui->aux2SpinBox->setEnabled(true); + } + else if (parameterName.startsWith("RC_MAP_AUX3")) { + rcMapping[7] = intValue; + ui->aux3SpinBox->setValue(rcMapping[7]+1); + ui->aux3SpinBox->setEnabled(true); + } + } + else if (parameterName.startsWith("RC_SCALE_")) { + // Scaling + float floatVal = value.toFloat(); + if (parameterName.startsWith("RC_SCALE_ROLL")) { + rcScaling[0] = floatVal; + } + else if (parameterName.startsWith("RC_SCALE_PITCH")) { + rcScaling[1] = floatVal; + } + else if (parameterName.startsWith("RC_SCALE_YAW")) { + rcScaling[2] = floatVal; + } + else if (parameterName.startsWith("RC_SCALE_THROTTLE")) { + rcScaling[3] = floatVal; + } + else if (parameterName.startsWith("RC_SCALE_MODE_SW")) { + rcScaling[4] = floatVal; + } + else if (parameterName.startsWith("RC_SCALE_AUX1")) { + rcScaling[5] = floatVal; + } + else if (parameterName.startsWith("RC_SCALE_AUX2")) { + rcScaling[6] = floatVal; + } + else if (parameterName.startsWith("RC_SCALE_AUX3")) { + rcScaling[7] = floatVal; + } + } + else if (parameterName.startsWith("RC_TYPE")) { + if (0 != rcTypeUpdateRequested) { + rcTypeUpdateRequested = 0; + updateStatus(tr("Received RC type update, setting parameters based on model.")); + rcType = value.toInt(); + // Request all other parameters as well + requestCalibrationRC(); + } + } + } + else { + // Channel calibration values + bool ok = false; + unsigned int index = chanMax; + QRegExp minTpl("RC?_MIN"); + minTpl.setPatternSyntax(QRegExp::Wildcard); + QRegExp maxTpl("RC?_MAX"); + maxTpl.setPatternSyntax(QRegExp::Wildcard); + QRegExp trimTpl("RC?_TRIM"); + trimTpl.setPatternSyntax(QRegExp::Wildcard); + QRegExp revTpl("RC?_REV"); + revTpl.setPatternSyntax(QRegExp::Wildcard); + + // Do not write the RC type, as these values depend on this + // active onboard parameter + int intVal = value.toInt(); + + if (minTpl.exactMatch(parameterName)) { + index = parameterName.mid(2, 1).toInt(&ok) - 1; + if (ok && index < chanMax) { + rcMin[index] = intVal; + updateRcWidgetValues(); + } + } + else if (maxTpl.exactMatch(parameterName)) { + index = parameterName.mid(2, 1).toInt(&ok) - 1; + if (ok && index < chanMax) { + rcMax[index] = intVal; + updateRcWidgetValues(); + } + } + else if (trimTpl.exactMatch(parameterName)) { + index = parameterName.mid(2, 1).toInt(&ok) - 1; + if (ok && index < chanMax) { + rcTrim[index] = intVal; + } + } + else if (revTpl.exactMatch(parameterName)) { + index = parameterName.mid(2, 1).toInt(&ok) - 1; + if (ok && index < chanMax) { + rcRev[index] = (intVal == -1) ? true : false; + updateInvertedCheckboxes(index); + } + } + } + +} + void QGCPX4VehicleConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { Q_UNUSED(uas); Q_UNUSED(component); - if (!doneLoadingConfig) - { + if (!doneLoadingConfig) { //We do not want to attempt to generate any UI elements until loading of the config file is complete. //We should re-request params later if needed, that is not implemented yet. return; } - if (paramToWidgetMap.contains(parameterName)) - { + if (parameterName.startsWith("RC")) { + handleRcParameterChange(parameterName,value); + return; + } + + if (paramToWidgetMap.contains(parameterName)) { //Main group of parameters of the selected airframe paramToWidgetMap.value(parameterName)->setParameterValue(uas,component,parameterName,value); - if (toolToBoxMap.contains(paramToWidgetMap.value(parameterName))) - { + if (toolToBoxMap.contains(paramToWidgetMap.value(parameterName))) { toolToBoxMap[paramToWidgetMap.value(parameterName)]->show(); } - else - { + else { qCritical() << "Widget with no box, possible memory corruption for param:" << parameterName; } } - else if (libParamToWidgetMap.contains(parameterName)) - { + else if (libParamToWidgetMap.contains(parameterName)) { //All the library parameters libParamToWidgetMap.value(parameterName)->setParameterValue(uas,component,parameterName,value); - if (toolToBoxMap.contains(libParamToWidgetMap.value(parameterName))) - { + if (toolToBoxMap.contains(libParamToWidgetMap.value(parameterName))) { toolToBoxMap[libParamToWidgetMap.value(parameterName)]->show(); } - else - { + else { qCritical() << "Widget with no box, possible memory corruption for param:" << parameterName; } } - else - { + else { //Param recieved that we have no metadata for. Search to see if it belongs in a //group with some other params bool found = false; - for (int i=0;iobjectName())) - { + for (int i=0;iobjectName())) { //It should be grouped with this one, add it. toolWidgets[i]->addParam(uas,component,parameterName,value); libParamToWidgetMap.insert(parameterName,toolWidgets[i]); @@ -1177,16 +1295,14 @@ void QGCPX4VehicleConfig::parameterChanged(int uas, int component, QString param break; } } - if (!found) - { + if (!found) { //New param type, create a QGroupBox for it. QWidget* parent = ui->advanceColumnContents; // Create the tool, attaching it to the QGroupBox QGCToolWidget *tool = new QGCToolWidget("", parent); QString tooltitle = parameterName; - if (parameterName.split("_").size() > 1) - { + if (parameterName.split("_").size() > 1) { tooltitle = parameterName.split("_")[0] + "_"; } tool->setTitle(tooltitle); @@ -1208,156 +1324,6 @@ void QGCPX4VehicleConfig::parameterChanged(int uas, int component, QString param } } - // Channel calibration values - QRegExp minTpl("RC?_MIN"); - minTpl.setPatternSyntax(QRegExp::Wildcard); - QRegExp maxTpl("RC?_MAX"); - maxTpl.setPatternSyntax(QRegExp::Wildcard); - QRegExp trimTpl("RC?_TRIM"); - trimTpl.setPatternSyntax(QRegExp::Wildcard); - QRegExp revTpl("RC?_REV"); - revTpl.setPatternSyntax(QRegExp::Wildcard); - - // Do not write the RC type, as these values depend on this - // active onboard parameter - - if (minTpl.exactMatch(parameterName)) { - bool ok; - unsigned int index = parameterName.mid(2, 1).toInt(&ok) - 1; - //qDebug() << "PARAM:" << parameterName << "index:" << index; - if (ok && index < chanMax) - { - rcMin[index] = value.toInt(); - updateMinMax(); - } - } - - if (maxTpl.exactMatch(parameterName)) { - bool ok; - unsigned int index = parameterName.mid(2, 1).toInt(&ok) - 1; - if (ok && index < chanMax) - { - rcMax[index] = value.toInt(); - updateMinMax(); - } - } - - if (trimTpl.exactMatch(parameterName)) { - bool ok; - unsigned int index = parameterName.mid(2, 1).toInt(&ok) - 1; - if (ok && index < chanMax) - { - rcTrim[index] = value.toInt(); - } - } - - if (revTpl.exactMatch(parameterName)) { - bool ok; - unsigned int index = parameterName.mid(2, 1).toInt(&ok) - 1; - if (ok && index < chanMax) - { - rcRev[index] = (value.toInt() == -1) ? true : false; - updateInvertedCheckboxes(index); - } - } - -// mav->setParameter(0, trimTpl.arg(i), rcTrim[i]); -// mav->setParameter(0, maxTpl.arg(i), rcMax[i]); -// mav->setParameter(0, revTpl.arg(i), (rcRev[i]) ? -1 : 1); -// } - - if (rcTypeUpdateRequested > 0 && parameterName == QString("RC_TYPE")) - { - rcTypeUpdateRequested = 0; - updateStatus(tr("Received RC type update, setting parameters based on model.")); - rcType = value.toInt(); - // Request all other parameters as well - requestCalibrationRC(); - } - - // Order is: roll, pitch, yaw, throttle, mode sw, aux 1-3 - - if (parameterName.contains("RC_MAP_ROLL")) { - rcMapping[0] = value.toInt() - 1; - ui->rollSpinBox->setValue(rcMapping[0]+1); - ui->rollSpinBox->setEnabled(true); - } - - if (parameterName.contains("RC_MAP_PITCH")) { - rcMapping[1] = value.toInt() - 1; - ui->pitchSpinBox->setValue(rcMapping[1]+1); - ui->pitchSpinBox->setEnabled(true); - } - - if (parameterName.contains("RC_MAP_YAW")) { - rcMapping[2] = value.toInt() - 1; - ui->yawSpinBox->setValue(rcMapping[2]+1); - ui->yawSpinBox->setEnabled(true); - } - - if (parameterName.contains("RC_MAP_THROTTLE")) { - rcMapping[3] = value.toInt() - 1; - ui->throttleSpinBox->setValue(rcMapping[3]+1); - ui->throttleSpinBox->setEnabled(true); - } - - if (parameterName.contains("RC_MAP_MODE_SW")) { - rcMapping[4] = value.toInt() - 1; - ui->modeSpinBox->setValue(rcMapping[4]+1); - ui->modeSpinBox->setEnabled(true); - } - - if (parameterName.contains("RC_MAP_AUX1")) { - rcMapping[5] = value.toInt() - 1; - ui->aux1SpinBox->setValue(rcMapping[5]+1); - ui->aux1SpinBox->setEnabled(true); - } - - if (parameterName.contains("RC_MAP_AUX2")) { - rcMapping[6] = value.toInt() - 1; - ui->aux2SpinBox->setValue(rcMapping[6]+1); - ui->aux2SpinBox->setEnabled(true); - } - - if (parameterName.contains("RC_MAP_AUX3")) { - rcMapping[7] = value.toInt() - 1; - ui->aux3SpinBox->setValue(rcMapping[7]+1); - ui->aux3SpinBox->setEnabled(true); - } - - // Scaling - - if (parameterName.contains("RC_SCALE_ROLL")) { - rcScaling[0] = value.toFloat(); - } - - if (parameterName.contains("RC_SCALE_PITCH")) { - rcScaling[1] = value.toFloat(); - } - - if (parameterName.contains("RC_SCALE_YAW")) { - rcScaling[2] = value.toFloat(); - } - - if (parameterName.contains("RC_SCALE_THROTTLE")) { - rcScaling[3] = value.toFloat(); - } - - if (parameterName.contains("RC_SCALE_MODE_SW")) { - rcScaling[4] = value.toFloat(); - } - - if (parameterName.contains("RC_SCALE_AUX1")) { - rcScaling[5] = value.toFloat(); - } - - if (parameterName.contains("RC_SCALE_AUX2")) { - rcScaling[6] = value.toFloat(); - } - - if (parameterName.contains("RC_SCALE_AUX3")) { - rcScaling[7] = value.toFloat(); - } } void QGCPX4VehicleConfig::updateStatus(const QString& str) @@ -1371,28 +1337,7 @@ void QGCPX4VehicleConfig::updateError(const QString& str) ui->advancedStatusLabel->setText(str); ui->advancedStatusLabel->setStyleSheet(QString("QLabel { margin: 0px 2px; font: 14px; color: %1; background-color: %2; }").arg(QGC::colorDarkWhite.name()).arg(QGC::colorMagenta.name())); } -void QGCPX4VehicleConfig::updateMinMax() -{ - // Order is: roll, pitch, yaw, throttle, mode sw, aux 1-3 - /* - *ui->rollWidget->setMin(rcMin[0]); - ui->rollWidget->setMax(rcMax[0]); - ui->pitchWidget->setMin(rcMin[1]); - ui->pitchWidget->setMax(rcMax[1]); - ui->yawWidget->setMin(rcMin[2]); - ui->yawWidget->setMax(rcMax[2]); - ui->throttleWidget->setMin(rcMin[3]); - ui->throttleWidget->setMax(rcMax[3]); - ui->radio5Widget->setMin(rcMin[4]); - ui->radio5Widget->setMax(rcMax[4]); - ui->radio6Widget->setMin(rcMin[5]); - ui->radio6Widget->setMax(rcMax[5]); - ui->radio7Widget->setMin(rcMin[6]); - ui->radio7Widget->setMax(rcMax[6]); - ui->radio8Widget->setMin(rcMin[7]); - ui->radio8Widget->setMax(rcMax[7]); -*/ -} + void QGCPX4VehicleConfig::setRCType(int type) { @@ -1419,143 +1364,87 @@ void QGCPX4VehicleConfig::checktimeOuts() void QGCPX4VehicleConfig::updateRcWidgetValues() { + //TODO set eg pitchSpinBox values + switch (rc_mode) { case RC_MODE_1: - ui->rollWidget->setValue(rcValue[0]); - ui->throttleWidget->setValue(rcValue[1]); - ui->yawWidget->setValue(rcValue[2]); - ui->pitchWidget->setValue(rcValue[3]); - - ui->rollWidget->setMin(rcMin[0]); - ui->rollWidget->setMax(rcMax[0]); - ui->throttleWidget->setMin(rcMin[1]); - ui->throttleWidget->setMax(rcMax[1]); - ui->yawWidget->setMin(rcMin[2]); - ui->yawWidget->setMax(rcMax[2]); - ui->pitchWidget->setMin(rcMin[3]); - ui->pitchWidget->setMax(rcMax[3]); - break; + ui->rollWidget->setValueAndRange(rcValue[0],rcMin[0],rcMax[0]); + ui->throttleWidget->setValueAndRange(rcValue[1],rcMin[1],rcMax[1]); + ui->yawWidget->setValueAndRange(rcValue[2],rcMin[2],rcMax[2]); + ui->pitchWidget->setValueAndRange(rcValue[3],rcMin[3],rcMax[3]); + setRollChan(1); + setThrottleChan(2); + break; + + case RC_MODE_NONE: case RC_MODE_2: - ui->rollWidget->setValue(rcValue[0]); - ui->pitchWidget->setValue(rcValue[1]); - ui->yawWidget->setValue(rcValue[2]); - ui->throttleWidget->setValue(rcValue[3]); - - ui->rollWidget->setMin(rcMin[0]); - ui->rollWidget->setMax(rcMax[0]); - ui->pitchWidget->setMin(rcMin[1]); - ui->pitchWidget->setMax(rcMax[1]); - ui->yawWidget->setMin(rcMin[2]); - ui->yawWidget->setMax(rcMax[2]); - ui->throttleWidget->setMin(rcMin[3]); - ui->throttleWidget->setMax(rcMax[3]); + ui->rollWidget->setValueAndRange(rcValue[0],rcMin[0],rcMax[0]); + ui->pitchWidget->setValueAndRange(rcValue[1],rcMin[1],rcMax[1]); + ui->throttleWidget->setValueAndRange(rcValue[2],rcMin[2],rcMax[2]); + ui->yawWidget->setValueAndRange(rcValue[3],rcMin[3],rcMax[3]); break; case RC_MODE_3: - ui->yawWidget->setValue(rcValue[0]); - ui->throttleWidget->setValue(rcValue[1]); - ui->rollWidget->setValue(rcValue[2]); - ui->pitchWidget->setValue(rcValue[3]); - - ui->yawWidget->setMin(rcMin[0]); - ui->yawWidget->setMax(rcMax[0]); - ui->throttleWidget->setMin(rcMin[1]); - ui->throttleWidget->setMax(rcMax[1]); - ui->rollWidget->setMin(rcMin[2]); - ui->rollWidget->setMax(rcMax[2]); - ui->pitchWidget->setMin(rcMin[3]); - ui->pitchWidget->setMax(rcMax[3]); + ui->yawWidget->setValueAndRange(rcValue[0],rcMin[0],rcMax[0]); + ui->throttleWidget->setValueAndRange(rcValue[1],rcMin[1],rcMax[1]); + ui->rollWidget->setValueAndRange(rcValue[2],rcMin[2],rcMax[2]); + ui->pitchWidget->setValueAndRange(rcValue[3],rcMin[3],rcMax[3]); break; case RC_MODE_4: - ui->yawWidget->setValue(rcValue[0]); - ui->pitchWidget->setValue(rcValue[1]); - ui->rollWidget->setValue(rcValue[2]); - ui->throttleWidget->setValue(rcValue[3]); - - ui->yawWidget->setMin(rcMin[0]); - ui->yawWidget->setMax(rcMax[0]); - ui->pitchWidget->setMin(rcMin[1]); - ui->pitchWidget->setMax(rcMax[1]); - ui->rollWidget->setMin(rcMin[2]); - ui->rollWidget->setMax(rcMax[2]); - ui->throttleWidget->setMin(rcMin[3]); - ui->throttleWidget->setMax(rcMax[3]); - break; - - case RC_MODE_NONE: - ui->rollWidget->setValue(rcValue[0]); - ui->pitchWidget->setValue(rcValue[1]); - ui->throttleWidget->setValue(rcValue[2]); - ui->yawWidget->setValue(rcValue[3]); - - ui->rollWidget->setMin(800); - ui->rollWidget->setMax(2200); - ui->pitchWidget->setMin(800); - ui->pitchWidget->setMax(2200); - ui->throttleWidget->setMin(800); - ui->throttleWidget->setMax(2200); - ui->yawWidget->setMin(800); - ui->yawWidget->setMax(2200); + ui->yawWidget->setValueAndRange(rcValue[0],rcMin[0],rcMax[0]); + ui->pitchWidget->setValueAndRange(rcValue[1],rcMin[1],rcMax[1]); + ui->rollWidget->setValueAndRange(rcValue[2],rcMin[2],rcMax[2]); + ui->throttleWidget->setValueAndRange(rcValue[3],rcMin[3],rcMax[3]); break; } - - ui->radio5Widget->setMin(rcMin[4]); - ui->radio5Widget->setMax(rcMax[4]); - ui->radio5Widget->setValue(rcValue[4]); - - ui->radio6Widget->setMin(rcMin[5]); - ui->radio6Widget->setMax(rcMax[5]); - ui->radio6Widget->setValue(rcValue[5]); - - ui->radio7Widget->setMin(rcMin[6]); - ui->radio7Widget->setMax(rcMax[6]); - ui->radio7Widget->setValue(rcValue[6]); - - ui->radio8Widget->setMin(rcMin[7]); - ui->radio8Widget->setMax(rcMax[7]); - ui->radio8Widget->setValue(rcValue[7]); - + ui->radio5Widget->setValueAndRange(rcValue[4],rcMin[4],rcMax[4]); + ui->radio6Widget->setValueAndRange(rcValue[5],rcMin[5],rcMax[5]); + ui->radio7Widget->setValueAndRange(rcValue[6],rcMin[6],rcMax[6]); + ui->radio8Widget->setValueAndRange(rcValue[7],rcMin[7],rcMax[7]); } void QGCPX4VehicleConfig::updateView() { - if (changed) - { + if (dataModelChanged) { + dataModelChanged = false; + //update the selected RC mode + int selectedRcModeIdx = (RC_MODE_NONE != rc_mode) ? (rc_mode -1) : -1; + ui->rcModeComboBox->setCurrentIndex(selectedRcModeIdx); + updateRcWidgetValues(); //update the channel labels - ui->chanLabel->setText(QString("%1/%2").arg(rcValue[rcMapping[0]]).arg(rcRoll, 5, 'f', 2, QChar(' '))); - ui->chanLabel_2->setText(QString("%1/%2").arg(rcValue[rcMapping[1]]).arg(rcPitch, 5, 'f', 2, QChar(' '))); - ui->chanLabel_3->setText(QString("%1/%2").arg(rcValue[rcMapping[2]]).arg(rcYaw, 5, 'f', 2, QChar(' '))); - ui->chanLabel_4->setText(QString("%1/%2").arg(rcValue[rcMapping[3]]).arg(rcThrottle, 5, 'f', 2, QChar(' '))); + ui->rollChanLabel->setText(QString("%1").arg(rcRoll, 5, 'f', 2, QChar(' '))); + ui->pitchChanLabel->setText(QString("%1").arg(rcPitch, 5, 'f', 2, QChar(' '))); + ui->yawChanLabel->setText(QString("%1").arg(rcYaw, 5, 'f', 2, QChar(' '))); + ui->throttleChanLabel->setText(QString("%1").arg(rcThrottle, 5, 'f', 2, QChar(' '))); if (rcValue[rcMapping[4] != UINT16_MAX]) { - ui->chanLabel_5->setText(QString("%1/%2").arg(rcValue[rcMapping[4]]).arg(rcMode, 5, 'f', 2, QChar(' '))); + ui->modeChanLabel->setText(QString("%1").arg(rcMode, 5, 'f', 2, QChar(' '))); } else { - ui->chanLabel_5->setText(tr("---")); + ui->modeChanLabel->setText(tr("---")); } if (rcValue[rcMapping[5]] != UINT16_MAX) { - ui->chanLabel_6->setText(QString("%1/%2").arg(rcValue[rcMapping[5]]).arg(rcAux1, 5, 'f', 2, QChar(' '))); + ui->aux1ChanLabel->setText(QString("%1").arg(rcAux1, 5, 'f', 2, QChar(' '))); } else { - ui->chanLabel_6->setText(tr("---")); + ui->aux1ChanLabel->setText(tr("---")); } if (rcValue[rcMapping[6]] != UINT16_MAX) { - ui->chanLabel_7->setText(QString("%1/%2").arg(rcValue[rcMapping[6]]).arg(rcAux2, 5, 'f', 2, QChar(' '))); + ui->aux2ChanLabel->setText(QString("%1").arg(rcAux2, 5, 'f', 2, QChar(' '))); } else { - ui->chanLabel_7->setText(tr("---")); + ui->aux2ChanLabel->setText(tr("---")); } if (rcValue[rcMapping[7]] != UINT16_MAX) { - ui->chanLabel_8->setText(QString("%1/%2").arg(rcValue[rcMapping[7]]).arg(rcAux3, 5, 'f', 2, QChar(' '))); + ui->aux3ChanLabel->setText(QString("%1").arg(rcAux3, 5, 'f', 2, QChar(' '))); } else { - ui->chanLabel_8->setText(tr("---")); + ui->aux3ChanLabel->setText(tr("---")); } - changed = false; } } diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index 360d481213..b11d2e60e2 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -57,8 +57,8 @@ public slots: /** Render the data updated */ void updateView(); void updateRcWidgetValues(); + void handleRcParameterChange(QString parameterName, QVariant value); - void updateMinMax(); /** Set the RC channel */ void setRollChan(int channel) { @@ -180,7 +180,7 @@ protected: float rcAux2; ///< PPM input channel used as aux 2 input float rcAux3; ///< PPM input channel used as aux 3 input bool rcCalChanged; ///< Set if the calibration changes (and needs to be written) - bool changed; ///< Set if any of the input data changed + bool dataModelChanged; ///< Set if any of the input data changed QTimer updateTimer; ///< Controls update intervals enum RC_MODE rc_mode; ///< Mode of the remote control, according to usual convention QList toolWidgets; ///< Configurable widgets diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index b28fcfe666..8607a55643 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -338,18 +338,13 @@ Config - - - false + + + RC Transmitter Mode - - false + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - Select transmitter model - - @@ -357,6 +352,12 @@ Config true + + + 320 + 16777215 + + Mode 1 @@ -383,8 +384,8 @@ Config - - + + 0000 @@ -393,72 +394,89 @@ Config - - + + - Invert + Aux 3 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - Qt::Horizontal + + + + false - - - 40 - 20 - + + 1 - + + 8 + + - - + + - Yaw / Rudder + Invert - - + + - 0000 + Roll / Ailerons - Qt::AlignCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - Qt::Horizontal + + + + Aux 1 - - - 40 - 20 - + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + - - + + Invert - - + + + + Mode Switch + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Invert - - + + + + Invert + + + + + false @@ -470,18 +488,21 @@ Config - - - - 0000 + + + + false - - Qt::AlignCenter + + 1 + + + 8 - - + + 0000 @@ -490,45 +511,48 @@ Config - - - - Pitch / Elevator + + + + false + + + 1 + + + 8 - - + + - 0000 + Yaw / Rudder - Qt::AlignCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - Aux 2 + Invert - - - - Qt::Horizontal + + + + Throttle - - - 40 - 20 - + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + - + 0000 @@ -537,15 +561,8 @@ Config - - - - Invert - - - - - + + false @@ -557,48 +574,48 @@ Config - - - - Qt::Horizontal + + + + Pitch / Elevator - - - 40 - 20 - + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + - - + + - Throttle + 0000 + + + Qt::AlignCenter - - + + - Invert + Aux 2 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - false - - - 1 + + + + 0000 - - 8 + + Qt::AlignCenter - - + + false @@ -610,15 +627,8 @@ Config - - - - Mode Switch - - - - + 0000 @@ -627,8 +637,8 @@ Config - - + + false @@ -640,28 +650,25 @@ Config - - - - false - - - 1 + + + + 0000 - - 8 + + Qt::AlignCenter - - + + - Aux 1 + Invert - - + + false @@ -673,8 +680,8 @@ Config - - + + 0000 @@ -683,53 +690,71 @@ Config - - + + - Aux 3 + Invert - - + + Invert - - - - false - - - 1 + + + + Qt::Horizontal - - 8 + + + 40 + 20 + - + - - - - Invert + + + + Qt::Horizontal - + + + 40 + 20 + + + - - - - Invert + + + + Qt::Horizontal - + + + 40 + 20 + + + - - - - Roll / Ailerons + + + + Qt::Horizontal - + + + 40 + 20 + + + diff --git a/src/ui/designer/QGCRadioChannelDisplay.cpp b/src/ui/designer/QGCRadioChannelDisplay.cpp index a0e4e458d4..275afc28e7 100644 --- a/src/ui/designer/QGCRadioChannelDisplay.cpp +++ b/src/ui/designer/QGCRadioChannelDisplay.cpp @@ -1,5 +1,10 @@ #include "QGCRadioChannelDisplay.h" #include + +#define DIMMEST_COLOR QColor::fromRgb(0,100,0) +#define MIDBRIGHT_COLOR QColor::fromRgb(0,180,0) +#define BRIGHTEST_COLOR QColor::fromRgb(64,255,0) + QGCRadioChannelDisplay::QGCRadioChannelDisplay(QWidget *parent) : QWidget(parent) { m_showMinMax = false; @@ -53,9 +58,9 @@ void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) if (m_orientation == Qt::Vertical) { QLinearGradient gradientBrush(0, 0, this->width(), this->height()); - gradientBrush.setColorAt(1.0,QColor::fromRgb(0,128,0)); - gradientBrush.setColorAt(0.5,QColor::fromRgb(0,200,0)); - gradientBrush.setColorAt(0.0, QColor::fromRgb(64,255,0)); + gradientBrush.setColorAt(1.0,DIMMEST_COLOR); + gradientBrush.setColorAt(0.5,MIDBRIGHT_COLOR); + gradientBrush.setColorAt(0.0, BRIGHTEST_COLOR); //draw border painter.drawRect(0,0,width()-1,(height()-1) - twiceFontHeight); @@ -105,9 +110,9 @@ void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event) else //horizontal orientation { QLinearGradient hGradientBrush(0, 0, this->width(), this->height()); - hGradientBrush.setColorAt(0.0,QColor::fromRgb(0,128,0)); - hGradientBrush.setColorAt(0.5,QColor::fromRgb(0,200,0)); - hGradientBrush.setColorAt(1.0, QColor::fromRgb(64,255,0)); + hGradientBrush.setColorAt(0.0,DIMMEST_COLOR); + hGradientBrush.setColorAt(0.5,MIDBRIGHT_COLOR); + hGradientBrush.setColorAt(1.0, BRIGHTEST_COLOR); //draw the value painter.drawRect(0,0,width()-1,(height()-1) - twiceFontHeight); @@ -178,6 +183,19 @@ void QGCRadioChannelDisplay::hideMinMax() update(); } + +void QGCRadioChannelDisplay::setValueAndRange(int val, int min, int max) +{ + setValue(val); + setMinMax(min,max); +} + +void QGCRadioChannelDisplay::setMinMax(int min, int max) +{ + setMin(min); + setMax(max); +} + void QGCRadioChannelDisplay::setMin(int value) { m_min = value; diff --git a/src/ui/designer/QGCRadioChannelDisplay.h b/src/ui/designer/QGCRadioChannelDisplay.h index 93abcff7a2..59bb65438a 100644 --- a/src/ui/designer/QGCRadioChannelDisplay.h +++ b/src/ui/designer/QGCRadioChannelDisplay.h @@ -12,6 +12,8 @@ public: void setValue(int value); void showMinMax(); void hideMinMax(); + void setValueAndRange(int val, int min, int max); + void setMinMax(int min, int max); void setMin(int value); void setMax(int value); void setName(QString name); -- GitLab From d3ccd004b96faea4b010e3fb51016dcd40e82a78 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Wed, 31 Jul 2013 12:51:17 -0700 Subject: [PATCH 133/460] Updated layout of APM Toolbar Status Display for ARM/DISARM --- qgroundcontrol.pro | 3 ++- qml/ApmToolBar.qml | 36 ++++++++++++++++--------------- qml/components/DigitalDisplay.qml | 2 +- qml/components/StatusDisplay.qml | 24 +++++++++++++++++++++ src/ui/apmtoolbar.cpp | 16 ++++++++++++-- src/ui/apmtoolbar.h | 6 ++++-- 6 files changed, 64 insertions(+), 23 deletions(-) create mode 100644 qml/components/StatusDisplay.qml diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 70501c5990..ce11196f39 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -801,7 +801,8 @@ unix:!macx:!symbian: LIBS += -losg OTHER_FILES += \ dongfang_notes.txt \ src/ui/dongfang-scrapyard.txt \ - qml/components/DigitalDisplay.qml + qml/components/DigitalDisplay.qml \ + qml/components/StatusDisplay.qml OTHER_FILES += \ qml/ApmToolBar.qml \ diff --git a/qml/ApmToolBar.qml b/qml/ApmToolBar.qml index 6065598aed..c147e66c3e 100644 --- a/qml/ApmToolBar.qml +++ b/qml/ApmToolBar.qml @@ -10,7 +10,7 @@ Rectangle { property alias baudrateLabel: baudrate.label property bool connected: false property bool armed: false - property string armedstr: "Disarmed" + property string armedstr: "DISARMED" width: toolbar.width height: 72 @@ -19,12 +19,14 @@ Rectangle { onArmedChanged: { if (armed) { - armedText.text = "Armed" - armedText.color = "Red" + statusDisplay.statusText = "ARMED" + statusDisplay.statusTextColor = "red" + statusDisplay.statusBackgroundColor = "#FF880000" } else { - armedText.text = "Disarmed" - armedText.color = "Green" + statusDisplay.statusText = "DISARMED" + statusDisplay.statusTextColor = "yellow" + statusDisplay.statusBackgroundColor = "black" } } @@ -110,19 +112,19 @@ Rectangle { image: "./resources/apmplanner/toolbar/terminal.png" onClicked: globalObj.triggerTerminalView() } - Rectangle { - width:150 + + Rectangle { // Spacer + width: 5 height: parent.height - Text { - id: armedText; - anchors.fill: parent - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font.pixelSize: 20 - color: "green" - text: "Disarmed" - } - color:"black" + color: "black" + } + + StatusDisplay { + id: statusDisplay + width: 110 + statusText: "DISARMED" + statusTextColor: "yellow" + statusBackgroundColor: "black" } Rectangle { // Spacer diff --git a/qml/components/DigitalDisplay.qml b/qml/components/DigitalDisplay.qml index be69b6712b..dc70d0149c 100644 --- a/qml/components/DigitalDisplay.qml +++ b/qml/components/DigitalDisplay.qml @@ -5,7 +5,7 @@ Rectangle { property alias title: displayTitle.text property string textValue: "none" - width: 100 + width: 110 height: parent.height/3 anchors.verticalCenter: parent.verticalCenter border.color: "white" diff --git a/qml/components/StatusDisplay.qml b/qml/components/StatusDisplay.qml new file mode 100644 index 0000000000..9d4f6ade62 --- /dev/null +++ b/qml/components/StatusDisplay.qml @@ -0,0 +1,24 @@ +import QtQuick 1.1 + +Rectangle { + id: statusDisplay + property alias statusText: armedText.text + property alias statusTextColor: armedText.color + property alias statusBackgroundColor: statusDisplay.color + + width: 100 + height: parent.height/3 + anchors.verticalCenter: parent.verticalCenter + radius: 3 + border.color: "white" + border.width: 1 + + Text { + id: armedText + anchors.centerIn: parent + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.pixelSize: 20 + } + +} diff --git a/src/ui/apmtoolbar.cpp b/src/ui/apmtoolbar.cpp index 2f4595cc64..b676dff1b4 100644 --- a/src/ui/apmtoolbar.cpp +++ b/src/ui/apmtoolbar.cpp @@ -33,15 +33,27 @@ void APMToolBar::activeUasSet(UASInterface *uas) } if (m_uas) { - disconnect(m_uas,SIGNAL(armingChanged(bool)),this,SLOT(armingChanged(bool))); + disconnect(m_uas,SIGNAL(armingChanged(bool)), + this,SLOT(armingChanged(bool))); + disconnect(uas,SIGNAL(armingChanged(int, QString)), + this,SLOT(armingChanged(int, QString))); } - connect(uas,SIGNAL(armingChanged(bool)),this,SLOT(armingChanged(bool))); + connect(uas,SIGNAL(armingChanged(bool)), + this,SLOT(armingChanged(bool))); + connect(uas,SIGNAL(armingChanged(int, QString)), + this,SLOT(armingChanged(int, QString))); + } void APMToolBar::armingChanged(bool armed) { this->rootObject()->setProperty("armed",armed); } +void APMToolBar::armingChanged(int sysId, QString armingState) +{ + qDebug() << "APMToolBar: sysid " << sysId << " armState" << armingState; +} + void APMToolBar::setFlightViewAction(QAction *action) { connect(this, SIGNAL(triggerFlightView()), action, SIGNAL(triggered())); diff --git a/src/ui/apmtoolbar.h b/src/ui/apmtoolbar.h index 9d5608d975..5bed5a224e 100644 --- a/src/ui/apmtoolbar.h +++ b/src/ui/apmtoolbar.h @@ -33,8 +33,6 @@ signals: void MAVConnected(bool connected); public slots: - void armingChanged(bool armed); - void activeUasSet(UASInterface *uas); void selectFlightView(); void selectFlightPlanView(); void selectHardwareView(); @@ -46,6 +44,10 @@ public slots: void showConnectionDialog(); void setConnection(bool connection); + void activeUasSet(UASInterface *uas); + void armingChanged(int sysId, QString armingState); + void armingChanged(bool armed); + void updateLinkDisplay(LinkInterface *newLink); private: -- GitLab From f843806c8e82e5580ecefada66f54f535dfcc7fd Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Wed, 31 Jul 2013 12:51:59 -0700 Subject: [PATCH 134/460] Added the use of QPointer guard wrapper to help fix stability issues --- src/ui/configuration/ApmHardwareConfig.h | 29 ++++++++++++------------ src/ui/configuration/ApmSoftwareConfig.h | 20 ++++++++-------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/ui/configuration/ApmHardwareConfig.h b/src/ui/configuration/ApmHardwareConfig.h index 8dc6876d2d..427403b6d9 100644 --- a/src/ui/configuration/ApmHardwareConfig.h +++ b/src/ui/configuration/ApmHardwareConfig.h @@ -59,21 +59,22 @@ public: explicit ApmHardwareConfig(QWidget *parent = 0); ~ApmHardwareConfig(); private: - FrameTypeConfig *m_frameConfig; - CompassConfig *m_compassConfig; - AccelCalibrationConfig *m_accelConfig; - RadioCalibrationConfig *m_radioConfig; + QPointer m_frameConfig; + QPointer m_compassConfig; + QPointer m_accelConfig; + QPointer m_radioConfig; + + QPointer m_apmFirmwareConfig; + QPointer m_radio3drConfig; + QPointer m_batteryConfig; + QPointer m_sonarConfig; + QPointer m_airspeedConfig; + QPointer m_opticalFlowConfig; + QPointer m_osdConfig; + QPointer m_cameraGimbalConfig; + QPointer m_antennaTrackerConfig; + QPointer m_planeLevel; - ApmFirmwareConfig *m_apmFirmwareConfig; - Radio3DRConfig *m_radio3drConfig; - BatteryMonitorConfig *m_batteryConfig; - SonarConfig *m_sonarConfig; - AirspeedConfig *m_airspeedConfig; - OpticalFlowConfig *m_opticalFlowConfig; - OsdConfig *m_osdConfig; - CameraGimbalConfig *m_cameraGimbalConfig; - AntennaTrackerConfig *m_antennaTrackerConfig; - ApmPlaneLevel *m_planeLevel; private slots: void activeUASSet(UASInterface *uas); void activateStackedWidget(); diff --git a/src/ui/configuration/ApmSoftwareConfig.h b/src/ui/configuration/ApmSoftwareConfig.h index c4eabf414e..77b97d0822 100644 --- a/src/ui/configuration/ApmSoftwareConfig.h +++ b/src/ui/configuration/ApmSoftwareConfig.h @@ -28,16 +28,16 @@ private slots: void activeUASSet(UASInterface *uas); private: Ui::ApmSoftwareConfig ui; - BasicPidConfig *m_basicPidConfig; - FlightModeConfig *m_flightConfig; - StandardParamConfig *m_standardParamConfig; - GeoFenceConfig *m_geoFenceConfig; - FailSafeConfig *m_failSafeConfig; - AdvancedParamConfig *m_advancedParamConfig; - ArduCopterPidConfig *m_arduCopterPidConfig; - ArduPlanePidConfig *m_arduPlanePidConfig; - ArduRoverPidConfig *m_arduRoverPidConfig; - AdvParameterList *m_advParameterList; + QPointer m_basicPidConfig; + QPointer m_flightConfig; + QPointer m_standardParamConfig; + QPointer m_geoFenceConfig; + QPointer m_failSafeConfig; + QPointer m_advancedParamConfig; + QPointer m_arduCopterPidConfig; + QPointer m_arduPlanePidConfig; + QPointer m_arduRoverPidConfig; + QPointer m_advParameterList; QMap m_buttonToConfigWidgetMap; }; -- GitLab From 4e29541c795ec4d458992d67d8e2f0509e0e67fe Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Wed, 31 Jul 2013 12:52:43 -0700 Subject: [PATCH 135/460] Fixed the accidental removal of UDP listening of startup --- src/QGCCore.cc | 22 ++++++++++++++++++++++ src/comm/UDPLink.cc | 3 ++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/QGCCore.cc b/src/QGCCore.cc index ee0e4ef818..e5817082a6 100644 --- a/src/QGCCore.cc +++ b/src/QGCCore.cc @@ -171,6 +171,28 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv) if (upgraded) mainWindow->showInfoMessage(tr("Default Settings Loaded"), tr("APM Planner has been upgraded from version %1 to version %2. Some of your user preferences have been reset to defaults for safety reasons. Please adjust them where needed.").arg(lastApplicationVersion).arg(QGC_APPLICATION_VERSION)); + // Check if link could be connected + if (!udpLink->connect()) + { + QMessageBox msgBox; + msgBox.setIcon(QMessageBox::Critical); + msgBox.setText("Could not connect UDP port. Is an instance of " + qAppName() + "already running?"); + msgBox.setInformativeText("You will not be able to receive data via UDP. Please check that you're running the right executable and then re-start " + qAppName() + ". Do you want to close the application?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::No); + int ret = msgBox.exec(); + + // Close the message box shortly after the click to prevent accidental clicks + QTimer::singleShot(15000, &msgBox, SLOT(reject())); + + // Exit application + if (ret == QMessageBox::Yes) + { + //mainWindow->close(); + QTimer::singleShot(200, mainWindow, SLOT(close())); + } + } + } /** diff --git a/src/comm/UDPLink.cc b/src/comm/UDPLink.cc index 708de75b82..0cade27866 100644 --- a/src/comm/UDPLink.cc +++ b/src/comm/UDPLink.cc @@ -50,6 +50,7 @@ UDPLink::UDPLink(QHostAddress host, quint16 port) this->name = tr("UDP Link (port:%1)").arg(this->port); emit nameChanged(this->name); // LinkManager::instance()->add(this); + qDebug() << "UDP Created " << name; } UDPLink::~UDPLink() @@ -104,7 +105,7 @@ void UDPLink::setPort(int port) */ void UDPLink::addHost(const QString& host) { - //qDebug() << "UDP:" << "ADDING HOST:" << host; + qDebug() << "UDP:" << "ADDING HOST:" << host; if (host.contains(":")) { //qDebug() << "HOST: " << host.split(":").first(); -- GitLab From d48036996ee3f40ad76830ecaaf331b599453320 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 31 Jul 2013 17:55:12 -0400 Subject: [PATCH 136/460] Change of Serial settings window size and baud/port combobox sizes --- src/ui/CommSettings.ui | 13 ++++---- src/ui/SerialConfigurationWindow.cc | 4 +-- src/ui/SerialSettings.ui | 51 +++++++++-------------------- 3 files changed, 24 insertions(+), 44 deletions(-) diff --git a/src/ui/CommSettings.ui b/src/ui/CommSettings.ui index 735340383e..46e5ca56e0 100644 --- a/src/ui/CommSettings.ui +++ b/src/ui/CommSettings.ui @@ -6,8 +6,8 @@ 0 0 - 770 - 563 + 324 + 415 @@ -36,8 +36,8 @@ 0 0 - 748 - 97 + 302 + 69 @@ -126,8 +126,8 @@ 0 0 - 748 - 96 + 302 + 69 @@ -230,7 +230,6 @@ connectionStatusLabel advCheckBox protocolTypeGroupBox - label_5 verticalSpacer diff --git a/src/ui/SerialConfigurationWindow.cc b/src/ui/SerialConfigurationWindow.cc index 9d26613979..338e2d3283 100644 --- a/src/ui/SerialConfigurationWindow.cc +++ b/src/ui/SerialConfigurationWindow.cc @@ -134,8 +134,8 @@ SerialConfigurationWindow::SerialConfigurationWindow(LinkInterface* link, QWidge ui.advGroupBox->setVisible(false); //connect(this->link, SIGNAL(connected(bool)), this, SLOT()); - ui.portName->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow); - ui.baudRate->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow); + //ui.portName->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow); + //ui.baudRate->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow); switch(this->link->getParityType()) { case 0: diff --git a/src/ui/SerialSettings.ui b/src/ui/SerialSettings.ui index fd96720ec6..2a23c835ff 100644 --- a/src/ui/SerialSettings.ui +++ b/src/ui/SerialSettings.ui @@ -6,8 +6,8 @@ 0 0 - 546 - 457 + 234 + 354 @@ -15,7 +15,7 @@ - + @@ -25,6 +25,12 @@ + + + 100 + 0 + + The serial port to which the system is connected. All ports listed here should work. @@ -47,23 +53,10 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + @@ -73,6 +66,12 @@ + + + 100 + 0 + + The data transmission rate. If unsure 57600 and 115200 are very common rates. @@ -215,19 +214,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -429,11 +415,6 @@ - horizontalLayoutWidget - horizontalLayoutWidget_2 - horizontalLayoutWidget_4 - portlabel_5 - horizontalLayoutWidget_3 -- GitLab From 1a40f01963d3339c902c993e745d4697fb660c3f Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Wed, 31 Jul 2013 18:18:30 -0400 Subject: [PATCH 137/460] Change for Failsafe config to correctly display GPS status and Disarmed on start --- src/ui/configuration/FailSafeConfig.cc | 21 +++++++++++++++++++++ src/ui/configuration/FailSafeConfig.h | 1 + 2 files changed, 22 insertions(+) diff --git a/src/ui/configuration/FailSafeConfig.cc b/src/ui/configuration/FailSafeConfig.cc index 66e1c10475..9d177cc735 100644 --- a/src/ui/configuration/FailSafeConfig.cc +++ b/src/ui/configuration/FailSafeConfig.cc @@ -82,6 +82,11 @@ FailSafeConfig::FailSafeConfig(QWidget *parent) : AP2ConfigWidget(parent) connect(ui.throttleCheckBox,SIGNAL(clicked(bool)),this,SLOT(throttleChecked(bool))); connect(ui.throttlePwmSpinBox,SIGNAL(editingFinished()),this,SLOT(throttlePwmChanged())); connect(ui.throttleFailSafeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(throttleFailSafeChanged(int))); + + ui.armedLabel->setText("

DISARMED

"); + + + ui.modeLabel->setText("

MODE

"); initConnections(); } void FailSafeConfig::gcsChecked(bool checked) @@ -225,6 +230,7 @@ void FailSafeConfig::activeUASSet(UASInterface *uas) connect(m_uas,SIGNAL(remoteControlChannelRawChanged(int,float)),this,SLOT(remoteControlChannelRawChanges(int,float))); connect(m_uas,SIGNAL(hilActuatorsChanged(uint64_t,float,float,float,float,float,float,float,float)),this,SLOT(hilActuatorsChanged(uint64_t,float,float,float,float,float,float,float,float))); connect(m_uas,SIGNAL(armingChanged(bool)),this,SLOT(armingChanged(bool))); + connect(m_uas,SIGNAL(gpsLocalizationChanged(UASInterface*,int)),this,SLOT(gpsStatusChanged(UASInterface*,int))); if (m_uas->getSystemType() == MAV_TYPE_FIXED_WING) { ui.batteryFailCheckBox->setVisible(false); @@ -417,3 +423,18 @@ void FailSafeConfig::hilActuatorsChanged(uint64_t time, float act1, float act2, ui.radio7Out->setValue(act7); ui.radio8Out->setValue(act8); } +void FailSafeConfig::gpsStatusChanged(UASInterface* uas,int fixtype) +{ + if (fixtype == 0 || fixtype == 1) + { + ui.gpsLabel->setText("

None

"); + } + else if (fixtype == 2) + { + ui.gpsLabel->setText("

2D Fix

"); + } + else if (fixtype == 3) + { + ui.gpsLabel->setText("

3D Fix

"); + } +} diff --git a/src/ui/configuration/FailSafeConfig.h b/src/ui/configuration/FailSafeConfig.h index 162246e899..8246739312 100644 --- a/src/ui/configuration/FailSafeConfig.h +++ b/src/ui/configuration/FailSafeConfig.h @@ -25,6 +25,7 @@ private slots: void throttleChecked(bool checked); void throttlePwmChanged(); void throttleFailSafeChanged(int index); + void gpsStatusChanged(UASInterface* uas,int fixtype); private: Ui::FailSafeConfig ui; }; -- GitLab From d95cf003993f4886f53d490fdea6f3e8273f95eb Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 1 Aug 2013 16:30:45 +0200 Subject: [PATCH 138/460] Serial link selection in toolbar operational --- src/QGCCore.cc | 4 -- src/comm/LinkManager.cc | 15 +++++ src/comm/LinkManager.h | 4 ++ src/comm/SerialLink.cc | 1 + src/ui/MainWindow.cc | 25 ++++---- src/ui/MainWindow.h | 4 +- src/ui/QGCToolBar.cc | 134 +++++++++++++++++++++++----------------- src/ui/QGCToolBar.h | 1 + 8 files changed, 116 insertions(+), 72 deletions(-) diff --git a/src/QGCCore.cc b/src/QGCCore.cc index 8c59e757b5..14031f1ea3 100644 --- a/src/QGCCore.cc +++ b/src/QGCCore.cc @@ -176,15 +176,11 @@ QGCCore::QGCCore(bool firstStart, int &argc, char* argv[]) : QApplication(argc, OpalLink* opalLink = new OpalLink(); MainWindow::instance()->addLink(opalLink); #endif - MAVLinkSimulationLink* simulationLink = new MAVLinkSimulationLink(":/demo-log.txt"); - simulationLink->disconnect(); //We want to have a default serial link available for "quick" connecting. SerialLink *slink = new SerialLink(); MainWindow::instance()->addLink(slink); - mainWindow = MainWindow::instance(splashScreen); - // Remove splash screen splashScreen->finish(mainWindow); diff --git a/src/comm/LinkManager.cc b/src/comm/LinkManager.cc index 59fc3a99ee..6dae9ad78c 100644 --- a/src/comm/LinkManager.cc +++ b/src/comm/LinkManager.cc @@ -210,3 +210,18 @@ const QList LinkManager::getLinks() { return QList(links); } + +const QList LinkManager::getSerialLinks() +{ + QList s; + + foreach (LinkInterface* i, links) + { + SerialLink* link = qobject_cast(i); + + if (link) + s.append(link); + } + + return s; +} diff --git a/src/comm/LinkManager.h b/src/comm/LinkManager.h index ae7590ce72..f949ba909a 100644 --- a/src/comm/LinkManager.h +++ b/src/comm/LinkManager.h @@ -36,6 +36,7 @@ This file is part of the PIXHAWK project #include #include #include +#include #include /** @@ -64,6 +65,9 @@ public: /** @brief Get a list of all links */ const QList getLinks(); + /** @brief Get a list of all serial links */ + const QList getSerialLinks(); + /** @brief Get a list of all protocols */ const QList getProtocols() { return protocolLinks.uniqueKeys(); diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index f583482e98..eb8d6dbbca 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -74,6 +74,7 @@ SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, // } loadSettings(); + LinkManager::instance()->add(this); } void SerialLink::requestReset() { diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 403beca57c..4cf545463a 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -124,6 +124,7 @@ MainWindow::MainWindow(QWidget *parent): darkStyleFileName(defaultDarkStyle), lightStyleFileName(defaultLightStyle), autoReconnect(false), + simulationLink(NULL), lowPowerMode(false), isAdvancedMode(false), dockWidgetTitleBarEnabled(true), @@ -343,11 +344,11 @@ MainWindow::~MainWindow() delete mavlink; mavlink = NULL; } - // if (simulationLink) - // { - // simulationLink->deleteLater(); - // simulationLink = NULL; - // } + if (simulationLink) + { + delete simulationLink; + simulationLink = NULL; + } if (joystick) { joystick->shutdown(); @@ -1525,6 +1526,8 @@ void MainWindow::connectCommonActions() connect(ui.actionJoystickSettings, SIGNAL(triggered()), this, SLOT(configure())); // Application Settings connect(ui.actionSettings, SIGNAL(triggered()), this, SLOT(showSettings())); + + connect(ui.actionSimulate, SIGNAL(triggered(bool)), this, SLOT(simulateLink(bool))); } void MainWindow::showHelp() @@ -1672,15 +1675,15 @@ void MainWindow::addLink(LinkInterface *link) // Error handling connect(link, SIGNAL(communicationError(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection); - // Special case for simulationlink - MAVLinkSimulationLink* sim = dynamic_cast(link); - if (sim) - { - connect(ui.actionSimulate, SIGNAL(triggered(bool)), sim, SLOT(connectLink(bool))); - } } } +void MainWindow::simulateLink(bool simulate) { + if (!simulationLink) + simulationLink = new MAVLinkSimulationLink(":/demo-log.txt"); + simulationLink->connectLink(simulate); +} + //void MainWindow::configLink(LinkInterface *link) //{ diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 98c6ec6655..8838d00aac 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -204,6 +204,8 @@ public slots: void addLink(LinkInterface* link); bool configLink(LinkInterface *link); void configure(); + /** @brief Simulate a link */ + void simulateLink(bool simulate); /** @brief Set the currently controlled UAS */ void setActiveUAS(UASInterface* uas); @@ -387,7 +389,6 @@ protected: // TODO Should be moved elsewhere, as the protocol does not belong to the UI MAVLinkProtocol* mavlink; - MAVLinkSimulationLink* simulationLink; LinkInterface* udpLink; QSettings settings; @@ -490,6 +491,7 @@ protected: QString darkStyleFileName; QString lightStyleFileName; bool autoReconnect; + MAVLinkSimulationLink* simulationLink; Qt::WindowStates windowStateVal; bool lowPowerMode; ///< If enabled, QGC reduces the update rates of all widgets QGCFlightGearLink* fgLink; diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 5e436f5769..52f112d835 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -158,20 +158,23 @@ void QGCToolBar::createUI() portComboBox = new QComboBox(this); portComboBox->setToolTip(tr("Choose the COM port to use")); portComboBox->setEnabled(true); - portComboBox->setMinimumWidth(200); + portComboBox->setMinimumWidth(100); addWidget(portComboBox); baudcomboBox = new QComboBox(this); baudcomboBox->setToolTip(tr("Choose what baud rate to use")); baudcomboBox->setEnabled(true); - baudcomboBox->setMinimumWidth(80); - baudcomboBox->addItem("9600"); - baudcomboBox->addItem("14400"); - baudcomboBox->addItem("19200"); - baudcomboBox->addItem("38400"); - baudcomboBox->addItem("57600"); - baudcomboBox->addItem("115200"); - baudcomboBox->setCurrentIndex(5); + baudcomboBox->setMinimumWidth(40); + baudcomboBox->addItem("9600", 9600); + baudcomboBox->addItem("14400", 14400); + baudcomboBox->addItem("19200", 19200); + baudcomboBox->addItem("38400", 38400); + baudcomboBox->addItem("57600", 57600); + baudcomboBox->addItem("115200", 115200); + baudcomboBox->addItem("230400", 230400); + baudcomboBox->addItem("460800", 460800); + baudcomboBox->addItem("921600", 921600); + baudcomboBox->setCurrentIndex(baudcomboBox->findData(57600)); addWidget(baudcomboBox); @@ -193,18 +196,25 @@ void QGCToolBar::createUI() // Configure the toolbar for the current default UAS setActiveUAS(UASManager::instance()->getActiveUAS()); connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); + qDebug() << "LINK COUNT" << LinkManager::instance()->getLinks().count(); + // Update label if required + if (LinkManager::instance()->getSerialLinks().count() < 1) { + connectButton->setText(tr("New Serial Link")); + baudcomboBox->hide(); + portComboBox->hide(); + } else { - if (LinkManager::instance()->getLinks().count() > 2) - addLink(LinkManager::instance()->getLinks().last()); - // XXX implies that connect button is always active for the last used link - connect(LinkManager::instance(), SIGNAL(newLink(LinkInterface*)), this, SLOT(addLink(LinkInterface*))); - connect(LinkManager::instance(), SIGNAL(linkRemoved(LinkInterface*)), this, SLOT(removeLink(LinkInterface*))); + QList links = LinkManager::instance()->getSerialLinks(); - // Update label if required - if (LinkManager::instance()->getLinks().count() < 3) { - connectButton->setText(tr("New Link")); + foreach(SerialLink* slink, links) + { + addLink(slink); + } } + connect(LinkManager::instance(), SIGNAL(newLink(LinkInterface*)), this, SLOT(addLink(LinkInterface*))); + connect(LinkManager::instance(), SIGNAL(linkRemoved(LinkInterface*)), this, SLOT(removeLink(LinkInterface*))); + loadSettings(); changed = false; @@ -591,27 +601,42 @@ void QGCToolBar::receiveTextMessage(int uasid, int componentid, int severity, QS void QGCToolBar::addLink(LinkInterface* link) { - // XXX magic number - if (LinkManager::instance()->getLinks().count() > 2) { + // Accept only serial links as current link + SerialLink* serial = qobject_cast(link); + + if (serial && !currentLink) + { + baudcomboBox->show(); + portComboBox->show(); + currentLink = link; connect(currentLink, SIGNAL(connected(bool)), this, SLOT(updateLinkState(bool))); updateLinkState(link->isConnected()); + + qDebug() << "ADD LINK"; + + updateComboBox(); } - updateComboBox(); } void QGCToolBar::removeLink(LinkInterface* link) { if (link == currentLink) { currentLink = NULL; - //portComboBox->setEnabled(false); - //portComboBox->clear(); - // XXX magic number - if (LinkManager::instance()->getLinks().count() > 2) { - currentLink = LinkManager::instance()->getLinks().last(); + + // Try to get a new serial link + foreach (SerialLink* s, LinkManager::instance()->getSerialLinks()) + { + addLink(s); + } + + // Update GUI according to scan result + if (currentLink) { updateLinkState(currentLink->isConnected()); } else { - connectButton->setText(tr("New Link")); + connectButton->setText(tr("New Serial Link")); + portComboBox->hide(); + baudcomboBox->hide(); } } updateComboBox(); @@ -619,26 +644,31 @@ void QGCToolBar::removeLink(LinkInterface* link) void QGCToolBar::updateComboBox() { portComboBox->clear(); - for (int i=0;igetLinks().count();i++) + if (currentLink) { - SerialLink *slink = qobject_cast(LinkManager::instance()->getLinks()[i]); - if (slink) + SerialLink *slink = qobject_cast(currentLink); + QList portlist = slink->getCurrentPorts(); + foreach(QString port, portlist) { + portComboBox->addItem(port, port); + } + + portComboBox->setCurrentIndex(portComboBox->findData(slink->getPortName())); + if (slink->getPortName().trimmed().length() > 0) { - //It's a serial link - QList portlist = slink->getCurrentPorts(); - //if (!slink->isConnected()) - //{ - for (int j=0;jaddItem("Serial port:" + QString::number(i) + ":" + portlist[j]); - } - //} - //We only really want to display from unconnected sources. + portComboBox->setEditText(slink->getPortName()); } else { - portComboBox->addItem(LinkManager::instance()->getLinks()[i]->getName()); + if (portlist.length() > 0) + { + portComboBox->setEditText(portlist.first()); + } + else + { + portComboBox->setEditText(tr("No serial port found")); + } } + baudcomboBox->setCurrentIndex(baudcomboBox->findData(slink->getBaudRate())); } } @@ -664,30 +694,22 @@ void QGCToolBar::updateLinkState(bool connected) void QGCToolBar::connectLink(bool connect) { // No serial port yet present - // XXX magic number - if (connect && LinkManager::instance()->getLinks().count() < 3) + if (connect && LinkManager::instance()->getSerialLinks().count() == 0) { MainWindow::instance()->addLink(); + currentLink = LinkManager::instance()->getLinks().last(); } else if (connect) { - if (portComboBox->currentText().split(":").count()>2) + SerialLink *link = qobject_cast(currentLink); + if (link) { - int linknum = portComboBox->currentText().split(":")[1].toInt(); - SerialLink *link = qobject_cast(LinkManager::instance()->getLinks().at(linknum)); - if (link) - { - QString portname = portComboBox->currentText().split(":")[2]; - link->setPortName(portname.trimmed()); - } + link->setPortName(portComboBox->itemData(portComboBox->currentIndex()).toString().trimmed()); int baud = baudcomboBox->currentText().toInt(); link->setBaudRate(baud); link->connect(); } - else - { - LinkManager::instance()->getLinks().last()->connect(); - } - } else if (!connect && LinkManager::instance()->getLinks().count() > 2) { - LinkManager::instance()->getLinks().last()->disconnect(); + + } else if (!connect && currentLink) { + currentLink->disconnect(); } } diff --git a/src/ui/QGCToolBar.h b/src/ui/QGCToolBar.h index dd2a5bf2e0..35a2ea88ed 100644 --- a/src/ui/QGCToolBar.h +++ b/src/ui/QGCToolBar.h @@ -33,6 +33,7 @@ This file is part of the QGROUNDCONTROL project #include #include "UASInterface.h" #include "QGCMAVLinkLogPlayer.h" +#include "SerialLink.h" class QGCToolBar : public QToolBar { -- GitLab From 011fc618f19ee0110559cd5d24310ba640ea5129 Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Wed, 31 Jul 2013 16:17:59 -0700 Subject: [PATCH 139/460] add /GeneratedFiles to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 3184e1aaa0..b18c66000a 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,4 @@ user_config.pri *.uhf.txt *.opensdf apmplanner2.xcodeproj/ +GeneratedFiles/ -- GitLab From 9244a09163957bf9a2d942d8c0412a2cc81d4b35 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 1 Aug 2013 20:16:00 +0200 Subject: [PATCH 140/460] Removed more debug statements --- src/ui/MainWindow.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 4cf545463a..d45a25b134 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -1193,7 +1193,6 @@ void MainWindow::loadSettings() QSettings settings; settings.sync(); customMode = static_cast(settings.value("QGC_CUSTOM_MODE", (unsigned int)MainWindow::CUSTOM_MODE_NONE).toInt()); - qDebug() << "MAINWINDOW: CUSTOM MODE:" << customMode; settings.beginGroup("QGC_MAINWINDOW"); autoReconnect = settings.value("AUTO_RECONNECT", autoReconnect).toBool(); currentStyle = (QGC_MAINWINDOW_STYLE)settings.value("CURRENT_STYLE", currentStyle).toInt(); -- GitLab From b34e16fb756ed58c720fc7fdf750d1c392044465 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 1 Aug 2013 20:16:49 +0200 Subject: [PATCH 141/460] Revert "eliminate refs to nonexistent toolbar files" This reverts commit 09452414f7115e47e2a21d9e5911a8b472a7343c. --- qgroundcontrol.pri | 6 ++++++ qgroundcontrol.pro | 12 +++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/qgroundcontrol.pri b/qgroundcontrol.pri index 1ba7dbdbe6..fdf608780b 100644 --- a/qgroundcontrol.pri +++ b/qgroundcontrol.pri @@ -73,6 +73,12 @@ macx|macx-g++42|macx-g++|macx-llvm: { QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/components/ QMAKE_POST_LINK += && cp -rf $$BASEDIR/qml/components/*.qml $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/components + QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/resources + QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/resources/qgroundcontrol + QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/resources/qgroundcontrol/toolbar + QMAKE_POST_LINK += && cp -rf $$BASEDIR/qml/resources/qgroundcontrol/toolbar/*.png $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/resources/qgroundcontrol/toolbar + + # Fix library paths inside executable QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qgroundcontrol QMAKE_POST_LINK += && install_name_tool -change libosg.dylib "@executable_path/../libs/libosg.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qgroundcontrol diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index eab224e442..5096f8451e 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -811,7 +811,17 @@ OTHER_FILES += \ OTHER_FILES += \ qml/ApmToolBar.qml \ qml/components/Button.qml \ - qml/components/TextButton.qml + qml/components/TextButton.qml \ + qml/resources/qgroundcontrol/toolbar/connect.png \ + qml/resources/qgroundcontrol/toolbar/flightplanner.png \ + qml/resources/qgroundcontrol/toolbar/helpwizard.png \ + qml/resources/qgroundcontrol/toolbar/softwareconfig.png \ + qml/resources/qgroundcontrol/toolbar/terminal.png \ + qml/resources/qgroundcontrol/toolbar/simulation.png \ + qml/resources/qgroundcontrol/toolbar/hardwareconfig.png \ + qml/resources/qgroundcontrol/toolbar/flightdata.png \ + qml/resources/qgroundcontrol/toolbar/disconnect.png \ + qml/resources/qgroundcontrol/toolbar/donate.png \ #qmlcomponents.path += $${DESTDIR}$${TARGET}/components -- GitLab From 1d28f6048608287a2ab1d8b28693c48e07f7c561 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 1 Aug 2013 20:37:14 +0200 Subject: [PATCH 142/460] Fixed APM toolbar assumptions about link count --- src/ui/apmtoolbar.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/ui/apmtoolbar.cpp b/src/ui/apmtoolbar.cpp index 42e85ddc91..56834a5721 100644 --- a/src/ui/apmtoolbar.cpp +++ b/src/ui/apmtoolbar.cpp @@ -96,20 +96,22 @@ void APMToolBar::connectMAV() { qDebug() << "APMToolBar: connectMAV "; - bool connected = LinkManager::instance()->getLinks().last()->isConnected(); + bool connected = false; + if (LinkManager::instance()->getSerialLinks().count() > 0) + connected = LinkManager::instance()->getSerialLinks().last()->isConnected(); bool result; - if (!connected && LinkManager::instance()->getLinks().count() < 3) + if (!connected && LinkManager::instance()->getSerialLinks().count() == 0) { // No Link so prompt to connect one MainWindow::instance()->addLink(); } else if (!connected) { // Need to Connect Link - result = LinkManager::instance()->getLinks().last()->connect(); + result = LinkManager::instance()->getSerialLinks().last()->connect(); - } else if (connected && LinkManager::instance()->getLinks().count() > 2) { + } else if (connected && LinkManager::instance()->getSerialLinks().count() > 0) { // result need to be the opposite of success. - result = !LinkManager::instance()->getLinks().last()->disconnect(); + result = !LinkManager::instance()->getSerialLinks().last()->disconnect(); } qDebug() << "result = " << result; @@ -137,11 +139,11 @@ void APMToolBar::showConnectionDialog() qDebug() << "APMToolBar: showConnectionDialog link count =" << LinkManager::instance()->getLinks().count(); - LinkInterface *link = LinkManager::instance()->getLinks().last(); bool result; - if (link && LinkManager::instance()->getLinks().count() >= 3) + if (LinkManager::instance()->getSerialLinks().count() > 0) { + SerialLink *link = LinkManager::instance()->getSerialLinks().last(); // Serial Link so prompt to config it connect(link, SIGNAL(updateLink(LinkInterface*)), this, SLOT(updateLinkDisplay(LinkInterface*))); -- GitLab From c1b77536e9e71f8cc92dc562b43d393a8247f90c Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 1 Aug 2013 20:46:14 +0200 Subject: [PATCH 143/460] Added missing files --- .gitignore | 7 +++++-- qml/resources/qgroundcontrol/toolbar/connect.png | Bin 0 -> 3335 bytes .../qgroundcontrol/toolbar/disconnect.png | Bin 0 -> 2471 bytes qml/resources/qgroundcontrol/toolbar/donate.png | Bin 0 -> 2872 bytes .../qgroundcontrol/toolbar/flightdata.png | Bin 0 -> 3428 bytes .../qgroundcontrol/toolbar/flightplanner.png | Bin 0 -> 4343 bytes .../qgroundcontrol/toolbar/hardwareconfig.png | Bin 0 -> 4030 bytes .../qgroundcontrol/toolbar/helpwizard.png | Bin 0 -> 2059 bytes .../qgroundcontrol/toolbar/simulation.png | Bin 0 -> 3901 bytes .../qgroundcontrol/toolbar/softwareconfig.png | Bin 0 -> 3434 bytes .../qgroundcontrol/toolbar/terminal.png | Bin 0 -> 2885 bytes 11 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 qml/resources/qgroundcontrol/toolbar/connect.png create mode 100644 qml/resources/qgroundcontrol/toolbar/disconnect.png create mode 100644 qml/resources/qgroundcontrol/toolbar/donate.png create mode 100644 qml/resources/qgroundcontrol/toolbar/flightdata.png create mode 100644 qml/resources/qgroundcontrol/toolbar/flightplanner.png create mode 100644 qml/resources/qgroundcontrol/toolbar/hardwareconfig.png create mode 100644 qml/resources/qgroundcontrol/toolbar/helpwizard.png create mode 100644 qml/resources/qgroundcontrol/toolbar/simulation.png create mode 100644 qml/resources/qgroundcontrol/toolbar/softwareconfig.png create mode 100644 qml/resources/qgroundcontrol/toolbar/terminal.png diff --git a/.gitignore b/.gitignore index 3184e1aaa0..2baa7745f4 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,7 @@ qrc_*.cpp tmp debug release -qgroundcontrol +/qgroundcontrol mavlinkgen-build-desktop qgroundcontrol.xcodeproj/** doc/html @@ -49,4 +49,7 @@ user_config.pri *.suo *.uhf.txt *.opensdf -apmplanner2.xcodeproj/ + +thirdParty/qserialport-build-desktop/ +thirdParty/qserialport/bin/ +thirdParty/qserialport/lib/ diff --git a/qml/resources/qgroundcontrol/toolbar/connect.png b/qml/resources/qgroundcontrol/toolbar/connect.png new file mode 100644 index 0000000000000000000000000000000000000000..8572674974bcefde8dc4b54972a423a5a19837ff GIT binary patch literal 3335 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 My85}Sb4q9e0O7Z*6aWAK literal 0 HcmV?d00001 diff --git a/qml/resources/qgroundcontrol/toolbar/disconnect.png b/qml/resources/qgroundcontrol/toolbar/disconnect.png new file mode 100644 index 0000000000000000000000000000000000000000..57f2f505da1eb32c90369f4fc9b154f7de5646f8 GIT binary patch literal 2471 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 YgId4AOSeh?r-0hBp00i_>zopr0M}*3)c^nh literal 0 HcmV?d00001 diff --git a/qml/resources/qgroundcontrol/toolbar/flightdata.png b/qml/resources/qgroundcontrol/toolbar/flightdata.png new file mode 100644 index 0000000000000000000000000000000000000000..aa8fb3663f815da198374f57b40db001778dc462 GIT binary patch literal 3428 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 literal 0 HcmV?d00001 diff --git a/qml/resources/qgroundcontrol/toolbar/flightplanner.png b/qml/resources/qgroundcontrol/toolbar/flightplanner.png new file mode 100644 index 0000000000000000000000000000000000000000..72e1b40ec8414bb24275b5f8d592b4284184e764 GIT binary patch literal 4343 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 literal 0 HcmV?d00001 diff --git a/qml/resources/qgroundcontrol/toolbar/helpwizard.png b/qml/resources/qgroundcontrol/toolbar/helpwizard.png new file mode 100644 index 0000000000000000000000000000000000000000..ac5c20a2a7c52fcb60a407c395919addf6202452 GIT binary patch literal 2059 zcmeAS@N?(olHy`uVBq!ia0y~yU@&7~V9@1YV_;x-8Zx7mfq_A?#5JNMI6tkVJh3R1 z!7(L2DOJHUH!(dmC^a#qvhZZ84FdynN@hqzNrbPDRdRl=ULr`1UPW#J0|?mIR}>^B zXQ!4ZB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT8h zBDWwnwIorYA~z?m*s8)-32d%aUa=KOSYJs2tfVB{Rte&$2;Tq&=lr5n1yel(-DCqZ z0|hffJwsy?b8~YY1tSAP1APM{eM2K%Lvt%*BP#;~1t?ImQ?MyYNwW%aaf8}bl#*tv zlu=SrV5P5LUS6(OZmgGIl&)`RX=w>E!^lXtC?!p|xH7LKu|hYmSQ%!5OKNd)QD#9& zW`3Rm$i&2?{L&IzB_*h_6}bhzzHo!{ilG6OoS&;-kyxN_sAr&`n+x(6*u%voL8%C5 zU{zflQdy9yACy|0Us{x$8kCx*jARvli$Dqse0{C_i!#$Q^AdAh@{>z*Q}aqZU2K&q zatriQGE=O~oh^(EOf5}JO0H#4*_FfcSXwuG61O|Pq=g`=a3xw(s} zsgt3htC6Lnse!YrxudbAvzw8liz!U6XI^nhVqS78%-+n*6f3A+GrW4OoQqNuOY)0C z^7C_GDIg#tza+mnBfmhwIoMPoJTosPzq}X}IpC1Da!D=9EK5ysE6UGR0EezsCKlVx z-3a*_qBn({5Yx9)u+ax44Wy(36AE&112Ms=8kEBA6cAY_H7~_hsYuD*?p<7_2m=F) zt*47)NX4x;v)*Ulc9S^nKQSe;Ea~(#@#CAtwBN>bY0msDZ&7Fsl*aH1&CrVPk zxQa`AeQOrAeyj1D)i2@wHbL{m4dsRLYw}m`_4=08w3fSfvu=-?ff&DP=7M#}ndehE zcg$TYrY_X=k-0tfe&oLMcR$y@+c}vt_IjXolz3KfcC^8(1?CDIho)ZnqV){7w|uetmm3bmz<|9nD#1cs6)nZ_bnzjBKC$;Ey7EQL)G(Nv6zO z^-F(AEYuBke!4a5S56 z&i+RRo`PQe^PT=0h8xMGzK{E1a7cESwwzIjP@Kv`mgbthCS|s%Z_a$mj44m`>d2p# z{p$DgXe9x#zt03?;RiB|9$v$ za7=v^mz?V<<9ybE&+PX0N1 z)akP1ZRS~Rla^#kRod95ZGPKr!l`$RQ(fk3>2u?FuENs2YORZTKCxx2*%)5H%CIiy z&)()5#iH#CH_w)7p58Q3+mAV*sGvZA^>g69JE#l<&6_m`Y}n;X%-wRpR9%=v?peD|#r&$UdBkNv%xgS%jJWbmB4OX~BIf@_(5gx4DZ^!hFwL)|1%h!H*P?yRPw4!SJlO1tdym>PO{OkmI)z#YGFYPd?A_IOhydEttK+0Gfpxr;NG_0IpjH(>t%$X(6bZl&d& z?T9G0*nY&DWlBtRL!!p??z3&IjI7NEZ|52(-!KR#`+@T&?vA|s{PWtThs?+SI{({ap|EJ}S>NchY)?AA*4E~2SednT*3sj) zZzOG;5xdvd^wuSl8jXz`HYhkw>O6nwu^H>3+2=bQ6gDLNY~KI%Yw2R?$9_-wnm0xM z_wDWyD6x8Y?^D73Gim8*kAF|xe6&D*=KT5oQ>J;jaVVM}R6TpT`njxgN@xNAm$pH! literal 0 HcmV?d00001 diff --git a/qml/resources/qgroundcontrol/toolbar/simulation.png b/qml/resources/qgroundcontrol/toolbar/simulation.png new file mode 100644 index 0000000000000000000000000000000000000000..e8a1c31a04ab6f9f9267abbf1c0bd08771ef97ce GIT binary patch literal 3901 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 A*Z=?k literal 0 HcmV?d00001 diff --git a/qml/resources/qgroundcontrol/toolbar/softwareconfig.png b/qml/resources/qgroundcontrol/toolbar/softwareconfig.png new file mode 100644 index 0000000000000000000000000000000000000000..e2516db4060dee69ff7486243576d3749edfe97f GIT binary patch literal 3434 zcmeAS@N?(olHy`uVBq!ia0y~yV9*6&4mJh`1}mvYvlti{BuiW)N`mv#O3D+9QW+dm z@{>{(JaZG%Q-e|yQz{EjrrIztFsEdOM3hAM`dB6B=jtVb)aX^@7BGN-jeSKyVsdtB zi9%9pdS;%j()-=}l@u~lY?Z=IeGPmIoKrJ0J*tXQgRA^PlB=?lEmM^2?G$V(tSWK~ za#KqZ6)JLb@`|l0Y?Z*~TICg6frRyy6u?SKvTcwn`Gtf;oFf&jv zGt@IQHZeCh*HJJsFf`CNFw!?P(ls=X%D*TxJu@#c$0a|xG&eP`#M8xAsUo*P zFC{a@%G}Yy$iURn#MH#a)YZrkUF}a*UGslHL)bWC?r2W z2bKZ?GV)9Ei!<^I6r6)i6~Z&~Qu51-L6HLvc`KLHqRg_?6t|-MTm^9GT4iFf-PFR| z$jQaf*whS{uOWI<$O$ohI|UnkP|`q3DlnlS7dH?SoT@=7+)e?JbyD+EY?X?X?CmNw zjOQ^haL(~`aSW-r^(L}9=jv5i`~BZ*_gCdd-?|icE65{YX5=PGW7V!RjlbJjl{RYf zo!DgfJfUg!iKn;e%dI zeE#R%-ltCbu?yc`I5N2=|M%~?*Pqv%|NhbP`SC!nlj&?u60_@{W@#-^(@r;oHRcDMGA$-rDU>_s(3aZTXquctJz8`2B2c z4~@3O819D9%O)SIwkmP#*}QC7*s66a<>Y2RudEIZ7Ph=zc`nd;@3q+2SYL}i<(;wa zfA`$;-dmKNeL6Vc)Nh775hmH`sW(qrEjqmQng4=wI~wo$bWh6Yn{B>Li^FM|pNMA5 z?p6I~1&&tG&}uyWmNmbvb;=k#sjUOcVo@204w*Ci(FY6);y2z~r< zm0Ri0@;lErC@YKp%w+fF$*TG0Ag(pPd0*HS?GJs@#tblb?N071A}Fyf7U0?+3izWd}qnb zcGk=v7gw#)n&h?ghR@^8B^lE*Z@m8OyUy46U4ST0o!oMDt*R9QZ`B?q_G$jt=hg`M zX%=y_aN4)yvsv`gh0gt1S}8dBxkI?|zd78MY)f}7lzjEK;DY{P%bz`}7YrNk@p}C@ z6u~I__xi<)FZcv4B&S?I#w0th zmtIo*!6V`MLif3AoP&J7nAkZ#cJDKnTRS)I^J~qiuKRXPs%)3((zX@5z#(*qceV=q z2BCaq&b9q5kK`xsJHlCH^@Xik{h-aO3rV=`^g&M(30UwPb@|tr* z-voT?3z;*`gKPVq6+UW{Sij|QZ0Gx?ef-sR@#$Hs3e`)#^N0HH-TD3I!4oaQYSYfD z+;hD2i@{R9vfU+dx$Z(+7qPi4v(CsYUvW|4#GSDGjXrmdD!u;VvcmhdxXPq2BHdzX zMpKFwrA)l8qVy%t@zLBa=L!|G75TLpu}{y(-@IdKu~CO#xQtJ(q3!UKkPPvOtn8O{ z91MP&&bhFTJy&ZFvmfH0Jn!da-1d_ZIxy>8n$eDE#nmj0!ZT(b7P)j&VvgcXA-{i0{zg&f zehHPGeJENe@T|knw{}alSL*vqy$2t3OW(e&&hsVmM{lgw*#_0a&v$B0_$p?-|3myYlf=OT)ATzRHARnaVzu;%={H zUPpL0GeoGC+nr6yYL#h|IsSV^;)SFi$EJVyW7?sfzu=|Mo~6qo&qn<#Ios*6|CWkh zkXGNVyG|kva}P6AOxo-CDDL?AZy|>)#H24gw$IKmetrF)+KZ`c4l$Q)-_iMaXJVLI zbcNEXj!w34y~rc2CwE*t({EqZBQj;bwAEkRC$Csa8N8!xMXuf7TVW=+|4QZ0D_h^* ze*19w^m#XLUY-^+*H0?8^_`IG%-syLmkS^G-Rd<_^O8$H{5EvQlL1Vq6%FiBtle2hr=#f{X<~%K7|IQa*{X?Z<>MFDP%w2zP<&H?P z3*6%z^h5rz=6<6*_c_lZ6Qn+^+&A}#n&|S03Q3dBh;OL%df?)6n&IIFg}J(Zr{zv< zRPQ>i|IDMmZJX64OQY9MH|p>?2IM$t+TZII5qsD4?q|xf{f$euG^+SNjor2G|HD^0 zZHH#`Pj9u$vF0v!FTR~`WuRE?7;n9aBhPus%%B&_tcxz(bebi%tNNTw>6!&MSrz*w zo8PT(>N<67X2IkA>{SPwR1?{AW*yj9?7Lq>`%X@Zql?&L={-rgIVUXANUM`st^@<$P7wi?^i!;TRzIbp@GB#HH%Em0&1D1``OP7b-6!ZUD z*%`P=<;vQ-L2=s8&9%2%wS;!XX7uq+kTZ4l|F&i6_8YZVRs~Ak+qUPX$&|MFA!iOQ z`C7I;BE7qL(@$yW{ z--nwg+MoTv(k0scmh1K72OiviQXdr;oG`7LHK*S_^UqJyw;yAgm%cvz-g)y|v+WU& zwSd^s}m5VbeWWTzEFv{Oyts@B1gn-T9=s&On6g6mn;IdZ^^S7OPc`e6GJ#xv?lVU1D7cQRu$hl1Uq}a+6p)I_Zj8_}( zFW6|4! z*KhUV1)B5SK3(wWGoNj~TdI~jLcCeHUUBvO|0&jI&Pk^!WY5}X<1E-&eagG552W!~R>FVdQ&MBb@0DsZzRsaA1 literal 0 HcmV?d00001 diff --git a/qml/resources/qgroundcontrol/toolbar/terminal.png b/qml/resources/qgroundcontrol/toolbar/terminal.png new file mode 100644 index 0000000000000000000000000000000000000000..bb639d3bd4c15454884a44cc664ca7585e99e3b7 GIT binary patch literal 2885 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 Date: Thu, 1 Aug 2013 09:34:53 -0400 Subject: [PATCH 144/460] Change so UASQuickView font sizes are now identical, and change properly based on window size and column count --- src/ui/uas/UASQuickView.cc | 26 ++++++++++- src/ui/uas/UASQuickView.h | 3 ++ src/ui/uas/UASQuickViewItem.h | 2 + src/ui/uas/UASQuickViewTextItem.cc | 71 +++++++++++++++++++++++++++++- src/ui/uas/UASQuickViewTextItem.h | 2 + 5 files changed, 102 insertions(+), 2 deletions(-) diff --git a/src/ui/uas/UASQuickView.cc b/src/ui/uas/UASQuickView.cc index 40039dd305..6d74b31a08 100644 --- a/src/ui/uas/UASQuickView.cc +++ b/src/ui/uas/UASQuickView.cc @@ -12,6 +12,7 @@ UASQuickView::UASQuickView(QWidget *parent) : QWidget(parent) m_currentColumn=0; ui.setupUi(this); + ui.horizontalLayout->setMargin(0); m_verticalLayoutList.append(new QVBoxLayout()); ui.horizontalLayout->addItem(m_verticalLayoutList[0]); @@ -35,7 +36,7 @@ UASQuickView::UASQuickView(QWidget *parent) : QWidget(parent) valueEnabled("roll"); } - QAction *action = new QAction("Add Item",this); + QAction *action = new QAction("Add/Remove Items",this); action->setCheckable(false); connect(action,SIGNAL(triggered()),this,SLOT(actionTriggered())); this->addAction(action); @@ -170,6 +171,7 @@ void UASQuickView::sortItems(int columncount) QVBoxLayout *layout = new QVBoxLayout(); ui.horizontalLayout->addItem(layout); m_verticalLayoutList.append(layout); + layout->setMargin(0); } //Cycle through all items and add them to the layout @@ -184,6 +186,28 @@ void UASQuickView::sortItems(int columncount) } } m_currentColumn = currcol; + QApplication::processEvents(); + recalculateItemTextSizing(); +} +void UASQuickView::resizeEvent(QResizeEvent *evt) +{ + recalculateItemTextSizing(); +} +void UASQuickView::recalculateItemTextSizing() +{ + int minpixelsize = 65535; + for (QMap::const_iterator i = uasPropertyToLabelMap.constBegin();i!=uasPropertyToLabelMap.constEnd();i++) + { + int tempmin = i.value()->minValuePixelSize(); + if (tempmin < minpixelsize) + { + minpixelsize = tempmin; + } + } + for (QMap::const_iterator i = uasPropertyToLabelMap.constBegin();i!=uasPropertyToLabelMap.constEnd();i++) + { + i.value()->setValuePixelSize(minpixelsize); + } } void UASQuickView::valueDisabled(QString value) diff --git a/src/ui/uas/UASQuickView.h b/src/ui/uas/UASQuickView.h index 977b5c21d0..33075bda81 100644 --- a/src/ui/uas/UASQuickView.h +++ b/src/ui/uas/UASQuickView.h @@ -41,6 +41,8 @@ private: /** Loads gauge layout from settings file */ void loadSettings(); + void recalculateItemTextSizing(); + /** Column Count */ int m_columnCount; @@ -53,6 +55,7 @@ private: //FlowLayout *layout; protected: Ui::Form ui; + void resizeEvent(QResizeEvent *evt); signals: public slots: diff --git a/src/ui/uas/UASQuickViewItem.h b/src/ui/uas/UASQuickViewItem.h index a406c4a2ab..1cd2d2017e 100644 --- a/src/ui/uas/UASQuickViewItem.h +++ b/src/ui/uas/UASQuickViewItem.h @@ -10,6 +10,8 @@ public: explicit UASQuickViewItem(QWidget *parent = 0); virtual void setValue(double value)=0; virtual void setTitle(QString title)=0; + virtual int minValuePixelSize()=0; + virtual void setValuePixelSize(int size)=0; }; #endif // UASQUICKVIEWITEM_H diff --git a/src/ui/uas/UASQuickViewTextItem.cc b/src/ui/uas/UASQuickViewTextItem.cc index 3fbdd932d2..a35a8d1e0a 100644 --- a/src/ui/uas/UASQuickViewTextItem.cc +++ b/src/ui/uas/UASQuickViewTextItem.cc @@ -27,7 +27,26 @@ UASQuickViewTextItem::UASQuickViewTextItem(QWidget *parent) : UASQuickViewItem(p } void UASQuickViewTextItem::setValue(double value) { - valueLabel->setText(QString::number(value,'f',4)); + if (value < 10 && value > -10) + { + valueLabel->setText(QString::number(value,'f',4)); + } + else if (value < 100 && value > -100) + { + valueLabel->setText(QString::number(value,'f',3)); + } + else if (value < 1000 && value > -1000) + { + valueLabel->setText(QString::number(value,'f',2)); + } + else if (value < 10000 && value > -10000) + { + valueLabel->setText(QString::number(value,'f',1)); + } + else if (value >= 100000 || value <= -100000) + { + valueLabel->setText(QString::number(value,'f',0)); + } } void UASQuickViewTextItem::setTitle(QString title) @@ -41,8 +60,58 @@ void UASQuickViewTextItem::setTitle(QString title) titleLabel->setText(title); } } +int UASQuickViewTextItem::minValuePixelSize() +{ + QFont valuefont = valueLabel->font(); + QFont titlefont = titleLabel->font(); + valuefont.setPixelSize(this->height()); + titlefont.setPixelSize(valuefont.pixelSize() / 2.0); + //spacerItem->setGeometry(QRect(0,0,20,this->height()/10.0)); + + QFontMetrics metrics(valuefont); + //valuefont.setPixelSize(this->height() / 2.0); + bool fit = false; + while (!fit) + { + + QFontMetrics valfm( valuefont ); + QRect valbound = valfm.boundingRect(0,0, valueLabel->width(), valueLabel->height(), Qt::TextWordWrap | Qt::AlignLeft, "12345678.00"/*valueLabel->text()*/); + //QFontMetrics titlefm( titlefont ); + //QRect titlebound = titlefm.boundingRect(0,0, titleLabel->width(), titleLabel->height(), Qt::TextWordWrap | Qt::AlignLeft, titleLabel->text()); + + if ((valbound.width() <= valueLabel->width() && valbound.height() <= valueLabel->height()))// && (titlebound.width() <= titleLabel->width() && titlebound.height() <= titleLabel->height())) + fit = true; + else + { + if (valuefont.pixelSize()-5 <= 0) + { + fit = true; + valuefont.setPixelSize(5); + } + else + { + valuefont.setPixelSize(valuefont.pixelSize() - 5); + } + //titlefont.setPixelSize(valuefont.pixelSize() / 2.0); + //qDebug() << "Point size:" << valuefont.pixelSize() << valueLabel->width() << valueLabel->height(); + } + } + return valuefont.pixelSize(); +} +void UASQuickViewTextItem::setValuePixelSize(int size) +{ + QFont valuefont = valueLabel->font(); + QFont titlefont = titleLabel->font(); + valuefont.setPixelSize(size); + titlefont.setPixelSize(valuefont.pixelSize() / 2.0); + valueLabel->setFont(valuefont); + titleLabel->setFont(titlefont); + update(); +} + void UASQuickViewTextItem::resizeEvent(QResizeEvent *event) { + return; QFont valuefont = valueLabel->font(); QFont titlefont = titleLabel->font(); valuefont.setPixelSize(this->height()); diff --git a/src/ui/uas/UASQuickViewTextItem.h b/src/ui/uas/UASQuickViewTextItem.h index dea8cc3b16..698c358f91 100644 --- a/src/ui/uas/UASQuickViewTextItem.h +++ b/src/ui/uas/UASQuickViewTextItem.h @@ -10,6 +10,8 @@ public: UASQuickViewTextItem(QWidget *parent=0); void setValue(double value); void setTitle(QString title); + int minValuePixelSize(); + void setValuePixelSize(int size); protected: void resizeEvent(QResizeEvent *event); private: -- GitLab From 738f451b464e2cebb3bb470c053cc4a606b720fa Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 2 Aug 2013 21:50:32 -0700 Subject: [PATCH 145/460] wip decoupling the UI (view) from the param data model --- qgroundcontrol.pro | 6 +- src/uas/QGCUASParamManager.cc | 1 + src/uas/QGCUASParamManager.h | 8 +- src/uas/UAS.cc | 3 + src/uas/UAS.h | 12 +++ src/uas/UASInterface.h | 6 ++ src/uas/UASParameterDataModel.cc | 26 ++++++ src/uas/UASParameterDataModel.h | 42 +++++++++ src/ui/QGCParamWidget.cc | 148 +++++++++++++++++-------------- src/ui/QGCParamWidget.h | 10 ++- 10 files changed, 189 insertions(+), 73 deletions(-) create mode 100644 src/uas/UASParameterDataModel.cc create mode 100644 src/uas/UASParameterDataModel.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 263586226c..fd4df5e5b5 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -468,7 +468,8 @@ HEADERS += src/MG.h \ src/ui/configuration/SerialSettingsDialog.h \ src/ui/configuration/terminalconsole.h \ src/ui/configuration/ApmHighlighter.h \ - src/ui/configuration/ApmFirmwareConfig.h + src/ui/configuration/ApmFirmwareConfig.h \ + src/uas/UASParameterDataModel.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -683,7 +684,8 @@ SOURCES += src/main.cc \ src/ui/configuration/console.cpp \ src/ui/configuration/SerialSettingsDialog.cc \ src/ui/configuration/ApmHighlighter.cc \ - src/ui/configuration/ApmFirmwareConfig.cc + src/ui/configuration/ApmFirmwareConfig.cc \ + src/uas/UASParameterDataModel.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 6e137b6329..7193bce82f 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -12,6 +12,7 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : retransmissionBurstRequestSize(5) { uas->setParamManager(this); + paramDataModel = uas->getParamDataModel(); } diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 69dee9eb44..d7f8adf976 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -7,6 +7,7 @@ #include class UASInterface; +class UASParameterDataModel; class QGCUASParamManager : public QWidget { @@ -62,9 +63,14 @@ public slots: virtual void requestParameterList() = 0; protected: + + //Parameter data model UASInterface* mav; ///< The MAV this widget is controlling - QMap* > changedValues; ///< Changed values +// QMap* > changedValues; ///< Changed values QMap* > parameters; ///< All parameters + UASParameterDataModel* paramDataModel;///< Shared data model of parameters + + // Communications management QVector received; ///< Successfully received parameters QMap* > transmissionMissingPackets; ///< Missing packets QMap* > transmissionMissingWriteAckPackets; ///< Missing write ACK packets diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index e932005e3c..3386deab79 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -131,6 +131,7 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), paramsOnceRequested(false), paramManager(NULL), + paramDataModel(NULL), simulation(0), @@ -151,6 +152,8 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), componentMulti[i] = false; } + paramDataModel->setUASID(this->getUASID()); + // Store a list of available actions for this UAS. // Basically everything exposted as a SLOT with no return value or arguments. diff --git a/src/uas/UAS.h b/src/uas/UAS.h index b1c027bd1f..c8b9a604c7 100644 --- a/src/uas/UAS.h +++ b/src/uas/UAS.h @@ -492,6 +492,7 @@ protected: //COMMENTS FOR TEST UNIT QMap* > parameters; ///< All parameters bool paramsOnceRequested; ///< If the parameter list has been read at least once QGCUASParamManager* paramManager; ///< Parameter manager class + UASParameterDataModel* paramDataModel; ///< The parameter data model for this UAS /// SIMULATION QGCHilLink* simulation; ///< Hardware in the loop simulation link @@ -519,10 +520,20 @@ public: QGCUASParamManager* getParamManager() const { return paramManager; } + + /** @brief Get reference to the parameter data model (same one shared with the parameter manager) **/ + UASParameterDataModel* getParamDataModel() { + return paramDataModel; + } + + /** @brief Get the HIL simulation */ QGCHilLink* getHILSimulation() const { return simulation; } + + + // TODO Will be removed /** @brief Set reference to the param manager **/ void setParamManager(QGCUASParamManager* manager) { @@ -949,6 +960,7 @@ protected: quint64 lastSendTimeSensors; QList actions; ///< A list of actions that this UAS can perform. + protected slots: /** @brief Write settings to disk */ void writeSettings(); diff --git a/src/uas/UASInterface.h b/src/uas/UASInterface.h index 127a51fb13..c47474dfe8 100644 --- a/src/uas/UASInterface.h +++ b/src/uas/UASInterface.h @@ -40,6 +40,7 @@ This file is part of the QGROUNDCONTROL project #include "LinkInterface.h" #include "ProtocolInterface.h" +#include "UASParameterDataModel.h" #include "UASWaypointManager.h" #include "QGCUASParamManager.h" #include "RadioCalibration/RadioCalibrationData.h" @@ -152,8 +153,13 @@ public: /** @brief Get reference to the waypoint manager **/ virtual UASWaypointManager* getWaypointManager(void) = 0; + + /** @brief Access the parameter data model for this UAS (sans widget). This is the same parameter data model used by the parameter manager. **/ + virtual UASParameterDataModel* getParamDataModel() = 0; + /** @brief Get reference to the param manager **/ virtual QGCUASParamManager* getParamManager() const = 0; + // TODO Will be removed /** @brief Set reference to the param manager **/ virtual void setParamManager(QGCUASParamManager* manager) = 0; diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc new file mode 100644 index 0000000000..8effd144ce --- /dev/null +++ b/src/uas/UASParameterDataModel.cc @@ -0,0 +1,26 @@ +#include "UASParameterDataModel.h" + +#include + +UASParameterDataModel::UASParameterDataModel(QObject *parent) : + QObject(parent) +{ + + + + + +} + + +void UASParameterDataModel::setPendingParameter(int componentId, QString& key, QVariant &value) +{ + QMap *compPendingParams = pendingParameters.value(componentId); + //TODO insert blank map if necessary + if (NULL == compPendingParams) { + pendingParameters.insert(componentId,new QMap()); + compPendingParams = pendingParameters.value(componentId); + } + + compPendingParams->insert(key,value); +} diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h new file mode 100644 index 0000000000..5c1d67d486 --- /dev/null +++ b/src/uas/UASParameterDataModel.h @@ -0,0 +1,42 @@ +#ifndef UASPARAMETERDATAMODEL_H +#define UASPARAMETERDATAMODEL_H + +#include +#include +#include + +class UASParameterDataModel : public QObject +{ + Q_OBJECT +public: + explicit UASParameterDataModel(QObject *parent = 0); + + + /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ + virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue) = 0; + + QMap* > getPendingParameters() { + return pendingParameters; + } + + QMap* > getOnboardParameters() { + return onboardParameters; + } + + + void setUASID(int anId) { this->uasId = anId; } + +signals: + +public slots: + + +protected: + int uasId; ///< The UAS / MAV to which this data model pertains + QMap* > pendingParameters; ///< Changed values that have not yet been transmitted to the UAS, by component ID + QMap* > onboardParameters; ///< All parameters confirmed to be stored onboard the UAS, by component ID + + +}; + +#endif // UASPARAMETERDATAMODEL_H diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 94e1697b52..abd1e913d5 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -105,13 +105,13 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QPushButton* loadFileButton = new QPushButton(tr("Load File")); loadFileButton->setToolTip(tr("Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them.")); loadFileButton->setWhatsThis(tr("Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them.")); - connect(loadFileButton, SIGNAL(clicked()), this, SLOT(loadParameters())); + connect(loadFileButton, SIGNAL(clicked()), this, SLOT(loadParametersFromFile())); horizontalLayout->addWidget(loadFileButton, 3, 0); QPushButton* saveFileButton = new QPushButton(tr("Save File")); saveFileButton->setToolTip(tr("Save parameters in this view to a file on this computer.")); saveFileButton->setWhatsThis(tr("Save parameters in this view to a file on this computer.")); - connect(saveFileButton, SIGNAL(clicked()), this, SLOT(saveParameters())); + connect(saveFileButton, SIGNAL(clicked()), this, SLOT(saveParametersToFile())); horizontalLayout->addWidget(saveFileButton, 3, 1); QPushButton* readButton = new QPushButton(tr("Read (ROM)")); @@ -142,7 +142,7 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); // New parameters from UAS - connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(addParameter(int,int,int,int,QString,QVariant))); + connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); // Connect retransmission guard connect(this, SIGNAL(requestParameter(int,QString)), uas, SLOT(requestParameter(int,QString))); @@ -335,10 +335,10 @@ void QGCParamWidget::addComponent(int uas, int component, QString componentName) if (!parameters.contains(component)) { parameters.insert(component, new QMap()); } - // Create map in changed parameters - if (!changedValues.contains(component)) { - changedValues.insert(component, new QMap()); - } +// // Create map in changed parameters +// if (!changedValues.contains(component)) { +// changedValues.insert(component, new QMap()); +// } } } @@ -347,9 +347,9 @@ void QGCParamWidget::addComponent(int uas, int component, QString componentName) * @param component id of the component * @param parameterName human friendly name of the parameter */ -void QGCParamWidget::addParameter(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) +void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) { - addParameter(uas, component, parameterName, value); + receivedParameterUpdate(uas, component, parameterName, value); // Missing packets list has to be instantiated for all components if (!transmissionMissingPackets.contains(component)) { @@ -494,7 +494,7 @@ void QGCParamWidget::addParameter(int uas, int component, int paramCount, int pa * @param component id of the component * @param parameterName human friendly name of the parameter */ -void QGCParamWidget::addParameter(int uas, int component, QString parameterName, QVariant value) +void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value) { //qDebug() << "PARAM WIDGET GOT PARAM:" << value; Q_UNUSED(uas); @@ -636,8 +636,18 @@ void QGCParamWidget::addParameter(int uas, int component, QString parameterName, parameterItem->setToolTip(0, tooltipFormat); parameterItem->setToolTip(1, tooltipFormat); - //tree->update(); - if (changedValues.contains(component)) changedValues.value(component)->remove(parameterName); + //verify that the value requested by the user matches the set value + //if it doesn't match, leave the pending parameter in the pending list! + QMap *> changedValues = this->paramDataModel->getPendingParameters(); + if (changedValues.contains(component)) { + QMap *compReqVals = changedValues.value(component); + if ((NULL != compReqVals) && compReqVals->contains(parameterName)) { + QVariant reqVal = compReqVals->value(parameterName); + if (reqVal == value) { + compReqVals->remove(parameterName); + } + } + } } /** @@ -682,9 +692,14 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) } // Parent is now top-level component int key = components->key(parent); + + //ensure we have a placeholder map for this component + QMap *> changedValues = this->paramDataModel->getPendingParameters(); if (!changedValues.contains(key)) { changedValues.insert(key, new QMap()); } + + //insert the changed value into the map QMap* map = changedValues.value(key, NULL); if (map) { QString str = current->data(0, Qt::DisplayRole).toString(); @@ -739,7 +754,7 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) } } -void QGCParamWidget::saveParameters() +void QGCParamWidget::saveParametersToFile() { if (!mav) return; QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "./parameters.txt", tr("Parameter File (*.txt)")); @@ -794,7 +809,47 @@ void QGCParamWidget::saveParameters() file.close(); } -void QGCParamWidget::loadParameters() + +void QGCParamWidget::loadedParameterForComponent(int componentId, QStringList& wpParams ) +{ + // Set parameter value + + QMap *> changedValues = this->paramDataModel->getPendingParameters(); + + // Create changed values data structure if necessary + if (!changedValues.contains(componentId)) { + changedValues.insert(componentId, new QMap()); + } + + // Add to changed values + if (changedValues.value(componentId)->contains(wpParams.at(2))) { + changedValues.value(componentId)->remove(wpParams.at(2)); + } + + switch (wpParams.at(4).toUInt()) + { + case (int)MAV_PARAM_TYPE_REAL32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toFloat()); + changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toFloat()); + setParameter(componentId, wpParams.at(2), wpParams.at(3).toFloat()); + break; + case (int)MAV_PARAM_TYPE_UINT32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toUInt()); + changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toUInt()); + setParameter(componentId, wpParams.at(2), QVariant(wpParams.at(3).toUInt())); + break; + case (int)MAV_PARAM_TYPE_INT32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toInt()); + changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toInt()); + setParameter(componentId, wpParams.at(2), QVariant(wpParams.at(3).toInt())); + break; + default: + qDebug() << "FAILED LOADING PARAM" << wpParams.at(2) << "NO KNOWN DATA TYPE"; + } + +} + +void QGCParamWidget::loadParametersFromFile() { if (!mav) return; QString fileName = QFileDialog::getOpenFileName(this, tr("Load File"), ".", tr("Parameter file (*.txt)")); @@ -817,59 +872,18 @@ void QGCParamWidget::loadParameters() } bool changed = false; - int component = wpParams.at(1).toInt(); + int componentId = wpParams.at(1).toInt(); QString parameterName = wpParams.at(2); - if (!parameters.contains(component) || - fabs((static_cast(parameters.value(component)->value(parameterName, wpParams.at(3).toDouble()).toDouble())) - (wpParams.at(3).toDouble())) > 2.0f * FLT_EPSILON) { + if (!parameters.contains(componentId) || + fabs((static_cast(parameters.value(componentId)->value(parameterName, wpParams.at(3).toDouble()).toDouble())) - (wpParams.at(3).toDouble())) > 2.0f * FLT_EPSILON) { changed = true; qDebug() << "Changed" << parameterName << "VAL" << wpParams.at(3).toDouble(); } - // Set parameter value - - // Create changed values data structure if necessary - if (changed && !changedValues.contains(wpParams.at(1).toInt())) { - changedValues.insert(wpParams.at(1).toInt(), new QMap()); - } - - // Add to changed values - if (changed && changedValues.value(wpParams.at(1).toInt())->contains(wpParams.at(2))) { - changedValues.value(wpParams.at(1).toInt())->remove(wpParams.at(2)); - } - - switch (wpParams.at(4).toUInt()) - { - case (int)MAV_PARAM_TYPE_REAL32: - addParameter(wpParams.at(0).toInt(), wpParams.at(1).toInt(), wpParams.at(2), wpParams.at(3).toFloat()); - if (changed) { - changedValues.value(wpParams.at(1).toInt())->insert(wpParams.at(2), wpParams.at(3).toFloat()); - setParameter(wpParams.at(1).toInt(), wpParams.at(2), wpParams.at(3).toFloat()); - qDebug() << "FLOAT PARAM CHANGED"; - } - break; - case (int)MAV_PARAM_TYPE_UINT32: - addParameter(wpParams.at(0).toInt(), wpParams.at(1).toInt(), wpParams.at(2), wpParams.at(3).toUInt()); - if (changed) { - changedValues.value(wpParams.at(1).toInt())->insert(wpParams.at(2), wpParams.at(3).toUInt()); - setParameter(wpParams.at(1).toInt(), wpParams.at(2), QVariant(wpParams.at(3).toUInt())); - } - break; - case (int)MAV_PARAM_TYPE_INT32: - addParameter(wpParams.at(0).toInt(), wpParams.at(1).toInt(), wpParams.at(2), wpParams.at(3).toInt()); - if (changed) { - changedValues.value(wpParams.at(1).toInt())->insert(wpParams.at(2), wpParams.at(3).toInt()); - setParameter(wpParams.at(1).toInt(), wpParams.at(2), QVariant(wpParams.at(3).toInt())); - } - break; - default: - qDebug() << "FAILED LOADING PARAM" << wpParams.at(2) << "NO KNOWN DATA TYPE"; + if (changed) { + loadedParameterForComponent(componentId,wpParams); } - //qDebug() << "MARKING COMP" << wpParams.at(1).toInt() << "PARAM" << wpParams.at(2) << "VALUE" << (float)wpParams.at(3).toDouble() << "AS CHANGED"; - - // Mark in UI - - } } } @@ -1098,6 +1112,7 @@ void QGCParamWidget::setParameters() { // Iterate through all components, through all parameters and emit them int parametersSent = 0; + QMap*> changedValues = paramDataModel->getPendingParameters(); QMap*>::iterator i; for (i = changedValues.begin(); i != changedValues.end(); ++i) { // Iterate through the parameters of the component @@ -1144,16 +1159,17 @@ void QGCParamWidget::writeParameters() int changedParamCount = 0; QMap*>::iterator i; - for (i = changedValues.begin(); i != changedValues.end(); ++i) + QMap*> changedValues = paramDataModel->getPendingParameters(); + + for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) { // Iterate through the parameters of the component QMap* comp = i.value(); + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) { - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) - { - changedParamCount++; - } + changedParamCount++; + break;//it only takes one changed param to warrant warning the user } } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index f62227d015..5b48fffb22 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -71,9 +71,9 @@ public slots: /** @brief Add a component to the list */ void addComponent(int uas, int component, QString componentName); /** @brief Add a parameter to the list with retransmission / safety checks */ - void addParameter(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); + void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); /** @brief Add a parameter to the list */ - void addParameter(int uas, int component, QString parameterName, QVariant value); + void receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ void requestParameterList(); /** @brief Request one single parameter */ @@ -92,9 +92,11 @@ public slots: void parameterItemChanged(QTreeWidgetItem* prev, int column); /** @brief Store parameters to a file */ - void saveParameters(); + void saveParametersToFile(); /** @brief Load parameters from a file */ - void loadParameters(); + void loadParametersFromFile(); + + void loadedParameterForComponent(int componentId, QStringList& wpParams ); /** @brief Check for missing parameters */ void retransmissionGuardTick(); -- GitLab From 4640d27e1fd55e86e70b07fbd558bbee4bdf2a87 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sat, 3 Aug 2013 15:45:46 +0200 Subject: [PATCH 146/460] Cleaned up comm settings widget --- src/ui/CommSettings.ui | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/ui/CommSettings.ui b/src/ui/CommSettings.ui index 46e5ca56e0..73b4d76efc 100644 --- a/src/ui/CommSettings.ui +++ b/src/ui/CommSettings.ui @@ -7,7 +7,7 @@ 0 0 324 - 415 + 475 @@ -36,8 +36,8 @@ 0 0 - 302 - 69 + 292 + 81 @@ -126,8 +126,8 @@ 0 0 - 302 - 69 + 292 + 81 @@ -136,19 +136,6 @@
- - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -230,7 +217,6 @@ connectionStatusLabel advCheckBox protocolTypeGroupBox - verticalSpacer -- GitLab From eb5a54c065f5ae1b17c213c240720d59b22a8a78 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sat, 3 Aug 2013 16:00:35 +0200 Subject: [PATCH 147/460] Compile and serial port error handling fixes --- .../src/internals/copyrightstrings.h | 10 +++---- src/QGCCore.cc | 4 +-- src/comm/SerialLink.cc | 30 +++++++++++++------ src/configuration.h | 2 +- src/uas/UAS.cc | 19 ++++++++++-- src/ui/DebugConsole.cc | 5 ++-- src/ui/ParameterInterface.cc | 25 +++++++++++++--- 7 files changed, 70 insertions(+), 25 deletions(-) diff --git a/libs/opmapcontrol/src/internals/copyrightstrings.h b/libs/opmapcontrol/src/internals/copyrightstrings.h index 42cebdd3d3..1334d27beb 100644 --- a/libs/opmapcontrol/src/internals/copyrightstrings.h +++ b/libs/opmapcontrol/src/internals/copyrightstrings.h @@ -31,11 +31,11 @@ #include namespace internals { -static const QString googleCopyright = QString("%1 Google - Map data %1 Tele Atlas, Imagery %1 TerraMetrics").arg(QDate::currentDate().year()); -static const QString openStreetMapCopyright = QString(" OpenStreetMap - Map data %1 OpenStreetMap").arg(QDate::currentDate().year()); -static const QString yahooMapCopyright = QString(" Yahoo! Inc. - Map data & Imagery %1 NAVTEQ").arg(QDate::currentDate().year()); -static const QString virtualEarthCopyright = QString("%1 Microsoft Corporation, %1 NAVTEQ, %1 Image courtesy of NASA").arg(QDate::currentDate().year()); -static const QString arcGisCopyright = QString("%1 ESRI - Map data %1 ArcGIS").arg(QDate::currentDate().year()); +static const QString googleCopyright = QString("(c)%1 Google - Map data (c)%1 Tele Atlas, Imagery (c)%1 TerraMetrics").arg(QDate::currentDate().year()); +static const QString openStreetMapCopyright = QString("(c) OpenStreetMap - Map data (c)%1 OpenStreetMap").arg(QDate::currentDate().year()); +static const QString yahooMapCopyright = QString("(c) Yahoo! Inc. - Map data & Imagery (c)%1 NAVTEQ").arg(QDate::currentDate().year()); +static const QString virtualEarthCopyright = QString("(c)%1 Microsoft Corporation, (c)%1 NAVTEQ, (c)%1 Image courtesy of NASA").arg(QDate::currentDate().year()); +static const QString arcGisCopyright = QString("(c)%1 ESRI - Map data (c)%1 ArcGIS").arg(QDate::currentDate().year()); } #endif // COPYRIGHTSTRINGS_H diff --git a/src/QGCCore.cc b/src/QGCCore.cc index f654e67257..4740f37059 100644 --- a/src/QGCCore.cc +++ b/src/QGCCore.cc @@ -169,15 +169,15 @@ QGCCore::QGCCore(bool firstStart, int &argc, char* argv[]) : QApplication(argc, // first messages arrive udpLink = new UDPLink(QHostAddress::Any, 14550); LinkManager::instance()->add(udpLink); - //MainWindow::instance()->addLink(udpLink); } else if (mainWindow->getCustomMode() == MainWindow::CUSTOM_MODE_PX4) { udpLink = new UDPLink(QHostAddress::Any, 14550); LinkManager::instance()->add(udpLink); SerialLink *slink = new SerialLink(); + LinkManager::instance()->add(slink); } else { // We want to have a default serial link available for "quick" connecting. SerialLink *slink = new SerialLink(); -// MainWindow::instance()->addLink(slink); + LinkManager::instance()->add(slink); } #ifdef OPAL_RT diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index b7046bc087..07807e550a 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -142,6 +142,7 @@ void SerialLink::run() //Need to error out here. emit communicationError(getName(),"Error connecting: " + m_port->errorString()); disconnect(); // This tidies up and sends the necessary signals + emit communicationError(tr("Serial Port %1").arg(getPortName()), tr("Cannot read / write data - check physical USB and cable connections.")); return; } @@ -152,6 +153,7 @@ void SerialLink::run() bool triedreset = false; bool triedDTR = false; qint64 timeout = 5000; + int linkErrorCount = 0; forever { @@ -173,20 +175,28 @@ void SerialLink::run() } } - if (m_transmitBuffer.length() > 0) { + if (isConnected() && (linkErrorCount > 100)) { + linkErrorCount = 0; + disconnect(); + } + + if (m_transmitBuffer.count() > 0) { QMutexLocker writeLocker(&m_writeMutex); int numWritten = m_port->write(m_transmitBuffer); - bool txError = m_port->waitForBytesWritten(-1); -// if ((txError) || (numWritten == -1)) -// qDebug() << "TX Error!"; + bool txSuccess = m_port->waitForBytesWritten(1); + if (!txSuccess || (numWritten != m_transmitBuffer.count())) + { + linkErrorCount++; + qDebug() << "TX Error! wrote" << numWritten << ", asked for " << m_transmitBuffer.count() << "bytes"; + } else { + linkErrorCount = 0; + } m_transmitBuffer = m_transmitBuffer.remove(0, numWritten); - } else { -// qDebug() << "Wait write response timeout %1" << QTime::currentTime().toString(); } - bool error = m_port->waitForReadyRead(10); + bool success = m_port->waitForReadyRead(10); - if(error) { // Waits for 1/2 second [TODO][BB] lower to SerialLink::poll_interval? + if (success) { // Waits for 1/2 second [TODO][BB] lower to SerialLink::poll_interval? QByteArray readData = m_port->readAll(); while (m_port->waitForReadyRead(10)) readData += m_port->readAll(); @@ -196,9 +206,11 @@ void SerialLink::run() m_bytesRead += readData.length(); m_bitsReceivedTotal += readData.length() * 8; + linkErrorCount = 0; } } else { -// qDebug() << "Wait write response timeout %1" << QTime::currentTime().toString(); + linkErrorCount++; + qDebug() << "Wait read response timeout" << QTime::currentTime().toString(); } if (bytes != m_bytesRead) // i.e things are good and data is being read. diff --git a/src/configuration.h b/src/configuration.h index 84b0f2530c..d2397ccc75 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -11,7 +11,7 @@ #define WITH_TEXT_TO_SPEECH 1 #define QGC_APPLICATION_NAME "QGroundControl" -#define QGC_APPLICATION_VERSION "v. 1.1.1 (beta)" +#define QGC_APPLICATION_VERSION "v. 1.1.2 (beta)" namespace QGC diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 142e53b20f..8dd3395506 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -1975,13 +1975,23 @@ void UAS::setMode(int mode) */ void UAS::sendMessage(mavlink_message_t message) { - if (!LinkManager::instance()) return; + if (!LinkManager::instance()) + { + qWarning() << "LINKMANAGER NOT AVAILABLE!"; + return; + } + + if (links->count() < 1) { + qDebug() << "NO LINK AVAILABLE TO SEND!"; + } + // Emit message on all links that are currently connected foreach (LinkInterface* link, *links) { if (LinkManager::instance()->getLinks().contains(link)) { sendMessage(link, message); + qDebug() << "SENT MESSAGE!"; } else { @@ -2034,12 +2044,17 @@ void UAS::sendMessage(LinkInterface* link, mavlink_message_t message) int len = mavlink_msg_to_send_buffer(buffer, &message); static uint8_t messageKeys[256] = MAVLINK_MESSAGE_CRCS; mavlink_finalize_message_chan(&message, mavlink->getSystemId(), mavlink->getComponentId(), link->getId(), message.len, messageKeys[message.msgid]); + // If link is connected if (link->isConnected()) { // Send the portion of the buffer now occupied by the message link->writeBytes((const char*)buffer, len); } + else + { + qDebug() << "LINK NOT CONNECTED, NOT SENDING!"; + } } /** @@ -2232,7 +2247,7 @@ void UAS::requestParameters() mavlink_message_t msg; mavlink_msg_param_request_list_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_COMP_ID_ALL); sendMessage(msg); - qDebug() << __FILE__ << __LINE__ << "LOADING PARAM LIST"; + qDebug() << __FILE__ << ":" << __LINE__ << "LOADING PARAM LIST"; } void UAS::writeParametersToStorage() diff --git a/src/ui/DebugConsole.cc b/src/ui/DebugConsole.cc index c89fc38114..bdc5f149de 100644 --- a/src/ui/DebugConsole.cc +++ b/src/ui/DebugConsole.cc @@ -217,6 +217,7 @@ void DebugConsole::removeLink(LinkInterface* const linkInterface) } void DebugConsole::linkStatusUpdate(const QString& name,const QString& text) { + Q_UNUSED(name); m_ui->receiveText->appendPlainText(text); // Ensure text area scrolls correctly m_ui->receiveText->ensureCursorVisible(); @@ -579,7 +580,7 @@ QString DebugConsole::bytesToSymbolNames(const QByteArray& b) } else if (b.contains(0x09)) { text = ""; } else if (b.contains((char)0x00)) { - text == ""; + text = ""; } else if (b.contains(0x1B)) { text = ""; } else if (b.contains(0x7E)) { @@ -688,7 +689,7 @@ void DebugConsole::sendBytes() str.append(specialSymbol); str.remove(' '); str.remove("0x"); - str.simplified(); + str = str.simplified(); int bufferIndex = 0; if ((str.size() % 2) == 0) { for (int i = 0; i < str.size(); i=i+2) { diff --git a/src/ui/ParameterInterface.cc b/src/ui/ParameterInterface.cc index ac0f1f097f..e387a20938 100644 --- a/src/ui/ParameterInterface.cc +++ b/src/ui/ParameterInterface.cc @@ -36,6 +36,8 @@ This file is part of the QGROUNDCONTROL project #include "QGCSensorSettingsWidget.h" #include +#include +#include "MainWindow.h" ParameterInterface::ParameterInterface(QWidget *parent) : QWidget(parent), @@ -45,6 +47,15 @@ ParameterInterface::ParameterInterface(QWidget *parent) : { m_ui->setupUi(this); + QSettings settings; + enum MainWindow::CUSTOM_MODE mode = static_cast(settings.value("QGC_CUSTOM_MODE", MainWindow::CUSTOM_MODE_NONE).toInt()); + + if (mode == MainWindow::CUSTOM_MODE_PX4) + { + delete m_ui->sensorSettings; + m_ui->sensorSettings = NULL; + } + // Get current MAV list QList systems = UASManager::instance()->getUASList(); @@ -67,7 +78,8 @@ ParameterInterface::~ParameterInterface() void ParameterInterface::selectUAS(int index) { m_ui->stackedWidget->setCurrentIndex(index); - m_ui->sensorSettings->setCurrentIndex(index); + if (m_ui->sensorSettings) + m_ui->sensorSettings->setCurrentIndex(index); curr = index; } @@ -81,14 +93,19 @@ void ParameterInterface::addUAS(UASInterface* uas) paramWidgets->insert(uas->getUASID(), param); m_ui->stackedWidget->addWidget(param); + QGCSensorSettingsWidget* sensor = NULL; - QGCSensorSettingsWidget* sensor = new QGCSensorSettingsWidget(uas, this); - m_ui->sensorSettings->addWidget(sensor); + if (m_ui->sensorSettings) + { + sensor = new QGCSensorSettingsWidget(uas, this); + m_ui->sensorSettings->addWidget(sensor); + } // Set widgets as default if (curr == -1) { // Clear - m_ui->sensorSettings->setCurrentWidget(sensor); + if (m_ui->sensorSettings && sensor) + m_ui->sensorSettings->setCurrentWidget(sensor); m_ui->stackedWidget->setCurrentWidget(param); curr = 0; } -- GitLab From f549453b7edbd87e511d5f54627f4f7abb9eb21e Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 5 Aug 2013 17:56:59 -0700 Subject: [PATCH 148/460] fix null ptr exception --- src/uas/UAS.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 3386deab79..aceff3b716 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -152,6 +152,7 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), componentMulti[i] = false; } + paramDataModel = new UASParameterDataModel(this); paramDataModel->setUASID(this->getUASID()); // Store a list of available actions for this UAS. -- GitLab From 03de182bacee9ad01ceb8c4917b26c4ebeb73035 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 5 Aug 2013 17:57:51 -0700 Subject: [PATCH 149/460] remove pure virtual --- src/uas/UASParameterDataModel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 5c1d67d486..60bfbbfa80 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -13,7 +13,7 @@ public: /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ - virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue) = 0; + virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue); QMap* > getPendingParameters() { return pendingParameters; -- GitLab From 29f3bdb1d682eec908dd07b9bd500c023bfebba5 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 2 Aug 2013 21:50:32 -0700 Subject: [PATCH 150/460] wip decoupling the UI (view) from the param data model --- qgroundcontrol.pro | 6 +- src/uas/QGCUASParamManager.cc | 1 + src/uas/QGCUASParamManager.h | 8 +- src/uas/UAS.cc | 3 + src/uas/UAS.h | 12 +++ src/uas/UASInterface.h | 6 ++ src/uas/UASParameterDataModel.cc | 26 ++++++ src/uas/UASParameterDataModel.h | 42 +++++++++ src/ui/QGCParamWidget.cc | 148 +++++++++++++++++-------------- src/ui/QGCParamWidget.h | 10 ++- 10 files changed, 189 insertions(+), 73 deletions(-) create mode 100644 src/uas/UASParameterDataModel.cc create mode 100644 src/uas/UASParameterDataModel.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 263586226c..fd4df5e5b5 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -468,7 +468,8 @@ HEADERS += src/MG.h \ src/ui/configuration/SerialSettingsDialog.h \ src/ui/configuration/terminalconsole.h \ src/ui/configuration/ApmHighlighter.h \ - src/ui/configuration/ApmFirmwareConfig.h + src/ui/configuration/ApmFirmwareConfig.h \ + src/uas/UASParameterDataModel.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -683,7 +684,8 @@ SOURCES += src/main.cc \ src/ui/configuration/console.cpp \ src/ui/configuration/SerialSettingsDialog.cc \ src/ui/configuration/ApmHighlighter.cc \ - src/ui/configuration/ApmFirmwareConfig.cc + src/ui/configuration/ApmFirmwareConfig.cc \ + src/uas/UASParameterDataModel.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 6e137b6329..7193bce82f 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -12,6 +12,7 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : retransmissionBurstRequestSize(5) { uas->setParamManager(this); + paramDataModel = uas->getParamDataModel(); } diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 69dee9eb44..d7f8adf976 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -7,6 +7,7 @@ #include class UASInterface; +class UASParameterDataModel; class QGCUASParamManager : public QWidget { @@ -62,9 +63,14 @@ public slots: virtual void requestParameterList() = 0; protected: + + //Parameter data model UASInterface* mav; ///< The MAV this widget is controlling - QMap* > changedValues; ///< Changed values +// QMap* > changedValues; ///< Changed values QMap* > parameters; ///< All parameters + UASParameterDataModel* paramDataModel;///< Shared data model of parameters + + // Communications management QVector received; ///< Successfully received parameters QMap* > transmissionMissingPackets; ///< Missing packets QMap* > transmissionMissingWriteAckPackets; ///< Missing write ACK packets diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 8dd3395506..8a8ef7539f 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -131,6 +131,7 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), paramsOnceRequested(false), paramManager(NULL), + paramDataModel(NULL), simulation(0), @@ -151,6 +152,8 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), componentMulti[i] = false; } + paramDataModel->setUASID(this->getUASID()); + // Store a list of available actions for this UAS. // Basically everything exposted as a SLOT with no return value or arguments. diff --git a/src/uas/UAS.h b/src/uas/UAS.h index b1c027bd1f..c8b9a604c7 100644 --- a/src/uas/UAS.h +++ b/src/uas/UAS.h @@ -492,6 +492,7 @@ protected: //COMMENTS FOR TEST UNIT QMap* > parameters; ///< All parameters bool paramsOnceRequested; ///< If the parameter list has been read at least once QGCUASParamManager* paramManager; ///< Parameter manager class + UASParameterDataModel* paramDataModel; ///< The parameter data model for this UAS /// SIMULATION QGCHilLink* simulation; ///< Hardware in the loop simulation link @@ -519,10 +520,20 @@ public: QGCUASParamManager* getParamManager() const { return paramManager; } + + /** @brief Get reference to the parameter data model (same one shared with the parameter manager) **/ + UASParameterDataModel* getParamDataModel() { + return paramDataModel; + } + + /** @brief Get the HIL simulation */ QGCHilLink* getHILSimulation() const { return simulation; } + + + // TODO Will be removed /** @brief Set reference to the param manager **/ void setParamManager(QGCUASParamManager* manager) { @@ -949,6 +960,7 @@ protected: quint64 lastSendTimeSensors; QList actions; ///< A list of actions that this UAS can perform. + protected slots: /** @brief Write settings to disk */ void writeSettings(); diff --git a/src/uas/UASInterface.h b/src/uas/UASInterface.h index 37382e3eb4..ed2aed28c8 100644 --- a/src/uas/UASInterface.h +++ b/src/uas/UASInterface.h @@ -40,6 +40,7 @@ This file is part of the QGROUNDCONTROL project #include "LinkInterface.h" #include "ProtocolInterface.h" +#include "UASParameterDataModel.h" #include "UASWaypointManager.h" #include "QGCUASParamManager.h" #include "RadioCalibration/RadioCalibrationData.h" @@ -152,8 +153,13 @@ public: /** @brief Get reference to the waypoint manager **/ virtual UASWaypointManager* getWaypointManager(void) = 0; + + /** @brief Access the parameter data model for this UAS (sans widget). This is the same parameter data model used by the parameter manager. **/ + virtual UASParameterDataModel* getParamDataModel() = 0; + /** @brief Get reference to the param manager **/ virtual QGCUASParamManager* getParamManager() const = 0; + // TODO Will be removed /** @brief Set reference to the param manager **/ virtual void setParamManager(QGCUASParamManager* manager) = 0; diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc new file mode 100644 index 0000000000..8effd144ce --- /dev/null +++ b/src/uas/UASParameterDataModel.cc @@ -0,0 +1,26 @@ +#include "UASParameterDataModel.h" + +#include + +UASParameterDataModel::UASParameterDataModel(QObject *parent) : + QObject(parent) +{ + + + + + +} + + +void UASParameterDataModel::setPendingParameter(int componentId, QString& key, QVariant &value) +{ + QMap *compPendingParams = pendingParameters.value(componentId); + //TODO insert blank map if necessary + if (NULL == compPendingParams) { + pendingParameters.insert(componentId,new QMap()); + compPendingParams = pendingParameters.value(componentId); + } + + compPendingParams->insert(key,value); +} diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h new file mode 100644 index 0000000000..5c1d67d486 --- /dev/null +++ b/src/uas/UASParameterDataModel.h @@ -0,0 +1,42 @@ +#ifndef UASPARAMETERDATAMODEL_H +#define UASPARAMETERDATAMODEL_H + +#include +#include +#include + +class UASParameterDataModel : public QObject +{ + Q_OBJECT +public: + explicit UASParameterDataModel(QObject *parent = 0); + + + /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ + virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue) = 0; + + QMap* > getPendingParameters() { + return pendingParameters; + } + + QMap* > getOnboardParameters() { + return onboardParameters; + } + + + void setUASID(int anId) { this->uasId = anId; } + +signals: + +public slots: + + +protected: + int uasId; ///< The UAS / MAV to which this data model pertains + QMap* > pendingParameters; ///< Changed values that have not yet been transmitted to the UAS, by component ID + QMap* > onboardParameters; ///< All parameters confirmed to be stored onboard the UAS, by component ID + + +}; + +#endif // UASPARAMETERDATAMODEL_H diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 94e1697b52..abd1e913d5 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -105,13 +105,13 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QPushButton* loadFileButton = new QPushButton(tr("Load File")); loadFileButton->setToolTip(tr("Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them.")); loadFileButton->setWhatsThis(tr("Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them.")); - connect(loadFileButton, SIGNAL(clicked()), this, SLOT(loadParameters())); + connect(loadFileButton, SIGNAL(clicked()), this, SLOT(loadParametersFromFile())); horizontalLayout->addWidget(loadFileButton, 3, 0); QPushButton* saveFileButton = new QPushButton(tr("Save File")); saveFileButton->setToolTip(tr("Save parameters in this view to a file on this computer.")); saveFileButton->setWhatsThis(tr("Save parameters in this view to a file on this computer.")); - connect(saveFileButton, SIGNAL(clicked()), this, SLOT(saveParameters())); + connect(saveFileButton, SIGNAL(clicked()), this, SLOT(saveParametersToFile())); horizontalLayout->addWidget(saveFileButton, 3, 1); QPushButton* readButton = new QPushButton(tr("Read (ROM)")); @@ -142,7 +142,7 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); // New parameters from UAS - connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(addParameter(int,int,int,int,QString,QVariant))); + connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); // Connect retransmission guard connect(this, SIGNAL(requestParameter(int,QString)), uas, SLOT(requestParameter(int,QString))); @@ -335,10 +335,10 @@ void QGCParamWidget::addComponent(int uas, int component, QString componentName) if (!parameters.contains(component)) { parameters.insert(component, new QMap()); } - // Create map in changed parameters - if (!changedValues.contains(component)) { - changedValues.insert(component, new QMap()); - } +// // Create map in changed parameters +// if (!changedValues.contains(component)) { +// changedValues.insert(component, new QMap()); +// } } } @@ -347,9 +347,9 @@ void QGCParamWidget::addComponent(int uas, int component, QString componentName) * @param component id of the component * @param parameterName human friendly name of the parameter */ -void QGCParamWidget::addParameter(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) +void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) { - addParameter(uas, component, parameterName, value); + receivedParameterUpdate(uas, component, parameterName, value); // Missing packets list has to be instantiated for all components if (!transmissionMissingPackets.contains(component)) { @@ -494,7 +494,7 @@ void QGCParamWidget::addParameter(int uas, int component, int paramCount, int pa * @param component id of the component * @param parameterName human friendly name of the parameter */ -void QGCParamWidget::addParameter(int uas, int component, QString parameterName, QVariant value) +void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value) { //qDebug() << "PARAM WIDGET GOT PARAM:" << value; Q_UNUSED(uas); @@ -636,8 +636,18 @@ void QGCParamWidget::addParameter(int uas, int component, QString parameterName, parameterItem->setToolTip(0, tooltipFormat); parameterItem->setToolTip(1, tooltipFormat); - //tree->update(); - if (changedValues.contains(component)) changedValues.value(component)->remove(parameterName); + //verify that the value requested by the user matches the set value + //if it doesn't match, leave the pending parameter in the pending list! + QMap *> changedValues = this->paramDataModel->getPendingParameters(); + if (changedValues.contains(component)) { + QMap *compReqVals = changedValues.value(component); + if ((NULL != compReqVals) && compReqVals->contains(parameterName)) { + QVariant reqVal = compReqVals->value(parameterName); + if (reqVal == value) { + compReqVals->remove(parameterName); + } + } + } } /** @@ -682,9 +692,14 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) } // Parent is now top-level component int key = components->key(parent); + + //ensure we have a placeholder map for this component + QMap *> changedValues = this->paramDataModel->getPendingParameters(); if (!changedValues.contains(key)) { changedValues.insert(key, new QMap()); } + + //insert the changed value into the map QMap* map = changedValues.value(key, NULL); if (map) { QString str = current->data(0, Qt::DisplayRole).toString(); @@ -739,7 +754,7 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) } } -void QGCParamWidget::saveParameters() +void QGCParamWidget::saveParametersToFile() { if (!mav) return; QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "./parameters.txt", tr("Parameter File (*.txt)")); @@ -794,7 +809,47 @@ void QGCParamWidget::saveParameters() file.close(); } -void QGCParamWidget::loadParameters() + +void QGCParamWidget::loadedParameterForComponent(int componentId, QStringList& wpParams ) +{ + // Set parameter value + + QMap *> changedValues = this->paramDataModel->getPendingParameters(); + + // Create changed values data structure if necessary + if (!changedValues.contains(componentId)) { + changedValues.insert(componentId, new QMap()); + } + + // Add to changed values + if (changedValues.value(componentId)->contains(wpParams.at(2))) { + changedValues.value(componentId)->remove(wpParams.at(2)); + } + + switch (wpParams.at(4).toUInt()) + { + case (int)MAV_PARAM_TYPE_REAL32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toFloat()); + changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toFloat()); + setParameter(componentId, wpParams.at(2), wpParams.at(3).toFloat()); + break; + case (int)MAV_PARAM_TYPE_UINT32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toUInt()); + changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toUInt()); + setParameter(componentId, wpParams.at(2), QVariant(wpParams.at(3).toUInt())); + break; + case (int)MAV_PARAM_TYPE_INT32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toInt()); + changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toInt()); + setParameter(componentId, wpParams.at(2), QVariant(wpParams.at(3).toInt())); + break; + default: + qDebug() << "FAILED LOADING PARAM" << wpParams.at(2) << "NO KNOWN DATA TYPE"; + } + +} + +void QGCParamWidget::loadParametersFromFile() { if (!mav) return; QString fileName = QFileDialog::getOpenFileName(this, tr("Load File"), ".", tr("Parameter file (*.txt)")); @@ -817,59 +872,18 @@ void QGCParamWidget::loadParameters() } bool changed = false; - int component = wpParams.at(1).toInt(); + int componentId = wpParams.at(1).toInt(); QString parameterName = wpParams.at(2); - if (!parameters.contains(component) || - fabs((static_cast(parameters.value(component)->value(parameterName, wpParams.at(3).toDouble()).toDouble())) - (wpParams.at(3).toDouble())) > 2.0f * FLT_EPSILON) { + if (!parameters.contains(componentId) || + fabs((static_cast(parameters.value(componentId)->value(parameterName, wpParams.at(3).toDouble()).toDouble())) - (wpParams.at(3).toDouble())) > 2.0f * FLT_EPSILON) { changed = true; qDebug() << "Changed" << parameterName << "VAL" << wpParams.at(3).toDouble(); } - // Set parameter value - - // Create changed values data structure if necessary - if (changed && !changedValues.contains(wpParams.at(1).toInt())) { - changedValues.insert(wpParams.at(1).toInt(), new QMap()); - } - - // Add to changed values - if (changed && changedValues.value(wpParams.at(1).toInt())->contains(wpParams.at(2))) { - changedValues.value(wpParams.at(1).toInt())->remove(wpParams.at(2)); - } - - switch (wpParams.at(4).toUInt()) - { - case (int)MAV_PARAM_TYPE_REAL32: - addParameter(wpParams.at(0).toInt(), wpParams.at(1).toInt(), wpParams.at(2), wpParams.at(3).toFloat()); - if (changed) { - changedValues.value(wpParams.at(1).toInt())->insert(wpParams.at(2), wpParams.at(3).toFloat()); - setParameter(wpParams.at(1).toInt(), wpParams.at(2), wpParams.at(3).toFloat()); - qDebug() << "FLOAT PARAM CHANGED"; - } - break; - case (int)MAV_PARAM_TYPE_UINT32: - addParameter(wpParams.at(0).toInt(), wpParams.at(1).toInt(), wpParams.at(2), wpParams.at(3).toUInt()); - if (changed) { - changedValues.value(wpParams.at(1).toInt())->insert(wpParams.at(2), wpParams.at(3).toUInt()); - setParameter(wpParams.at(1).toInt(), wpParams.at(2), QVariant(wpParams.at(3).toUInt())); - } - break; - case (int)MAV_PARAM_TYPE_INT32: - addParameter(wpParams.at(0).toInt(), wpParams.at(1).toInt(), wpParams.at(2), wpParams.at(3).toInt()); - if (changed) { - changedValues.value(wpParams.at(1).toInt())->insert(wpParams.at(2), wpParams.at(3).toInt()); - setParameter(wpParams.at(1).toInt(), wpParams.at(2), QVariant(wpParams.at(3).toInt())); - } - break; - default: - qDebug() << "FAILED LOADING PARAM" << wpParams.at(2) << "NO KNOWN DATA TYPE"; + if (changed) { + loadedParameterForComponent(componentId,wpParams); } - //qDebug() << "MARKING COMP" << wpParams.at(1).toInt() << "PARAM" << wpParams.at(2) << "VALUE" << (float)wpParams.at(3).toDouble() << "AS CHANGED"; - - // Mark in UI - - } } } @@ -1098,6 +1112,7 @@ void QGCParamWidget::setParameters() { // Iterate through all components, through all parameters and emit them int parametersSent = 0; + QMap*> changedValues = paramDataModel->getPendingParameters(); QMap*>::iterator i; for (i = changedValues.begin(); i != changedValues.end(); ++i) { // Iterate through the parameters of the component @@ -1144,16 +1159,17 @@ void QGCParamWidget::writeParameters() int changedParamCount = 0; QMap*>::iterator i; - for (i = changedValues.begin(); i != changedValues.end(); ++i) + QMap*> changedValues = paramDataModel->getPendingParameters(); + + for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) { // Iterate through the parameters of the component QMap* comp = i.value(); + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) { - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) - { - changedParamCount++; - } + changedParamCount++; + break;//it only takes one changed param to warrant warning the user } } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index f62227d015..5b48fffb22 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -71,9 +71,9 @@ public slots: /** @brief Add a component to the list */ void addComponent(int uas, int component, QString componentName); /** @brief Add a parameter to the list with retransmission / safety checks */ - void addParameter(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); + void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); /** @brief Add a parameter to the list */ - void addParameter(int uas, int component, QString parameterName, QVariant value); + void receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ void requestParameterList(); /** @brief Request one single parameter */ @@ -92,9 +92,11 @@ public slots: void parameterItemChanged(QTreeWidgetItem* prev, int column); /** @brief Store parameters to a file */ - void saveParameters(); + void saveParametersToFile(); /** @brief Load parameters from a file */ - void loadParameters(); + void loadParametersFromFile(); + + void loadedParameterForComponent(int componentId, QStringList& wpParams ); /** @brief Check for missing parameters */ void retransmissionGuardTick(); -- GitLab From e39d9db46336ba721a69079a96ca67155ec34afc Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 5 Aug 2013 17:56:59 -0700 Subject: [PATCH 151/460] fix null ptr exception --- src/uas/UAS.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 8a8ef7539f..597472af5a 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -152,6 +152,7 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), componentMulti[i] = false; } + paramDataModel = new UASParameterDataModel(this); paramDataModel->setUASID(this->getUASID()); // Store a list of available actions for this UAS. -- GitLab From c7ac0e63c730d2b8f7ec6ca85e9dad8a64ce8415 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 5 Aug 2013 17:57:51 -0700 Subject: [PATCH 152/460] remove pure virtual --- src/uas/UASParameterDataModel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 5c1d67d486..60bfbbfa80 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -13,7 +13,7 @@ public: /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ - virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue) = 0; + virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue); QMap* > getPendingParameters() { return pendingParameters; -- GitLab From 0c739bc2b3a9658e78b76e809e47718289f643df Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 5 Aug 2013 18:20:28 -0700 Subject: [PATCH 153/460] rename parameters --- src/uas/QGCUASParamManager.h | 15 +++++++-------- src/ui/QGCParamWidget.cc | 36 ++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index d7f8adf976..130e9a18cb 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -16,23 +16,23 @@ public: QGCUASParamManager(UASInterface* uas, QWidget *parent = 0); QList getParameterNames(int component) const { - return parameters.value(component)->keys(); + return onboardParameters.value(component)->keys(); } QList getParameterValues(int component) const { - return parameters.value(component)->values(); + return onboardParameters.value(component)->values(); } bool getParameterValue(int component, const QString& parameter, QVariant& value) const { - if (!parameters.contains(component)) + if (!onboardParameters.contains(component)) { return false; } - if (!parameters.value(component)->contains(parameter)) + if (!onboardParameters.value(component)->contains(parameter)) { return false; } - value = parameters.value(component)->value(parameter); + value = onboardParameters.value(component)->value(parameter); return true; } @@ -64,10 +64,9 @@ public slots: protected: - //Parameter data model + // Parameter data model UASInterface* mav; ///< The MAV this widget is controlling -// QMap* > changedValues; ///< Changed values - QMap* > parameters; ///< All parameters + QMap* > onboardParameters; ///< All parameters UASParameterDataModel* paramDataModel;///< Shared data model of parameters // Communications management diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index abd1e913d5..fb1e6eb964 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -332,8 +332,8 @@ void QGCParamWidget::addComponent(int uas, int component, QString componentName) tree->addTopLevelItem(comp); tree->update(); // Create map in parameters - if (!parameters.contains(component)) { - parameters.insert(component, new QMap()); + if (!onboardParameters.contains(component)) { + onboardParameters.insert(component, new QMap()); } // // Create map in changed parameters // if (!changedValues.contains(component)) { @@ -524,8 +524,8 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString par // Replace value in map // FIXME - if (parameters.value(component)->contains(parameterName)) parameters.value(component)->remove(parameterName); - parameters.value(component)->insert(parameterName, value); + if (onboardParameters.value(component)->contains(parameterName)) onboardParameters.value(component)->remove(parameterName); + onboardParameters.value(component)->insert(parameterName, value); QString splitToken = "_"; @@ -666,7 +666,7 @@ void QGCParamWidget::requestParameterList() // Clear view and request param list clear(); - parameters.clear(); + onboardParameters.clear(); received.clear(); // Clear transmission state transmissionListMode = true; @@ -715,35 +715,35 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) map->insert(str, value); // Check if the value was numerically changed - if (!parameters.value(key)->contains(str) || parameters.value(key)->value(str, value.toDouble()-1) != value) { + if (!onboardParameters.value(key)->contains(str) || onboardParameters.value(key)->value(str, value.toDouble()-1) != value) { current->setBackground(0, QBrush(QColor(QGC::colorOrange))); current->setBackground(1, QBrush(QColor(QGC::colorOrange))); } - switch ((int)parameters.value(key)->value(str).type()) + switch ((int)onboardParameters.value(key)->value(str).type()) { case QVariant::Int: { QVariant fixedValue(value.toInt()); - parameters.value(key)->insert(str, fixedValue); + onboardParameters.value(key)->insert(str, fixedValue); } break; case QVariant::UInt: { QVariant fixedValue(value.toUInt()); - parameters.value(key)->insert(str, fixedValue); + onboardParameters.value(key)->insert(str, fixedValue); } break; case QMetaType::Float: { QVariant fixedValue(value.toFloat()); - parameters.value(key)->insert(str, fixedValue); + onboardParameters.value(key)->insert(str, fixedValue); } break; case QMetaType::QChar: { QVariant fixedValue(QChar((unsigned char)value.toUInt())); - parameters.value(key)->insert(str, fixedValue); + onboardParameters.value(key)->insert(str, fixedValue); } break; default: @@ -771,7 +771,7 @@ void QGCParamWidget::saveParametersToFile() // Iterate through all components, through all parameters and emit them QMap*>::iterator i; - for (i = parameters.begin(); i != parameters.end(); ++i) { + for (i = onboardParameters.begin(); i != onboardParameters.end(); ++i) { // Iterate through the parameters of the component int compid = i.key(); QMap* comp = i.value(); @@ -874,8 +874,8 @@ void QGCParamWidget::loadParametersFromFile() bool changed = false; int componentId = wpParams.at(1).toInt(); QString parameterName = wpParams.at(2); - if (!parameters.contains(componentId) || - fabs((static_cast(parameters.value(componentId)->value(parameterName, wpParams.at(3).toDouble()).toDouble())) - (wpParams.at(3).toDouble())) > 2.0f * FLT_EPSILON) { + if (!onboardParameters.contains(componentId) || + fabs((static_cast(onboardParameters.value(componentId)->value(parameterName, wpParams.at(3).toDouble()).toDouble())) - (wpParams.at(3).toDouble())) > 2.0f * FLT_EPSILON) { changed = true; qDebug() << "Changed" << parameterName << "VAL" << wpParams.at(3).toDouble(); } @@ -940,7 +940,7 @@ void QGCParamWidget::retransmissionGuardTick() // Re-request at maximum retransmissionBurstRequestSize parameters at once // to prevent link flooding QMap*>::iterator i; - for (i = parameters.begin(); i != parameters.end(); ++i) { + for (i = onboardParameters.begin(); i != onboardParameters.end(); ++i) { // Iterate through the parameters of the component int component = i.key(); // Request n parameters from this component (at maximum) @@ -971,7 +971,7 @@ void QGCParamWidget::retransmissionGuardTick() if (count < retransmissionBurstRequestSize) { // Re-request write operation QVariant value = missingParams->value(key); - switch ((int)parameters.value(component)->value(key).type()) + switch ((int)onboardParameters.value(component)->value(key).type()) { case QVariant::Int: { @@ -1035,13 +1035,13 @@ void QGCParamWidget::setParameter(int component, QString parameterName, QVariant statusLabel->setText(tr("REJ. %1 > max").arg(value.toDouble())); return; } - if (parameters.value(component)->value(parameterName) == value) + if (onboardParameters.value(component)->value(parameterName) == value) { statusLabel->setText(tr("REJ. %1 > max").arg(value.toDouble())); return; } - switch ((int)parameters.value(component)->value(parameterName).type()) + switch ((int)onboardParameters.value(component)->value(parameterName).type()) { case QVariant::Char: { -- GitLab From 83409be57cd2e6843a0cd1c1726a730ae014f193 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 5 Aug 2013 21:29:48 -0700 Subject: [PATCH 154/460] utility methods for data model --- src/uas/UASParameterDataModel.cc | 40 +++++++++++++++++++++++++------- src/uas/UASParameterDataModel.h | 15 ++++++++++++ 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 8effd144ce..8396594e17 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -7,20 +7,44 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : { +} +void UASParameterDataModel::addPendingIfParameterChanged(int componentId, QString& key, QVariant &value) +{ + addComponent(componentId); + QMap *existParams = getOnbardParametersForComponent(componentId); + QMap *pendParams = getPendingParametersForComponent(componentId); + + QVariant existValue = existParams->value(key); + QVariant pendValue = pendParams->value(key); + if (!(existValue == pendValue)) { + setPendingParameter(componentId,key,value); + } +} +void UASParameterDataModel::setPendingParameter(int componentId, QString& key, QVariant &value) +{ + //ensure we have a placeholder map for this component + addComponent(componentId); + QMap *params = getPendingParametersForComponent(componentId); + params->insert(key,value); } +void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, QVariant &value) +{ + //ensure we have a placeholder map for this component + addComponent(componentId); + QMap *params = getOnbardParametersForComponent(componentId); + params->insert(key,value); +} -void UASParameterDataModel::setPendingParameter(int componentId, QString& key, QVariant &value) +void UASParameterDataModel::addComponent(int componentId) { - QMap *compPendingParams = pendingParameters.value(componentId); - //TODO insert blank map if necessary - if (NULL == compPendingParams) { - pendingParameters.insert(componentId,new QMap()); - compPendingParams = pendingParameters.value(componentId); + if (!onboardParameters.contains(componentId)) { + onboardParameters.insert(componentId, new QMap()); + } + if (!pendingParameters.contains(componentId)) { + pendingParameters.insert(componentId, new QMap()); } - - compPendingParams->insert(key,value); } diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 60bfbbfa80..7122d523eb 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -12,8 +12,23 @@ public: explicit UASParameterDataModel(QObject *parent = 0); + virtual void addComponent(int componentId); + /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue); + virtual void setOnboardParameter(int componentId, QString& key, QVariant &value); + + /** @brief add this parameter to pending list iff it has changed from onboard value */ + virtual void addPendingIfParameterChanged(int componentId, QString& key, QVariant &value); + + + QMap* getPendingParametersForComponent(int componentId) { + return pendingParameters.value(componentId); + } + + QMap* getOnbardParametersForComponent(int componentId) { + return onboardParameters.value(componentId); + } QMap* > getPendingParameters() { return pendingParameters; -- GitLab From 529a08739edb903ee13d94f540d1c92c8b1ace8e Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 5 Aug 2013 21:43:24 -0700 Subject: [PATCH 155/460] Move handleParameterUpdate into data model class --- src/uas/UASParameterDataModel.cc | 24 +++++++++++++++++++++++- src/uas/UASParameterDataModel.h | 2 ++ src/ui/QGCParamWidget.cc | 14 ++------------ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 8396594e17..dbf4610601 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -1,5 +1,6 @@ #include "UASParameterDataModel.h" +#include #include UASParameterDataModel::UASParameterDataModel(QObject *parent) : @@ -31,7 +32,7 @@ void UASParameterDataModel::setPendingParameter(int componentId, QString& key, params->insert(key,value); } -void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, QVariant &value) +void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, QVariant& value) { //ensure we have a placeholder map for this component addComponent(componentId); @@ -48,3 +49,24 @@ void UASParameterDataModel::addComponent(int componentId) pendingParameters.insert(componentId, new QMap()); } } + + +void UASParameterDataModel::handleParameterUpdate(int componentId, QString& key, QVariant& value) +{ + //verify that the value requested by the user matches the set value + //if it doesn't match, leave the pending parameter in the pending list! + if (pendingParameters.contains(componentId)) { + QMap *pendingParams = pendingParameters.value(componentId); + if ((NULL != pendingParams) && pendingParams->contains(key)) { + QVariant reqVal = pendingParams->value(key); + if (reqVal == value) { + pendingParams->remove(key); + } + else { + qDebug() << "Pending commit for " << key << " want: " << reqVal << " got: " << value; + } + } + } + + setOnboardParameter(componentId,key, value); +} diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 7122d523eb..b3e56b7a74 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -22,6 +22,8 @@ public: virtual void addPendingIfParameterChanged(int componentId, QString& key, QVariant &value); + void handleParameterUpdate(int componentId, QString& key, QVariant& value); + QMap* getPendingParametersForComponent(int componentId) { return pendingParameters.value(componentId); } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index fb1e6eb964..0e415d8bd9 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -636,18 +636,8 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString par parameterItem->setToolTip(0, tooltipFormat); parameterItem->setToolTip(1, tooltipFormat); - //verify that the value requested by the user matches the set value - //if it doesn't match, leave the pending parameter in the pending list! - QMap *> changedValues = this->paramDataModel->getPendingParameters(); - if (changedValues.contains(component)) { - QMap *compReqVals = changedValues.value(component); - if ((NULL != compReqVals) && compReqVals->contains(parameterName)) { - QVariant reqVal = compReqVals->value(parameterName); - if (reqVal == value) { - compReqVals->remove(parameterName); - } - } - } + paramDataModel->handleParameterUpdate(component,parameterName,value); + } /** -- GitLab From 47831affec67bf6b5f0ae31b64a58cc3ff9658eb Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 07:42:05 -0700 Subject: [PATCH 156/460] remove unused methods --- src/uas/QGCUASParamManager.cc | 3 +++ src/uas/QGCUASParamManager.h | 23 +---------------------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 7193bce82f..ee42aa9684 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -24,4 +24,7 @@ void QGCUASParamManager::requestParameterListUpdate(int component) Q_UNUSED(component); } +bool QGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const { + return paramDataModel->getOnboardParameterValue(component,parameter,value); +} diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 130e9a18cb..7f970ef6dc 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -15,27 +15,7 @@ class QGCUASParamManager : public QWidget public: QGCUASParamManager(UASInterface* uas, QWidget *parent = 0); - QList getParameterNames(int component) const { - return onboardParameters.value(component)->keys(); - } - QList getParameterValues(int component) const { - return onboardParameters.value(component)->values(); - } - bool getParameterValue(int component, const QString& parameter, QVariant& value) const { - if (!onboardParameters.contains(component)) - { - return false; - } - - if (!onboardParameters.value(component)->contains(parameter)) - { - return false; - } - - value = onboardParameters.value(component)->value(parameter); - - return true; - } + virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; virtual bool isParamMinKnown(const QString& param) = 0; virtual bool isParamMaxKnown(const QString& param) = 0; @@ -66,7 +46,6 @@ protected: // Parameter data model UASInterface* mav; ///< The MAV this widget is controlling - QMap* > onboardParameters; ///< All parameters UASParameterDataModel* paramDataModel;///< Shared data model of parameters // Communications management -- GitLab From 59a2cbbc858692ccb1369183300d1d43a2cdec91 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 07:43:45 -0700 Subject: [PATCH 157/460] Move more model code into the model class --- src/uas/UASParameterDataModel.cc | 218 +++++++++++++++++++++++++++++-- src/uas/UASParameterDataModel.h | 31 ++++- 2 files changed, 236 insertions(+), 13 deletions(-) diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index dbf4610601..3269efd185 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -1,8 +1,13 @@ #include "UASParameterDataModel.h" +#include + #include +#include #include +#include "QGCMAVLink.h" + UASParameterDataModel::UASParameterDataModel(QObject *parent) : QObject(parent) { @@ -10,21 +15,43 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : } -void UASParameterDataModel::addPendingIfParameterChanged(int componentId, QString& key, QVariant &value) + + +bool UASParameterDataModel::checkParameterChanged(int componentId, const QString& key, const QVariant &value) { + bool changed = true; addComponent(componentId); - QMap *existParams = getOnbardParametersForComponent(componentId); - QMap *pendParams = getPendingParametersForComponent(componentId); + QMap* existParams = getOnbardParametersForComponent(componentId); + + if (existParams->contains(key)) { + QVariant existValue = existParams->value(key); + QMap* pendParams = getPendingParametersForComponent(componentId); + if (pendParams->contains(key)) { + QVariant pendValue = pendParams->value(key); + if (existValue == pendValue) { + changed = false; + } + } + } - QVariant existValue = existParams->value(key); - QVariant pendValue = pendParams->value(key); - if (!(existValue == pendValue)) { + return changed; + +} + +bool UASParameterDataModel::addPendingIfParameterChanged(int componentId, QString& key, QVariant &value) + +{ + bool changed = checkParameterChanged(componentId,key,value); + + if (changed ) { setPendingParameter(componentId,key,value); } + + return changed; } -void UASParameterDataModel::setPendingParameter(int componentId, QString& key, QVariant &value) +void UASParameterDataModel::setPendingParameter(int componentId, QString& key, const QVariant &value) { //ensure we have a placeholder map for this component addComponent(componentId); @@ -32,7 +59,7 @@ void UASParameterDataModel::setPendingParameter(int componentId, QString& key, params->insert(key,value); } -void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, QVariant& value) +void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, const QVariant& value) { //ensure we have a placeholder map for this component addComponent(componentId); @@ -40,6 +67,42 @@ void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, params->insert(key,value); } +void UASParameterDataModel::setOnboardParameterWithType(int componentId, QString& key, QVariant& value) +{ + +// switch ((int)onboardParameters.value(componentId)->value(key).type()) + switch ((int)value.type()) + { + case QVariant::Int: + { + QVariant fixedValue(value.toInt()); + onboardParameters.value(componentId)->insert(key, fixedValue); + } + break; + case QVariant::UInt: + { + QVariant fixedValue(value.toUInt()); + onboardParameters.value(componentId)->insert(key, fixedValue); + } + break; + case QMetaType::Float: + { + QVariant fixedValue(value.toFloat()); + onboardParameters.value(componentId)->insert(key, fixedValue); + } + break; + case QMetaType::QChar: + { + QVariant fixedValue(QChar((unsigned char)value.toUInt())); + onboardParameters.value(componentId)->insert(key, fixedValue); + } + break; + default: + qCritical() << "ABORTED PARAM UPDATE, NO VALID QVARIANT TYPE"; + return; + } +} + void UASParameterDataModel::addComponent(int componentId) { if (!onboardParameters.contains(componentId)) { @@ -70,3 +133,142 @@ void UASParameterDataModel::handleParameterUpdate(int componentId, QString& key, setOnboardParameter(componentId,key, value); } + +bool UASParameterDataModel::getOnboardParameterValue(int componentId, const QString& key, QVariant& value) const +{ + + if (onboardParameters.contains(componentId)) { + if (onboardParameters.value(componentId)->contains(key)) { + value = onboardParameters.value(componentId)->value(key); + return true; + } + } + + return false; +} + +void UASParameterDataModel::forgetAllOnboardParameters() +{ + onboardParameters.clear(); +} + +void UASParameterDataModel::readUpdateParametersFromStream(QTextStream& stream) +{ + + bool userWarned = false; + + while (!stream.atEnd()) { + QString line = stream.readLine(); + if (!line.startsWith("#")) { + QStringList wpParams = line.split("\t"); + int lineMavId = wpParams.at(0).toInt(); + if (wpParams.size() == 5) { + // Only load parameters for right mav + if (!userWarned && (uasId != lineMavId)) { + //TODO warn the user somehow + QString msg = tr("The parameters in the stream have been saved from system %1, but the currently selected system has the ID %2.").arg(lineMavId).arg(uasId); +// MainWindow::instance()->showCriticalMessage( +// tr("Parameter loading warning"), +// tr("The parameters from the file %1 have been saved from system %2, but the currently selected system has the ID %3. If this is unintentional, please click on to revert to the parameters that are currently onboard").arg(fileName).arg(wpParams.at(0).toInt()).arg(mav->getUASID())); + userWarned = true; + return; + } + + bool changed = false; + int componentId = wpParams.at(1).toInt(); + QString key = wpParams.at(2); + QString valStr = wpParams.at(3); + double dblVal = wpParams.at(3).toDouble(); + uint paramType = wpParams.at(4).toUInt(); + + + if (!onboardParameters.contains(componentId)) { + addComponent(componentId); + changed = true; + } + else { + if (fabs((static_cast(onboardParameters.value(componentId)->value(key, dblVal).toDouble())) - (dblVal)) > + 2.0f * FLT_EPSILON) { + changed = true; + qDebug() << "Changed" << key << "VAL" << dblVal; + } + } + + + if (changed) { + switch (paramType) + { + case MAV_PARAM_TYPE_REAL32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toFloat()); + setPendingParameter(componentId,key,QVariant(valStr.toFloat())); + //setParameter(componentId, key, valStr.toFloat()); + break; + case MAV_PARAM_TYPE_UINT32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toUInt()); + setPendingParameter(componentId,key, QVariant(valStr.toUInt())); + //setParameter(componentId, key, QVariant(valStr.toUInt())); + break; + case MAV_PARAM_TYPE_INT32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toInt()); + setPendingParameter(componentId,key,QVariant(valStr.toInt())); + //setParameter(componentId, key, QVariant(valStr.toInt())); + break; + default: + qDebug() << "FAILED LOADING PARAM" << key << "UNKNOWN DATA TYPE"; + } + + //TODO update display + + } + + + } + } + } + +} + +void UASParameterDataModel::writeOnboardParametersToStream(QTextStream& stream, const QString& name) +{ + stream << "# Onboard parameters for system " << name << "\n"; + stream << "#\n"; + stream << "# MAV ID COMPONENT ID PARAM NAME VALUE (FLOAT)\n"; + + // Iterate through all components, through all parameters and emit them + QMap*>::iterator i; + for (i = onboardParameters.begin(); i != onboardParameters.end(); ++i) { + // Iterate through the parameters of the component + int compid = i.key(); + QMap* comp = i.value(); + { + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) + { + QString paramValue("%1"); + QString paramType("%1"); + switch ((int)j.value().type()) + { + case QVariant::Int: + paramValue = paramValue.arg(j.value().toInt()); + paramType = paramType.arg(MAV_PARAM_TYPE_INT32); + break; + case QVariant::UInt: + paramValue = paramValue.arg(j.value().toUInt()); + paramType = paramType.arg(MAV_PARAM_TYPE_UINT32); + break; + case QMetaType::Float: + // We store parameters as floats, with only 6 digits of precision guaranteed for decimal string conversion + // (see IEEE 754, 32 bit single-precision) + paramValue = paramValue.arg((double)j.value().toFloat(), 25, 'g', 6); + paramType = paramType.arg(MAV_PARAM_TYPE_REAL32); + break; + default: + qCritical() << "ABORTED PARAM WRITE TO FILE, NO VALID QVARIANT TYPE" << j.value(); + return; + } + stream << this->uasId << "\t" << compid << "\t" << j.key() << "\t" << paramValue << "\t" << paramType << "\n"; + stream.flush(); + } + } + } +} diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index b3e56b7a74..e38e06c8c4 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -5,6 +5,8 @@ #include #include +class QTextStream; + class UASParameterDataModel : public QObject { Q_OBJECT @@ -15,14 +17,30 @@ public: virtual void addComponent(int componentId); /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ - virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue); - virtual void setOnboardParameter(int componentId, QString& key, QVariant &value); + virtual void setPendingParameter(int componentId, QString& key, const QVariant& value); + virtual void setOnboardParameter(int componentId, QString& key, const QVariant& value); + + /** @brief Save the onboard parameter with a the type specified in the QVariant as fixed */ + virtual void setOnboardParameterWithType(int componentId, QString& key, QVariant& value); + + /** @brief clears every parameter for every loaded component */ + virtual void forgetAllOnboardParameters(); + + /** + * @return true if the parameter has changed + */ + virtual bool checkParameterChanged(int componentId, const QString& key, const QVariant &value); - /** @brief add this parameter to pending list iff it has changed from onboard value */ - virtual void addPendingIfParameterChanged(int componentId, QString& key, QVariant &value); + /** @brief add this parameter to pending list iff it has changed from onboard value + * @return true if the parameter has changed + */ + virtual bool addPendingIfParameterChanged(int componentId, QString& key, QVariant& value); - void handleParameterUpdate(int componentId, QString& key, QVariant& value); + + virtual void handleParameterUpdate(int componentId, QString& key, QVariant& value); + + virtual bool getOnboardParameterValue(int componentId, const QString& key, QVariant& value) const; QMap* getPendingParametersForComponent(int componentId) { return pendingParameters.value(componentId); @@ -41,6 +59,9 @@ public: } + virtual void writeOnboardParametersToStream(QTextStream& stream, const QString& uasName); + virtual void readUpdateParametersFromStream(QTextStream& stream); + void setUASID(int anId) { this->uasId = anId; } signals: -- GitLab From defc1e034ea60c14b346c85b5ede72bb52342e85 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 07:52:25 -0700 Subject: [PATCH 158/460] cleanupt paramInfo (tooltips) --- src/ui/QGCParamWidget.cc | 244 +++++++++------------------------------ src/ui/QGCParamWidget.h | 4 +- 2 files changed, 55 insertions(+), 193 deletions(-) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 0e415d8bd9..07c948457b 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -165,6 +165,15 @@ void QGCParamWidget::loadSettings() settings.endGroup(); } + +void QGCParamWidget::setParamInfo(const QMap& paramInfo) { + if (paramInfo.isEmpty()) { + qDebug() << << __FILE__ << ":" << __LINE__ << "setParamInfo with empty"; + } + paramToolTips = paramInfo; +} + + void QGCParamWidget::loadParameterInfoCSV(const QString& autopilot, const QString& airframe) { Q_UNUSED(airframe); @@ -331,15 +340,10 @@ void QGCParamWidget::addComponent(int uas, int component, QString componentName) paramGroups.insert(component, new QMap()); tree->addTopLevelItem(comp); tree->update(); - // Create map in parameters - if (!onboardParameters.contains(component)) { - onboardParameters.insert(component, new QMap()); - } -// // Create map in changed parameters -// if (!changedValues.contains(component)) { -// changedValues.insert(component, new QMap()); -// } } + + paramDataModel->addComponent(component); + } /** @@ -496,7 +500,7 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCo */ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value) { - //qDebug() << "PARAM WIDGET GOT PARAM:" << value; + qDebug() << "PARAM WIDGET GOT PARAM:" << parameterName; Q_UNUSED(uas); // Reference to item in tree QTreeWidgetItem* parameterItem = NULL; @@ -523,9 +527,7 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString par // Replace value in map - // FIXME - if (onboardParameters.value(component)->contains(parameterName)) onboardParameters.value(component)->remove(parameterName); - onboardParameters.value(component)->insert(parameterName, value); + paramDataModel->setOnboardParameter(component,parameterName,value); QString splitToken = "_"; @@ -656,7 +658,7 @@ void QGCParamWidget::requestParameterList() // Clear view and request param list clear(); - onboardParameters.clear(); + paramDataModel->forgetAllOnboardParameters(); received.clear(); // Clear transmission state transmissionListMode = true; @@ -681,69 +683,34 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) parent = parent->parent(); } // Parent is now top-level component - int key = components->key(parent); + int componentId = components->key(parent); - //ensure we have a placeholder map for this component - QMap *> changedValues = this->paramDataModel->getPendingParameters(); - if (!changedValues.contains(key)) { - changedValues.insert(key, new QMap()); - } + QString key = current->data(0, Qt::DisplayRole).toString(); + QVariant value = current->data(1, Qt::DisplayRole); + // Set parameter on changed list to be transmitted to MAV + QPalette pal = statusLabel->palette(); + pal.setColor(backgroundRole(), QGC::colorOrange); + statusLabel->setPalette(pal); + statusLabel->setText(tr("Transmit pend. %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); + //qDebug() << "PARAM CHANGED: COMP:" << key << "KEY:" << str << "VALUE:" << value; + // Changed values list - //insert the changed value into the map - QMap* map = changedValues.value(key, NULL); - if (map) { - QString str = current->data(0, Qt::DisplayRole).toString(); - QVariant value = current->data(1, Qt::DisplayRole); - // Set parameter on changed list to be transmitted to MAV - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorOrange); - statusLabel->setPalette(pal); - statusLabel->setText(tr("Transmit pend. %1:%2: %3").arg(key).arg(str).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); - //qDebug() << "PARAM CHANGED: COMP:" << key << "KEY:" << str << "VALUE:" << value; - // Changed values list - if (map->contains(str)) map->remove(str); - map->insert(str, value); - - // Check if the value was numerically changed - if (!onboardParameters.value(key)->contains(str) || onboardParameters.value(key)->value(str, value.toDouble()-1) != value) { - current->setBackground(0, QBrush(QColor(QGC::colorOrange))); - current->setBackground(1, QBrush(QColor(QGC::colorOrange))); - } + bool changed = paramDataModel->addPendingIfParameterChanged(componentId,key,value); - switch ((int)onboardParameters.value(key)->value(str).type()) - { - case QVariant::Int: - { - QVariant fixedValue(value.toInt()); - onboardParameters.value(key)->insert(str, fixedValue); - } - break; - case QVariant::UInt: - { - QVariant fixedValue(value.toUInt()); - onboardParameters.value(key)->insert(str, fixedValue); - } - break; - case QMetaType::Float: - { - QVariant fixedValue(value.toFloat()); - onboardParameters.value(key)->insert(str, fixedValue); - } - break; - case QMetaType::QChar: - { - QVariant fixedValue(QChar((unsigned char)value.toUInt())); - onboardParameters.value(key)->insert(str, fixedValue); - } - break; - default: - qCritical() << "ABORTED PARAM UPDATE, NO VALID QVARIANT TYPE"; - return; - } + // If the value was numerically changed, display it differently + if (changed) { + current->setBackground(0, QBrush(QColor(QGC::colorOrange))); + current->setBackground(1, QBrush(QColor(QGC::colorOrange))); + + //TODO this seems incorrect-- we're pre-updating the onboard value before we've received confirmation + paramDataModel->setOnboardParameterWithType(componentId,key,value); } + } } + + void QGCParamWidget::saveParametersToFile() { if (!mav) return; @@ -753,92 +720,12 @@ void QGCParamWidget::saveParametersToFile() return; } - QTextStream in(&file); - - in << "# Onboard parameters for system " << mav->getUASName() << "\n"; - in << "#\n"; - in << "# MAV ID COMPONENT ID PARAM NAME VALUE (FLOAT)\n"; - - // Iterate through all components, through all parameters and emit them - QMap*>::iterator i; - for (i = onboardParameters.begin(); i != onboardParameters.end(); ++i) { - // Iterate through the parameters of the component - int compid = i.key(); - QMap* comp = i.value(); - { - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) - { - QString paramValue("%1"); - QString paramType("%1"); - switch ((int)j.value().type()) - { - case QVariant::Int: - paramValue = paramValue.arg(j.value().toInt()); - paramType = paramType.arg(MAV_PARAM_TYPE_INT32); - break; - case QVariant::UInt: - paramValue = paramValue.arg(j.value().toUInt()); - paramType = paramType.arg(MAV_PARAM_TYPE_UINT32); - break; - case QMetaType::Float: - // We store parameters as floats, with only 6 digits of precision guaranteed for decimal string conversion - // (see IEEE 754, 32 bit single-precision) - paramValue = paramValue.arg((double)j.value().toFloat(), 25, 'g', 6); - paramType = paramType.arg(MAV_PARAM_TYPE_REAL32); - break; - default: - qCritical() << "ABORTED PARAM WRITE TO FILE, NO VALID QVARIANT TYPE" << j.value(); - return; - } - in << mav->getUASID() << "\t" << compid << "\t" << j.key() << "\t" << paramValue << "\t" << paramType << "\n"; - in.flush(); - } - } - } + QTextStream outstream(&file); + paramDataModel->writeOnboardParametersToStream(outstream,mav->getUASName()); file.close(); } -void QGCParamWidget::loadedParameterForComponent(int componentId, QStringList& wpParams ) -{ - // Set parameter value - - QMap *> changedValues = this->paramDataModel->getPendingParameters(); - - // Create changed values data structure if necessary - if (!changedValues.contains(componentId)) { - changedValues.insert(componentId, new QMap()); - } - - // Add to changed values - if (changedValues.value(componentId)->contains(wpParams.at(2))) { - changedValues.value(componentId)->remove(wpParams.at(2)); - } - - switch (wpParams.at(4).toUInt()) - { - case (int)MAV_PARAM_TYPE_REAL32: - //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toFloat()); - changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toFloat()); - setParameter(componentId, wpParams.at(2), wpParams.at(3).toFloat()); - break; - case (int)MAV_PARAM_TYPE_UINT32: - //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toUInt()); - changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toUInt()); - setParameter(componentId, wpParams.at(2), QVariant(wpParams.at(3).toUInt())); - break; - case (int)MAV_PARAM_TYPE_INT32: - //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toInt()); - changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toInt()); - setParameter(componentId, wpParams.at(2), QVariant(wpParams.at(3).toInt())); - break; - default: - qDebug() << "FAILED LOADING PARAM" << wpParams.at(2) << "NO KNOWN DATA TYPE"; - } - -} - void QGCParamWidget::loadParametersFromFile() { if (!mav) return; @@ -847,36 +734,8 @@ void QGCParamWidget::loadParametersFromFile() if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return; - bool userWarned = false; - QTextStream in(&file); - while (!in.atEnd()) { - QString line = in.readLine(); - if (!line.startsWith("#")) { - QStringList wpParams = line.split("\t"); - if (wpParams.size() == 5) { - // Only load parameters for right mav - if (!userWarned && (mav->getUASID() != wpParams.at(0).toInt())) { - MainWindow::instance()->showCriticalMessage(tr("Parameter loading warning"), tr("The parameters from the file %1 have been saved from system %2, but the currently selected system has the ID %3. If this is unintentional, please click on to revert to the parameters that are currently onboard").arg(fileName).arg(wpParams.at(0).toInt()).arg(mav->getUASID())); - userWarned = true; - } - - bool changed = false; - int componentId = wpParams.at(1).toInt(); - QString parameterName = wpParams.at(2); - if (!onboardParameters.contains(componentId) || - fabs((static_cast(onboardParameters.value(componentId)->value(parameterName, wpParams.at(3).toDouble()).toDouble())) - (wpParams.at(3).toDouble())) > 2.0f * FLT_EPSILON) { - changed = true; - qDebug() << "Changed" << parameterName << "VAL" << wpParams.at(3).toDouble(); - } - - if (changed) { - loadedParameterForComponent(componentId,wpParams); - } - - } - } - } + paramDataModel->readUpdateParametersFromStream(in); file.close(); } @@ -930,7 +789,8 @@ void QGCParamWidget::retransmissionGuardTick() // Re-request at maximum retransmissionBurstRequestSize parameters at once // to prevent link flooding QMap*>::iterator i; - for (i = onboardParameters.begin(); i != onboardParameters.end(); ++i) { + QMap*> onboardParams = paramDataModel->getOnboardParameters(); + for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { // Iterate through the parameters of the component int component = i.key(); // Request n parameters from this component (at maximum) @@ -961,7 +821,7 @@ void QGCParamWidget::retransmissionGuardTick() if (count < retransmissionBurstRequestSize) { // Re-request write operation QVariant value = missingParams->value(key); - switch ((int)onboardParameters.value(component)->value(key).type()) + switch ((int)onboardParams.value(component)->value(key).type()) { case QVariant::Int: { @@ -1015,23 +875,27 @@ void QGCParamWidget::requestParameterUpdate(int component, const QString& parame */ void QGCParamWidget::setParameter(int component, QString parameterName, QVariant value) { - if (paramMin.contains(parameterName) && value.toDouble() < paramMin.value(parameterName)) + double dblValue = value.toDouble(); + if (paramMin.contains(parameterName) && dblValue < paramMin.value(parameterName)) { - statusLabel->setText(tr("REJ. %1 < min").arg(value.toDouble())); + statusLabel->setText(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); return; } - if (paramMax.contains(parameterName) && value.toDouble() > paramMax.value(parameterName)) + if (paramMax.contains(parameterName) && dblValue > paramMax.value(parameterName)) { - statusLabel->setText(tr("REJ. %1 > max").arg(value.toDouble())); + statusLabel->setText(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); return; } - if (onboardParameters.value(component)->value(parameterName) == value) - { - statusLabel->setText(tr("REJ. %1 > max").arg(value.toDouble())); + QVariant onboardVal; + paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); + if (onboardVal == value) { + statusLabel->setText(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue)); return; } - switch ((int)onboardParameters.value(component)->value(parameterName).type()) + //int paramType = (int)onboardParameters.value(component)->value(parameterName).type(); + int paramType = (int)value.type(); + switch (paramType) { case QVariant::Char: { diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 5b48fffb22..0b810bc5bd 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -58,7 +58,7 @@ public: double getParamMax(const QString& param) { return paramMax.value(param, 0.0f); } double getParamDefault(const QString& param) { return paramDefault.value(param, 0.0f); } QString getParamInfo(const QString& param) { return paramToolTips.value(param, ""); } - void setParamInfo(const QMap& param) { paramToolTips = param; } + void setParamInfo(const QMap& paramInfo); signals: /** @brief A parameter was changed in the widget, NOT onboard */ @@ -96,8 +96,6 @@ public slots: /** @brief Load parameters from a file */ void loadParametersFromFile(); - void loadedParameterForComponent(int componentId, QStringList& wpParams ); - /** @brief Check for missing parameters */ void retransmissionGuardTick(); -- GitLab From 8d98abe2102185dbf33330a96d674e9be5aa0ccf Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 07:54:25 -0700 Subject: [PATCH 159/460] fix debug str --- src/ui/QGCParamWidget.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 07c948457b..95b58eadd1 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -168,7 +168,7 @@ void QGCParamWidget::loadSettings() void QGCParamWidget::setParamInfo(const QMap& paramInfo) { if (paramInfo.isEmpty()) { - qDebug() << << __FILE__ << ":" << __LINE__ << "setParamInfo with empty"; + qDebug() << __FILE__ << ":" << __LINE__ << "setParamInfo with empty"; } paramToolTips = paramInfo; } -- GitLab From 9f17108e03b4aa4381ed485e0689766ccac0c129 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 08:05:47 -0700 Subject: [PATCH 160/460] ignoring UAS updates while slider has no param name --- src/ui/designer/QGCParamSlider.cc | 42 +++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/ui/designer/QGCParamSlider.cc b/src/ui/designer/QGCParamSlider.cc index edba2c78cd..6733c5790a 100644 --- a/src/ui/designer/QGCParamSlider.cc +++ b/src/ui/designer/QGCParamSlider.cc @@ -92,29 +92,29 @@ void QGCParamSlider::refreshParamList() void QGCParamSlider::setActiveUAS(UASInterface* activeUas) { - if (activeUas) - { - if (uas) - { - disconnect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant))); - } - - // Connect buttons and signals - connect(activeUas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant)), Qt::UniqueConnection); - uas = activeUas; - // Update current param value - //requestParameter(); + if (activeUas) { // Set param info - QString text = uas->getParamManager()->getParamInfo(parameterName); - if (text != "") - { - ui->infoLabel->setToolTip(text); - ui->infoLabel->show(); + if (!parameterName.isEmpty()) { + //disconnect from any existing uas signals + if (uas != activeUas) { + disconnect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant))); + connect(activeUas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant)), Qt::UniqueConnection); + uas = activeUas; + } + + QString text = uas->getParamManager()->getParamInfo(parameterName); + if (text != "") { + ui->infoLabel->setToolTip(text); + ui->infoLabel->show(); + } + // Force-uncheck and hide label if no description is available + if (ui->editInfoCheckBox->isChecked()) { + showInfo((text.length() > 0)); + } } - // Force-uncheck and hide label if no description is available - if (ui->editInfoCheckBox->isChecked()) - { - showInfo((text.length() > 0)); + else { + //when parameter widgets are first loaded, they are disconnected from any parameter? + qWarning() << __FILE__ << ":" << __LINE__ << "slider has no parameterName??"; } } } -- GitLab From a4b6d92f371bdf498e56d093179cac2fbe2d11cf Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 08:45:59 -0700 Subject: [PATCH 161/460] Refactoring comms code --- src/uas/QGCUASParamManager.cc | 154 ++++++++++++++++ src/uas/QGCUASParamManager.h | 16 +- src/ui/QGCParamWidget.cc | 324 +++++++++++----------------------- src/ui/QGCParamWidget.h | 16 +- 4 files changed, 278 insertions(+), 232 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index ee42aa9684..2bbe1fb610 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -28,3 +28,157 @@ bool QGCUASParamManager::getParameterValue(int component, const QString& paramet return paramDataModel->getOnboardParameterValue(component,parameter,value); } + + + + +/** + * Send a request to deliver the list of onboard parameters + * to the MAV. + */ +void QGCUASParamManager::requestParameterList() +{ + if (!mav) { + return; + } + + paramDataModel->forgetAllOnboardParameters(); + received.clear(); + // Clear transmission state + transmissionListMode = true; + transmissionListSizeKnown.clear(); + foreach (int key, transmissionMissingPackets.keys()) + { + transmissionMissingPackets.value(key)->clear(); + } + transmissionActive = true; + + setParameterStatusMsg(tr("Requested param list.. waiting")); + mav->requestParameters(); + +} + + +/** + * Enabling the retransmission guard enables the parameter widget to track + * dropped parameters and to re-request them. This works for both individual + * parameter reads as well for whole list requests. + * + * @param enabled True if retransmission checking should be enabled, false else + */ +void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) +{ + if (enabled) { + retransmissionTimer.start(retransmissionTimeout); + } else { + retransmissionTimer.stop(); + } +} + +void QGCUASParamManager::setParameterStatusMsg(const QString& msg) +{ + parameterStatusMsg = msg; +} + +void QGCUASParamManager::retransmissionGuardTick() +{ + if (transmissionActive) { + //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; + + // Check for timeout + // stop retransmission attempts on timeout + if (QGC::groundTimeMilliseconds() > transmissionTimeout) { + setRetransmissionGuardEnabled(false); + transmissionActive = false; + + // Empty read retransmission list + // Empty write retransmission list + int missingReadCount = 0; + QList readKeys = transmissionMissingPackets.keys(); + foreach (int component, readKeys) { + missingReadCount += transmissionMissingPackets.value(component)->count(); + transmissionMissingPackets.value(component)->clear(); + } + + // Empty write retransmission list + int missingWriteCount = 0; + QList writeKeys = transmissionMissingWriteAckPackets.keys(); + foreach (int component, writeKeys) { + missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); + transmissionMissingWriteAckPackets.value(component)->clear(); + } + setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); + } + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent link flooding + QMap*>::iterator i; + QMap*> onboardParams = paramDataModel->getOnboardParameters(); + for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { + // Iterate through the parameters of the component + int component = i.key(); + // Request n parameters from this component (at maximum) + QList * paramList = transmissionMissingPackets.value(component, NULL); + if (paramList) { + int count = 0; + foreach (int id, *paramList) { + if (count < retransmissionBurstRequestSize) { + //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; + //TODO mavlink msg type for "request parameter set" ? + emit requestParameter(component, id); + setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); + count++; + } else { + break; + } + } + } + } + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent write-request link flooding + // Empty write retransmission list + QList writeKeys = transmissionMissingWriteAckPackets.keys(); + foreach (int component, writeKeys) { + int count = 0; + QMap * missingParams = transmissionMissingWriteAckPackets.value(component); + foreach (QString key, missingParams->keys()) { + if (count < retransmissionBurstRequestSize) { + // Re-request write operation + QVariant value = missingParams->value(key); + switch ((int)onboardParams.value(component)->value(key).type()) + { + case QVariant::Int: + { + QVariant fixedValue(value.toInt()); + emit parameterChanged(component, key, fixedValue); + } + break; + case QVariant::UInt: + { + QVariant fixedValue(value.toUInt()); + emit parameterChanged(component, key, fixedValue); + } + break; + case QMetaType::Float: + { + QVariant fixedValue(value.toFloat()); + emit parameterChanged(component, key, fixedValue); + } + break; + default: + //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; + return; + } + setParameterStatusMsg(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); + count++; + } else { + break; + } + } + } + } else { + //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; + setRetransmissionGuardEnabled(false); + } +} diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 7f970ef6dc..c6351a6c38 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -31,16 +31,29 @@ public: /** @brief Request an update for this specific parameter */ virtual void requestParameterUpdate(int component, const QString& parameter) = 0; +protected: + /** @brief Check for missing parameters */ + virtual void retransmissionGuardTick(); + /** @brief Activate / deactivate parameter retransmission */ + virtual void setRetransmissionGuardEnabled(bool enabled); + + //TODO decouple this UI message display further + virtual void setParameterStatusMsg(const QString& msg); + signals: void parameterChanged(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); void parameterListUpToDate(int component); + /** @brief Request a single parameter */ + void requestParameter(int component, int parameter); + /** @brief Request a single parameter by name */ + void requestParameter(int component, const QString& parameter); public slots: /** @brief Write one parameter to the MAV */ virtual void setParameter(int component, QString parameterName, QVariant value) = 0; /** @brief Request list of parameters from MAV */ - virtual void requestParameterList() = 0; + virtual void requestParameterList(); protected: @@ -60,6 +73,7 @@ protected: int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds int rewriteTimeout; ///< Write request timeout, in milliseconds int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst + QString parameterStatusMsg; }; diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 95b58eadd1..40fc49195a 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -87,7 +87,7 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QPushButton* refreshButton = new QPushButton(tr("Get")); refreshButton->setToolTip(tr("Load parameters currently in non-permanent memory of aircraft.")); refreshButton->setWhatsThis(tr("Load parameters currently in non-permanent memory of aircraft.")); - connect(refreshButton, SIGNAL(clicked()), this, SLOT(requestParameterList())); + connect(refreshButton, SIGNAL(clicked()), this, SLOT(requestParameterListUpdate())); horizontalLayout->addWidget(refreshButton, 2, 0); QPushButton* setButton = new QPushButton(tr("Set")); @@ -150,9 +150,12 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); // Get parameters - if (uas) requestParameterList(); + if (uas) { + requestParameterListUpdate(); + } } + void QGCParamWidget::loadSettings() { QSettings settings; @@ -642,38 +645,7 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString par } -/** - * Send a request to deliver the list of onboard parameters - * to the MAV. - */ -void QGCParamWidget::requestParameterList() -{ - if (!mav) return; - // FIXME This call does not belong here - // Once the comm handling is moved to a new - // Param manager class the settings can be directly - // loaded from MAVLink protocol - loadSettings(); - // End of FIXME - - // Clear view and request param list - clear(); - paramDataModel->forgetAllOnboardParameters(); - received.clear(); - // Clear transmission state - transmissionListMode = true; - transmissionListSizeKnown.clear(); - foreach (int key, transmissionMissingPackets.keys()) - { - transmissionMissingPackets.value(key)->clear(); - } - transmissionActive = true; - - // Set status text - statusLabel->setText(tr("Requested param list.. waiting")); - mav->requestParameters(); -} void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) { @@ -740,133 +712,122 @@ void QGCParamWidget::loadParametersFromFile() } -/** - * Enabling the retransmission guard enables the parameter widget to track - * dropped parameters and to re-request them. This works for both individual - * parameter reads as well for whole list requests. - * - * @param enabled True if retransmission checking should be enabled, false else - */ -void QGCParamWidget::setRetransmissionGuardEnabled(bool enabled) +void QGCParamWidget::setParameterStatusMsg(const QString& msg) { - if (enabled) { - retransmissionTimer.start(retransmissionTimeout); - } else { - retransmissionTimer.stop(); + statusLabel->setText(msg); +} + + + +void QGCParamWidget::requestParameterListUpdate() +{ + if (!mav) { + return; } + + // FIXME This call does not belong here + // Once the comm handling is moved to a new + // Param manager class the settings can be directly + // loaded from MAVLink protocol + loadSettings(); + // End of FIXME + + // Clear view and request param list + clear(); + + requestParameterList(); } -void QGCParamWidget::retransmissionGuardTick() +/** + * The .. signal is emitted + */ +void QGCParamWidget::requestParameterUpdate(int component, const QString& parameter) { - if (transmissionActive) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; - - // Check for timeout - // stop retransmission attempts on timeout - if (QGC::groundTimeMilliseconds() > transmissionTimeout) { - setRetransmissionGuardEnabled(false); - transmissionActive = false; - - // Empty read retransmission list - // Empty write retransmission list - int missingReadCount = 0; - QList readKeys = transmissionMissingPackets.keys(); - foreach (int component, readKeys) { - missingReadCount += transmissionMissingPackets.value(component)->count(); - transmissionMissingPackets.value(component)->clear(); - } + if (mav) mav->requestParameter(component, parameter); +} - // Empty write retransmission list - int missingWriteCount = 0; - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); - transmissionMissingWriteAckPackets.value(component)->clear(); - } - statusLabel->setText(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); - } - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent link flooding - QMap*>::iterator i; - QMap*> onboardParams = paramDataModel->getOnboardParameters(); - for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { - // Iterate through the parameters of the component - int component = i.key(); - // Request n parameters from this component (at maximum) - QList * paramList = transmissionMissingPackets.value(component, NULL); - if (paramList) { - int count = 0; - foreach (int id, *paramList) { - if (count < retransmissionBurstRequestSize) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; - emit requestParameter(component, id); - statusLabel->setText(tr("Requested retransmission of #%1").arg(id+1)); - count++; - } else { - break; - } - } + +/** + * Set all parameter in the parameter tree on the MAV + */ +void QGCParamWidget::setParameters() +{ + // Iterate through all components, through all parameters and emit them + int parametersSent = 0; + QMap*> changedValues = paramDataModel->getPendingParameters(); + QMap*>::iterator i; + for (i = changedValues.begin(); i != changedValues.end(); ++i) { + // Iterate through the parameters of the component + int compid = i.key(); + QMap* comp = i.value(); + { + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) { + setParameter(compid, j.key(), j.value()); + parametersSent++; } } + } - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent write-request link flooding - // Empty write retransmission list - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - int count = 0; - QMap * missingParams = transmissionMissingWriteAckPackets.value(component); - foreach (QString key, missingParams->keys()) { - if (count < retransmissionBurstRequestSize) { - // Re-request write operation - QVariant value = missingParams->value(key); - switch ((int)onboardParams.value(component)->value(key).type()) - { - case QVariant::Int: - { - QVariant fixedValue(value.toInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QVariant::UInt: - { - QVariant fixedValue(value.toUInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QMetaType::Float: - { - QVariant fixedValue(value.toFloat()); - emit parameterChanged(component, key, fixedValue); - } - break; - default: - //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; - return; - } - statusLabel->setText(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); - count++; - } else { - break; - } + // Change transmission status if necessary + if (parametersSent == 0) { + statusLabel->setText(tr("No transmission: No changed values.")); + } else { + statusLabel->setText(tr("Transmitting %1 parameters.").arg(parametersSent)); + // Set timeouts + if (transmissionActive) + { + transmissionTimeout += parametersSent*rewriteTimeout; + } + else + { + transmissionActive = true; + quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + parametersSent*rewriteTimeout; + if (newTransmissionTimeout > transmissionTimeout) { + transmissionTimeout = newTransmissionTimeout; } } - } else { - //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; - setRetransmissionGuardEnabled(false); + // Enable guard + setRetransmissionGuardEnabled(true); } } - /** - * The .. signal is emitted + * Write the current onboard parameters from RAM into + * permanent storage, e.g. EEPROM or harddisk */ -void QGCParamWidget::requestParameterUpdate(int component, const QString& parameter) +void QGCParamWidget::writeParameters() { - if (mav) mav->requestParameter(component, parameter); -} + int changedParamCount = 0; + + QMap*>::iterator i; + QMap*> changedValues = paramDataModel->getPendingParameters(); + + for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) + { + // Iterate through the parameters of the component + QMap* comp = i.value(); + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) + { + changedParamCount++; + break;//it only takes one changed param to warrant warning the user + } + } + if (changedParamCount > 0) + { + QMessageBox msgBox; + msgBox.setText(tr("There are locally changed parameters. Please transmit them first () or update them with the onboard values () before storing onboard from RAM to ROM.")); + msgBox.exec(); + } + else + { + if (!mav) return; + mav->writeParametersToStorage(); + } +} /** * @param component the subsystem which has the parameter @@ -959,87 +920,6 @@ void QGCParamWidget::setParameter(int component, QString parameterName, QVariant setRetransmissionGuardEnabled(true); } -/** - * Set all parameter in the parameter tree on the MAV - */ -void QGCParamWidget::setParameters() -{ - // Iterate through all components, through all parameters and emit them - int parametersSent = 0; - QMap*> changedValues = paramDataModel->getPendingParameters(); - QMap*>::iterator i; - for (i = changedValues.begin(); i != changedValues.end(); ++i) { - // Iterate through the parameters of the component - int compid = i.key(); - QMap* comp = i.value(); - { - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) { - setParameter(compid, j.key(), j.value()); - parametersSent++; - } - } - } - - // Change transmission status if necessary - if (parametersSent == 0) { - statusLabel->setText(tr("No transmission: No changed values.")); - } else { - statusLabel->setText(tr("Transmitting %1 parameters.").arg(parametersSent)); - // Set timeouts - if (transmissionActive) - { - transmissionTimeout += parametersSent*rewriteTimeout; - } - else - { - transmissionActive = true; - quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + parametersSent*rewriteTimeout; - if (newTransmissionTimeout > transmissionTimeout) { - transmissionTimeout = newTransmissionTimeout; - } - } - // Enable guard - setRetransmissionGuardEnabled(true); - } -} - -/** - * Write the current onboard parameters from RAM into - * permanent storage, e.g. EEPROM or harddisk - */ -void QGCParamWidget::writeParameters() -{ - int changedParamCount = 0; - - QMap*>::iterator i; - QMap*> changedValues = paramDataModel->getPendingParameters(); - - for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) - { - // Iterate through the parameters of the component - QMap* comp = i.value(); - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) - { - changedParamCount++; - break;//it only takes one changed param to warrant warning the user - } - } - - if (changedParamCount > 0) - { - QMessageBox msgBox; - msgBox.setText(tr("There are locally changed parameters. Please transmit them first () or update them with the onboard values () before storing onboard from RAM to ROM.")); - msgBox.exec(); - } - else - { - if (!mav) return; - mav->writeParametersToStorage(); - } -} - void QGCParamWidget::readParameters() { if (!mav) return; diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 0b810bc5bd..c49f5a55cb 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -60,13 +60,13 @@ public: QString getParamInfo(const QString& param) { return paramToolTips.value(param, ""); } void setParamInfo(const QMap& paramInfo); +protected: + virtual void setParameterStatusMsg(const QString& msg); + signals: /** @brief A parameter was changed in the widget, NOT onboard */ //void parameterChanged(int component, QString parametername, float value); // defined in QGCUASParamManager already - /** @brief Request a single parameter */ - void requestParameter(int component, int parameter); - /** @brief Request a single parameter by name */ - void requestParameter(int component, const QString& parameter); + public slots: /** @brief Add a component to the list */ void addComponent(int uas, int component, QString componentName); @@ -75,7 +75,7 @@ public slots: /** @brief Add a parameter to the list */ void receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ - void requestParameterList(); + void requestParameterListUpdate(); /** @brief Request one single parameter */ void requestParameterUpdate(int component, const QString& parameter); /** @brief Set one parameter, changes value in RAM of MAV */ @@ -96,8 +96,7 @@ public slots: /** @brief Load parameters from a file */ void loadParametersFromFile(); - /** @brief Check for missing parameters */ - void retransmissionGuardTick(); + protected: QTreeWidget* tree; ///< The parameter tree @@ -112,8 +111,7 @@ protected: QMap paramDefault; ///< Default param values QMap paramMax; ///< Minimum param values - /** @brief Activate / deactivate parameter retransmission */ - void setRetransmissionGuardEnabled(bool enabled); + /** @brief Load settings */ void loadSettings(); /** @brief Load meta information from CSV */ -- GitLab From a3dc2fb6a7102cdaad0683572c4039407f0cf872 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 08:54:27 -0700 Subject: [PATCH 162/460] more comms refactoring --- src/uas/QGCUASParamManager.cc | 6 ++++-- src/uas/QGCUASParamManager.h | 2 +- src/ui/QGCParamWidget.cc | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 2bbe1fb610..af62e3916e 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -43,10 +43,12 @@ void QGCUASParamManager::requestParameterList() } paramDataModel->forgetAllOnboardParameters(); - received.clear(); + // Clear transmission state - transmissionListMode = true; + receivedParamsList.clear(); transmissionListSizeKnown.clear(); + + transmissionListMode = true; foreach (int key, transmissionMissingPackets.keys()) { transmissionMissingPackets.value(key)->clear(); diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index c6351a6c38..f16be9f7b2 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -62,7 +62,7 @@ protected: UASParameterDataModel* paramDataModel;///< Shared data model of parameters // Communications management - QVector received; ///< Successfully received parameters + QVector receivedParamsList; ///< Successfully received parameters QMap* > transmissionMissingPackets; ///< Missing packets QMap* > transmissionMissingWriteAckPackets; ///< Missing write ACK packets bool transmissionListMode; ///< Currently requesting list diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 40fc49195a..1cb641fdde 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -764,6 +764,7 @@ void QGCParamWidget::setParameters() { QMap::iterator j; for (j = comp->begin(); j != comp->end(); ++j) { + //TODO mavlink command for "set parameter list" ? setParameter(compid, j.key(), j.value()); parametersSent++; } -- GitLab From 714a00981236e3ec40814518c28a629b117f35f5 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 10:25:33 -0700 Subject: [PATCH 163/460] move parameter meta info into param data model --- src/uas/QGCUASParamManager.cc | 8 +- src/uas/QGCUASParamManager.h | 12 +-- src/uas/UASParameterDataModel.cc | 144 ++++++++++++++++++++++++++++- src/uas/UASParameterDataModel.h | 29 +++++- src/ui/QGCPX4VehicleConfig.cc | 4 +- src/ui/QGCParamWidget.cc | 146 ++++-------------------------- src/ui/QGCParamWidget.h | 17 +--- src/ui/QGCVehicleConfig.cc | 4 +- src/ui/designer/QGCComboBox.cc | 31 +++---- src/ui/designer/QGCParamSlider.cc | 30 ++---- 10 files changed, 225 insertions(+), 200 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index af62e3916e..06774ec25d 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -11,8 +11,8 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : rewriteTimeout(500), retransmissionBurstRequestSize(5) { - uas->setParamManager(this); paramDataModel = uas->getParamDataModel(); + uas->setParamManager(this); } @@ -82,6 +82,12 @@ void QGCUASParamManager::setParameterStatusMsg(const QString& msg) parameterStatusMsg = msg; } +void QGCUASParamManager::setParamDescriptions(const QMap& paramInfo) { + paramDataModel->setParamDescriptions(paramInfo); +} + + + void QGCUASParamManager::retransmissionGuardTick() { if (transmissionActive) { diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index f16be9f7b2..2a0165959a 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -17,20 +17,14 @@ public: virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; - virtual bool isParamMinKnown(const QString& param) = 0; - virtual bool isParamMaxKnown(const QString& param) = 0; - virtual bool isParamDefaultKnown(const QString& param) = 0; - virtual double getParamMin(const QString& param) = 0; - virtual double getParamMax(const QString& param) = 0; - virtual double getParamDefault(const QString& param) = 0; - virtual QString getParamInfo(const QString& param) = 0; - virtual void setParamInfo(const QMap& param) = 0; - /** @brief Request an update for the parameter list */ void requestParameterListUpdate(int component = 0); /** @brief Request an update for this specific parameter */ virtual void requestParameterUpdate(int component, const QString& parameter) = 0; + /** @brief Provide tooltips / user-visible descriptions for parameters */ + virtual void setParamDescriptions(const QMap& paramDescs); + protected: /** @brief Check for missing parameters */ virtual void retransmissionGuardTick(); diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 3269efd185..d678385dcf 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -152,7 +152,7 @@ void UASParameterDataModel::forgetAllOnboardParameters() onboardParameters.clear(); } -void UASParameterDataModel::readUpdateParametersFromStream(QTextStream& stream) +void UASParameterDataModel::readUpdateParametersFromStream( QTextStream& stream) { bool userWarned = false; @@ -228,7 +228,7 @@ void UASParameterDataModel::readUpdateParametersFromStream(QTextStream& stream) } -void UASParameterDataModel::writeOnboardParametersToStream(QTextStream& stream, const QString& name) +void UASParameterDataModel::writeOnboardParametersToStream( QTextStream &stream, const QString& name) { stream << "# Onboard parameters for system " << name << "\n"; stream << "#\n"; @@ -272,3 +272,143 @@ void UASParameterDataModel::writeOnboardParametersToStream(QTextStream& stream, } } } + + +void UASParameterDataModel::loadParamMetaInfoFromStream(QTextStream& stream) +{ + + // First line is header + // there might be more lines, but the first + // line is assumed to be at least header + QString header = stream.readLine(); + + // Ignore top-level comment lines + while (header.startsWith('#') || header.startsWith('/') + || header.startsWith('=') || header.startsWith('^')) + { + header = stream.readLine(); + } + + bool charRead = false; + QString separator = ""; + QList sepCandidates; + sepCandidates << '\t'; + sepCandidates << ','; + sepCandidates << ';'; + //sepCandidates << ' '; + sepCandidates << '~'; + sepCandidates << '|'; + + // Iterate until separator is found + // or full header is parsed + for (int i = 0; i < header.length(); i++) + { + if (sepCandidates.contains(header.at(i))) + { + // Separator found + if (charRead) + { + separator += header[i]; + } + } + else + { + // Char found + charRead = true; + // If the separator is not empty, this char + // has been read after a separator, so detection + // is now complete + if (separator != "") break; + } + } + + bool stripFirstSeparator = false; + bool stripLastSeparator = false; + + // Figure out if the lines start with the separator (e.g. wiki syntax) + if (header.startsWith(separator)) stripFirstSeparator = true; + + // Figure out if the lines end with the separator (e.g. wiki syntax) + if (header.endsWith(separator)) stripLastSeparator = true; + + QString out = separator; + out.replace("\t", ""); + //qDebug() << " Separator: \"" << out << "\""; + //qDebug() << "READING CSV:" << header; + + + // Read data + while (!stream.atEnd()) + { + QString line = stream.readLine(); + + //qDebug() << "LINE PRE-STRIP" << line; + + // Strip separtors if necessary + if (stripFirstSeparator) line.remove(0, separator.length()); + if (stripLastSeparator) line.remove(line.length()-separator.length(), line.length()-1); + + //qDebug() << "LINE POST-STRIP" << line; + + // Keep empty parts here - we still have to act on them + QStringList parts = line.split(separator, QString::KeepEmptyParts); + + // Each line is: + // variable name, Min, Max, Default, Multiplier, Enabled (0 = no, 1 = yes), Comment + + + // Fill in min, max and default values + if (parts.count() > 1) + { + // min + paramMin.insert(parts.at(0).trimmed(), parts.at(1).toDouble()); + } + if (parts.count() > 2) + { + // max + paramMax.insert(parts.at(0).trimmed(), parts.at(2).toDouble()); + } + if (parts.count() > 3) + { + // default + paramDefault.insert(parts.at(0).trimmed(), parts.at(3).toDouble()); + } + // IGNORING 4 and 5 for now + if (parts.count() > 6) + { + // tooltip + paramDescriptions.insert(parts.at(0).trimmed(), parts.at(6).trimmed()); + qDebug() << "PARAM META:" << parts.at(0).trimmed(); + } + } +} + + void UASParameterDataModel::setParamDescriptions(const QMap& paramInfo) +{ + if (paramInfo.isEmpty()) { + qDebug() << __FILE__ << ":" << __LINE__ << "setParamDescriptions with empty"; + } + + paramDescriptions = paramInfo; +} + +bool UASParameterDataModel::isValueGreaterThanParamMax(const QString& paramName, double dblVal) +{ + if (paramMax.contains(paramName)) { + if (dblVal > paramMax.value(paramName)) + return true; + } + + return false; +} + +bool UASParameterDataModel::isValueLessThanParamMin(const QString& paramName, double dblVal) +{ + if (paramMin.contains(paramName)) { + if (dblVal < paramMin.value(paramName)) + return true; + } + + return false; + } + diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index e38e06c8c4..0f89ed4365 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -14,6 +14,21 @@ public: explicit UASParameterDataModel(QObject *parent = 0); + //Parameter meta info + bool isParamMinKnown(const QString& param) { return paramMin.contains(param); } + virtual bool isValueLessThanParamMin(const QString& param, double dblVal); + + bool isParamMaxKnown(const QString& param) { return paramMax.contains(param); } + virtual bool isValueGreaterThanParamMax(const QString& param, double dblVal); + + bool isParamDefaultKnown(const QString& param) { return paramDefault.contains(param); } + double getParamMin(const QString& param) { return paramMin.value(param, 0.0f); } + double getParamMax(const QString& param) { return paramMax.value(param, 0.0f); } + double getParamDefault(const QString& param) { return paramDefault.value(param, 0.0f); } + virtual QString getParamDescription(const QString& param) { return paramDescriptions.value(param, ""); } + virtual void setParamDescriptions(const QMap& paramInfo); + + virtual void addComponent(int componentId); /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ @@ -59,8 +74,10 @@ public: } - virtual void writeOnboardParametersToStream(QTextStream& stream, const QString& uasName); - virtual void readUpdateParametersFromStream(QTextStream& stream); + virtual void writeOnboardParametersToStream(QTextStream &stream, const QString& uasName); + virtual void readUpdateParametersFromStream(QTextStream &stream); + + virtual void loadParamMetaInfoFromStream(QTextStream& stream); void setUASID(int anId) { this->uasId = anId; } @@ -74,6 +91,14 @@ protected: QMap* > pendingParameters; ///< Changed values that have not yet been transmitted to the UAS, by component ID QMap* > onboardParameters; ///< All parameters confirmed to be stored onboard the UAS, by component ID + // Tooltip data structures + QMap paramDescriptions; ///< Tooltip values + + // Min / Default / Max data structures + QMap paramMin; ///< Minimum param values + QMap paramDefault; ///< Default param values + QMap paramMax; ///< Minimum param values + }; diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 3ea93d914b..f43f20a881 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -793,7 +793,7 @@ void QGCPX4VehicleConfig::loadConfig() xml.readNext(); } - mav->getParamManager()->setParamInfo(paramTooltips); + mav->getParamManager()->setParamDescriptions(paramTooltips); doneLoadingConfig = true; mav->requestParameters(); //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. } @@ -892,7 +892,7 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) if (!paramTooltips.isEmpty()) { - mav->getParamManager()->setParamInfo(paramTooltips); + mav->getParamManager()->setParamDescriptions(paramTooltips); } qDebug() << "CALIBRATION!! System Type Name:" << mav->getSystemTypeName(); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 1cb641fdde..7b6f333011 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -55,9 +55,9 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : loadSettings(); // Load default values and tooltips - QString hey(uas->getAutopilotTypeName()); - QString hey2(uas->getSystemTypeName()); - loadParameterInfoCSV(hey, hey2); + QString autoPilotName(uas->getAutopilotTypeName()); + QString sysTypeName(uas->getSystemTypeName()); + loadParamMetaInfoCSV(autoPilotName, sysTypeName); // Create tree widget tree = new QTreeWidget(this); @@ -169,15 +169,9 @@ void QGCParamWidget::loadSettings() } -void QGCParamWidget::setParamInfo(const QMap& paramInfo) { - if (paramInfo.isEmpty()) { - qDebug() << __FILE__ << ":" << __LINE__ << "setParamInfo with empty"; - } - paramToolTips = paramInfo; -} -void QGCParamWidget::loadParameterInfoCSV(const QString& autopilot, const QString& airframe) +void QGCParamWidget::loadParamMetaInfoCSV(const QString& autopilot, const QString& airframe) { Q_UNUSED(airframe); @@ -198,116 +192,11 @@ void QGCParamWidget::loadParameterInfoCSV(const QString& autopilot, const QStrin return; } - // Extract header - // Read in values - // Find all keys QTextStream in(¶mMetaFile); + paramDataModel->loadParamMetaInfoFromStream(in); + paramMetaFile.close(); - // First line is header - // there might be more lines, but the first - // line is assumed to be at least header - QString header = in.readLine(); - - // Ignore top-level comment lines - while (header.startsWith('#') || header.startsWith('/') - || header.startsWith('=') || header.startsWith('^')) - { - header = in.readLine(); - } - - bool charRead = false; - QString separator = ""; - QList sepCandidates; - sepCandidates << '\t'; - sepCandidates << ','; - sepCandidates << ';'; - //sepCandidates << ' '; - sepCandidates << '~'; - sepCandidates << '|'; - - // Iterate until separator is found - // or full header is parsed - for (int i = 0; i < header.length(); i++) - { - if (sepCandidates.contains(header.at(i))) - { - // Separator found - if (charRead) - { - separator += header[i]; - } - } - else - { - // Char found - charRead = true; - // If the separator is not empty, this char - // has been read after a separator, so detection - // is now complete - if (separator != "") break; - } - } - - bool stripFirstSeparator = false; - bool stripLastSeparator = false; - - // Figure out if the lines start with the separator (e.g. wiki syntax) - if (header.startsWith(separator)) stripFirstSeparator = true; - - // Figure out if the lines end with the separator (e.g. wiki syntax) - if (header.endsWith(separator)) stripLastSeparator = true; - - QString out = separator; - out.replace("\t", ""); - //qDebug() << " Separator: \"" << out << "\""; - //qDebug() << "READING CSV:" << header; - - - // Read data - while (!in.atEnd()) - { - QString line = in.readLine(); - - //qDebug() << "LINE PRE-STRIP" << line; - - // Strip separtors if necessary - if (stripFirstSeparator) line.remove(0, separator.length()); - if (stripLastSeparator) line.remove(line.length()-separator.length(), line.length()-1); - - //qDebug() << "LINE POST-STRIP" << line; - - // Keep empty parts here - we still have to act on them - QStringList parts = line.split(separator, QString::KeepEmptyParts); - - // Each line is: - // variable name, Min, Max, Default, Multiplier, Enabled (0 = no, 1 = yes), Comment - - - // Fill in min, max and default values - if (parts.count() > 1) - { - // min - paramMin.insert(parts.at(0).trimmed(), parts.at(1).toDouble()); - } - if (parts.count() > 2) - { - // max - paramMax.insert(parts.at(0).trimmed(), parts.at(2).toDouble()); - } - if (parts.count() > 3) - { - // default - paramDefault.insert(parts.at(0).trimmed(), parts.at(3).toDouble()); - } - // IGNORING 4 and 5 for now - if (parts.count() > 6) - { - // tooltip - paramToolTips.insert(parts.at(0).trimmed(), parts.at(6).trimmed()); - qDebug() << "PARAM META:" << parts.at(0).trimmed(); - } - } } /** @@ -628,15 +517,15 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString par parameterItem->setBackground(0, Qt::NoBrush); parameterItem->setBackground(1, Qt::NoBrush); // Add tooltip + QString paramDesc = paramDataModel->getParamDescription(parameterName); QString tooltipFormat; - if (paramDefault.contains(parameterName)) - { + if (paramDataModel->isParamDefaultKnown(parameterName)) { tooltipFormat = tr("Default: %1, %2"); - tooltipFormat = tooltipFormat.arg(paramDefault.value(parameterName, 0.0f)).arg(paramToolTips.value(parameterName, "")); + double paramDefValue = paramDataModel->getParamDefault(parameterName); + tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc); } - else - { - tooltipFormat = paramToolTips.value(parameterName, ""); + else { + tooltipFormat = paramDesc; } parameterItem->setToolTip(0, tooltipFormat); parameterItem->setToolTip(1, tooltipFormat); @@ -837,14 +726,17 @@ void QGCParamWidget::writeParameters() */ void QGCParamWidget::setParameter(int component, QString parameterName, QVariant value) { + if (parameterName.isEmpty()) { + return; + } + double dblValue = value.toDouble(); - if (paramMin.contains(parameterName) && dblValue < paramMin.value(parameterName)) - { + + if (paramDataModel->isValueLessThanParamMin(parameterName,dblValue)) { statusLabel->setText(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); return; } - if (paramMax.contains(parameterName) && dblValue > paramMax.value(parameterName)) - { + if (paramDataModel->isValueGreaterThanParamMax(parameterName,dblValue)) { statusLabel->setText(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); return; } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index c49f5a55cb..9b34813b06 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -51,14 +51,6 @@ public: /** @brief Get the UAS of this widget */ UASInterface* getUAS(); - bool isParamMinKnown(const QString& param) { return paramMin.contains(param); } - bool isParamMaxKnown(const QString& param) { return paramMax.contains(param); } - bool isParamDefaultKnown(const QString& param) { return paramDefault.contains(param); } - double getParamMin(const QString& param) { return paramMin.value(param, 0.0f); } - double getParamMax(const QString& param) { return paramMax.value(param, 0.0f); } - double getParamDefault(const QString& param) { return paramDefault.value(param, 0.0f); } - QString getParamInfo(const QString& param) { return paramToolTips.value(param, ""); } - void setParamInfo(const QMap& paramInfo); protected: virtual void setParameterStatusMsg(const QString& msg); @@ -104,18 +96,13 @@ protected: QMap* components; ///< The list of components QMap* > paramGroups; ///< Parameter groups - // Tooltip data structures - QMap paramToolTips; ///< Tooltip values - // Min / Default / Max data structures - QMap paramMin; ///< Minimum param values - QMap paramDefault; ///< Default param values - QMap paramMax; ///< Minimum param values + /** @brief Load settings */ void loadSettings(); /** @brief Load meta information from CSV */ - void loadParameterInfoCSV(const QString& autopilot, const QString& airframe); + void loadParamMetaInfoCSV(const QString& autopilot, const QString& airframe); }; #endif // QGCPARAMWIDGET_H diff --git a/src/ui/QGCVehicleConfig.cc b/src/ui/QGCVehicleConfig.cc index d94076dbd4..dd2c769a7a 100644 --- a/src/ui/QGCVehicleConfig.cc +++ b/src/ui/QGCVehicleConfig.cc @@ -786,7 +786,7 @@ void QGCVehicleConfig::loadConfig() xml.readNext(); } - mav->getParamManager()->setParamInfo(paramTooltips); + mav->getParamManager()->setParamDescriptions(paramTooltips); doneLoadingConfig = true; mav->requestParameters(); //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. } @@ -888,7 +888,7 @@ void QGCVehicleConfig::setActiveUAS(UASInterface* active) if (!paramTooltips.isEmpty()) { - mav->getParamManager()->setParamInfo(paramTooltips); + mav->getParamManager()->setParamDescriptions(paramTooltips); } qDebug() << "CALIBRATION!! System Type Name:" << mav->getSystemTypeName(); diff --git a/src/ui/designer/QGCComboBox.cc b/src/ui/designer/QGCComboBox.cc index 21d86f6795..91f9dfc21b 100644 --- a/src/ui/designer/QGCComboBox.cc +++ b/src/ui/designer/QGCComboBox.cc @@ -108,15 +108,14 @@ void QGCComboBox::setActiveUAS(UASInterface* activeUas) // Update current param value //requestParameter(); // Set param info - QString text = uas->getParamManager()->getParamInfo(parameterName); - if (text != "") - { + + QString text = uas->getParamDataModel()->getParamDescription(parameterName); + if (!text.isEmpty()) { ui->infoLabel->setToolTip(text); ui->infoLabel->show(); } // Force-uncheck and hide label if no description is available - if (ui->editInfoCheckBox->isChecked()) - { + if (ui->editInfoCheckBox->isChecked()) { showInfo((text.length() > 0)); } } @@ -147,27 +146,21 @@ void QGCComboBox::selectParameter(int paramIndex) parameterName = ui->editSelectParamComboBox->itemText(paramIndex); // Update min and max values if available - if (uas) - { - if (uas->getParamManager()) - { - // Current value - //uas->getParamManager()->requestParameterUpdate(component, parameterName); - + if (uas) { + UASParameterDataModel* dataModel = uas->getParamDataModel(); + if (dataModel) { // Minimum - if (uas->getParamManager()->isParamMinKnown(parameterName)) - { - parameterMin = uas->getParamManager()->getParamMin(parameterName); + if (dataModel->isParamMinKnown(parameterName)) { + parameterMin = dataModel->getParamMin(parameterName); } // Maximum - if (uas->getParamManager()->isParamMaxKnown(parameterName)) - { - parameterMax = uas->getParamManager()->getParamMax(parameterName); + if (dataModel->isParamMaxKnown(parameterName)) { + parameterMax = dataModel->getParamMax(parameterName); } // Description - QString text = uas->getParamManager()->getParamInfo(parameterName); + QString text = dataModel->getParamDescription(parameterName); //ui->infoLabel->setText(text); showInfo(!(text.length() > 0)); } diff --git a/src/ui/designer/QGCParamSlider.cc b/src/ui/designer/QGCParamSlider.cc index 6733c5790a..7f76759424 100644 --- a/src/ui/designer/QGCParamSlider.cc +++ b/src/ui/designer/QGCParamSlider.cc @@ -102,8 +102,8 @@ void QGCParamSlider::setActiveUAS(UASInterface* activeUas) uas = activeUas; } - QString text = uas->getParamManager()->getParamInfo(parameterName); - if (text != "") { + QString text = uas->getParamDataModel()->getParamDescription(parameterName); + if (!text.isEmpty()) { ui->infoLabel->setToolTip(text); ui->infoLabel->show(); } @@ -176,32 +176,20 @@ void QGCParamSlider::selectParameter(int paramIndex) parameterName = ui->editSelectParamComboBox->itemText(paramIndex); // Update min and max values if available - if (uas) - { - if (uas->getParamManager()) - { - // Current value - //uas->getParamManager()->requestParameterUpdate(component, parameterName); - + if (uas) { + UASParameterDataModel* dataModel = uas->getParamDataModel(); + if (dataModel) { // Minimum - if (uas->getParamManager()->isParamMinKnown(parameterName)) - { - parameterMin = uas->getParamManager()->getParamMin(parameterName); + if (dataModel->isParamMinKnown(parameterName)) { + parameterMin = dataModel->getParamMin(parameterName); ui->editMinSpinBox->setValue(parameterMin); } // Maximum - if (uas->getParamManager()->isParamMaxKnown(parameterName)) - { - parameterMax = uas->getParamManager()->getParamMax(parameterName); + if (dataModel->isParamMaxKnown(parameterName)) { + parameterMax = dataModel->getParamMax(parameterName); ui->editMaxSpinBox->setValue(parameterMax); } - - // Description - //QString text = uas->getParamManager()->getParamInfo(parameterName); - //ui->infoLabel->setText(text); - - //showInfo(!(text.length() > 0)); } } } -- GitLab From b09e81f79a0fb275611b0563845d0ddf5256a4a2 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 10:49:52 -0700 Subject: [PATCH 164/460] debugging retransmission of read param list --- src/uas/QGCUASParamManager.cc | 6 ++++-- src/uas/QGCUASParamManager.h | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 06774ec25d..3e61077310 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -49,8 +49,7 @@ void QGCUASParamManager::requestParameterList() transmissionListSizeKnown.clear(); transmissionListMode = true; - foreach (int key, transmissionMissingPackets.keys()) - { + foreach (int key, transmissionMissingPackets.keys()) { transmissionMissingPackets.value(key)->clear(); } transmissionActive = true; @@ -70,6 +69,8 @@ void QGCUASParamManager::requestParameterList() */ void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) { + qDebug() << "setRetransmissionGuardEnabled: " << enabled; + if (enabled) { retransmissionTimer.start(retransmissionTimeout); } else { @@ -79,6 +80,7 @@ void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) void QGCUASParamManager::setParameterStatusMsg(const QString& msg) { + qDebug() << "parameterStatusMsg: " << msg; parameterStatusMsg = msg; } diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 2a0165959a..6e3927b085 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -26,8 +26,6 @@ public: virtual void setParamDescriptions(const QMap& paramDescs); protected: - /** @brief Check for missing parameters */ - virtual void retransmissionGuardTick(); /** @brief Activate / deactivate parameter retransmission */ virtual void setRetransmissionGuardEnabled(bool enabled); @@ -48,6 +46,8 @@ public slots: virtual void setParameter(int component, QString parameterName, QVariant value) = 0; /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); + /** @brief Check for missing parameters */ + virtual void retransmissionGuardTick(); protected: @@ -67,6 +67,8 @@ protected: int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds int rewriteTimeout; ///< Write request timeout, in milliseconds int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst + + // Status QString parameterStatusMsg; }; -- GitLab From 0757b49e899e9d5c904e5695c1b7d71bfe97a3fd Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 13:02:28 -0700 Subject: [PATCH 165/460] debug multiple parameter widgets creation --- src/uas/QGCUASParamManager.cc | 13 ++----------- src/uas/QGCUASParamManager.h | 2 -- src/uas/UAS.cc | 2 +- src/ui/ParameterInterface.cc | 12 +++++++++++- src/ui/QGCParamWidget.cc | 25 +++++++++++++++---------- src/ui/QGCParamWidget.h | 4 ++-- 6 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 3e61077310..532efe813a 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -16,22 +16,13 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : } -/** - * The .. signal is emitted - */ -void QGCUASParamManager::requestParameterListUpdate(int component) -{ - Q_UNUSED(component); -} + bool QGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const { return paramDataModel->getOnboardParameterValue(component,parameter,value); } - - - /** * Send a request to deliver the list of onboard parameters * to the MAV. @@ -69,7 +60,7 @@ void QGCUASParamManager::requestParameterList() */ void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) { - qDebug() << "setRetransmissionGuardEnabled: " << enabled; +// qDebug() << "setRetransmissionGuardEnabled: " << enabled; if (enabled) { retransmissionTimer.start(retransmissionTimeout); diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 6e3927b085..3607552df2 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -17,8 +17,6 @@ public: virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; - /** @brief Request an update for the parameter list */ - void requestParameterListUpdate(int component = 0); /** @brief Request an update for this specific parameter */ virtual void requestParameterUpdate(int component, const QString& parameter) = 0; diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 597472af5a..3e34dd48ab 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -1995,7 +1995,7 @@ void UAS::sendMessage(mavlink_message_t message) if (LinkManager::instance()->getLinks().contains(link)) { sendMessage(link, message); - qDebug() << "SENT MESSAGE!"; + qDebug() << "SENT MESSAGE id" << message.msgid; } else { diff --git a/src/ui/ParameterInterface.cc b/src/ui/ParameterInterface.cc index e387a20938..8ad4a450ca 100644 --- a/src/ui/ParameterInterface.cc +++ b/src/ui/ParameterInterface.cc @@ -89,8 +89,18 @@ void ParameterInterface::selectUAS(int index) */ void ParameterInterface::addUAS(UASInterface* uas) { + int uasId = uas->getUASID(); + if (paramWidgets->contains(uasId) ) { + qDebug() << "Already have QGCParamWidget for: " << uasId ; + return; + } + QGCParamWidget* param = new QGCParamWidget(uas, this); - paramWidgets->insert(uas->getUASID(), param); + QString ptrStr; + ptrStr.sprintf("%8p", param); + qDebug() << "Created QGCParamWidget " << ptrStr << "for UAS id: " << uasId << " count: " << paramWidgets->count(); + + paramWidgets->insert(uasId, param); m_ui->stackedWidget->addWidget(param); QGCSensorSettingsWidget* sensor = NULL; diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 7b6f333011..b26348be63 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -87,7 +87,7 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QPushButton* refreshButton = new QPushButton(tr("Get")); refreshButton->setToolTip(tr("Load parameters currently in non-permanent memory of aircraft.")); refreshButton->setWhatsThis(tr("Load parameters currently in non-permanent memory of aircraft.")); - connect(refreshButton, SIGNAL(clicked()), this, SLOT(requestParameterListUpdate())); + connect(refreshButton, SIGNAL(clicked()), this, SLOT(requestAllParamsUpdate())); horizontalLayout->addWidget(refreshButton, 2, 0); QPushButton* setButton = new QPushButton(tr("Set")); @@ -151,7 +151,7 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : // Get parameters if (uas) { - requestParameterListUpdate(); + requestAllParamsUpdate(); } } @@ -245,7 +245,8 @@ void QGCParamWidget::addComponent(int uas, int component, QString componentName) */ void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) { - receivedParameterUpdate(uas, component, parameterName, value); + + updateParameterDisplay(uas, component, parameterName, value); // Missing packets list has to be instantiated for all components if (!transmissionMissingPackets.contains(component)) { @@ -390,10 +391,15 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCo * @param component id of the component * @param parameterName human friendly name of the parameter */ -void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value) +void QGCParamWidget::updateParameterDisplay(int uas, int component, QString parameterName, QVariant value) { - qDebug() << "PARAM WIDGET GOT PARAM:" << parameterName; Q_UNUSED(uas); + + + QString ptrStr; + ptrStr.sprintf("%8p", this); + qDebug() << "QGCParamWidget " << ptrStr << " got param" << parameterName; + // Reference to item in tree QTreeWidgetItem* parameterItem = NULL; @@ -417,9 +423,8 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString par addComponent(uas, component, componentName); } - // Replace value in map - - paramDataModel->setOnboardParameter(component,parameterName,value); + // Replace value in data model + paramDataModel->handleParameterUpdate(component,parameterName,value); QString splitToken = "_"; @@ -564,7 +569,7 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) current->setBackground(1, QBrush(QColor(QGC::colorOrange))); //TODO this seems incorrect-- we're pre-updating the onboard value before we've received confirmation - paramDataModel->setOnboardParameterWithType(componentId,key,value); + //paramDataModel->setOnboardParameterWithType(componentId,key,value); } } @@ -608,7 +613,7 @@ void QGCParamWidget::setParameterStatusMsg(const QString& msg) -void QGCParamWidget::requestParameterListUpdate() +void QGCParamWidget::requestAllParamsUpdate() { if (!mav) { return; diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 9b34813b06..48edbb3103 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -65,9 +65,9 @@ public slots: /** @brief Add a parameter to the list with retransmission / safety checks */ void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); /** @brief Add a parameter to the list */ - void receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value); + void updateParameterDisplay(int uas, int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ - void requestParameterListUpdate(); + void requestAllParamsUpdate(); /** @brief Request one single parameter */ void requestParameterUpdate(int component, const QString& parameter); /** @brief Set one parameter, changes value in RAM of MAV */ -- GitLab From e8c6dbb2f059a30a27bce3f2c13f1a50ddeb2bbe Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 15:30:49 -0700 Subject: [PATCH 166/460] consolidating comms-related methods --- src/uas/QGCUASParamManager.cc | 12 ++++-- src/uas/QGCUASParamManager.h | 10 ++--- src/ui/ParameterInterface.cc | 5 ++- src/ui/QGCParamWidget.cc | 69 ++++++++++++----------------------- src/ui/QGCParamWidget.h | 6 +-- 5 files changed, 42 insertions(+), 60 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 532efe813a..dc11769a90 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -16,13 +16,19 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : } - - -bool QGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const { +bool QGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const +{ return paramDataModel->getOnboardParameterValue(component,parameter,value); } +void QGCUASParamManager::requestParameterUpdate(int component, const QString& parameter) +{ + if (mav) { + mav->requestParameter(component, parameter); + } +} + /** * Send a request to deliver the list of onboard parameters * to the MAV. diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 3607552df2..872273c522 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -17,9 +17,6 @@ public: virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; - /** @brief Request an update for this specific parameter */ - virtual void requestParameterUpdate(int component, const QString& parameter) = 0; - /** @brief Provide tooltips / user-visible descriptions for parameters */ virtual void setParamDescriptions(const QMap& paramDescs); @@ -36,8 +33,7 @@ signals: void parameterListUpToDate(int component); /** @brief Request a single parameter */ void requestParameter(int component, int parameter); - /** @brief Request a single parameter by name */ - void requestParameter(int component, const QString& parameter); + public slots: /** @brief Write one parameter to the MAV */ @@ -47,6 +43,10 @@ public slots: /** @brief Check for missing parameters */ virtual void retransmissionGuardTick(); + + /** @brief Request one single parameter */ + virtual void requestParameterUpdate(int component, const QString& parameter); + protected: // Parameter data model diff --git a/src/ui/ParameterInterface.cc b/src/ui/ParameterInterface.cc index 8ad4a450ca..2936394cec 100644 --- a/src/ui/ParameterInterface.cc +++ b/src/ui/ParameterInterface.cc @@ -72,6 +72,7 @@ ParameterInterface::ParameterInterface(QWidget *parent) : ParameterInterface::~ParameterInterface() { + delete paramWidgets; delete m_ui; } @@ -97,8 +98,8 @@ void ParameterInterface::addUAS(UASInterface* uas) QGCParamWidget* param = new QGCParamWidget(uas, this); QString ptrStr; - ptrStr.sprintf("%8p", param); - qDebug() << "Created QGCParamWidget " << ptrStr << "for UAS id: " << uasId << " count: " << paramWidgets->count(); + ptrStr.sprintf("QGCParamWidget %8p (parent %8p)", param,this); + qDebug() << "Created " << ptrStr << " for UAS id: " << uasId << " count: " << paramWidgets->count(); paramWidgets->insert(uasId, param); m_ui->stackedWidget->addWidget(param); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index b26348be63..6b10632b7e 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -49,7 +49,7 @@ This file is part of the QGROUNDCONTROL project */ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QGCUASParamManager(uas, parent), - components(new QMap()) + componentItems(new QMap()) { // Load settings loadSettings(); @@ -145,8 +145,8 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); // Connect retransmission guard - connect(this, SIGNAL(requestParameter(int,QString)), uas, SLOT(requestParameter(int,QString))); - connect(this, SIGNAL(requestParameter(int,int)), uas, SLOT(requestParameter(int,int))); + connect(this, SIGNAL(requestParameterByName(int,QString)), uas, SLOT(requestParameterByName(int,QString))); + connect(this, SIGNAL(requestParameterByName(int,int)), uas, SLOT(requestParameterByName(int,int))); connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); // Get parameters @@ -214,20 +214,20 @@ UASInterface* QGCParamWidget::getUAS() * @param component id of the component * @param componentName human friendly name of the component */ -void QGCParamWidget::addComponent(int uas, int component, QString componentName) +void QGCParamWidget::addComponentItem(int uas, int component, QString componentName) { Q_UNUSED(uas); - if (components->contains(component)) { + if (componentItems->contains(component)) { // Update existing - components->value(component)->setData(0, Qt::DisplayRole, QString("%1 (#%2)").arg(componentName).arg(component)); + componentItems->value(component)->setData(0, Qt::DisplayRole, QString("%1 (#%2)").arg(componentName).arg(component)); //components->value(component)->setData(1, Qt::DisplayRole, QString::number(component)); - components->value(component)->setFirstColumnSpanned(true); + componentItems->value(component)->setFirstColumnSpanned(true); } else { // Add new QStringList list(QString("%1 (#%2)").arg(componentName).arg(component)); QTreeWidgetItem* comp = new QTreeWidgetItem(list); comp->setFirstColumnSpanned(true); - components->insert(component, comp); + componentItems->insert(component, comp); // Create grouping and update maps paramGroups.insert(component, new QMap()); tree->addTopLevelItem(comp); @@ -391,40 +391,26 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCo * @param component id of the component * @param parameterName human friendly name of the parameter */ -void QGCParamWidget::updateParameterDisplay(int uas, int component, QString parameterName, QVariant value) +void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString parameterName, QVariant value) { Q_UNUSED(uas); - QString ptrStr; - ptrStr.sprintf("%8p", this); - qDebug() << "QGCParamWidget " << ptrStr << " got param" << parameterName; +// QString ptrStr; +// ptrStr.sprintf("%8p", this); +// qDebug() << "QGCParamWidget " << ptrStr << " got param" << parameterName; // Reference to item in tree QTreeWidgetItem* parameterItem = NULL; // Get component - if (!components->contains(component)) - { - // QString componentName; - // switch (component) - // { - // case MAV_COMP_ID_CAMERA: - // componentName = tr("Camera (#%1)").arg(component); - // break; - // case MAV_COMP_ID_IMU: - // componentName = tr("IMU (#%1)").arg(component); - // break; - // default: - // componentName = tr("Component #").arg(component); - // break; - // } - QString componentName = tr("Component #%1").arg(component); - addComponent(uas, component, componentName); + if (!componentItems->contains(componentId)) { + QString componentName = tr("Component #%1").arg(componentId); + addComponentItem(uas, componentId, componentName); } // Replace value in data model - paramDataModel->handleParameterUpdate(component,parameterName,value); + paramDataModel->handleParameterUpdate(componentId,parameterName,value); QString splitToken = "_"; @@ -432,7 +418,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int component, QString para if (parameterName.contains(splitToken)) { QString parent = parameterName.section(splitToken, 0, 0, QString::SectionSkipEmpty); - QMap* compParamGroups = paramGroups.value(component); + QMap* compParamGroups = paramGroups.value(componentId); if (!compParamGroups->contains(parent)) { // Insert group item @@ -440,7 +426,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int component, QString para glist.append(parent); QTreeWidgetItem* item = new QTreeWidgetItem(glist); compParamGroups->insert(parent, item); - components->value(component)->addChild(item); + componentItems->value(componentId)->addChild(item); } // Append child to group @@ -489,7 +475,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int component, QString para else { bool found = false; - QTreeWidgetItem* parent = components->value(component); + QTreeWidgetItem* parent = componentItems->value(componentId); for (int i = 0; i < parent->childCount(); i++) { QTreeWidgetItem* child = parent->child(i); @@ -513,7 +499,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int component, QString para // CONFIGURE PARAMETER ITEM parameterItem->setData(1, Qt::DisplayRole, value); - components->value(component)->addChild(parameterItem); + componentItems->value(componentId)->addChild(parameterItem); parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); } //tree->expandAll(); @@ -535,7 +521,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int component, QString para parameterItem->setToolTip(0, tooltipFormat); parameterItem->setToolTip(1, tooltipFormat); - paramDataModel->handleParameterUpdate(component,parameterName,value); + paramDataModel->handleParameterUpdate(componentId,parameterName,value); } @@ -549,7 +535,7 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) parent = parent->parent(); } // Parent is now top-level component - int componentId = components->key(parent); + int componentId = componentItems->key(parent); QString key = current->data(0, Qt::DisplayRole).toString(); QVariant value = current->data(1, Qt::DisplayRole); @@ -603,7 +589,6 @@ void QGCParamWidget::loadParametersFromFile() QTextStream in(&file); paramDataModel->readUpdateParametersFromStream(in); file.close(); - } void QGCParamWidget::setParameterStatusMsg(const QString& msg) @@ -632,14 +617,6 @@ void QGCParamWidget::requestAllParamsUpdate() requestParameterList(); } -/** - * The .. signal is emitted - */ -void QGCParamWidget::requestParameterUpdate(int component, const QString& parameter) -{ - if (mav) mav->requestParameter(component, parameter); -} - /** @@ -830,5 +807,5 @@ void QGCParamWidget::readParameters() void QGCParamWidget::clear() { tree->clear(); - components->clear(); + componentItems->clear(); } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 48edbb3103..06a15b83bb 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -61,15 +61,13 @@ signals: public slots: /** @brief Add a component to the list */ - void addComponent(int uas, int component, QString componentName); + void addComponentItem(int uas, int component, QString componentName); /** @brief Add a parameter to the list with retransmission / safety checks */ void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); /** @brief Add a parameter to the list */ void updateParameterDisplay(int uas, int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ void requestAllParamsUpdate(); - /** @brief Request one single parameter */ - void requestParameterUpdate(int component, const QString& parameter); /** @brief Set one parameter, changes value in RAM of MAV */ void setParameter(int component, QString parameterName, QVariant value); /** @brief Set all parameters, changes the value in RAM of MAV */ @@ -93,7 +91,7 @@ public slots: protected: QTreeWidget* tree; ///< The parameter tree QLabel* statusLabel; ///< Parameter transmission label - QMap* components; ///< The list of components + QMap* componentItems; ///< The list of component items, stored by component ID QMap* > paramGroups; ///< Parameter groups -- GitLab From 189135d447aea616c596483ef86a34181634101e Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 16:50:08 -0700 Subject: [PATCH 167/460] Fixing inter-object wiring --- src/uas/QGCUASParamManager.cc | 12 +++++++++++- src/uas/QGCUASParamManager.h | 8 ++++---- src/uas/UASManager.cc | 1 + src/ui/ParameterInterface.cc | 3 ++- src/ui/QGCParamWidget.cc | 10 +++++++--- src/ui/QGCParamWidget.h | 3 ++- 6 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index dc11769a90..9103a2b437 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -13,6 +13,12 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : { paramDataModel = uas->getParamDataModel(); uas->setParamManager(this); + + // Connect retransmission guard + connect(this, SIGNAL(parameterUpdateRequested(int,QString)), this, SLOT(requestParameterUpdate(int,QString))); + connect(this, SIGNAL(parameterUpdateRequestedById(int,int)), mav, SLOT(requestParameter(int,int))); + + } @@ -29,6 +35,10 @@ void QGCUASParamManager::requestParameterUpdate(int component, const QString& pa } } + + + + /** * Send a request to deliver the list of onboard parameters * to the MAV. @@ -132,7 +142,7 @@ void QGCUASParamManager::retransmissionGuardTick() if (count < retransmissionBurstRequestSize) { //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; //TODO mavlink msg type for "request parameter set" ? - emit requestParameter(component, id); + emit parameterUpdateRequestedById(component, id); setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); count++; } else { diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 872273c522..6a87ba7632 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -27,12 +27,13 @@ protected: //TODO decouple this UI message display further virtual void setParameterStatusMsg(const QString& msg); + signals: void parameterChanged(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); void parameterListUpToDate(int component); - /** @brief Request a single parameter */ - void requestParameter(int component, int parameter); + void parameterUpdateRequested(int component, const QString& parameter); + void parameterUpdateRequestedById(int componentId, int paramId); public slots: @@ -43,8 +44,7 @@ public slots: /** @brief Check for missing parameters */ virtual void retransmissionGuardTick(); - - /** @brief Request one single parameter */ + /** @brief Request a single parameter by name */ virtual void requestParameterUpdate(int component, const QString& parameter); protected: diff --git a/src/uas/UASManager.cc b/src/uas/UASManager.cc index 072c7aea7a..8ee92242db 100644 --- a/src/uas/UASManager.cc +++ b/src/uas/UASManager.cc @@ -280,6 +280,7 @@ void UASManager::addUAS(UASInterface* uas) // Only execute if there is no UAS at this index if (!systems.contains(uas)) { + qDebug() << "Add new UAS: " << uas->getUASID(); systems.append(uas); // Set home position on UAV if set in UI // - this is done on a per-UAV basis diff --git a/src/ui/ParameterInterface.cc b/src/ui/ParameterInterface.cc index 2936394cec..c7d5f811b3 100644 --- a/src/ui/ParameterInterface.cc +++ b/src/ui/ParameterInterface.cc @@ -91,8 +91,9 @@ void ParameterInterface::selectUAS(int index) void ParameterInterface::addUAS(UASInterface* uas) { int uasId = uas->getUASID(); + qDebug() << "ParameterInterface::addUAS : " << uasId ; + if (paramWidgets->contains(uasId) ) { - qDebug() << "Already have QGCParamWidget for: " << uasId ; return; } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 6b10632b7e..4c973cd2aa 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -144,11 +144,15 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : // New parameters from UAS connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); - // Connect retransmission guard - connect(this, SIGNAL(requestParameterByName(int,QString)), uas, SLOT(requestParameterByName(int,QString))); - connect(this, SIGNAL(requestParameterByName(int,int)), uas, SLOT(requestParameterByName(int,int))); + connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); + +// connect(this, SIGNAL(requestParameter(int,QString)), uas, SLOT(requestParameter(int,QString))); +// connect(this, SIGNAL(requestParameter(int,int)), uas, SLOT(requestParameter(int,int))); + + + // Get parameters if (uas) { requestAllParamsUpdate(); diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 06a15b83bb..af58eabf3f 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -59,6 +59,7 @@ signals: /** @brief A parameter was changed in the widget, NOT onboard */ //void parameterChanged(int component, QString parametername, float value); // defined in QGCUASParamManager already + public slots: /** @brief Add a component to the list */ void addComponentItem(int uas, int component, QString componentName); @@ -69,7 +70,7 @@ public slots: /** @brief Request list of parameters from MAV */ void requestAllParamsUpdate(); /** @brief Set one parameter, changes value in RAM of MAV */ - void setParameter(int component, QString parameterName, QVariant value); + virtual void setParameter(int component, QString parameterName, QVariant value); /** @brief Set all parameters, changes the value in RAM of MAV */ void setParameters(); /** @brief Write the current parameters to permanent storage (EEPROM/HDD) */ -- GitLab From dd455b95b7a0f3d2a556fa8d2ae4db13a2b0fbcf Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 19:52:30 -0700 Subject: [PATCH 168/460] start moving comms mgmt code to a separate class --- qgroundcontrol.pro | 6 +- src/uas/QGCUASParamManager.cc | 63 ++++---- src/uas/UASParameterCommsMgr.cc | 278 ++++++++++++++++++++++++++++++++ src/uas/UASParameterCommsMgr.h | 72 +++++++++ 4 files changed, 386 insertions(+), 33 deletions(-) create mode 100644 src/uas/UASParameterCommsMgr.cc create mode 100644 src/uas/UASParameterCommsMgr.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index fd4df5e5b5..6f0f51ca48 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -469,7 +469,8 @@ HEADERS += src/MG.h \ src/ui/configuration/terminalconsole.h \ src/ui/configuration/ApmHighlighter.h \ src/ui/configuration/ApmFirmwareConfig.h \ - src/uas/UASParameterDataModel.h + src/uas/UASParameterDataModel.h \ + src/uas/UASParameterCommsMgr.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -685,7 +686,8 @@ SOURCES += src/main.cc \ src/ui/configuration/SerialSettingsDialog.cc \ src/ui/configuration/ApmHighlighter.cc \ src/ui/configuration/ApmFirmwareConfig.cc \ - src/uas/UASParameterDataModel.cc + src/uas/UASParameterDataModel.cc \ + src/uas/UASParameterCommsMgr.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 9103a2b437..de1d19afd1 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -66,37 +66,6 @@ void QGCUASParamManager::requestParameterList() } - -/** - * Enabling the retransmission guard enables the parameter widget to track - * dropped parameters and to re-request them. This works for both individual - * parameter reads as well for whole list requests. - * - * @param enabled True if retransmission checking should be enabled, false else - */ -void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) -{ -// qDebug() << "setRetransmissionGuardEnabled: " << enabled; - - if (enabled) { - retransmissionTimer.start(retransmissionTimeout); - } else { - retransmissionTimer.stop(); - } -} - -void QGCUASParamManager::setParameterStatusMsg(const QString& msg) -{ - qDebug() << "parameterStatusMsg: " << msg; - parameterStatusMsg = msg; -} - -void QGCUASParamManager::setParamDescriptions(const QMap& paramInfo) { - paramDataModel->setParamDescriptions(paramInfo); -} - - - void QGCUASParamManager::retransmissionGuardTick() { if (transmissionActive) { @@ -199,3 +168,35 @@ void QGCUASParamManager::retransmissionGuardTick() setRetransmissionGuardEnabled(false); } } + + + +/** + * Enabling the retransmission guard enables the parameter widget to track + * dropped parameters and to re-request them. This works for both individual + * parameter reads as well for whole list requests. + * + * @param enabled True if retransmission checking should be enabled, false else + */ +void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) +{ +// qDebug() << "setRetransmissionGuardEnabled: " << enabled; + + if (enabled) { + retransmissionTimer.start(retransmissionTimeout); + } else { + retransmissionTimer.stop(); + } +} + +void QGCUASParamManager::setParameterStatusMsg(const QString& msg) +{ + qDebug() << "parameterStatusMsg: " << msg; + parameterStatusMsg = msg; +} + +void QGCUASParamManager::setParamDescriptions(const QMap& paramInfo) { + paramDataModel->setParamDescriptions(paramInfo); +} + + diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc new file mode 100644 index 0000000000..9f0d60e051 --- /dev/null +++ b/src/uas/UASParameterCommsMgr.cc @@ -0,0 +1,278 @@ +#include "UASParameterCommsMgr.h" + +#include "QGCUASParamManager.h" +#include "UASInterface.h" + +UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : + QObject(parent) +{ + mav = uas; + + // Sending params to the UAS + connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), mav, SLOT(setParameter(int,QString,QVariant))); + + // New parameters from UAS + connect(mav, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); + +} + + +/** + * Send a request to deliver the list of onboard parameters + * from the MAV. + */ +void UASParameterCommsMgr::requestParameterList() +{ + if (!mav) { + return; + } + + //TODO check: no need to cause datamodel to forget params here? +// paramDataModel->forgetAllOnboardParameters(); + + // Clear transmission state + receivedParamsList.clear(); + transmissionListSizeKnown.clear(); + + transmissionListMode = true; + foreach (int key, transmissionMissingPackets.keys()) { + transmissionMissingPackets.value(key)->clear(); + } + transmissionActive = true; + + setParameterStatusMsg(tr("Requested param list.. waiting")); + mav->requestParameters(); + +} + + +void UASParameterCommsMgr::retransmissionGuardTick() +{ + if (transmissionActive) { + //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; + + // Check for timeout + // stop retransmission attempts on timeout + if (QGC::groundTimeMilliseconds() > transmissionTimeout) { + setRetransmissionGuardEnabled(false); + transmissionActive = false; + + // Empty read retransmission list + // Empty write retransmission list + int missingReadCount = 0; + QList readKeys = transmissionMissingPackets.keys(); + foreach (int component, readKeys) { + missingReadCount += transmissionMissingPackets.value(component)->count(); + transmissionMissingPackets.value(component)->clear(); + } + + // Empty write retransmission list + int missingWriteCount = 0; + QList writeKeys = transmissionMissingWriteAckPackets.keys(); + foreach (int component, writeKeys) { + missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); + transmissionMissingWriteAckPackets.value(component)->clear(); + } + setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); + } + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent link flooding + QMap*>::iterator i; + QMap*> onboardParams = paramDataModel->getOnboardParameters(); + for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { + // Iterate through the parameters of the component + int component = i.key(); + // Request n parameters from this component (at maximum) + QList * paramList = transmissionMissingPackets.value(component, NULL); + if (paramList) { + int count = 0; + foreach (int id, *paramList) { + if (count < retransmissionBurstRequestSize) { + //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; + //TODO mavlink msg type for "request parameter set" ? + emit parameterUpdateRequestedById(component, id); + setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); + count++; + } else { + break; + } + } + } + } + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent write-request link flooding + // Empty write retransmission list + QList writeKeys = transmissionMissingWriteAckPackets.keys(); + foreach (int component, writeKeys) { + int count = 0; + QMap * missingParams = transmissionMissingWriteAckPackets.value(component); + foreach (QString key, missingParams->keys()) { + if (count < retransmissionBurstRequestSize) { + // Re-request write operation + QVariant value = missingParams->value(key); + switch ((int)onboardParams.value(component)->value(key).type()) + { + case QVariant::Int: + { + QVariant fixedValue(value.toInt()); + emit parameterChanged(component, key, fixedValue); + } + break; + case QVariant::UInt: + { + QVariant fixedValue(value.toUInt()); + emit parameterChanged(component, key, fixedValue); + } + break; + case QMetaType::Float: + { + QVariant fixedValue(value.toFloat()); + emit parameterChanged(component, key, fixedValue); + } + break; + default: + //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; + return; + } + setParameterStatusMsg(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); + count++; + } else { + break; + } + } + } + } else { + //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; + setRetransmissionGuardEnabled(false); + } +} + + + +/** + * Enabling the retransmission guard enables the parameter widget to track + * dropped parameters and to re-request them. This works for both individual + * parameter reads as well for whole list requests. + * + * @param enabled True if retransmission checking should be enabled, false else + */ + +void UASParameterCommsMgr::setRetransmissionGuardEnabled(bool enabled) +{ +// qDebug() << "setRetransmissionGuardEnabled: " << enabled; + + if (enabled) { + retransmissionTimer.start(retransmissionTimeout); + } else { + retransmissionTimer.stop(); + } +} + +void UASParameterCommsMgr::requestParameterUpdate(int component, const QString& parameter) +{ + if (mav) { + mav->requestParameter(component, parameter); + } +} + +/** + * @param component the subsystem which has the parameter + * @param parameterName name of the parameter, as delivered by the system + * @param value value of the parameter + */ +void UASParameterCommsMgr::setParameter(int component, QString parameterName, QVariant value) +{ + if (parameterName.isEmpty()) { + return; + } + + double dblValue = value.toDouble(); + + if (paramDataModel->isValueLessThanParamMin(parameterName,dblValue)) { + setParameterStatusMsg(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); + return; + } + if (paramDataModel->isValueGreaterThanParamMax(parameterName,dblValue)) { + setParameterStatusMsg(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); + return; + } + QVariant onboardVal; + paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); + if (onboardVal == value) { + setParameterStatusMsg(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue)); + return; + } + + //int paramType = (int)onboardParameters.value(component)->value(parameterName).type(); + int paramType = (int)value.type(); + switch (paramType) + { + case QVariant::Char: + { + QVariant fixedValue(QChar((unsigned char)value.toInt())); + emit parameterChanged(component, parameterName, fixedValue); + //qDebug() << "PARAM WIDGET SENT:" << fixedValue; + } + break; + case QVariant::Int: + { + QVariant fixedValue(value.toInt()); + emit parameterChanged(component, parameterName, fixedValue); + //qDebug() << "PARAM WIDGET SENT:" << fixedValue; + } + break; + case QVariant::UInt: + { + QVariant fixedValue(value.toUInt()); + emit parameterChanged(component, parameterName, fixedValue); + //qDebug() << "PARAM WIDGET SENT:" << fixedValue; + } + break; + case QMetaType::Float: + { + QVariant fixedValue(value.toFloat()); + emit parameterChanged(component, parameterName, fixedValue); + //qDebug() << "PARAM WIDGET SENT:" << fixedValue; + } + break; + default: + qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE"; + return; + } + + // Wait for parameter to be written back + // mark it therefore as missing + if (!transmissionMissingWriteAckPackets.contains(component)) + { + transmissionMissingWriteAckPackets.insert(component, new QMap()); + } + + // Insert it in missing write ACK list + transmissionMissingWriteAckPackets.value(component)->insert(parameterName, value); + + // Set timeouts + if (transmissionActive) + { + transmissionTimeout += rewriteTimeout; + } + else + { + quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + rewriteTimeout; + if (newTransmissionTimeout > transmissionTimeout) + { + transmissionTimeout = newTransmissionTimeout; + } + transmissionActive = true; + } + + // Enable guard / reset timeouts + setRetransmissionGuardEnabled(true); +} + +void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg) +{ + qDebug() << "parameterStatusMsg: " << msg; + parameterStatusMsg = msg; +} diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h new file mode 100644 index 0000000000..72da05d8f8 --- /dev/null +++ b/src/uas/UASParameterCommsMgr.h @@ -0,0 +1,72 @@ +#ifndef UASPARAMETERCOMMSMGR_H +#define UASPARAMETERCOMMSMGR_H + +#include +#include +#include +#include +#include + +class UASInterface; +class UASParameterDataModel; + +class UASParameterCommsMgr : public QObject +{ + Q_OBJECT +public: + explicit UASParameterCommsMgr(QObject *parent = 0, UASInterface* uas = NULL); + + +protected: + /** @brief Activate / deactivate parameter retransmission */ + virtual void setRetransmissionGuardEnabled(bool enabled); + + virtual void setParameterStatusMsg(const QString& msg); + +signals: + void parameterChanged(int component, QString parameter, QVariant value); + void parameterChanged(int component, int parameterIndex, QVariant value); + void parameterValueConfirmed(int component, QString parameter, QVariant value); + + void parameterListUpToDate(int component); + void parameterUpdateRequested(int component, const QString& parameter); + void parameterUpdateRequestedById(int componentId, int paramId); + + +public slots: + /** @brief Write one parameter to the MAV */ + virtual void setParameter(int component, QString parameterName, QVariant value); + /** @brief Request list of parameters from MAV */ + virtual void requestParameterList(); + /** @brief Check for missing parameters */ + virtual void retransmissionGuardTick(); + + /** @brief Request a single parameter update by name */ + virtual void requestParameterUpdate(int component, const QString& parameter); + +protected: + + UASInterface* mav; ///< The MAV we're talking to + + UASParameterDataModel* paramDataModel; + + // Communications management + QVector receivedParamsList; ///< Successfully received parameters + QMap* > transmissionMissingPackets; ///< Missing packets + QMap* > transmissionMissingWriteAckPackets; ///< Missing write ACK packets + bool transmissionListMode; ///< Currently requesting list + QMap transmissionListSizeKnown; ///< List size initialized? + bool transmissionActive; ///< Missing packets, working on list? + quint64 transmissionTimeout; ///< Timeout + QTimer retransmissionTimer; ///< Timer handling parameter retransmission + int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds + int rewriteTimeout; ///< Write request timeout, in milliseconds + int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst + + // Status + QString parameterStatusMsg; + +}; + + +#endif // UASPARAMETERCOMMSMGR_H -- GitLab From 74f1acf5aada45f2a910eb8f0fa70f4bc49da771 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 7 Aug 2013 17:40:32 -0700 Subject: [PATCH 169/460] wip-- more mvc refactoring --- src/uas/QGCUASParamManager.cc | 337 ++++++++++++--------- src/uas/QGCUASParamManager.h | 38 ++- src/uas/UAS.cc | 4 + src/uas/UAS.h | 6 + src/uas/UASInterface.h | 3 + src/uas/UASParameterCommsMgr.cc | 217 ++++++++++++- src/uas/UASParameterCommsMgr.h | 31 +- src/uas/UASParameterDataModel.cc | 10 +- src/uas/UASParameterDataModel.h | 11 +- src/ui/QGCParamWidget.cc | 505 ++++++++++++------------------- src/ui/QGCParamWidget.h | 33 +- 11 files changed, 686 insertions(+), 509 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index de1d19afd1..79b03d2059 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -1,22 +1,43 @@ #include "QGCUASParamManager.h" #include "UASInterface.h" +#include "UASParameterCommsMgr.h" + QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : QWidget(parent), - mav(uas), - transmissionListMode(false), - transmissionActive(false), - transmissionTimeout(0), - retransmissionTimeout(350), - rewriteTimeout(500), - retransmissionBurstRequestSize(5) + mav(uas) { paramDataModel = uas->getParamDataModel(); - uas->setParamManager(this); + paramCommsMgr = uas->getParamCommsMgr(); + mav->setParamManager(this); + + // Load default values and tooltips + loadParamMetaInfoCSV(); + // Connect retransmission guard - connect(this, SIGNAL(parameterUpdateRequested(int,QString)), this, SLOT(requestParameterUpdate(int,QString))); - connect(this, SIGNAL(parameterUpdateRequestedById(int,int)), mav, SLOT(requestParameter(int,int))); + connect(this, SIGNAL(parameterUpdateRequested(int,QString)), + this, SLOT(requestParameterUpdate(int,QString))); + +// //TODO connect in paramCommsMgr instead +// connect(this, SIGNAL(parameterUpdateRequestedById(int,int)), +// mav, SLOT(requestParameter(int,int))); + + // New parameters from UAS + + void parameterUpdated(int compId, int paramId, QString paramName, QVariant value); + + connect(paramDataModel, SIGNAL(parameterUpdated(int, int, QString , QVariant )), + this, SLOT(handleParameterUpdate(int,int,int,QString,QVariant)); + +// connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), +// this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); + + + // Listen for param list reload finished + connect(paramCommsMgr, SIGNAL(parameterListUpToDate(int)), + this, SLOT(handleParameterListUpToDate(int)))); + } @@ -31,14 +52,12 @@ bool QGCUASParamManager::getParameterValue(int component, const QString& paramet void QGCUASParamManager::requestParameterUpdate(int component, const QString& parameter) { if (mav) { - mav->requestParameter(component, parameter); + paramCommsMgr->requestParameterUpdate(component,parameter); } } - - /** * Send a request to deliver the list of onboard parameters * to the MAV. @@ -48,146 +67,133 @@ void QGCUASParamManager::requestParameterList() if (!mav) { return; } - - paramDataModel->forgetAllOnboardParameters(); - - // Clear transmission state - receivedParamsList.clear(); - transmissionListSizeKnown.clear(); - - transmissionListMode = true; - foreach (int key, transmissionMissingPackets.keys()) { - transmissionMissingPackets.value(key)->clear(); - } - transmissionActive = true; - + //paramDataModel->forgetAllOnboardParameters(); //TODO really?? setParameterStatusMsg(tr("Requested param list.. waiting")); - mav->requestParameters(); - -} - -void QGCUASParamManager::retransmissionGuardTick() -{ - if (transmissionActive) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; - - // Check for timeout - // stop retransmission attempts on timeout - if (QGC::groundTimeMilliseconds() > transmissionTimeout) { - setRetransmissionGuardEnabled(false); - transmissionActive = false; - - // Empty read retransmission list - // Empty write retransmission list - int missingReadCount = 0; - QList readKeys = transmissionMissingPackets.keys(); - foreach (int component, readKeys) { - missingReadCount += transmissionMissingPackets.value(component)->count(); - transmissionMissingPackets.value(component)->clear(); - } - - // Empty write retransmission list - int missingWriteCount = 0; - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); - transmissionMissingWriteAckPackets.value(component)->clear(); - } - setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); - } - - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent link flooding - QMap*>::iterator i; - QMap*> onboardParams = paramDataModel->getOnboardParameters(); - for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { - // Iterate through the parameters of the component - int component = i.key(); - // Request n parameters from this component (at maximum) - QList * paramList = transmissionMissingPackets.value(component, NULL); - if (paramList) { - int count = 0; - foreach (int id, *paramList) { - if (count < retransmissionBurstRequestSize) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; - //TODO mavlink msg type for "request parameter set" ? - emit parameterUpdateRequestedById(component, id); - setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); - count++; - } else { - break; - } - } - } - } - - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent write-request link flooding - // Empty write retransmission list - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - int count = 0; - QMap * missingParams = transmissionMissingWriteAckPackets.value(component); - foreach (QString key, missingParams->keys()) { - if (count < retransmissionBurstRequestSize) { - // Re-request write operation - QVariant value = missingParams->value(key); - switch ((int)onboardParams.value(component)->value(key).type()) - { - case QVariant::Int: - { - QVariant fixedValue(value.toInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QVariant::UInt: - { - QVariant fixedValue(value.toUInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QMetaType::Float: - { - QVariant fixedValue(value.toFloat()); - emit parameterChanged(component, key, fixedValue); - } - break; - default: - //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; - return; - } - setParameterStatusMsg(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); - count++; - } else { - break; - } - } - } - } else { - //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; - setRetransmissionGuardEnabled(false); - } + paramCommsMgr->requestParameterList(); } - - -/** - * Enabling the retransmission guard enables the parameter widget to track - * dropped parameters and to re-request them. This works for both individual - * parameter reads as well for whole list requests. - * - * @param enabled True if retransmission checking should be enabled, false else - */ -void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) -{ +//void QGCUASParamManager::retransmissionGuardTick() +//{ +// if (transmissionActive) { +// //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; + +// // Check for timeout +// // stop retransmission attempts on timeout +// if (QGC::groundTimeMilliseconds() > transmissionTimeout) { +// setRetransmissionGuardEnabled(false); +// transmissionActive = false; + +// // Empty read retransmission list +// // Empty write retransmission list +// int missingReadCount = 0; +// QList readKeys = transmissionMissingPackets.keys(); +// foreach (int component, readKeys) { +// missingReadCount += transmissionMissingPackets.value(component)->count(); +// transmissionMissingPackets.value(component)->clear(); +// } + +// // Empty write retransmission list +// int missingWriteCount = 0; +// QList writeKeys = transmissionMissingWriteAckPackets.keys(); +// foreach (int component, writeKeys) { +// missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); +// transmissionMissingWriteAckPackets.value(component)->clear(); +// } +// setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); +// } + +// // Re-request at maximum retransmissionBurstRequestSize parameters at once +// // to prevent link flooding +// QMap*>::iterator i; +// QMap*> onboardParams = paramDataModel->getOnboardParameters(); +// for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { +// // Iterate through the parameters of the component +// int component = i.key(); +// // Request n parameters from this component (at maximum) +// QList * paramList = transmissionMissingPackets.value(component, NULL); +// if (paramList) { +// int count = 0; +// foreach (int id, *paramList) { +// if (count < retransmissionBurstRequestSize) { +// //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; +// //TODO mavlink msg type for "request parameter set" ? +// emit parameterUpdateRequestedById(component, id); +// setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); +// count++; +// } else { +// break; +// } +// } +// } +// } + +// // Re-request at maximum retransmissionBurstRequestSize parameters at once +// // to prevent write-request link flooding +// // Empty write retransmission list +// QList writeKeys = transmissionMissingWriteAckPackets.keys(); +// foreach (int component, writeKeys) { +// int count = 0; +// QMap * missingParams = transmissionMissingWriteAckPackets.value(component); +// foreach (QString key, missingParams->keys()) { +// if (count < retransmissionBurstRequestSize) { +// // Re-request write operation +// QVariant value = missingParams->value(key); +// switch ((int)onboardParams.value(component)->value(key).type()) +// { +// case QVariant::Int: +// { +// QVariant fixedValue(value.toInt()); +// emit parameterChanged(component, key, fixedValue); +// } +// break; +// case QVariant::UInt: +// { +// QVariant fixedValue(value.toUInt()); +// emit parameterChanged(component, key, fixedValue); +// } +// break; +// case QMetaType::Float: +// { +// QVariant fixedValue(value.toFloat()); +// emit parameterChanged(component, key, fixedValue); +// } +// break; +// default: +// //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; +// return; +// } +// setParameterStatusMsg(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); +// count++; +// } else { +// break; +// } +// } +// } +// } else { +// //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; +// setRetransmissionGuardEnabled(false); +// } +//} + + + +//* +// * Enabling the retransmission guard enables the parameter widget to track +// * dropped parameters and to re-request them. This works for both individual +// * parameter reads as well for whole list requests. +// * +// * @param enabled True if retransmission checking should be enabled, false else + +//void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) +//{ // qDebug() << "setRetransmissionGuardEnabled: " << enabled; - - if (enabled) { - retransmissionTimer.start(retransmissionTimeout); - } else { - retransmissionTimer.stop(); - } -} +// +// if (enabled) { +// retransmissionTimer.start(retransmissionTimeout); +// } else { +// retransmissionTimer.stop(); +// } +//} void QGCUASParamManager::setParameterStatusMsg(const QString& msg) { @@ -200,3 +206,36 @@ void QGCUASParamManager::setParamDescriptions(const QMap& param } + + +void QGCUASParamManager::loadParamMetaInfoCSV() +{ + // Load default values and tooltips + QString autopilot(mav->getAutopilotTypeName()); + + QDir appDir = QApplication::applicationDirPath(); + appDir.cd("files"); + QString fileName = QString("%1/%2/parameter_tooltips/tooltips.txt").arg(appDir.canonicalPath()).arg(autopilot.toLower()); + QFile paramMetaFile(fileName); + + qDebug() << "loadParamMetaInfoCSV for autopilot: " << autopilot << " from file: " << fileName; + + if (!paramMetaFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning() << "loadParamMetaInfoCSV couldn't open:" << fileName; + return; + } + + QTextStream in(¶mMetaFile); + paramDataModel->loadParamMetaInfoFromStream(in); + paramMetaFile.close(); + +} + +/** + * @return The MAV of this mgr. Unless the MAV object has been destroyed, this + * pointer is never zero. + */ +UASInterface* QGCUASParamManager::getUAS() +{ + return mav; +} diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 6a87ba7632..313c0927ad 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -6,7 +6,9 @@ #include #include +//forward declarations class UASInterface; +class UASParameterCommsMgr; class UASParameterDataModel; class QGCUASParamManager : public QWidget @@ -15,25 +17,29 @@ class QGCUASParamManager : public QWidget public: QGCUASParamManager(UASInterface* uas, QWidget *parent = 0); + /** @brief Get the known, confirmed value of a parameter */ virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; /** @brief Provide tooltips / user-visible descriptions for parameters */ virtual void setParamDescriptions(const QMap& paramDescs); -protected: - /** @brief Activate / deactivate parameter retransmission */ - virtual void setRetransmissionGuardEnabled(bool enabled); + /** @brief Get the UAS of this widget + * @return The MAV of this mgr. Unless the MAV object has been destroyed, this is never null. + */ + UASInterface* getUAS(); +protected: //TODO decouple this UI message display further virtual void setParameterStatusMsg(const QString& msg); + /** @brief Load parameter meta information from appropriate CSV file */ + virtual void loadParamMetaInfoCSV(); signals: void parameterChanged(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); - void parameterListUpToDate(int component); - void parameterUpdateRequested(int component, const QString& parameter); - void parameterUpdateRequestedById(int componentId, int paramId); +// void parameterUpdateRequested(int component, const QString& parameter); +// void parameterUpdateRequestedById(int componentId, int paramId); public slots: @@ -41,30 +47,20 @@ public slots: virtual void setParameter(int component, QString parameterName, QVariant value) = 0; /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); - /** @brief Check for missing parameters */ - virtual void retransmissionGuardTick(); /** @brief Request a single parameter by name */ virtual void requestParameterUpdate(int component, const QString& parameter); + virtual void handleParameterUpdate(int component, int paramCount, int paramId, const QString& parameterName, QVariant value) = 0; + virtual void handleParameterListUpToDate(int component) = 0; + + protected: // Parameter data model UASInterface* mav; ///< The MAV this widget is controlling UASParameterDataModel* paramDataModel;///< Shared data model of parameters - - // Communications management - QVector receivedParamsList; ///< Successfully received parameters - QMap* > transmissionMissingPackets; ///< Missing packets - QMap* > transmissionMissingWriteAckPackets; ///< Missing write ACK packets - bool transmissionListMode; ///< Currently requesting list - QMap transmissionListSizeKnown; ///< List size initialized? - bool transmissionActive; ///< Missing packets, working on list? - quint64 transmissionTimeout; ///< Timeout - QTimer retransmissionTimer; ///< Timer handling parameter retransmission - int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds - int rewriteTimeout; ///< Write request timeout, in milliseconds - int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst + UASParameterCommsMgr* paramCommsMgr; ///< Shared comms mgr for parameters // Status QString parameterStatusMsg; diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 3e34dd48ab..772341413c 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -26,6 +26,7 @@ #include "QGCMAVLink.h" #include "LinkManager.h" #include "SerialLink.h" +#include "UASParameterCommsMgr.h" #include #ifdef QGC_PROTOBUF_ENABLED @@ -132,6 +133,7 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), paramsOnceRequested(false), paramManager(NULL), paramDataModel(NULL), + paramCommsMgr(NULL), simulation(0), @@ -155,6 +157,8 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), paramDataModel = new UASParameterDataModel(this); paramDataModel->setUASID(this->getUASID()); + paramCommsMgr = new UASParameterCommsMgr(this,this); + // Store a list of available actions for this UAS. // Basically everything exposted as a SLOT with no return value or arguments. diff --git a/src/uas/UAS.h b/src/uas/UAS.h index c8b9a604c7..5acd2c9ef4 100644 --- a/src/uas/UAS.h +++ b/src/uas/UAS.h @@ -41,6 +41,7 @@ This file is part of the QGROUNDCONTROL project #include "QGCJSBSimLink.h" #include "QGCXPlaneLink.h" + /** * @brief A generic MAVLINK-connected MAV/UAV * @@ -493,6 +494,7 @@ protected: //COMMENTS FOR TEST UNIT bool paramsOnceRequested; ///< If the parameter list has been read at least once QGCUASParamManager* paramManager; ///< Parameter manager class UASParameterDataModel* paramDataModel; ///< The parameter data model for this UAS + UASParameterCommsMgr* paramCommsMgr; /// SIMULATION QGCHilLink* simulation; ///< Hardware in the loop simulation link @@ -526,6 +528,10 @@ public: return paramDataModel; } + UASParameterCommsMgr* getParamCommsMgr() { + return paramCommsMgr; + } + /** @brief Get the HIL simulation */ QGCHilLink* getHILSimulation() const { diff --git a/src/uas/UASInterface.h b/src/uas/UASInterface.h index ed2aed28c8..6e6fe2fb33 100644 --- a/src/uas/UASInterface.h +++ b/src/uas/UASInterface.h @@ -157,6 +157,9 @@ public: /** @brief Access the parameter data model for this UAS (sans widget). This is the same parameter data model used by the parameter manager. **/ virtual UASParameterDataModel* getParamDataModel() = 0; + + virtual UASParameterCommsMgr* getParamCommsMgr() = 0; + /** @brief Get reference to the param manager **/ virtual QGCUASParamManager* getParamManager() const = 0; diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 9f0d60e051..22940e5fd3 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -4,9 +4,22 @@ #include "UASInterface.h" UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : - QObject(parent) + QObject(parent), + mav(uas), + transmissionListMode(false), + transmissionActive(false), + transmissionTimeout(0), + retransmissionTimeout(350), + rewriteTimeout(500), + retransmissionBurstRequestSize(5) { mav = uas; + loadParamCommsSettings(); + + + //Requesting parameters one-by-one from mav + connect(this, SIGNAL(parameterUpdateRequestedById(int,int)), + mav, SLOT(requestParameter(int,int))); // Sending params to the UAS connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), mav, SLOT(setParameter(int,QString,QVariant))); @@ -14,9 +27,29 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : // New parameters from UAS connect(mav, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); + //connecto retransmissionTimer + connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); + } + +void UASParameterCommsMgr::loadParamCommsSettings() +{ + QSettings settings; + settings.beginGroup("QGC_MAVLINK_PROTOCOL"); + bool valid; + int val = settings.value("PARAMETER_RETRANSMISSION_TIMEOUT", retransmissionTimeout).toInt(&ok); + if (valid) { + retransmissionTimeout = temp; + } + val = settings.value("PARAMETER_REWRITE_TIMEOUT", rewriteTimeout).toInt(&ok); + if (valid) { + rewriteTimeout = temp; + } + settings.endGroup(); +} + /** * Send a request to deliver the list of onboard parameters * from the MAV. @@ -271,8 +304,188 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV setRetransmissionGuardEnabled(true); } -void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg) +void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg, ParamCommsStatusLevel_t level) { qDebug() << "parameterStatusMsg: " << msg; parameterStatusMsg = msg; + + //TODO indicate OK status somehow (eg color) +// QPalette pal = statusLabel->palette(); +// pal.setColor(backgroundRole(), QGC::colorGreen); +// statusLabel->setPalette(pal); + +// pal.setColor(backgroundRole(), QGC::colorRed); + // pal.setColor(backgroundRole(), QGC::colorOrange); + + } + + +/** + * @param uas System which has the component + * @param component id of the component + * @param parameterName human friendly name of the parameter + */ +void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value) +{ + + // Missing packets list has to be instantiated for all components + if (!transmissionMissingPackets.contains(compId)) { + transmissionMissingPackets.insert(compId, new QList()); + } + + // List mode is different from single parameter transfers + if (transmissionListMode) { + // Only accept the list size once on the first packet from + // each component + if (!transmissionListSizeKnown.contains(compId)) { + // Mark list size as known + transmissionListSizeKnown.insert(compId, true); + + // Mark all parameters as missing + for (int i = 0; i < paramCount; ++i) { + if (!transmissionMissingPackets.value(compId)->contains(i)) { + transmissionMissingPackets.value(compId)->append(i); + } + } + + // There is only one transmission timeout for all components + // since components do not manage their transmission, + // the longest timeout is safe for all components. + quint64 thisTransmissionTimeout = QGC::groundTimeMilliseconds() + ((paramCount)*retransmissionTimeout); + if (thisTransmissionTimeout > transmissionTimeout) { + transmissionTimeout = thisTransmissionTimeout; + } + } + + // Start retransmission guard + // or reset timer + paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO + } + + // Mark this parameter as received in read list + int index = transmissionMissingPackets.value(compId)->indexOf(paramId); + // If the MAV sent the parameter without request, it wont be in missing list + if (index != -1) { + transmissionMissingPackets.value(compId)->removeAt(index); + } + + bool justWritten = false; + bool writeMismatch = false; + //bool lastWritten = false; + // Mark this parameter as received in write ACK list + QMap* map = transmissionMissingWriteAckPackets.value(compId); + if (map && map->contains(paramName)) { + justWritten = true; + QVariant newval = map->value(paramName); + if (map->value(paramName) != value) { + writeMismatch = true; + } + map->remove(paramName); + } + + int missCount = 0; + foreach (int key, transmissionMissingPackets.keys()) { + missCount += transmissionMissingPackets.value(key)->count(); + } + + int missWriteCount = 0; + foreach (int key, transmissionMissingWriteAckPackets.keys()) { + missWriteCount += transmissionMissingWriteAckPackets.value(key)->count(); + } + + //TODO simplify this if-else tree + if (justWritten && !writeMismatch && missWriteCount == 0) { + // Just wrote one and count went to 0 - this was the last missing write parameter + setParameterStatusMsg(tr("SUCCESS: WROTE ALL PARAMETERS")); + } + else if (justWritten && !writeMismatch) { + setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount)); + } + else if (justWritten && writeMismatch) { + // Mismatch, tell user + setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(map->value(paramName).toDouble()).arg(value.toDouble()), + ParamCommsStatusLevel_Warning); + } + else { + QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); + if (missCount == 0) { + // Transmission done + QTime time = QTime::currentTime(); + QString timeString = time.toString(); + setParameterStatusMsg(tr("All received. (updated at %1)").arg(timeString)); + } + else { + // Transmission in progress + setParameterStatusMsg(tr("OK: %1 %2 (%3/%4)").arg(paramName).arg(val).arg(paramCount-missCount).arg(paramCount), + ParamCommsStatusLevel_Warning); + } + } + + // Check if last parameter was received + if (missCount == 0 && missWriteCount == 0) { + this->transmissionActive = false; + this->transmissionListMode = false; + transmissionListSizeKnown.clear(); + foreach (int key, transmissionMissingPackets.keys()) { + transmissionMissingPackets.value(key)->clear(); + } + + //all parameters have been received, broadcast to UI + emit parameterListUpToDate(); + //TODO in UI + // Expand visual tree + //tree->expandItem(tree->topLevelItem(0)); + } +} + + +void UASParameterCommsMgr::writeParamsToPersistentStorage() +{ + if (mav) { + mav->writeParametersToStorage(); //TODO track timeout, retransmit etc? + } +} + + +void UASParameterCommsMgr::sendPendingParameters() +{ + // Iterate through all components, through all pending parameters and send them to UAS + int parametersSent = 0; + QMap*> changedValues = paramDataModel->getPendingParameters(); + QMap*>::iterator i; + for (i = changedValues.begin(); i != changedValues.end(); ++i) { + // Iterate through the parameters of the component + int compid = i.key(); + QMap* comp = i.value(); + { + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) { + //TODO mavlink command for "set parameter list" ? + setParameter(compid, j.key(), j.value()); + parametersSent++; + } + } + } + + // Change transmission status if necessary + if (parametersSent == 0) { + setParameterStatusMsg(tr("No transmission: No changed values."),ParamCommsStatusLevel_Warning); + } else { + setParameterStatusMsg(tr("Transmitting %1 parameters.").arg(parametersSent)); + // Set timeouts + if (transmissionActive) { + transmissionTimeout += parametersSent*rewriteTimeout; + } + else { + transmissionActive = true; + quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + parametersSent*rewriteTimeout; + if (newTransmissionTimeout > transmissionTimeout) { + transmissionTimeout = newTransmissionTimeout; + } + } + // Enable guard + setRetransmissionGuardEnabled(true); + } +} + diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 72da05d8f8..ff366c38e1 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -10,9 +10,19 @@ class UASInterface; class UASParameterDataModel; + + class UASParameterCommsMgr : public QObject { Q_OBJECT + +typedef enum ParamCommsStatusLevel { + ParamCommsStatusLevel_OK = 0, + ParamCommsStatusLevel_Warning = 2, + ParamCommsStatusLevel_Error = 4, + ParamCommsStatusLevel_Count +} ParamCommsStatusLevel_t; + public: explicit UASParameterCommsMgr(QObject *parent = 0, UASInterface* uas = NULL); @@ -21,19 +31,30 @@ protected: /** @brief Activate / deactivate parameter retransmission */ virtual void setRetransmissionGuardEnabled(bool enabled); - virtual void setParameterStatusMsg(const QString& msg); + virtual void setParameterStatusMsg(const QString& msg, ParamCommsStatusLevel_t level=ParamCommsStatusLevel_OK); + + /** @brief Load settings that control eg retransmission timeouts */ + void loadParamCommsSettings(); signals: void parameterChanged(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); - void parameterValueConfirmed(int component, QString parameter, QVariant value); + void parameterValueConfirmed(int uas, int component,int paramCount, int paramId, QString parameter, QVariant value); void parameterListUpToDate(int component); void parameterUpdateRequested(int component, const QString& parameter); void parameterUpdateRequestedById(int componentId, int paramId); + /** @brief We updated the parameter status message */ + void parameterStatusMsgUpdated(QString msg, ParamCommsStatusLevel_t level); public slots: + /** @brief Iterate through all components, through all pending parameters and send them to UAS */ + virtual void sendPendingParameters(); + + /** @brief Write the current onboard parameters from transient RAM into persistent storage, e.g. EEPROM or harddisk */ + virtual void writeParamsToPersistentStorage(); + /** @brief Write one parameter to the MAV */ virtual void setParameter(int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ @@ -44,6 +65,12 @@ public slots: /** @brief Request a single parameter update by name */ virtual void requestParameterUpdate(int component, const QString& parameter); + virtual void receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value); + +protected slots: + void receivedParameterChange(int uas, int component, QString parameterName, QVariant value); + void receivedParameterListChange(int uas, int component, int parameterCount, int parameterId, QString parameterName, QVariant value); + protected: UASInterface* mav; ///< The MAV we're talking to diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index d678385dcf..0a5f9d9724 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -103,13 +103,13 @@ void UASParameterDataModel::setOnboardParameterWithType(int componentId, QString } } -void UASParameterDataModel::addComponent(int componentId) +void UASParameterDataModel::addComponent(int compId) { - if (!onboardParameters.contains(componentId)) { - onboardParameters.insert(componentId, new QMap()); + if (!onboardParameters.contains(compId)) { + onboardParameters.insert(compId, new QMap()); } - if (!pendingParameters.contains(componentId)) { - pendingParameters.insert(componentId, new QMap()); + if (!pendingParameters.contains(compId)) { + pendingParameters.insert(compId, new QMap()); } } diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 0f89ed4365..240d375071 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -14,6 +14,7 @@ public: explicit UASParameterDataModel(QObject *parent = 0); + int getTotalOnboardParams() { return totalOnboardParameters; } //Parameter meta info bool isParamMinKnown(const QString& param) { return paramMin.contains(param); } virtual bool isValueLessThanParamMin(const QString& param, double dblVal); @@ -28,8 +29,11 @@ public: virtual QString getParamDescription(const QString& param) { return paramDescriptions.value(param, ""); } virtual void setParamDescriptions(const QMap& paramInfo); - - virtual void addComponent(int componentId); + //TODO make this method protected? + /** @brief Ensure that the data model is aware of this component + * @param compId Id of the component + */ + virtual void addComponent(int compId); /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ virtual void setPendingParameter(int componentId, QString& key, const QVariant& value); @@ -83,6 +87,8 @@ public: signals: + void parameterUpdated(int compId, int paramId, QString paramName, QVariant value); + public slots: @@ -90,6 +96,7 @@ protected: int uasId; ///< The UAS / MAV to which this data model pertains QMap* > pendingParameters; ///< Changed values that have not yet been transmitted to the UAS, by component ID QMap* > onboardParameters; ///< All parameters confirmed to be stored onboard the UAS, by component ID + int totalOnboardParameters;///< The known count of onboard parameters, may not match onboardParameters until all params are received // Tooltip data structures QMap paramDescriptions; ///< Tooltip values diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 4c973cd2aa..97e0d1eb31 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -36,12 +36,13 @@ This file is part of the QGROUNDCONTROL project #include #include #include +#include -#include "QGCParamWidget.h" -#include "UASInterface.h" #include "MainWindow.h" -#include #include "QGC.h" +#include "QGCParamWidget.h" +#include "UASInterface.h" +#include "UASParameterCommsMgr.h" /** * @param uas MAV to set the parameters on @@ -51,13 +52,6 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QGCUASParamManager(uas, parent), componentItems(new QMap()) { - // Load settings - loadSettings(); - - // Load default values and tooltips - QString autoPilotName(uas->getAutopilotTypeName()); - QString sysTypeName(uas->getSystemTypeName()); - loadParamMetaInfoCSV(autoPilotName, sysTypeName); // Create tree widget tree = new QTreeWidget(this); @@ -145,14 +139,10 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); - connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); - - +// connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); // connect(this, SIGNAL(requestParameter(int,QString)), uas, SLOT(requestParameter(int,QString))); // connect(this, SIGNAL(requestParameter(int,int)), uas, SLOT(requestParameter(int,int))); - - // Get parameters if (uas) { requestAllParamsUpdate(); @@ -160,245 +150,203 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : } -void QGCParamWidget::loadSettings() -{ - QSettings settings; - settings.beginGroup("QGC_MAVLINK_PROTOCOL"); - bool ok; - int temp = settings.value("PARAMETER_RETRANSMISSION_TIMEOUT", retransmissionTimeout).toInt(&ok); - if (ok) retransmissionTimeout = temp; - temp = settings.value("PARAMETER_REWRITE_TIMEOUT", rewriteTimeout).toInt(&ok); - if (ok) rewriteTimeout = temp; - settings.endGroup(); -} - - -void QGCParamWidget::loadParamMetaInfoCSV(const QString& autopilot, const QString& airframe) -{ - Q_UNUSED(airframe); - qDebug() << "ATTEMPTING TO LOAD CSV"; - QDir appDir = QApplication::applicationDirPath(); - appDir.cd("files"); - QString fileName = QString("%1/%2/parameter_tooltips/tooltips.txt").arg(appDir.canonicalPath()).arg(autopilot.toLower()); - QFile paramMetaFile(fileName); - qDebug() << "AUTOPILOT:" << autopilot; - qDebug() << "FILENAME: " << fileName; - - // Load CSV data - if (!paramMetaFile.open(QIODevice::ReadOnly | QIODevice::Text)) - { - //qDebug() << "COULD NOT OPEN PARAM META INFO FILE:" << fileName; - return; - } - - - QTextStream in(¶mMetaFile); - paramDataModel->loadParamMetaInfoFromStream(in); - paramMetaFile.close(); - -} - -/** - * @return The MAV of this widget. Unless the MAV object has been destroyed, this - * pointer is never zero. - */ -UASInterface* QGCParamWidget::getUAS() -{ - return mav; -} - -/** - * - * @param uas System which has the component - * @param component id of the component - * @param componentName human friendly name of the component - */ -void QGCParamWidget::addComponentItem(int uas, int component, QString componentName) +void QGCParamWidget::addComponentItem( int compId, QString compName) { - Q_UNUSED(uas); - if (componentItems->contains(component)) { + if (componentItems->contains(compId)) { // Update existing - componentItems->value(component)->setData(0, Qt::DisplayRole, QString("%1 (#%2)").arg(componentName).arg(component)); + componentItems->value(compId)->setData(0, Qt::DisplayRole, QString("%1 (#%2)").arg(compName).arg(compId)); //components->value(component)->setData(1, Qt::DisplayRole, QString::number(component)); - componentItems->value(component)->setFirstColumnSpanned(true); + componentItems->value(compId)->setFirstColumnSpanned(true); } else { // Add new - QStringList list(QString("%1 (#%2)").arg(componentName).arg(component)); + QStringList list(QString("%1 (#%2)").arg(compName).arg(compId)); QTreeWidgetItem* comp = new QTreeWidgetItem(list); comp->setFirstColumnSpanned(true); - componentItems->insert(component, comp); + componentItems->insert(compId, comp); // Create grouping and update maps - paramGroups.insert(component, new QMap()); + paramGroups.insert(compId, new QMap()); tree->addTopLevelItem(comp); tree->update(); } - paramDataModel->addComponent(component); + //TODO it seems unlikely that the UI would know about a component before the data model... + paramDataModel->addComponent(compId); } + + /** * @param uas System which has the component * @param component id of the component * @param parameterName human friendly name of the parameter */ -void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) +//void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) +//{ + +// updateParameterDisplay(component, parameterName, value); + +// // Missing packets list has to be instantiated for all components +// if (!transmissionMissingPackets.contains(component)) { +// transmissionMissingPackets.insert(component, new QList()); +// } + +// // List mode is different from single parameter transfers +// if (transmissionListMode) { +// // Only accept the list size once on the first packet from +// // each component +// if (!transmissionListSizeKnown.contains(component)) +// { +// // Mark list size as known +// transmissionListSizeKnown.insert(component, true); + +// // Mark all parameters as missing +// for (int i = 0; i < paramCount; ++i) +// { +// if (!transmissionMissingPackets.value(component)->contains(i)) +// { +// transmissionMissingPackets.value(component)->append(i); +// } +// } + +// // There is only one transmission timeout for all components +// // since components do not manage their transmission, +// // the longest timeout is safe for all components. +// quint64 thisTransmissionTimeout = QGC::groundTimeMilliseconds() + ((paramCount)*retransmissionTimeout); +// if (thisTransmissionTimeout > transmissionTimeout) +// { +// transmissionTimeout = thisTransmissionTimeout; +// } +// } + +// // Start retransmission guard +// // or reset timer +// paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO +// } + +// // Mark this parameter as received in read list +// int index = transmissionMissingPackets.value(component)->indexOf(paramId); +// // If the MAV sent the parameter without request, it wont be in missing list +// if (index != -1) transmissionMissingPackets.value(component)->removeAt(index); + +// bool justWritten = false; +// bool writeMismatch = false; +// //bool lastWritten = false; +// // Mark this parameter as received in write ACK list +// QMap* map = transmissionMissingWriteAckPackets.value(component); +// if (map && map->contains(parameterName)) +// { +// justWritten = true; +// QVariant newval = map->value(parameterName); +// if (map->value(parameterName) != value) +// { +// writeMismatch = true; +// } +// map->remove(parameterName); +// } + +// int missCount = 0; +// foreach (int key, transmissionMissingPackets.keys()) +// { +// missCount += transmissionMissingPackets.value(key)->count(); +// } + +// int missWriteCount = 0; +// foreach (int key, transmissionMissingWriteAckPackets.keys()) +// { +// missWriteCount += transmissionMissingWriteAckPackets.value(key)->count(); +// } + +// if (justWritten && !writeMismatch && missWriteCount == 0) +// { +// // Just wrote one and count went to 0 - this was the last missing write parameter +// statusLabel->setText(tr("SUCCESS: WROTE ALL PARAMETERS")); +// QPalette pal = statusLabel->palette(); +// pal.setColor(backgroundRole(), QGC::colorGreen); +// statusLabel->setPalette(pal); +// } else if (justWritten && !writeMismatch) +// { +// statusLabel->setText(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(parameterName).arg(value.toDouble()).arg(paramCount)); +// QPalette pal = statusLabel->palette(); +// pal.setColor(backgroundRole(), QGC::colorGreen); +// statusLabel->setPalette(pal); +// } else if (justWritten && writeMismatch) +// { +// // Mismatch, tell user +// QPalette pal = statusLabel->palette(); +// pal.setColor(backgroundRole(), QGC::colorRed); +// statusLabel->setPalette(pal); +// statusLabel->setText(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(parameterName).arg(map->value(parameterName).toDouble()).arg(value.toDouble())); +// } +// else +// { +// if (missCount > 0) +// { +// QPalette pal = statusLabel->palette(); +// pal.setColor(backgroundRole(), QGC::colorOrange); +// statusLabel->setPalette(pal); +// } +// else +// { +// QPalette pal = statusLabel->palette(); +// pal.setColor(backgroundRole(), QGC::colorGreen); +// statusLabel->setPalette(pal); +// } +// QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); +// //statusLabel->setText(tr("OK: %1 %2 #%3/%4, %5 miss").arg(parameterName).arg(val).arg(paramId+1).arg(paramCount).arg(missCount)); +// if (missCount == 0) +// { +// // Transmission done +// QTime time = QTime::currentTime(); +// QString timeString = time.toString(); +// statusLabel->setText(tr("All received. (updated at %1)").arg(timeString)); +// } +// else +// { +// // Transmission in progress +// statusLabel->setText(tr("OK: %1 %2 (%3/%4)").arg(parameterName).arg(val).arg(paramCount-missCount).arg(paramCount)); +// } +// } + +// // Check if last parameter was received +// if (missCount == 0 && missWriteCount == 0) +// { +// this->transmissionActive = false; +// this->transmissionListMode = false; +// transmissionListSizeKnown.clear(); +// foreach (int key, transmissionMissingPackets.keys()) +// { +// transmissionMissingPackets.value(key)->clear(); +// } + +// // Expand visual tree +// tree->expandItem(tree->topLevelItem(0)); +// } +//} + + +void QGCParamWidget::handleParameterUpdate(int componentId, int paramCount, int paramId, const QString& paramName, QVariant value) { + Q_UNUSED(paramCount); + Q_UNUSED(paramId); + updateParameterDisplay(componentId, paramName, value); +} - updateParameterDisplay(uas, component, parameterName, value); - - // Missing packets list has to be instantiated for all components - if (!transmissionMissingPackets.contains(component)) { - transmissionMissingPackets.insert(component, new QList()); - } - - // List mode is different from single parameter transfers - if (transmissionListMode) { - // Only accept the list size once on the first packet from - // each component - if (!transmissionListSizeKnown.contains(component)) - { - // Mark list size as known - transmissionListSizeKnown.insert(component, true); - - // Mark all parameters as missing - for (int i = 0; i < paramCount; ++i) - { - if (!transmissionMissingPackets.value(component)->contains(i)) - { - transmissionMissingPackets.value(component)->append(i); - } - } - - // There is only one transmission timeout for all components - // since components do not manage their transmission, - // the longest timeout is safe for all components. - quint64 thisTransmissionTimeout = QGC::groundTimeMilliseconds() + ((paramCount)*retransmissionTimeout); - if (thisTransmissionTimeout > transmissionTimeout) - { - transmissionTimeout = thisTransmissionTimeout; - } - } - - // Start retransmission guard - // or reset timer - setRetransmissionGuardEnabled(true); - } - - // Mark this parameter as received in read list - int index = transmissionMissingPackets.value(component)->indexOf(paramId); - // If the MAV sent the parameter without request, it wont be in missing list - if (index != -1) transmissionMissingPackets.value(component)->removeAt(index); - - bool justWritten = false; - bool writeMismatch = false; - //bool lastWritten = false; - // Mark this parameter as received in write ACK list - QMap* map = transmissionMissingWriteAckPackets.value(component); - if (map && map->contains(parameterName)) - { - justWritten = true; - QVariant newval = map->value(parameterName); - if (map->value(parameterName) != value) - { - writeMismatch = true; - } - map->remove(parameterName); - } - - int missCount = 0; - foreach (int key, transmissionMissingPackets.keys()) - { - missCount += transmissionMissingPackets.value(key)->count(); - } - - int missWriteCount = 0; - foreach (int key, transmissionMissingWriteAckPackets.keys()) - { - missWriteCount += transmissionMissingWriteAckPackets.value(key)->count(); - } - - if (justWritten && !writeMismatch && missWriteCount == 0) - { - // Just wrote one and count went to 0 - this was the last missing write parameter - statusLabel->setText(tr("SUCCESS: WROTE ALL PARAMETERS")); - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorGreen); - statusLabel->setPalette(pal); - } else if (justWritten && !writeMismatch) - { - statusLabel->setText(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(parameterName).arg(value.toDouble()).arg(paramCount)); - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorGreen); - statusLabel->setPalette(pal); - } else if (justWritten && writeMismatch) - { - // Mismatch, tell user - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorRed); - statusLabel->setPalette(pal); - statusLabel->setText(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(parameterName).arg(map->value(parameterName).toDouble()).arg(value.toDouble())); - } - else - { - if (missCount > 0) - { - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorOrange); - statusLabel->setPalette(pal); - } - else - { - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorGreen); - statusLabel->setPalette(pal); - } - QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); - //statusLabel->setText(tr("OK: %1 %2 #%3/%4, %5 miss").arg(parameterName).arg(val).arg(paramId+1).arg(paramCount).arg(missCount)); - if (missCount == 0) - { - // Transmission done - QTime time = QTime::currentTime(); - QString timeString = time.toString(); - statusLabel->setText(tr("All received. (updated at %1)").arg(timeString)); - } - else - { - // Transmission in progress - statusLabel->setText(tr("OK: %1 %2 (%3/%4)").arg(parameterName).arg(val).arg(paramCount-missCount).arg(paramCount)); - } - } - - // Check if last parameter was received - if (missCount == 0 && missWriteCount == 0) - { - this->transmissionActive = false; - this->transmissionListMode = false; - transmissionListSizeKnown.clear(); - foreach (int key, transmissionMissingPackets.keys()) - { - transmissionMissingPackets.value(key)->clear(); - } - // Expand visual tree - tree->expandItem(tree->topLevelItem(0)); - } +void QGCParamWidget::handleParameterListUpToDate(int component) +{ + // Expand visual tree + tree->expandItem(tree->topLevelItem(0)); } -/** - * @param uas System which has the component - * @param component id of the component - * @param parameterName human friendly name of the parameter - */ -void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString parameterName, QVariant value) -{ - Q_UNUSED(uas); +void QGCParamWidget::updateParameterDisplay(int componentId, QString parameterName, QVariant value) +{ // QString ptrStr; // ptrStr.sprintf("%8p", this); @@ -410,11 +358,12 @@ void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString pa // Get component if (!componentItems->contains(componentId)) { QString componentName = tr("Component #%1").arg(componentId); - addComponentItem(uas, componentId, componentName); + addComponentItem(componentId, componentName); } - // Replace value in data model - paramDataModel->handleParameterUpdate(componentId,parameterName,value); + //TODO this should be bubbling up from the model, not vice-versa, right? +// // Replace value in data model +// paramDataModel->handleParameterUpdate(componentId,parameterName,value); QString splitToken = "_"; @@ -439,36 +388,30 @@ void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString pa for (int i = 0; i < parentItem->childCount(); i++) { QTreeWidgetItem* child = parentItem->child(i); QString key = child->data(0, Qt::DisplayRole).toString(); - if (key == parameterName) - { + if (key == parameterName) { //qDebug() << "UPDATED CHILD"; parameterItem = child; - if (value.type() == QVariant::Char) - { + if (value.type() == QVariant::Char) { parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); } - else - { + else { parameterItem->setData(1, Qt::DisplayRole, value); } found = true; } } - if (!found) - { + if (!found) { // Insert parameter into map QStringList plist; plist.append(parameterName); // CREATE PARAMETER ITEM parameterItem = new QTreeWidgetItem(plist); // CONFIGURE PARAMETER ITEM - if (value.type() == QVariant::Char) - { + if (value.type() == QVariant::Char) { parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); } - else - { + else { parameterItem->setData(1, Qt::DisplayRole, value); } @@ -476,16 +419,13 @@ void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString pa parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); } } - else - { + else { bool found = false; QTreeWidgetItem* parent = componentItems->value(componentId); - for (int i = 0; i < parent->childCount(); i++) - { + for (int i = 0; i < parent->childCount(); i++) { QTreeWidgetItem* child = parent->child(i); QString key = child->data(0, Qt::DisplayRole).toString(); - if (key == parameterName) - { + if (key == parameterName) { //qDebug() << "UPDATED CHILD"; parameterItem = child; parameterItem->setData(1, Qt::DisplayRole, value); @@ -493,8 +433,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString pa } } - if (!found) - { + if (!found) { // Insert parameter into map QStringList plist; plist.append(parameterName); @@ -525,7 +464,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString pa parameterItem->setToolTip(0, tooltipFormat); parameterItem->setToolTip(1, tooltipFormat); - paramDataModel->handleParameterUpdate(componentId,parameterName,value); + //paramDataModel->handleParameterUpdate(componentId,parameterName,value); } @@ -600,21 +539,12 @@ void QGCParamWidget::setParameterStatusMsg(const QString& msg) statusLabel->setText(msg); } - - void QGCParamWidget::requestAllParamsUpdate() { if (!mav) { return; } - // FIXME This call does not belong here - // Once the comm handling is moved to a new - // Param manager class the settings can be directly - // loaded from MAVLink protocol - loadSettings(); - // End of FIXME - // Clear view and request param list clear(); @@ -628,45 +558,7 @@ void QGCParamWidget::requestAllParamsUpdate() */ void QGCParamWidget::setParameters() { - // Iterate through all components, through all parameters and emit them - int parametersSent = 0; - QMap*> changedValues = paramDataModel->getPendingParameters(); - QMap*>::iterator i; - for (i = changedValues.begin(); i != changedValues.end(); ++i) { - // Iterate through the parameters of the component - int compid = i.key(); - QMap* comp = i.value(); - { - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) { - //TODO mavlink command for "set parameter list" ? - setParameter(compid, j.key(), j.value()); - parametersSent++; - } - } - } - - // Change transmission status if necessary - if (parametersSent == 0) { - statusLabel->setText(tr("No transmission: No changed values.")); - } else { - statusLabel->setText(tr("Transmitting %1 parameters.").arg(parametersSent)); - // Set timeouts - if (transmissionActive) - { - transmissionTimeout += parametersSent*rewriteTimeout; - } - else - { - transmissionActive = true; - quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + parametersSent*rewriteTimeout; - if (newTransmissionTimeout > transmissionTimeout) { - transmissionTimeout = newTransmissionTimeout; - } - } - // Enable guard - setRetransmissionGuardEnabled(true); - } + paramCommsMgr->sendPendingParameters(); } /** @@ -680,28 +572,19 @@ void QGCParamWidget::writeParameters() QMap*>::iterator i; QMap*> changedValues = paramDataModel->getPendingParameters(); - for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) - { + for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) { // Iterate through the parameters of the component - QMap* comp = i.value(); - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) - { - changedParamCount++; - break;//it only takes one changed param to warrant warning the user - } + QMap* compPending = i.value(); + changedParamCount += compPending->count(); } - if (changedParamCount > 0) - { + if (changedParamCount > 0) { QMessageBox msgBox; msgBox.setText(tr("There are locally changed parameters. Please transmit them first () or update them with the onboard values () before storing onboard from RAM to ROM.")); msgBox.exec(); } - else - { - if (!mav) return; - mav->writeParametersToStorage(); + else { + paramCommsMgr->writeParamsToPersistentStorage(); } } @@ -796,7 +679,7 @@ void QGCParamWidget::setParameter(int component, QString parameterName, QVariant } // Enable guard / reset timeouts - setRetransmissionGuardEnabled(true); + paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO } void QGCParamWidget::readParameters() diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index af58eabf3f..0ada126d7e 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -48,9 +48,6 @@ class QGCParamWidget : public QGCUASParamManager Q_OBJECT public: QGCParamWidget(UASInterface* uas, QWidget *parent = 0); - /** @brief Get the UAS of this widget */ - UASInterface* getUAS(); - protected: virtual void setParameterStatusMsg(const QString& msg); @@ -61,12 +58,20 @@ signals: public slots: - /** @brief Add a component to the list */ - void addComponentItem(int uas, int component, QString componentName); + /** @brief Add a component to the list + * @param compId Component id of the component + * @param compName Human friendly name of the component + */ + void addComponentItem(int compId, QString compName); + /** @brief Add a parameter to the list with retransmission / safety checks */ - void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); - /** @brief Add a parameter to the list */ - void updateParameterDisplay(int uas, int component, QString parameterName, QVariant value); +// void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); + + virtual void handleParameterUpdate(int component, int paramCount, int paramId, const QString& parameterName, QVariant value); + virtual void handleParameterListUpToDate(int component); + + /** @brief Ensure that view of parameter matches data in the model */ + void updateParameterDisplay(int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ void requestAllParamsUpdate(); /** @brief Set one parameter, changes value in RAM of MAV */ @@ -91,17 +96,11 @@ public slots: protected: QTreeWidget* tree; ///< The parameter tree - QLabel* statusLabel; ///< Parameter transmission label - QMap* componentItems; ///< The list of component items, stored by component ID - QMap* > paramGroups; ///< Parameter groups - - + QLabel* statusLabel; ///< User-facing parameter status label + QMap* componentItems; ///< The tree of component items, stored by component ID + QMap* > paramGroups; ///< Parameter groups to organize component items - /** @brief Load settings */ - void loadSettings(); - /** @brief Load meta information from CSV */ - void loadParamMetaInfoCSV(const QString& autopilot, const QString& airframe); }; #endif // QGCPARAMWIDGET_H -- GitLab From 39bb543e1c9d8a00a5a99e7fb655cb3490cbd6e4 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 7 Aug 2013 18:11:39 -0700 Subject: [PATCH 170/460] fix build --- src/uas/QGCUASParamManager.cc | 15 ++- src/uas/QGCUASParamManager.h | 9 +- src/uas/UASParameterCommsMgr.cc | 32 +++--- src/uas/UASParameterCommsMgr.h | 25 ++-- src/ui/QGCParamWidget.cc | 197 +++++++++++++++++--------------- src/ui/QGCParamWidget.h | 6 +- 6 files changed, 161 insertions(+), 123 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 79b03d2059..186bfac74b 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -1,6 +1,9 @@ #include "QGCUASParamManager.h" -#include "UASInterface.h" +#include > +#include + +#include "UASInterface.h" #include "UASParameterCommsMgr.h" QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : @@ -28,15 +31,15 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : void parameterUpdated(int compId, int paramId, QString paramName, QVariant value); connect(paramDataModel, SIGNAL(parameterUpdated(int, int, QString , QVariant )), - this, SLOT(handleParameterUpdate(int,int,int,QString,QVariant)); + this, SLOT(handleParameterUpdate(int,int,int,QString,QVariant))); // connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), // this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); // Listen for param list reload finished - connect(paramCommsMgr, SIGNAL(parameterListUpToDate(int)), - this, SLOT(handleParameterListUpToDate(int)))); + connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), + this, SLOT(handleParameterListUpToDate())); @@ -206,6 +209,10 @@ void QGCUASParamManager::setParamDescriptions(const QMap& param } +void QGCUASParamManager::setParameter(int component, QString parameterName, QVariant value) +{ + paramCommsMgr->setParameter(component,parameterName,value); +} void QGCUASParamManager::loadParamMetaInfoCSV() diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 313c0927ad..3c1fb7e78c 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -43,16 +43,17 @@ signals: public slots: - /** @brief Write one parameter to the MAV */ - virtual void setParameter(int component, QString parameterName, QVariant value) = 0; + /** @brief Send one parameter to the MAV: changes value in transient memory of MAV */ + virtual void setParameter(int component, QString parameterName, QVariant value); + /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); - /** @brief Request a single parameter by name */ + /** @brief Request a single parameter by name from the MAV */ virtual void requestParameterUpdate(int component, const QString& parameter); virtual void handleParameterUpdate(int component, int paramCount, int paramId, const QString& parameterName, QVariant value) = 0; - virtual void handleParameterListUpToDate(int component) = 0; + virtual void handleParameterListUpToDate() = 0; protected: diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 22940e5fd3..594e2447ec 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -1,5 +1,7 @@ #include "UASParameterCommsMgr.h" +#include + #include "QGCUASParamManager.h" #include "UASInterface.h" @@ -38,14 +40,14 @@ void UASParameterCommsMgr::loadParamCommsSettings() { QSettings settings; settings.beginGroup("QGC_MAVLINK_PROTOCOL"); - bool valid; + bool ok; int val = settings.value("PARAMETER_RETRANSMISSION_TIMEOUT", retransmissionTimeout).toInt(&ok); - if (valid) { - retransmissionTimeout = temp; + if (ok) { + retransmissionTimeout = val; } val = settings.value("PARAMETER_REWRITE_TIMEOUT", rewriteTimeout).toInt(&ok); - if (valid) { - rewriteTimeout = temp; + if (ok) { + rewriteTimeout = val; } settings.endGroup(); } @@ -224,17 +226,23 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV double dblValue = value.toDouble(); if (paramDataModel->isValueLessThanParamMin(parameterName,dblValue)) { - setParameterStatusMsg(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); + setParameterStatusMsg(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue), + ParamCommsStatusLevel_Error + ); return; } if (paramDataModel->isValueGreaterThanParamMax(parameterName,dblValue)) { - setParameterStatusMsg(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); + setParameterStatusMsg(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue), + ParamCommsStatusLevel_Error + ); return; } QVariant onboardVal; paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); if (onboardVal == value) { - setParameterStatusMsg(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue)); + setParameterStatusMsg(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue), + ParamCommsStatusLevel_Warning + ); return; } @@ -246,28 +254,24 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV { QVariant fixedValue(QChar((unsigned char)value.toInt())); emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; } break; case QVariant::Int: { QVariant fixedValue(value.toInt()); emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; } break; case QVariant::UInt: { QVariant fixedValue(value.toUInt()); emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; } break; case QMetaType::Float: { QVariant fixedValue(value.toFloat()); emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; } break; default: @@ -309,6 +313,8 @@ void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg, ParamCommsS qDebug() << "parameterStatusMsg: " << msg; parameterStatusMsg = msg; + emit parameterStatusMsgUpdated(msg,level); + //TODO indicate OK status somehow (eg color) // QPalette pal = statusLabel->palette(); // pal.setColor(backgroundRole(), QGC::colorGreen); @@ -360,7 +366,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para // Start retransmission guard // or reset timer - paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO + setRetransmissionGuardEnabled(true); //TODO } // Mark this parameter as received in read list diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index ff366c38e1..68c908bade 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -16,16 +16,16 @@ class UASParameterCommsMgr : public QObject { Q_OBJECT -typedef enum ParamCommsStatusLevel { - ParamCommsStatusLevel_OK = 0, - ParamCommsStatusLevel_Warning = 2, - ParamCommsStatusLevel_Error = 4, - ParamCommsStatusLevel_Count -} ParamCommsStatusLevel_t; public: explicit UASParameterCommsMgr(QObject *parent = 0, UASInterface* uas = NULL); - + typedef enum ParamCommsStatusLevel { + ParamCommsStatusLevel_OK = 0, + ParamCommsStatusLevel_Warning = 2, + ParamCommsStatusLevel_Error = 4, + ParamCommsStatusLevel_Count + } ParamCommsStatusLevel_t; + protected: /** @brief Activate / deactivate parameter retransmission */ @@ -41,7 +41,9 @@ signals: void parameterChanged(int component, int parameterIndex, QVariant value); void parameterValueConfirmed(int uas, int component,int paramCount, int paramId, QString parameter, QVariant value); - void parameterListUpToDate(int component); + /** @brief We have received a complete list of all parameters onboard the MAV */ + void parameterListUpToDate(); + void parameterUpdateRequested(int component, const QString& parameter); void parameterUpdateRequestedById(int componentId, int paramId); @@ -57,6 +59,7 @@ public slots: /** @brief Write one parameter to the MAV */ virtual void setParameter(int component, QString parameterName, QVariant value); + /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); /** @brief Check for missing parameters */ @@ -67,9 +70,9 @@ public slots: virtual void receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value); -protected slots: - void receivedParameterChange(int uas, int component, QString parameterName, QVariant value); - void receivedParameterListChange(int uas, int component, int parameterCount, int parameterId, QString parameterName, QVariant value); +//protected slots: +// void receivedParameterChange(int uas, int component, QString parameterName, QVariant value); +// void receivedParameterListChange(int uas, int component, int parameterCount, int parameterId, QString parameterName, QVariant value); protected: diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 97e0d1eb31..09ee9c970a 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -27,16 +27,17 @@ This file is part of the QGROUNDCONTROL project */ #include #include -#include -#include -#include +#include +#include #include +#include +#include + #include -#include -#include #include -#include -#include +#include +#include +#include #include "MainWindow.h" #include "QGC.h" @@ -338,7 +339,7 @@ void QGCParamWidget::handleParameterUpdate(int componentId, int paramCount, int } -void QGCParamWidget::handleParameterListUpToDate(int component) +void QGCParamWidget::handleParameterListUpToDate() { // Expand visual tree tree->expandItem(tree->topLevelItem(0)); @@ -593,94 +594,95 @@ void QGCParamWidget::writeParameters() * @param parameterName name of the parameter, as delivered by the system * @param value value of the parameter */ -void QGCParamWidget::setParameter(int component, QString parameterName, QVariant value) -{ - if (parameterName.isEmpty()) { - return; - } +//void QGCParamWidget::setParameter(int component, QString parameterName, QVariant value) +//{ - double dblValue = value.toDouble(); +// if (parameterName.isEmpty()) { +// return; +// } - if (paramDataModel->isValueLessThanParamMin(parameterName,dblValue)) { - statusLabel->setText(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); - return; - } - if (paramDataModel->isValueGreaterThanParamMax(parameterName,dblValue)) { - statusLabel->setText(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); - return; - } - QVariant onboardVal; - paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); - if (onboardVal == value) { - statusLabel->setText(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue)); - return; - } +// double dblValue = value.toDouble(); - //int paramType = (int)onboardParameters.value(component)->value(parameterName).type(); - int paramType = (int)value.type(); - switch (paramType) - { - case QVariant::Char: - { - QVariant fixedValue(QChar((unsigned char)value.toInt())); - emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; - } - break; - case QVariant::Int: - { - QVariant fixedValue(value.toInt()); - emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; - } - break; - case QVariant::UInt: - { - QVariant fixedValue(value.toUInt()); - emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; - } - break; - case QMetaType::Float: - { - QVariant fixedValue(value.toFloat()); - emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; - } - break; - default: - qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE"; - return; - } +// if (paramDataModel->isValueLessThanParamMin(parameterName,dblValue)) { +// statusLabel->setText(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); +// return; +// } +// if (paramDataModel->isValueGreaterThanParamMax(parameterName,dblValue)) { +// statusLabel->setText(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); +// return; +// } +// QVariant onboardVal; +// paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); +// if (onboardVal == value) { +// statusLabel->setText(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue)); +// return; +// } - // Wait for parameter to be written back - // mark it therefore as missing - if (!transmissionMissingWriteAckPackets.contains(component)) - { - transmissionMissingWriteAckPackets.insert(component, new QMap()); - } +// //int paramType = (int)onboardParameters.value(component)->value(parameterName).type(); +// int paramType = (int)value.type(); +// switch (paramType) +// { +// case QVariant::Char: +// { +// QVariant fixedValue(QChar((unsigned char)value.toInt())); +// emit parameterChanged(component, parameterName, fixedValue); +// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; +// } +// break; +// case QVariant::Int: +// { +// QVariant fixedValue(value.toInt()); +// emit parameterChanged(component, parameterName, fixedValue); +// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; +// } +// break; +// case QVariant::UInt: +// { +// QVariant fixedValue(value.toUInt()); +// emit parameterChanged(component, parameterName, fixedValue); +// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; +// } +// break; +// case QMetaType::Float: +// { +// QVariant fixedValue(value.toFloat()); +// emit parameterChanged(component, parameterName, fixedValue); +// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; +// } +// break; +// default: +// qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE"; +// return; +// } - // Insert it in missing write ACK list - transmissionMissingWriteAckPackets.value(component)->insert(parameterName, value); +// // Wait for parameter to be written back +// // mark it therefore as missing +// if (!transmissionMissingWriteAckPackets.contains(component)) +// { +// transmissionMissingWriteAckPackets.insert(component, new QMap()); +// } - // Set timeouts - if (transmissionActive) - { - transmissionTimeout += rewriteTimeout; - } - else - { - quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + rewriteTimeout; - if (newTransmissionTimeout > transmissionTimeout) - { - transmissionTimeout = newTransmissionTimeout; - } - transmissionActive = true; - } +// // Insert it in missing write ACK list +// transmissionMissingWriteAckPackets.value(component)->insert(parameterName, value); - // Enable guard / reset timeouts - paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO -} +// // Set timeouts +// if (transmissionActive) +// { +// transmissionTimeout += rewriteTimeout; +// } +// else +// { +// quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + rewriteTimeout; +// if (newTransmissionTimeout > transmissionTimeout) +// { +// transmissionTimeout = newTransmissionTimeout; +// } +// transmissionActive = true; +// } + +// // Enable guard / reset timeouts +// paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO +//} void QGCParamWidget::readParameters() { @@ -696,3 +698,20 @@ void QGCParamWidget::clear() tree->clear(); componentItems->clear(); } + +void QGCParamWidget::handleParamStatusMsgUpdate(QString msg, int level) +{ + QColor bgColor = QGC::colorGreen; + if ((int)UASParameterCommsMgr::ParamCommsStatusLevel_Warning == level) { + bgColor = QGC::colorOrange; + } + else if ((int)UASParameterCommsMgr::ParamCommsStatusLevel_Error == level) { + bgColor = QGC::colorRed; + } + + QPalette pal = statusLabel->palette(); + pal.setColor(backgroundRole(), bgColor); + statusLabel->setPalette(pal); + statusLabel->setText(msg); + +} diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 0ada126d7e..3d2f7779eb 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -68,14 +68,16 @@ public slots: // void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); virtual void handleParameterUpdate(int component, int paramCount, int paramId, const QString& parameterName, QVariant value); - virtual void handleParameterListUpToDate(int component); + virtual void handleParameterListUpToDate(); + + virtual void handleParamStatusMsgUpdate(QString msg, int level); /** @brief Ensure that view of parameter matches data in the model */ void updateParameterDisplay(int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ void requestAllParamsUpdate(); /** @brief Set one parameter, changes value in RAM of MAV */ - virtual void setParameter(int component, QString parameterName, QVariant value); +// virtual void setParameter(int component, QString parameterName, QVariant value); /** @brief Set all parameters, changes the value in RAM of MAV */ void setParameters(); /** @brief Write the current parameters to permanent storage (EEPROM/HDD) */ -- GitLab From c1ed602e42889b885adbd64e9a3b96cdc398837f Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 7 Aug 2013 18:28:58 -0700 Subject: [PATCH 171/460] fixing signals / slots --- src/uas/QGCUASParamManager.cc | 12 ++++++------ src/uas/QGCUASParamManager.h | 2 +- src/uas/UASParameterDataModel.cc | 11 +++++++---- src/uas/UASParameterDataModel.h | 3 ++- src/ui/QGCParamWidget.cc | 3 +-- src/ui/QGCParamWidget.h | 2 +- src/ui/uas/UASListWidget.cc | 2 +- 7 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 186bfac74b..450fe79701 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -18,9 +18,9 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : loadParamMetaInfoCSV(); - // Connect retransmission guard - connect(this, SIGNAL(parameterUpdateRequested(int,QString)), - this, SLOT(requestParameterUpdate(int,QString))); +// // Connect retransmission guard +// connect(this, SIGNAL(parameterUpdateRequested(int,QString)), +// this, SLOT(requestParameterUpdate(int,QString))); // //TODO connect in paramCommsMgr instead // connect(this, SIGNAL(parameterUpdateRequestedById(int,int)), @@ -28,10 +28,10 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : // New parameters from UAS - void parameterUpdated(int compId, int paramId, QString paramName, QVariant value); + void parameterUpdated(int compId, QString paramName, QVariant value); - connect(paramDataModel, SIGNAL(parameterUpdated(int, int, QString , QVariant )), - this, SLOT(handleParameterUpdate(int,int,int,QString,QVariant))); + connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), + this, SLOT(handleParameterUpdate(int,QString,QVariant))); // connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), // this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 3c1fb7e78c..4cb6d446c1 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -52,7 +52,7 @@ public slots: /** @brief Request a single parameter by name from the MAV */ virtual void requestParameterUpdate(int component, const QString& parameter); - virtual void handleParameterUpdate(int component, int paramCount, int paramId, const QString& parameterName, QVariant value) = 0; + virtual void handleParameterUpdate(int component, int paramId, const QString& parameterName, QVariant value) = 0; virtual void handleParameterListUpToDate() = 0; diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 0a5f9d9724..9815ce7779 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -114,12 +114,12 @@ void UASParameterDataModel::addComponent(int compId) } -void UASParameterDataModel::handleParameterUpdate(int componentId, QString& key, QVariant& value) +void UASParameterDataModel::handleParameterUpdate(int compId, QString& key, QVariant& value) { //verify that the value requested by the user matches the set value //if it doesn't match, leave the pending parameter in the pending list! - if (pendingParameters.contains(componentId)) { - QMap *pendingParams = pendingParameters.value(componentId); + if (pendingParameters.contains(compId)) { + QMap *pendingParams = pendingParameters.value(compId); if ((NULL != pendingParams) && pendingParams->contains(key)) { QVariant reqVal = pendingParams->value(key); if (reqVal == value) { @@ -131,7 +131,10 @@ void UASParameterDataModel::handleParameterUpdate(int componentId, QString& key, } } - setOnboardParameter(componentId,key, value); + setOnboardParameter(compId,key,value); + + emit parameterUpdated(compId,key,value); + } bool UASParameterDataModel::getOnboardParameterValue(int componentId, const QString& key, QVariant& value) const diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 240d375071..352fb0eea6 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -87,7 +87,8 @@ public: signals: - void parameterUpdated(int compId, int paramId, QString paramName, QVariant value); + /** @brief We've received an update of a parameter's value */ + void parameterUpdated(int compId, QString paramName, QVariant value); public slots: diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 09ee9c970a..5b4b137239 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -331,9 +331,8 @@ void QGCParamWidget::addComponentItem( int compId, QString compName) //} -void QGCParamWidget::handleParameterUpdate(int componentId, int paramCount, int paramId, const QString& paramName, QVariant value) +void QGCParamWidget::handleParameterUpdate(int componentId, int paramId, const QString& paramName, QVariant value) { - Q_UNUSED(paramCount); Q_UNUSED(paramId); updateParameterDisplay(componentId, paramName, value); } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 3d2f7779eb..49ae507402 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -67,7 +67,7 @@ public slots: /** @brief Add a parameter to the list with retransmission / safety checks */ // void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); - virtual void handleParameterUpdate(int component, int paramCount, int paramId, const QString& parameterName, QVariant value); + virtual void handleParameterUpdate(int component, int paramId, const QString& parameterName, QVariant value); virtual void handleParameterListUpToDate(); virtual void handleParamStatusMsgUpdate(QString msg, int level); diff --git a/src/ui/uas/UASListWidget.cc b/src/ui/uas/UASListWidget.cc index d1cdde02eb..2b000d3769 100644 --- a/src/ui/uas/UASListWidget.cc +++ b/src/ui/uas/UASListWidget.cc @@ -149,7 +149,7 @@ void UASListWidget::addUAS(UASInterface* uas) QList* x = uas->getLinks(); if (x->size()) { - LinkInterface* li = x->at(0); + LinkInterface* li = x->first(); // Find an existing QGroupBox for this LinkInterface or create a // new one. -- GitLab From 73ce117b9ed78bf7a8d35a104a8b6cd0ffd025c3 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 7 Aug 2013 18:45:50 -0700 Subject: [PATCH 172/460] More signal /slot fixes --- src/uas/QGCUASParamManager.cc | 5 ----- src/uas/QGCUASParamManager.h | 2 +- src/ui/QGCParamWidget.cc | 21 +++++++++++++++------ src/ui/QGCParamWidget.h | 2 +- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 450fe79701..f1cc5fd20c 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -30,16 +30,11 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : void parameterUpdated(int compId, QString paramName, QVariant value); - connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), - this, SLOT(handleParameterUpdate(int,QString,QVariant))); // connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), // this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); - // Listen for param list reload finished - connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), - this, SLOT(handleParameterListUpToDate())); diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 4cb6d446c1..a5c4b40f2f 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -52,7 +52,7 @@ public slots: /** @brief Request a single parameter by name from the MAV */ virtual void requestParameterUpdate(int component, const QString& parameter); - virtual void handleParameterUpdate(int component, int paramId, const QString& parameterName, QVariant value) = 0; + virtual void handleParameterUpdate(int component, const QString& parameterName, QVariant value) = 0; virtual void handleParameterListUpToDate() = 0; diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 5b4b137239..5ec85bceba 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -133,17 +133,27 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : tree->setExpandsOnDoubleClick(true); // Connect signals/slots - connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), mav, SLOT(setParameter(int,QString,QVariant))); - connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); +// connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), +// mav, SLOT(setParameter(int,QString,QVariant))); + connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), + this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); - // New parameters from UAS - connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); +// // New parameters from UAS +// connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); // connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); // connect(this, SIGNAL(requestParameter(int,QString)), uas, SLOT(requestParameter(int,QString))); // connect(this, SIGNAL(requestParameter(int,int)), uas, SLOT(requestParameter(int,int))); + + connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), + this, SLOT(handleParameterUpdate(int,QString,QVariant))); + + // Listen for param list reload finished + connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), + this, SLOT(handleParameterListUpToDate())); + // Get parameters if (uas) { requestAllParamsUpdate(); @@ -331,9 +341,8 @@ void QGCParamWidget::addComponentItem( int compId, QString compName) //} -void QGCParamWidget::handleParameterUpdate(int componentId, int paramId, const QString& paramName, QVariant value) +void QGCParamWidget::handleParameterUpdate(int componentId, const QString& paramName, QVariant value) { - Q_UNUSED(paramId); updateParameterDisplay(componentId, paramName, value); } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 49ae507402..5a356b722b 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -67,7 +67,7 @@ public slots: /** @brief Add a parameter to the list with retransmission / safety checks */ // void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); - virtual void handleParameterUpdate(int component, int paramId, const QString& parameterName, QVariant value); + virtual void handleParameterUpdate(int component,const QString& parameterName, QVariant value); virtual void handleParameterListUpToDate(); virtual void handleParamStatusMsgUpdate(QString msg, int level); -- GitLab From 7b9f9806cba5e5c35c2abc382d27541cba0b80a3 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 06:37:44 -0700 Subject: [PATCH 173/460] fix setting of current mav in QGCConfigView --- src/ui/QGCConfigView.cc | 10 ++++++---- src/ui/QGCConfigView.h | 2 +- src/ui/QGCPX4VehicleConfig.cc | 17 ++++++++++------- src/ui/QGCVehicleConfig.cc | 1 + 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/ui/QGCConfigView.cc b/src/ui/QGCConfigView.cc index fb8f519b73..16fc3ecf94 100644 --- a/src/ui/QGCConfigView.cc +++ b/src/ui/QGCConfigView.cc @@ -8,7 +8,7 @@ QGCConfigView::QGCConfigView(QWidget *parent) : QWidget(parent), ui(new Ui::QGCConfigView), - currUAS(NULL) + mav(NULL) { ui->setupUi(this); @@ -26,7 +26,7 @@ QGCConfigView::~QGCConfigView() void QGCConfigView::activeUASChanged(UASInterface* uas) { - if (currUAS == uas) + if (mav == uas) return; //remove all child widgets since they could contain stale data @@ -41,11 +41,13 @@ void QGCConfigView::activeUASChanged(UASInterface* uas) } } - if (NULL != uas) { + mav = uas; + if (NULL != mav) { ui->gridLayout->removeWidget(ui->waitingLabel); ui->waitingLabel->setVisible(false); - switch (uas->getAutopilotType()) { + int autopilotType = mav->getAutopilotType(); + switch (autopilotType) { case MAV_AUTOPILOT_PX4: ui->gridLayout->addWidget(new QGCPX4VehicleConfig()); break; diff --git a/src/ui/QGCConfigView.h b/src/ui/QGCConfigView.h index 182d50c3b7..0c1bda9a57 100644 --- a/src/ui/QGCConfigView.h +++ b/src/ui/QGCConfigView.h @@ -21,7 +21,7 @@ public slots: private: Ui::QGCConfigView *ui; - UASInterface* currUAS; + UASInterface* mav; }; diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index f43f20a881..d526ed53b3 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -941,6 +941,7 @@ void QGCPX4VehicleConfig::writeCalibrationRC() // Do not write the RC type, as these values depend on this // active onboard parameter + //TODO consolidate RC param sending in the UAS comms mgr for (unsigned int i = 0; i < chanCount; ++i) { //qDebug() << "SENDING" << minTpl.arg(i+1) << rcMin[i]; @@ -975,7 +976,9 @@ void QGCPX4VehicleConfig::writeCalibrationRC() void QGCPX4VehicleConfig::requestCalibrationRC() { - if (!mav) return; + if (!mav ) { + return; + } QString minTpl("RC%1_MIN"); QString maxTpl("RC%1_MAX"); @@ -985,15 +988,15 @@ void QGCPX4VehicleConfig::requestCalibrationRC() // Do not request the RC type, as these values depend on this // active onboard parameter - for (unsigned int i = 0; i < chanMax; ++i) - { - mav->requestParameter(0, minTpl.arg(i+1)); + for (unsigned int i = 1; i < (chanMax+1); ++i) { + qDebug() << "Request RC " << i; + mav->requestParameter(0, minTpl.arg(i)); QGC::SLEEP::usleep(5000); - mav->requestParameter(0, trimTpl.arg(i+1)); + mav->requestParameter(0, trimTpl.arg(i)); QGC::SLEEP::usleep(5000); - mav->requestParameter(0, maxTpl.arg(i+1)); + mav->requestParameter(0, maxTpl.arg(i)); QGC::SLEEP::usleep(5000); - mav->requestParameter(0, revTpl.arg(i+1)); + mav->requestParameter(0, revTpl.arg(i)); QGC::SLEEP::usleep(5000); } } diff --git a/src/ui/QGCVehicleConfig.cc b/src/ui/QGCVehicleConfig.cc index dd2c769a7a..ce923ff49f 100644 --- a/src/ui/QGCVehicleConfig.cc +++ b/src/ui/QGCVehicleConfig.cc @@ -937,6 +937,7 @@ void QGCVehicleConfig::writeCalibrationRC() // Do not write the RC type, as these values depend on this // active onboard parameter + //TODO consolidate RC param sending in the UAS comms mgr for (unsigned int i = 0; i < chanCount; ++i) { //qDebug() << "SENDING" << minTpl.arg(i+1) << rcMin[i]; -- GitLab From 8f9d30cf5371f8a527dc3f447df0b920705837d3 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 06:56:38 -0700 Subject: [PATCH 174/460] Move requestCalibrationRC into commsmgr --- src/uas/UASParameterCommsMgr.cc | 31 +++++++++++++++++++++++++++++++ src/uas/UASParameterCommsMgr.h | 3 +++ src/ui/QGCPX4VehicleConfig.cc | 28 +++++----------------------- src/ui/QGCVehicleConfig.cc | 26 +++++--------------------- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 594e2447ec..25e772b3cc 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -5,6 +5,8 @@ #include "QGCUASParamManager.h" #include "UASInterface.h" +#define RC_CAL_CHAN_MAX 8 + UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : QObject(parent), mav(uas), @@ -212,6 +214,35 @@ void UASParameterCommsMgr::requestParameterUpdate(int component, const QString& } } +void UASParameterCommsMgr::requestRcCalibrationParamsUpdate() +{ + if (!transmissionListMode) { + QString minTpl("RC%1_MIN"); + QString maxTpl("RC%1_MAX"); + QString trimTpl("RC%1_TRIM"); + QString revTpl("RC%1_REV"); + + // Do not request the RC type, as these values depend on this + // active onboard parameter + + for (unsigned int i = 1; i < (RC_CAL_CHAN_MAX+1); ++i) { + qDebug() << "Request RC " << i; + mav->requestParameter(0, minTpl.arg(i)); + QGC::SLEEP::usleep(5000); + mav->requestParameter(0, trimTpl.arg(i)); + QGC::SLEEP::usleep(5000); + mav->requestParameter(0, maxTpl.arg(i)); + QGC::SLEEP::usleep(5000); + mav->requestParameter(0, revTpl.arg(i)); + QGC::SLEEP::usleep(5000); + } + } + else { + qDebug() << __FILE__ << __LINE__ << "Ignoring requestRcCalibrationParamsUpdate because we're receiving params list"; + } +} + + /** * @param component the subsystem which has the parameter * @param parameterName name of the parameter, as delivered by the system diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 68c908bade..03f24bb1d7 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -68,6 +68,9 @@ public slots: /** @brief Request a single parameter update by name */ virtual void requestParameterUpdate(int component, const QString& parameter); + /** @brief Request an update of RC parameters */ + virtual void requestRcCalibrationParamsUpdate(); + virtual void receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value); //protected slots: diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index d526ed53b3..708d5a0b7b 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -13,9 +13,11 @@ #include #include "QGCPX4VehicleConfig.h" -#include "UASManager.h" + #include "QGC.h" #include "QGCToolWidget.h" +#include "UASManager.h" +#include "UASParameterCommsMgr.h" #include "ui_QGCPX4VehicleConfig.h" @@ -976,28 +978,8 @@ void QGCPX4VehicleConfig::writeCalibrationRC() void QGCPX4VehicleConfig::requestCalibrationRC() { - if (!mav ) { - return; - } - - QString minTpl("RC%1_MIN"); - QString maxTpl("RC%1_MAX"); - QString trimTpl("RC%1_TRIM"); - QString revTpl("RC%1_REV"); - - // Do not request the RC type, as these values depend on this - // active onboard parameter - - for (unsigned int i = 1; i < (chanMax+1); ++i) { - qDebug() << "Request RC " << i; - mav->requestParameter(0, minTpl.arg(i)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, trimTpl.arg(i)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, maxTpl.arg(i)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, revTpl.arg(i)); - QGC::SLEEP::usleep(5000); + if (mav) { + mav->getParamCommsMgr()->requestRcCalibrationParamsUpdate(); } } diff --git a/src/ui/QGCVehicleConfig.cc b/src/ui/QGCVehicleConfig.cc index ce923ff49f..a296f28ff3 100644 --- a/src/ui/QGCVehicleConfig.cc +++ b/src/ui/QGCVehicleConfig.cc @@ -13,9 +13,11 @@ #include #include "QGCVehicleConfig.h" -#include "UASManager.h" + #include "QGC.h" #include "QGCToolWidget.h" +#include "UASManager.h" +#include "UASParameterCommsMgr.h" #include "ui_QGCVehicleConfig.h" QGCVehicleConfig::QGCVehicleConfig(QWidget *parent) : @@ -972,26 +974,8 @@ void QGCVehicleConfig::writeCalibrationRC() void QGCVehicleConfig::requestCalibrationRC() { - if (!mav) return; - - QString minTpl("RC%1_MIN"); - QString maxTpl("RC%1_MAX"); - QString trimTpl("RC%1_TRIM"); - QString revTpl("RC%1_REV"); - - // Do not request the RC type, as these values depend on this - // active onboard parameter - - for (unsigned int i = 0; i < chanMax; ++i) - { - mav->requestParameter(0, minTpl.arg(i+1)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, trimTpl.arg(i+1)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, maxTpl.arg(i+1)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, revTpl.arg(i+1)); - QGC::SLEEP::usleep(5000); + if (mav) { + mav->getParamCommsMgr()->requestRcCalibrationParamsUpdate(); } } -- GitLab From a0e6c55e9844733b5f145bffd054d9dbe17e8340 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 07:03:29 -0700 Subject: [PATCH 175/460] fix setActiveUAS; fix build warnings for enum switches --- src/ui/designer/QGCParamSlider.cc | 49 ++++++++++++++++--------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/ui/designer/QGCParamSlider.cc b/src/ui/designer/QGCParamSlider.cc index 7f76759424..e927dea032 100644 --- a/src/ui/designer/QGCParamSlider.cc +++ b/src/ui/designer/QGCParamSlider.cc @@ -92,31 +92,32 @@ void QGCParamSlider::refreshParamList() void QGCParamSlider::setActiveUAS(UASInterface* activeUas) { - if (activeUas) { - // Set param info - if (!parameterName.isEmpty()) { - //disconnect from any existing uas signals - if (uas != activeUas) { - disconnect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant))); - connect(activeUas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant)), Qt::UniqueConnection); - uas = activeUas; - } - QString text = uas->getParamDataModel()->getParamDescription(parameterName); - if (!text.isEmpty()) { - ui->infoLabel->setToolTip(text); - ui->infoLabel->show(); - } - // Force-uncheck and hide label if no description is available - if (ui->editInfoCheckBox->isChecked()) { - showInfo((text.length() > 0)); - } + if (uas != activeUas) { + if (uas) { + disconnect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), + this, SLOT(setParameterValue(int,int,int,int,QString,QVariant))); } - else { - //when parameter widgets are first loaded, they are disconnected from any parameter? - qWarning() << __FILE__ << ":" << __LINE__ << "slider has no parameterName??"; + if (activeUas) { + connect(activeUas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), + this, SLOT(setParameterValue(int,int,int,int,QString,QVariant)), Qt::UniqueConnection); } + uas = activeUas; } + + if (uas && !parameterName.isEmpty()) { + QString text = uas->getParamDataModel()->getParamDescription(parameterName); + if (!text.isEmpty()) { + ui->infoLabel->setToolTip(text); + ui->infoLabel->show(); + } + // Force-uncheck and hide label if no description is available + if (ui->editInfoCheckBox->isChecked()) { + showInfo((text.length() > 0)); + } + } + + } void QGCParamSlider::requestParameter() @@ -245,7 +246,7 @@ void QGCParamSlider::endEditMode() ui->writeButton->show(); ui->readButton->show(); ui->valueSlider->show(); - switch (parameterValue.type()) + switch ((int)parameterValue.type()) { case QVariant::Char: case QVariant::Int: @@ -289,7 +290,7 @@ void QGCParamSlider::setSliderValue(int sliderValue) if (!valueModLock && !valueModLockParam) { valueModLock = true; - switch (parameterValue.type()) + switch ((int)parameterValue.type()) { case QVariant::Char: parameterValue = QVariant(QChar((unsigned char)scaledIntToFloat(sliderValue))); @@ -393,7 +394,7 @@ void QGCParamSlider::setParameterValue(int uas, int component, int paramCount, i parameterValue = value; ui->valueSlider->setEnabled(true); valueModLockParam = true; - switch (value.type()) + switch ((int)value.type()) { case QVariant::Char: ui->intValueSpinBox->show(); -- GitLab From 2b75f468ec448c8c2f230a50b3b7a0857972beb3 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 07:08:56 -0700 Subject: [PATCH 176/460] Fix miswired slot/signals --- src/ui/PrimaryFlightDisplay.cc | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/ui/PrimaryFlightDisplay.cc b/src/ui/PrimaryFlightDisplay.cc index d0070d2292..651500ea23 100644 --- a/src/ui/PrimaryFlightDisplay.cc +++ b/src/ui/PrimaryFlightDisplay.cc @@ -267,15 +267,24 @@ void PrimaryFlightDisplay::forgetUAS(UASInterface* uas) { if (this->uas != NULL && this->uas == uas) { // Disconnect any previously connected active MAV - disconnect(this->uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*, double, double, double, quint64))); - disconnect(this->uas, SIGNAL(attitudeChanged(UASInterface*,int,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*,int,double, double, double, quint64))); - disconnect(this->uas, SIGNAL(waypointSelected(int,int)), this, SLOT(selectWaypoint(int, int))); - disconnect(this->uas, SIGNAL(primarySpeedChanged(UASInterface*, double, quint64)), this, SLOT(updatePrimarySpeed(UASInterface*,double,quint64))); - disconnect(this->uas, SIGNAL(gpsSpeedChanged(UASInterface*, double, quint64)), this, SLOT(updateGPSSpeed(UASInterface*,double,quint64))); - disconnect(this->uas, SIGNAL(climbRateChanged(UASInterface*, double, quint64)), this, SLOT(updateClimbRate(UASInterface*, AltitudeMeasurementSource, double, quint64))); - disconnect(this->uas, SIGNAL(primaryAltitudeChanged(UASInterface*, double, quint64)), this, SLOT(updatePrimaryAltitude(UASInterface*, double, quint64))); - disconnect(this->uas, SIGNAL(gpsAltitudeChanged(UASInterface*, double, quint64)), this, SLOT(updateGPSAltitude(UASInterface*, double, quint64))); - disconnect(this->uas, SIGNAL(navigationControllerErrorsChanged(UASInterface*, double, double, double)), this, SLOT(updateNavigationControllerErrors(UASInterface*, double, double, double))); + disconnect(this->uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), + this, SLOT(updateAttitude(UASInterface*, double, double, double, quint64))); + disconnect(this->uas, SIGNAL(attitudeChanged(UASInterface*,int,double,double,double,quint64)), + this, SLOT(updateAttitude(UASInterface*,int,double, double, double, quint64))); + //disconnect(this->uas, SIGNAL(waypointSelected(int,int)), + // this, SLOT(selectWaypoint(int, int))); + disconnect(this->uas, SIGNAL(primarySpeedChanged(UASInterface*, double, quint64)), + this, SLOT(updatePrimarySpeed(UASInterface*,double,quint64))); + disconnect(this->uas, SIGNAL(gpsSpeedChanged(UASInterface*, double, quint64)), + this, SLOT(updateGPSSpeed(UASInterface*,double,quint64))); + disconnect(this->uas, SIGNAL(climbRateChanged(UASInterface*, double, quint64)), + this,SLOT(updateClimbRate(UASInterface*, double, quint64))); + disconnect(this->uas, SIGNAL(primaryAltitudeChanged(UASInterface*, double, quint64)), + this, SLOT(updatePrimaryAltitude(UASInterface*, double, quint64))); + disconnect(this->uas, SIGNAL(gpsAltitudeChanged(UASInterface*, double, quint64)), + this, SLOT(updateGPSAltitude(UASInterface*, double, quint64))); + disconnect(this->uas, SIGNAL(navigationControllerErrorsChanged(UASInterface*, double, double, double)), + this, SLOT(updateNavigationControllerErrors(UASInterface*, double, double, double))); //disconnect(this->uas, SIGNAL(batteryChanged(UASInterface*, double, double, double, int)), this, SLOT(updateBattery(UASInterface*, double, double, double, int))); //disconnect(this->uas, SIGNAL(statusChanged(UASInterface*,QString,QString)), this, SLOT(updateState(UASInterface*,QString))); @@ -314,10 +323,12 @@ void PrimaryFlightDisplay::setActiveUAS(UASInterface* uas) //connect(uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateLocalPosition(UASInterface*,double,double,double,quint64))); //connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64))); - connect(uas, SIGNAL(waypointSelected(int,int)), this, SLOT(selectWaypoint(int, int))); + //connect(uas, SIGNAL(waypointSelected(int,int)), this, + // SLOT(selectWaypoint(int, int))); connect(uas, SIGNAL(primarySpeedChanged(UASInterface*, double, quint64)), this, SLOT(updatePrimarySpeed(UASInterface*,double,quint64))); connect(uas, SIGNAL(gpsSpeedChanged(UASInterface*, double, quint64)), this, SLOT(updateGPSSpeed(UASInterface*,double,quint64))); - connect(uas, SIGNAL(climbRateChanged(UASInterface*, double, quint64)), this, SLOT(updateClimbRate(UASInterface*, AltitudeMeasurementSource, double, quint64))); + connect(uas, SIGNAL(climbRateChanged(UASInterface*, double, quint64)), this, + SLOT(updateClimbRate(UASInterface*, double, quint64))); connect(uas, SIGNAL(primaryAltitudeChanged(UASInterface*, double, quint64)), this, SLOT(updatePrimaryAltitude(UASInterface*, double, quint64))); connect(uas, SIGNAL(gpsAltitudeChanged(UASInterface*, double, quint64)), this, SLOT(updateGPSAltitude(UASInterface*, double, quint64))); connect(uas, SIGNAL(navigationControllerErrorsChanged(UASInterface*, double, double, double)), this, SLOT(updateNavigationControllerErrors(UASInterface*, double, double, double))); -- GitLab From cccb392dc640e4a8da10cbd8cf4a8f9ca29a54f8 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 07:24:24 -0700 Subject: [PATCH 177/460] Fix signal/slot mismatch; update formatting of some signal/slot wiring --- src/uas/UASParameterCommsMgr.cc | 9 ++-- src/ui/HSIDisplay.cc | 83 +++++++++++++++++++++------------ 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 25e772b3cc..26a5ce4da2 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -26,13 +26,16 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : mav, SLOT(requestParameter(int,int))); // Sending params to the UAS - connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), mav, SLOT(setParameter(int,QString,QVariant))); + connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), + mav, SLOT(setParameter(int,QString,QVariant))); // New parameters from UAS - connect(mav, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); + connect(mav, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), + this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); //connecto retransmissionTimer - connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); + connect(&retransmissionTimer, SIGNAL(timeout()), + this, SLOT(retransmissionGuardTick())); } diff --git a/src/ui/HSIDisplay.cc b/src/ui/HSIDisplay.cc index d3a2a9d2a3..8974032bfa 100644 --- a/src/ui/HSIDisplay.cc +++ b/src/ui/HSIDisplay.cc @@ -950,35 +950,60 @@ void HSIDisplay::setActiveUAS(UASInterface* uas) if (uas) { - connect(uas, SIGNAL(gpsSatelliteStatusChanged(int,int,float,float,float,bool)), this, SLOT(updateSatellite(int,int,float,float,float,bool))); - connect(uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateLocalPosition(UASInterface*,double,double,double,quint64))); - connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64))); - connect(uas, SIGNAL(attitudeThrustSetPointChanged(UASInterface*,double,double,double,double,quint64)), this, SLOT(updateAttitudeSetpoints(UASInterface*,double,double,double,double,quint64))); - connect(uas, SIGNAL(positionSetPointsChanged(int,float,float,float,float,quint64)), this, SLOT(updatePositionSetpoints(int,float,float,float,float,quint64))); - connect(uas, SIGNAL(userPositionSetPointsChanged(int,float,float,float,float)), this, SLOT(updateUserPositionSetpoints(int,float,float,float,float))); - connect(uas, SIGNAL(speedChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateSpeed(UASInterface*,double,double,double,quint64))); - connect(uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*,double,double,double,quint64))); - - connect(uas, SIGNAL(attitudeControlEnabled(bool)), this, SLOT(updateAttitudeControllerEnabled(bool))); - connect(uas, SIGNAL(positionXYControlEnabled(bool)), this, SLOT(updatePositionXYControllerEnabled(bool))); - connect(uas, SIGNAL(positionZControlEnabled(bool)), this, SLOT(updatePositionZControllerEnabled(bool))); - connect(uas, SIGNAL(positionYawControlEnabled(bool)), this, SLOT(updatePositionYawControllerEnabled(bool))); - - connect(uas, SIGNAL(localizationChanged(UASInterface*,int)), this, SLOT(updateLocalization(UASInterface*,int))); - connect(uas, SIGNAL(visionLocalizationChanged(UASInterface*,int)), this, SLOT(updateVisionLocalization(UASInterface*,int))); - connect(uas, SIGNAL(gpsLocalizationChanged(UASInterface*,int)), this, SLOT(updateGpsLocalization(UASInterface*,int))); - connect(uas, SIGNAL(irUltraSoundLocalizationChanged(UASInterface*,int)), this, SLOT(updateInfraredUltrasoundLocalization(UASInterface*,int))); - connect(uas, SIGNAL(objectDetected(uint,int,int,QString,int,float,float)), this, SLOT(updateObjectPosition(uint,int,int,QString,int,float,float))); - - connect(uas, SIGNAL(gyroStatusChanged(bool,bool,bool)), this, SLOT(updateGyroStatus(bool,bool,bool))); - connect(uas, SIGNAL(accelStatusChanged(bool,bool,bool)), this, SLOT(updateAccelStatus(bool,bool,bool))); - connect(uas, SIGNAL(magSensorStatusChanged(bool,bool,bool)), this, SLOT(updateMagSensorStatus(bool,bool,bool))); - connect(uas, SIGNAL(baroStatusChanged(bool,bool,bool)), this, SLOT(updateBaroStatus(bool,bool,bool))); - connect(uas, SIGNAL(airspeedStatusChanged(bool,bool,bool)), this, SLOT(updateAirspeedStatus(bool,bool,bool))); - connect(uas, SIGNAL(opticalFlowStatusChanged(bool,bool,bool)), this, SLOT(updateOpticalFlowStatus(bool,bool,bool))); - connect(uas, SIGNAL(laserStatusChanged(bool,bool,bool)), this, SLOT(updateLaserStatus(bool,bool,bool))); - connect(uas, SIGNAL(groundTruthSensorStatusChanged(bool,bool,bool)), this, SLOT(updateGroundTruthSensorStatus(bool,bool,bool))); - connect(uas, SIGNAL(actuatorStatusChanged(bool,bool,bool)), this, SLOT(updateActuatorStatus(bool,bool,bool))); + connect(uas, SIGNAL(gpsSatelliteStatusChanged(int,int,float,float,float,bool)), + this, SLOT(updateSatellite(int,int,float,float,float,bool))); + connect(uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), + this, SLOT(updateLocalPosition(UASInterface*,double,double,double,quint64))); + connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), + this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64))); + connect(uas, SIGNAL(attitudeThrustSetPointChanged(UASInterface*,double,double,double,double,quint64)), + this, SLOT(updateAttitudeSetpoints(UASInterface*,double,double,double,double,quint64))); + connect(uas, SIGNAL(positionSetPointsChanged(int,float,float,float,float,quint64)), + this, SLOT(updatePositionSetpoints(int,float,float,float,float,quint64))); + connect(uas, SIGNAL(userPositionSetPointsChanged(int,float,float,float,float)), + this, SLOT(updateUserPositionSetpoints(int,float,float,float,float))); + connect(uas, SIGNAL(velocityChanged_NED(UASInterface*,double,double,double,quint64)), + this, SLOT(updateSpeed(UASInterface*,double,double,double,quint64))); + connect(uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), + this, SLOT(updateAttitude(UASInterface*,double,double,double,quint64))); + connect(uas, SIGNAL(attitudeControlEnabled(bool)), + this, SLOT(updateAttitudeControllerEnabled(bool))); + connect(uas, SIGNAL(positionXYControlEnabled(bool)), + this, SLOT(updatePositionXYControllerEnabled(bool))); + connect(uas, SIGNAL(positionZControlEnabled(bool)), + this, SLOT(updatePositionZControllerEnabled(bool))); + connect(uas, SIGNAL(positionYawControlEnabled(bool)), + this, SLOT(updatePositionYawControllerEnabled(bool))); + + connect(uas, SIGNAL(localizationChanged(UASInterface*,int)), + this, SLOT(updateLocalization(UASInterface*,int))); + connect(uas, SIGNAL(visionLocalizationChanged(UASInterface*,int)), + this, SLOT(updateVisionLocalization(UASInterface*,int))); + connect(uas, SIGNAL(gpsLocalizationChanged(UASInterface*,int)), + this, SLOT(updateGpsLocalization(UASInterface*,int))); + connect(uas, SIGNAL(irUltraSoundLocalizationChanged(UASInterface*,int)), + this, SLOT(updateInfraredUltrasoundLocalization(UASInterface*,int))); + connect(uas, SIGNAL(objectDetected(uint,int,int,QString,int,float,float)), + this, SLOT(updateObjectPosition(uint,int,int,QString,int,float,float))); + + connect(uas, SIGNAL(gyroStatusChanged(bool,bool,bool)), + this, SLOT(updateGyroStatus(bool,bool,bool))); + connect(uas, SIGNAL(accelStatusChanged(bool,bool,bool)), + this, SLOT(updateAccelStatus(bool,bool,bool))); + connect(uas, SIGNAL(magSensorStatusChanged(bool,bool,bool)), + this, SLOT(updateMagSensorStatus(bool,bool,bool))); + connect(uas, SIGNAL(baroStatusChanged(bool,bool,bool)), + this, SLOT(updateBaroStatus(bool,bool,bool))); + connect(uas, SIGNAL(airspeedStatusChanged(bool,bool,bool)), + this, SLOT(updateAirspeedStatus(bool,bool,bool))); + connect(uas, SIGNAL(opticalFlowStatusChanged(bool,bool,bool)), + this, SLOT(updateOpticalFlowStatus(bool,bool,bool))); + connect(uas, SIGNAL(laserStatusChanged(bool,bool,bool)), + this, SLOT(updateLaserStatus(bool,bool,bool))); + connect(uas, SIGNAL(groundTruthSensorStatusChanged(bool,bool,bool)), + this, SLOT(updateGroundTruthSensorStatus(bool,bool,bool))); + connect(uas, SIGNAL(actuatorStatusChanged(bool,bool,bool)), + this, SLOT(updateActuatorStatus(bool,bool,bool))); statusClearTimer.start(3000); } else -- GitLab From 055ad29f0dc2bb2864550c872a291d80fed41b44 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 07:58:39 -0700 Subject: [PATCH 178/460] ignore duplicate request param list --- src/uas/UAS.cc | 2 +- src/uas/UASParameterCommsMgr.cc | 25 ++++++++++------- src/uas/UASParameterCommsMgr.h | 1 + src/ui/QGCPX4VehicleConfig.cc | 50 ++++++++++++++++----------------- src/ui/QGCPX4VehicleConfig.h | 3 ++ src/ui/QGCVehicleConfig.cc | 3 +- 6 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 772341413c..89f9d44e87 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -1999,7 +1999,7 @@ void UAS::sendMessage(mavlink_message_t message) if (LinkManager::instance()->getLinks().contains(link)) { sendMessage(link, message); - qDebug() << "SENT MESSAGE id" << message.msgid; + qDebug() << "SENT MESSAGE id" << message.msgid << "component" << message.compid; } else { diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 26a5ce4da2..e2231064db 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -70,18 +70,23 @@ void UASParameterCommsMgr::requestParameterList() //TODO check: no need to cause datamodel to forget params here? // paramDataModel->forgetAllOnboardParameters(); - // Clear transmission state - receivedParamsList.clear(); - transmissionListSizeKnown.clear(); + if (!transmissionListMode) { + // Clear transmission state + receivedParamsList.clear(); + transmissionListSizeKnown.clear(); - transmissionListMode = true; - foreach (int key, transmissionMissingPackets.keys()) { - transmissionMissingPackets.value(key)->clear(); - } - transmissionActive = true; + transmissionListMode = true; + foreach (int key, transmissionMissingPackets.keys()) { + transmissionMissingPackets.value(key)->clear(); + } + transmissionActive = true; - setParameterStatusMsg(tr("Requested param list.. waiting")); - mav->requestParameters(); + setParameterStatusMsg(tr("Requested param list.. waiting")); + mav->requestParameters(); + } + else { + qDebug() << __FILE__ << __LINE__ << "Ignoring requestParameterList because we're receiving params list"; + } } diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 03f24bb1d7..8f5a2eeb67 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -62,6 +62,7 @@ public slots: /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); + /** @brief Check for missing parameters */ virtual void retransmissionGuardTick(); diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 708d5a0b7b..177a5e0660 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -795,9 +795,12 @@ void QGCPX4VehicleConfig::loadConfig() xml.readNext(); } - mav->getParamManager()->setParamDescriptions(paramTooltips); + if (!paramTooltips.isEmpty()) { + mav->getParamManager()->setParamDescriptions(paramTooltips); + } doneLoadingConfig = true; - mav->requestParameters(); //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. + //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. + mav->getParamCommsMgr()->requestParameterList(); } void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) @@ -826,31 +829,28 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) // Disconnect old system disconnect(mav, SIGNAL(remoteControlChannelRawChanged(int,float)), this, SLOT(remoteControlChannelRawChanged(int,float))); + //TODO use paramCommsMgr instead disconnect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); - disconnect(ui->refreshButton,SIGNAL(clicked()),mav,SLOT(requestParameters())); + disconnect(ui->refreshButton,SIGNAL(clicked()), + paramCommsMgr,SLOT(requestParameterList())); // Delete all children from all fixed tabs. - foreach(QWidget* child, ui->generalLeftContents->findChildren()) - { + foreach(QWidget* child, ui->generalLeftContents->findChildren()) { child->deleteLater(); } - foreach(QWidget* child, ui->generalRightContents->findChildren()) - { + foreach(QWidget* child, ui->generalRightContents->findChildren()) { child->deleteLater(); } - foreach(QWidget* child, ui->advanceColumnContents->findChildren()) - { + foreach(QWidget* child, ui->advanceColumnContents->findChildren()) { child->deleteLater(); } - foreach(QWidget* child, ui->sensorContents->findChildren()) - { + foreach(QWidget* child, ui->sensorContents->findChildren()) { child->deleteLater(); } // And then delete any custom tabs - foreach(QWidget* child, additionalTabs) - { + foreach(QWidget* child, additionalTabs) { child->deleteLater(); } additionalTabs.clear(); @@ -866,6 +866,7 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) // Connect new system mav = active; + paramCommsMgr = mav->getParamCommsMgr(); // Reset current state resetCalibrationRC(); @@ -875,25 +876,23 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) chanCount = 0; // Connect new system - connect(active, SIGNAL(remoteControlChannelRawChanged(int,float)), this, + connect(mav, SIGNAL(remoteControlChannelRawChanged(int,float)), this, SLOT(remoteControlChannelRawChanged(int,float))); - connect(active, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, + connect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); - connect(ui->refreshButton, SIGNAL(clicked()), active, SLOT(requestParameters())); + connect(ui->refreshButton, SIGNAL(clicked()), + paramCommsMgr,SLOT(requestParameterList())); - if (systemTypeToParamMap.contains(mav->getSystemTypeName())) - { + if (systemTypeToParamMap.contains(mav->getSystemTypeName())) { paramToWidgetMap = systemTypeToParamMap[mav->getSystemTypeName()]; } - else - { + else { //Indication that we have no meta data for this system type. qDebug() << "No parameters defined for system type:" << mav->getSystemTypeName(); paramToWidgetMap = systemTypeToParamMap[mav->getSystemTypeName()]; } - if (!paramTooltips.isEmpty()) - { + if (!paramTooltips.isEmpty()) { mav->getParamManager()->setParamDescriptions(paramTooltips); } @@ -912,8 +911,7 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) ui->writeButton->setEnabled(true); ui->loadFileButton->setEnabled(true); ui->saveFileButton->setEnabled(true); - if (mav->getAutopilotTypeName() == "ARDUPILOTMEGA") - { + if (mav->getAutopilotTypeName() == "ARDUPILOTMEGA") { ui->readButton->hide(); ui->writeButton->hide(); } @@ -978,8 +976,8 @@ void QGCPX4VehicleConfig::writeCalibrationRC() void QGCPX4VehicleConfig::requestCalibrationRC() { - if (mav) { - mav->getParamCommsMgr()->requestRcCalibrationParamsUpdate(); + if (paramCommsMgr) { + paramCommsMgr->requestRcCalibrationParamsUpdate(); } } diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index b11d2e60e2..93761d52f2 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -10,6 +10,8 @@ #include "QGCToolWidget.h" #include "UASInterface.h" +class UASParameterCommsMgr; + namespace Ui { class QGCPX4VehicleConfig; } @@ -159,6 +161,7 @@ protected slots: protected: bool doneLoadingConfig; UASInterface* mav; ///< The current MAV + UASParameterCommsMgr* paramCommsMgr; ///< param comms mgr for the mav static const unsigned int chanMax = 8; ///< Maximum number of channels unsigned int chanCount; ///< Actual channels int rcType; ///< Type of the remote control diff --git a/src/ui/QGCVehicleConfig.cc b/src/ui/QGCVehicleConfig.cc index a296f28ff3..2aa2ead2e6 100644 --- a/src/ui/QGCVehicleConfig.cc +++ b/src/ui/QGCVehicleConfig.cc @@ -790,7 +790,8 @@ void QGCVehicleConfig::loadConfig() mav->getParamManager()->setParamDescriptions(paramTooltips); doneLoadingConfig = true; - mav->requestParameters(); //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. + //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. + mav->getParamCommsMgr()->requestParameterList(); } void QGCVehicleConfig::setActiveUAS(UASInterface* active) -- GitLab From d8e54be41a94348867d1e44e8ec26871bcc6670a Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 09:23:44 -0700 Subject: [PATCH 179/460] Fix statusMsgUpdate wiring; remove cruft --- src/uas/QGCUASParamManager.cc | 122 -------------------------------- src/uas/UASParameterCommsMgr.cc | 19 ++--- src/uas/UASParameterCommsMgr.h | 4 +- src/uas/UASWaypointManager.cc | 4 +- src/ui/QGCParamWidget.cc | 3 + 5 files changed, 16 insertions(+), 136 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index f1cc5fd20c..1dd6050c57 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -70,128 +70,6 @@ void QGCUASParamManager::requestParameterList() paramCommsMgr->requestParameterList(); } -//void QGCUASParamManager::retransmissionGuardTick() -//{ -// if (transmissionActive) { -// //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; - -// // Check for timeout -// // stop retransmission attempts on timeout -// if (QGC::groundTimeMilliseconds() > transmissionTimeout) { -// setRetransmissionGuardEnabled(false); -// transmissionActive = false; - -// // Empty read retransmission list -// // Empty write retransmission list -// int missingReadCount = 0; -// QList readKeys = transmissionMissingPackets.keys(); -// foreach (int component, readKeys) { -// missingReadCount += transmissionMissingPackets.value(component)->count(); -// transmissionMissingPackets.value(component)->clear(); -// } - -// // Empty write retransmission list -// int missingWriteCount = 0; -// QList writeKeys = transmissionMissingWriteAckPackets.keys(); -// foreach (int component, writeKeys) { -// missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); -// transmissionMissingWriteAckPackets.value(component)->clear(); -// } -// setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); -// } - -// // Re-request at maximum retransmissionBurstRequestSize parameters at once -// // to prevent link flooding -// QMap*>::iterator i; -// QMap*> onboardParams = paramDataModel->getOnboardParameters(); -// for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { -// // Iterate through the parameters of the component -// int component = i.key(); -// // Request n parameters from this component (at maximum) -// QList * paramList = transmissionMissingPackets.value(component, NULL); -// if (paramList) { -// int count = 0; -// foreach (int id, *paramList) { -// if (count < retransmissionBurstRequestSize) { -// //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; -// //TODO mavlink msg type for "request parameter set" ? -// emit parameterUpdateRequestedById(component, id); -// setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); -// count++; -// } else { -// break; -// } -// } -// } -// } - -// // Re-request at maximum retransmissionBurstRequestSize parameters at once -// // to prevent write-request link flooding -// // Empty write retransmission list -// QList writeKeys = transmissionMissingWriteAckPackets.keys(); -// foreach (int component, writeKeys) { -// int count = 0; -// QMap * missingParams = transmissionMissingWriteAckPackets.value(component); -// foreach (QString key, missingParams->keys()) { -// if (count < retransmissionBurstRequestSize) { -// // Re-request write operation -// QVariant value = missingParams->value(key); -// switch ((int)onboardParams.value(component)->value(key).type()) -// { -// case QVariant::Int: -// { -// QVariant fixedValue(value.toInt()); -// emit parameterChanged(component, key, fixedValue); -// } -// break; -// case QVariant::UInt: -// { -// QVariant fixedValue(value.toUInt()); -// emit parameterChanged(component, key, fixedValue); -// } -// break; -// case QMetaType::Float: -// { -// QVariant fixedValue(value.toFloat()); -// emit parameterChanged(component, key, fixedValue); -// } -// break; -// default: -// //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; -// return; -// } -// setParameterStatusMsg(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); -// count++; -// } else { -// break; -// } -// } -// } -// } else { -// //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; -// setRetransmissionGuardEnabled(false); -// } -//} - - - -//* -// * Enabling the retransmission guard enables the parameter widget to track -// * dropped parameters and to re-request them. This works for both individual -// * parameter reads as well for whole list requests. -// * -// * @param enabled True if retransmission checking should be enabled, false else - -//void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) -//{ -// qDebug() << "setRetransmissionGuardEnabled: " << enabled; -// -// if (enabled) { -// retransmissionTimer.start(retransmissionTimeout); -// } else { -// retransmissionTimer.stop(); -// } -//} void QGCUASParamManager::setParameterStatusMsg(const QString& msg) { diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index e2231064db..93cab1d195 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -94,7 +94,7 @@ void UASParameterCommsMgr::requestParameterList() void UASParameterCommsMgr::retransmissionGuardTick() { if (transmissionActive) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; + qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; // Check for timeout // stop retransmission attempts on timeout @@ -189,7 +189,7 @@ void UASParameterCommsMgr::retransmissionGuardTick() } } } else { - //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; + qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; setRetransmissionGuardEnabled(false); } } @@ -353,16 +353,6 @@ void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg, ParamCommsS parameterStatusMsg = msg; emit parameterStatusMsgUpdated(msg,level); - - //TODO indicate OK status somehow (eg color) -// QPalette pal = statusLabel->palette(); -// pal.setColor(backgroundRole(), QGC::colorGreen); -// statusLabel->setPalette(pal); - -// pal.setColor(backgroundRole(), QGC::colorRed); - // pal.setColor(backgroundRole(), QGC::colorOrange); - - } @@ -534,3 +524,8 @@ void UASParameterCommsMgr::sendPendingParameters() } } +UASParameterCommsMgr::~UASParameterCommsMgr() +{ + setRetransmissionGuardEnabled(false); +} + diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 8f5a2eeb67..3ac5f53d6e 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -19,6 +19,8 @@ class UASParameterCommsMgr : public QObject public: explicit UASParameterCommsMgr(QObject *parent = 0, UASInterface* uas = NULL); + ~UASParameterCommsMgr(); + typedef enum ParamCommsStatusLevel { ParamCommsStatusLevel_OK = 0, ParamCommsStatusLevel_Warning = 2, @@ -48,7 +50,7 @@ signals: void parameterUpdateRequestedById(int componentId, int paramId); /** @brief We updated the parameter status message */ - void parameterStatusMsgUpdated(QString msg, ParamCommsStatusLevel_t level); + void parameterStatusMsgUpdated(QString msg, int level); public slots: /** @brief Iterate through all components, through all pending parameters and send them to UAS */ diff --git a/src/uas/UASWaypointManager.cc b/src/uas/UASWaypointManager.cc index d6bdb29b86..888a548e70 100644 --- a/src/uas/UASWaypointManager.cc +++ b/src/uas/UASWaypointManager.cc @@ -975,7 +975,9 @@ void UASWaypointManager::sendWaypointRequestList() wprl.target_system = uasid; wprl.target_component = MAV_COMP_ID_MISSIONPLANNER; - emit updateStatusString(QString("Requesting waypoint list...")); + QString statusMsg(tr("Requesting waypoint list...")); + qDebug() << __FILE__ << __LINE__ << statusMsg; + emit updateStatusString(statusMsg); mavlink_msg_mission_request_list_encode(uas->mavlink->getSystemId(), uas->mavlink->getComponentId(), &message, &wprl); uas->sendMessage(message); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 5ec85bceba..ef79ac437f 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -154,6 +154,9 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), this, SLOT(handleParameterListUpToDate())); + connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), + this, SLOT(handleParamStatusMsgUpdate(QString , int ))); + // Get parameters if (uas) { requestAllParamsUpdate(); -- GitLab From 6fbc9b427ab6915d9b0cd43633e2c2094951c999 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 10:20:52 -0700 Subject: [PATCH 180/460] Retransmit param list request; fix null data model --- libs/eigen/Eigen/src/Core/BandMatrix.h | 1 + src/uas/UAS.cc | 12 ++++++++---- src/uas/UASParameterCommsMgr.cc | 27 ++++++++++++++++++++++---- src/uas/UASParameterCommsMgr.h | 1 + 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/libs/eigen/Eigen/src/Core/BandMatrix.h b/libs/eigen/Eigen/src/Core/BandMatrix.h index dda8efba36..e6922b50f5 100644 --- a/libs/eigen/Eigen/src/Core/BandMatrix.h +++ b/libs/eigen/Eigen/src/Core/BandMatrix.h @@ -285,6 +285,7 @@ class BandMatrixWrapper : public BandMatrixBaseat(i)) { - qDebug()<<"Antenna tracking: Forwarding Over link: "<getName()<<" "<isConnected()) { + qDebug()<<"Antenna tracking: Forwarding Over link: "<getName()<<" "<getParamDataModel(); loadParamCommsSettings(); @@ -57,6 +58,8 @@ void UASParameterCommsMgr::loadParamCommsSettings() settings.endGroup(); } + + /** * Send a request to deliver the list of onboard parameters * from the MAV. @@ -82,7 +85,9 @@ void UASParameterCommsMgr::requestParameterList() transmissionActive = true; setParameterStatusMsg(tr("Requested param list.. waiting")); + listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; mav->requestParameters(); + setRetransmissionGuardEnabled(true); } else { qDebug() << __FILE__ << __LINE__ << "Ignoring requestParameterList because we're receiving params list"; @@ -94,6 +99,17 @@ void UASParameterCommsMgr::requestParameterList() void UASParameterCommsMgr::retransmissionGuardTick() { if (transmissionActive) { + if (transmissionListMode && transmissionListSizeKnown.isEmpty() ) { + //we are still waitin for the first parameter list response + if (QGC::groundTimeMilliseconds() > this->listRecvTimeout) { + //re-request parameters + setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); + listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; + mav->requestParameters(); + } + return; + } + qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; // Check for timeout @@ -466,11 +482,9 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para transmissionMissingPackets.value(key)->clear(); } + setRetransmissionGuardEnabled(false); //all parameters have been received, broadcast to UI emit parameterListUpToDate(); - //TODO in UI - // Expand visual tree - //tree->expandItem(tree->topLevelItem(0)); } } @@ -527,5 +541,10 @@ void UASParameterCommsMgr::sendPendingParameters() UASParameterCommsMgr::~UASParameterCommsMgr() { setRetransmissionGuardEnabled(false); + + QString ptrStr; + ptrStr.sprintf("%8p", this); + qDebug() << "UASParameterCommsMgr destructor: " << ptrStr ; + } diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 3ac5f53d6e..03286c1e1e 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -98,6 +98,7 @@ protected: int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds int rewriteTimeout; ///< Write request timeout, in milliseconds int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst + quint64 listRecvTimeout; ///< How long to wait for first parameter list response before re-requesting // Status QString parameterStatusMsg; -- GitLab From c6ebc6b27d24cb355e8ba46cf0cc9fb7de6b995e Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 10:31:59 -0700 Subject: [PATCH 181/460] Debug parameter list receive; remove cruft --- src/uas/UASParameterCommsMgr.cc | 22 +++-- src/ui/QGCParamWidget.cc | 150 -------------------------------- 2 files changed, 15 insertions(+), 157 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index bdd2494b27..58f02733ef 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -99,13 +99,15 @@ void UASParameterCommsMgr::requestParameterList() void UASParameterCommsMgr::retransmissionGuardTick() { if (transmissionActive) { - if (transmissionListMode && transmissionListSizeKnown.isEmpty() ) { - //we are still waitin for the first parameter list response - if (QGC::groundTimeMilliseconds() > this->listRecvTimeout) { - //re-request parameters - setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); - listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; - mav->requestParameters(); + if (transmissionListMode) { + if (transmissionListSizeKnown.isEmpty() ) { + //we are still waitin for the first parameter list response + if (QGC::groundTimeMilliseconds() > this->listRecvTimeout) { + //re-request parameters + setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); + listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; + mav->requestParameters(); + } } return; } @@ -486,6 +488,12 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para //all parameters have been received, broadcast to UI emit parameterListUpToDate(); } + else { + qDebug() << "missCount:" << missCount << "missWriteCount:" << missWriteCount; + foreach (int key, transmissionMissingPackets.keys()) { + qDebug() << "Missing:" << key ; + } + } } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index ef79ac437f..b125b083a4 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -194,156 +194,6 @@ void QGCParamWidget::addComponentItem( int compId, QString compName) } - -/** - * @param uas System which has the component - * @param component id of the component - * @param parameterName human friendly name of the parameter - */ -//void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) -//{ - -// updateParameterDisplay(component, parameterName, value); - -// // Missing packets list has to be instantiated for all components -// if (!transmissionMissingPackets.contains(component)) { -// transmissionMissingPackets.insert(component, new QList()); -// } - -// // List mode is different from single parameter transfers -// if (transmissionListMode) { -// // Only accept the list size once on the first packet from -// // each component -// if (!transmissionListSizeKnown.contains(component)) -// { -// // Mark list size as known -// transmissionListSizeKnown.insert(component, true); - -// // Mark all parameters as missing -// for (int i = 0; i < paramCount; ++i) -// { -// if (!transmissionMissingPackets.value(component)->contains(i)) -// { -// transmissionMissingPackets.value(component)->append(i); -// } -// } - -// // There is only one transmission timeout for all components -// // since components do not manage their transmission, -// // the longest timeout is safe for all components. -// quint64 thisTransmissionTimeout = QGC::groundTimeMilliseconds() + ((paramCount)*retransmissionTimeout); -// if (thisTransmissionTimeout > transmissionTimeout) -// { -// transmissionTimeout = thisTransmissionTimeout; -// } -// } - -// // Start retransmission guard -// // or reset timer -// paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO -// } - -// // Mark this parameter as received in read list -// int index = transmissionMissingPackets.value(component)->indexOf(paramId); -// // If the MAV sent the parameter without request, it wont be in missing list -// if (index != -1) transmissionMissingPackets.value(component)->removeAt(index); - -// bool justWritten = false; -// bool writeMismatch = false; -// //bool lastWritten = false; -// // Mark this parameter as received in write ACK list -// QMap* map = transmissionMissingWriteAckPackets.value(component); -// if (map && map->contains(parameterName)) -// { -// justWritten = true; -// QVariant newval = map->value(parameterName); -// if (map->value(parameterName) != value) -// { -// writeMismatch = true; -// } -// map->remove(parameterName); -// } - -// int missCount = 0; -// foreach (int key, transmissionMissingPackets.keys()) -// { -// missCount += transmissionMissingPackets.value(key)->count(); -// } - -// int missWriteCount = 0; -// foreach (int key, transmissionMissingWriteAckPackets.keys()) -// { -// missWriteCount += transmissionMissingWriteAckPackets.value(key)->count(); -// } - -// if (justWritten && !writeMismatch && missWriteCount == 0) -// { -// // Just wrote one and count went to 0 - this was the last missing write parameter -// statusLabel->setText(tr("SUCCESS: WROTE ALL PARAMETERS")); -// QPalette pal = statusLabel->palette(); -// pal.setColor(backgroundRole(), QGC::colorGreen); -// statusLabel->setPalette(pal); -// } else if (justWritten && !writeMismatch) -// { -// statusLabel->setText(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(parameterName).arg(value.toDouble()).arg(paramCount)); -// QPalette pal = statusLabel->palette(); -// pal.setColor(backgroundRole(), QGC::colorGreen); -// statusLabel->setPalette(pal); -// } else if (justWritten && writeMismatch) -// { -// // Mismatch, tell user -// QPalette pal = statusLabel->palette(); -// pal.setColor(backgroundRole(), QGC::colorRed); -// statusLabel->setPalette(pal); -// statusLabel->setText(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(parameterName).arg(map->value(parameterName).toDouble()).arg(value.toDouble())); -// } -// else -// { -// if (missCount > 0) -// { -// QPalette pal = statusLabel->palette(); -// pal.setColor(backgroundRole(), QGC::colorOrange); -// statusLabel->setPalette(pal); -// } -// else -// { -// QPalette pal = statusLabel->palette(); -// pal.setColor(backgroundRole(), QGC::colorGreen); -// statusLabel->setPalette(pal); -// } -// QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); -// //statusLabel->setText(tr("OK: %1 %2 #%3/%4, %5 miss").arg(parameterName).arg(val).arg(paramId+1).arg(paramCount).arg(missCount)); -// if (missCount == 0) -// { -// // Transmission done -// QTime time = QTime::currentTime(); -// QString timeString = time.toString(); -// statusLabel->setText(tr("All received. (updated at %1)").arg(timeString)); -// } -// else -// { -// // Transmission in progress -// statusLabel->setText(tr("OK: %1 %2 (%3/%4)").arg(parameterName).arg(val).arg(paramCount-missCount).arg(paramCount)); -// } -// } - -// // Check if last parameter was received -// if (missCount == 0 && missWriteCount == 0) -// { -// this->transmissionActive = false; -// this->transmissionListMode = false; -// transmissionListSizeKnown.clear(); -// foreach (int key, transmissionMissingPackets.keys()) -// { -// transmissionMissingPackets.value(key)->clear(); -// } - -// // Expand visual tree -// tree->expandItem(tree->topLevelItem(0)); -// } -//} - - void QGCParamWidget::handleParameterUpdate(int componentId, const QString& paramName, QVariant value) { updateParameterDisplay(componentId, paramName, value); -- GitLab From 13ecf8196624aa0189a27b0237921ae81a7185dc Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 11:14:48 -0700 Subject: [PATCH 182/460] keep the received params list clean --- src/uas/UASParameterCommsMgr.cc | 43 +++++++++++++++++++-------------- src/uas/UASParameterDataModel.h | 8 +++--- src/ui/QGCParamWidget.cc | 4 +-- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 58f02733ef..8b65d65ee7 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -99,15 +99,14 @@ void UASParameterCommsMgr::requestParameterList() void UASParameterCommsMgr::retransmissionGuardTick() { if (transmissionActive) { - if (transmissionListMode) { - if (transmissionListSizeKnown.isEmpty() ) { - //we are still waitin for the first parameter list response - if (QGC::groundTimeMilliseconds() > this->listRecvTimeout) { - //re-request parameters - setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); - listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; - mav->requestParameters(); - } + + if (transmissionListMode && transmissionListSizeKnown.isEmpty() ) { + //we are still waitin for the first parameter list response + if (QGC::groundTimeMilliseconds() > this->listRecvTimeout) { + //re-request parameters + setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); + listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; + mav->requestParameters(); } return; } @@ -142,8 +141,8 @@ void UASParameterCommsMgr::retransmissionGuardTick() // Re-request at maximum retransmissionBurstRequestSize parameters at once // to prevent link flooding QMap*>::iterator i; - QMap*> onboardParams = paramDataModel->getOnboardParameters(); - for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { + QMap*>* onboardParams = paramDataModel->getOnboardParameters(); + for (i = onboardParams->begin(); i != onboardParams->end(); ++i) { // Iterate through the parameters of the component int component = i.key(); // Request n parameters from this component (at maximum) @@ -175,7 +174,7 @@ void UASParameterCommsMgr::retransmissionGuardTick() if (count < retransmissionBurstRequestSize) { // Re-request write operation QVariant value = missingParams->value(key); - switch ((int)onboardParams.value(component)->value(key).type()) + switch ((int)onboardParams->value(component)->value(key).type()) { case QVariant::Int: { @@ -395,13 +394,20 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para // Mark list size as known transmissionListSizeKnown.insert(compId, true); - // Mark all parameters as missing + qDebug() << "Mark all parameters as missing"; + QList* compParamList = transmissionMissingPackets.value(compId); for (int i = 0; i < paramCount; ++i) { - if (!transmissionMissingPackets.value(compId)->contains(i)) { - transmissionMissingPackets.value(compId)->append(i); + if (!compParamList->contains(i)) { + if (i != paramId) { + compParamList->append(i); + } + else { + qDebug() << "Already received " << paramId; + } } } + // There is only one transmission timeout for all components // since components do not manage their transmission, // the longest timeout is safe for all components. @@ -491,7 +497,8 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para else { qDebug() << "missCount:" << missCount << "missWriteCount:" << missWriteCount; foreach (int key, transmissionMissingPackets.keys()) { - qDebug() << "Missing:" << key ; + QList* list = transmissionMissingPackets.value(key); + qDebug() << "Component" << key << "missing numParams:" << list->count() ; } } } @@ -509,9 +516,9 @@ void UASParameterCommsMgr::sendPendingParameters() { // Iterate through all components, through all pending parameters and send them to UAS int parametersSent = 0; - QMap*> changedValues = paramDataModel->getPendingParameters(); + QMap*>* changedValues = paramDataModel->getPendingParameters(); QMap*>::iterator i; - for (i = changedValues.begin(); i != changedValues.end(); ++i) { + for (i = changedValues->begin(); i != changedValues->end(); ++i) { // Iterate through the parameters of the component int compid = i.key(); QMap* comp = i.value(); diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 352fb0eea6..219eff900b 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -69,12 +69,12 @@ public: return onboardParameters.value(componentId); } - QMap* > getPendingParameters() { - return pendingParameters; + QMap* >* getPendingParameters() { + return &pendingParameters; } - QMap* > getOnboardParameters() { - return onboardParameters; + QMap* >* getOnboardParameters() { + return &onboardParameters; } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index b125b083a4..7600d15768 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -432,9 +432,9 @@ void QGCParamWidget::writeParameters() int changedParamCount = 0; QMap*>::iterator i; - QMap*> changedValues = paramDataModel->getPendingParameters(); + QMap*>* changedValues = paramDataModel->getPendingParameters(); - for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) { + for (i = changedValues->begin(); (i != changedValues->end()) && (0 == changedParamCount); ++i) { // Iterate through the parameters of the component QMap* compPending = i.value(); changedParamCount += compPending->count(); -- GitLab From cdb33d12e9112496ebb12ab70bebd6a691db0e58 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 22:51:29 -0700 Subject: [PATCH 183/460] debugging premature timeouts of param list recv --- src/uas/UAS.cc | 4 +- src/uas/UASParameterCommsMgr.cc | 294 ++++++++++++++++---------------- src/uas/UASParameterCommsMgr.h | 7 + src/ui/QGCParamWidget.cc | 94 ---------- 4 files changed, 159 insertions(+), 240 deletions(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 2a95b08862..d21f55343d 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -2259,7 +2259,9 @@ void UAS::requestParameters() mavlink_message_t msg; mavlink_msg_param_request_list_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_COMP_ID_ALL); sendMessage(msg); - qDebug() << __FILE__ << ":" << __LINE__ << "LOADING PARAM LIST"; + + QDateTime time = QDateTime::currentDateTime(); + qDebug() << __FILE__ << ":" << __LINE__ << time.toString() << "LOADING PARAM LIST"; } void UAS::writeParametersToStorage() diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 8b65d65ee7..712cd9b1cb 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -14,8 +14,8 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : transmissionListMode(false), transmissionActive(false), transmissionTimeout(0), - retransmissionTimeout(350), - rewriteTimeout(500), + retransmissionTimeout(1000), + rewriteTimeout(1000), retransmissionBurstRequestSize(5) { paramDataModel = mav->getParamDataModel(); @@ -96,6 +96,125 @@ void UASParameterCommsMgr::requestParameterList() } +/* + Empty read retransmission list + Empty write retransmission list +*/ +void UASParameterCommsMgr::clearRetransmissionLists() +{ + qDebug() << __FILE__ << __LINE__ << "clearRetransmissionLists"; + + int missingReadCount = 0; + QList readKeys = transmissionMissingPackets.keys(); + foreach (int component, readKeys) { + missingReadCount += transmissionMissingPackets.value(component)->count(); + transmissionMissingPackets.value(component)->clear(); + } + + int missingWriteCount = 0; + QList writeKeys = transmissionMissingWriteAckPackets.keys(); + foreach (int component, writeKeys) { + missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); + transmissionMissingWriteAckPackets.value(component)->clear(); + } + setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount), + ParamCommsStatusLevel_Warning); + +} + + +void UASParameterCommsMgr::emitParameterChanged(int compId, const QString& key, QVariant& value) +{ + int paramType = (int)value.type(); + switch (paramType) + { + case QVariant::Char: + { + QVariant fixedValue(QChar((unsigned char)value.toInt())); + emit parameterChanged(compId, key, fixedValue); + } + break; + case QVariant::Int: + { + QVariant fixedValue(value.toInt()); + emit parameterChanged(compId, key, fixedValue); + } + break; + case QVariant::UInt: + { + QVariant fixedValue(value.toUInt()); + emit parameterChanged(compId, key, fixedValue); + } + break; + case QMetaType::Float: + { + QVariant fixedValue(value.toFloat()); + emit parameterChanged(compId, key, fixedValue); + } + break; + default: + qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE"; + return; + } + + setParameterStatusMsg(tr("Requested write of: %1: %2").arg(key).arg(value.toDouble())); + +} + + +void UASParameterCommsMgr::resendReadWriteRequests() +{ + int compId; + QList compIds; + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent link flooding' + int requestedReadCount = 0; + + compIds = transmissionMissingPackets.keys(); + foreach (compId, compIds) { + // Request n parameters from this component (at maximum) + QList* missingReadParams = transmissionMissingPackets.value(compId, NULL); + foreach (int paramId, *missingReadParams) { + if (requestedReadCount < retransmissionBurstRequestSize) { + qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << paramId << "FROM COMPONENT #" << compId; + emit parameterUpdateRequestedById(compId, paramId); + setParameterStatusMsg(tr("Requested retransmission of #%1").arg(paramId+1)); + requestedReadCount++; + } + else { + qDebug() << "Throttling read retransmit requests at" << requestedReadCount; + break; + } + } + } + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent write-request link flooding + int requestedWriteCount = 0; + compIds = transmissionMissingWriteAckPackets.keys(); + foreach (compId, compIds) { + QMap * missingParams = transmissionMissingWriteAckPackets.value(compId); + foreach (QString key, missingParams->keys()) { + if (requestedWriteCount < retransmissionBurstRequestSize) { + // Re-request write operation + QVariant value = missingParams->value(key); + emitParameterChanged(compId, key, value); + requestedWriteCount++; + } + else { + qDebug() << "Throttling write retransmit requests at" << requestedWriteCount; + break; + } + } + } + + if ((0 == requestedWriteCount) && (0 == requestedReadCount) ) { + qDebug() << __FILE__ << __LINE__ << "NO re-read or rewrite requests??"; + //setRetransmissionGuardEnabled(false); + } +} + void UASParameterCommsMgr::retransmissionGuardTick() { if (transmissionActive) { @@ -118,94 +237,14 @@ void UASParameterCommsMgr::retransmissionGuardTick() if (QGC::groundTimeMilliseconds() > transmissionTimeout) { setRetransmissionGuardEnabled(false); transmissionActive = false; - - // Empty read retransmission list - // Empty write retransmission list - int missingReadCount = 0; - QList readKeys = transmissionMissingPackets.keys(); - foreach (int component, readKeys) { - missingReadCount += transmissionMissingPackets.value(component)->count(); - transmissionMissingPackets.value(component)->clear(); - } - - // Empty write retransmission list - int missingWriteCount = 0; - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); - transmissionMissingWriteAckPackets.value(component)->clear(); - } - setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); - } - - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent link flooding - QMap*>::iterator i; - QMap*>* onboardParams = paramDataModel->getOnboardParameters(); - for (i = onboardParams->begin(); i != onboardParams->end(); ++i) { - // Iterate through the parameters of the component - int component = i.key(); - // Request n parameters from this component (at maximum) - QList * paramList = transmissionMissingPackets.value(component, NULL); - if (paramList) { - int count = 0; - foreach (int id, *paramList) { - if (count < retransmissionBurstRequestSize) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; - //TODO mavlink msg type for "request parameter set" ? - emit parameterUpdateRequestedById(component, id); - setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); - count++; - } else { - break; - } - } - } + transmissionListMode = false; + clearRetransmissionLists(); + return; } - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent write-request link flooding - // Empty write retransmission list - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - int count = 0; - QMap * missingParams = transmissionMissingWriteAckPackets.value(component); - foreach (QString key, missingParams->keys()) { - if (count < retransmissionBurstRequestSize) { - // Re-request write operation - QVariant value = missingParams->value(key); - switch ((int)onboardParams->value(component)->value(key).type()) - { - case QVariant::Int: - { - QVariant fixedValue(value.toInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QVariant::UInt: - { - QVariant fixedValue(value.toUInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QMetaType::Float: - { - QVariant fixedValue(value.toFloat()); - emit parameterChanged(component, key, fixedValue); - } - break; - default: - //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; - return; - } - setParameterStatusMsg(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); - count++; - } else { - break; - } - } - } - } else { + resendReadWriteRequests(); + } + else { qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; setRetransmissionGuardEnabled(false); } @@ -293,6 +332,7 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV ); return; } + QVariant onboardVal; paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); if (onboardVal == value) { @@ -302,43 +342,11 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV return; } - //int paramType = (int)onboardParameters.value(component)->value(parameterName).type(); - int paramType = (int)value.type(); - switch (paramType) - { - case QVariant::Char: - { - QVariant fixedValue(QChar((unsigned char)value.toInt())); - emit parameterChanged(component, parameterName, fixedValue); - } - break; - case QVariant::Int: - { - QVariant fixedValue(value.toInt()); - emit parameterChanged(component, parameterName, fixedValue); - } - break; - case QVariant::UInt: - { - QVariant fixedValue(value.toUInt()); - emit parameterChanged(component, parameterName, fixedValue); - } - break; - case QMetaType::Float: - { - QVariant fixedValue(value.toFloat()); - emit parameterChanged(component, parameterName, fixedValue); - } - break; - default: - qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE"; - return; - } + emitParameterChanged(component, parameterName, value); // Wait for parameter to be written back // mark it therefore as missing - if (!transmissionMissingWriteAckPackets.contains(component)) - { + if (!transmissionMissingWriteAckPackets.contains(component)) { transmissionMissingWriteAckPackets.insert(component, new QMap()); } @@ -346,15 +354,12 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV transmissionMissingWriteAckPackets.value(component)->insert(parameterName, value); // Set timeouts - if (transmissionActive) - { + if (transmissionActive) { transmissionTimeout += rewriteTimeout; } - else - { + else { quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + rewriteTimeout; - if (newTransmissionTimeout > transmissionTimeout) - { + if (newTransmissionTimeout > transmissionTimeout) { transmissionTimeout = newTransmissionTimeout; } transmissionActive = true; @@ -386,6 +391,8 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para transmissionMissingPackets.insert(compId, new QList()); } + QList* compXmitMissing = transmissionMissingPackets.value(compId); + // List mode is different from single parameter transfers if (transmissionListMode) { // Only accept the list size once on the first packet from @@ -394,20 +401,13 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para // Mark list size as known transmissionListSizeKnown.insert(compId, true); - qDebug() << "Mark all parameters as missing"; - QList* compParamList = transmissionMissingPackets.value(compId); + qDebug() << "Mark all parameters as missing: " << paramCount; for (int i = 0; i < paramCount; ++i) { - if (!compParamList->contains(i)) { - if (i != paramId) { - compParamList->append(i); - } - else { - qDebug() << "Already received " << paramId; - } + if (!compXmitMissing->contains(i)) { + compXmitMissing->append(i); } } - // There is only one transmission timeout for all components // since components do not manage their transmission, // the longest timeout is safe for all components. @@ -419,19 +419,19 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para // Start retransmission guard // or reset timer - setRetransmissionGuardEnabled(true); //TODO + setRetransmissionGuardEnabled(true); } // Mark this parameter as received in read list - int index = transmissionMissingPackets.value(compId)->indexOf(paramId); + int index = compXmitMissing->indexOf(paramId); // If the MAV sent the parameter without request, it wont be in missing list if (index != -1) { - transmissionMissingPackets.value(compId)->removeAt(index); + compXmitMissing->removeAt(index); } bool justWritten = false; bool writeMismatch = false; - //bool lastWritten = false; + // Mark this parameter as received in write ACK list QMap* map = transmissionMissingWriteAckPackets.value(compId); if (map && map->contains(paramName)) { @@ -496,10 +496,14 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para } else { qDebug() << "missCount:" << missCount << "missWriteCount:" << missWriteCount; - foreach (int key, transmissionMissingPackets.keys()) { - QList* list = transmissionMissingPackets.value(key); - qDebug() << "Component" << key << "missing numParams:" << list->count() ; + + if (missCount < 4) { + foreach (int key, transmissionMissingPackets.keys()) { + QList* list = transmissionMissingPackets.value(key); + qDebug() << "Component" << key << "missing params:" << list ; + } } + setRetransmissionGuardEnabled(true); //reset the timeout timer since we received one } } diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 03286c1e1e..327d99a94b 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -38,6 +38,13 @@ protected: /** @brief Load settings that control eg retransmission timeouts */ void loadParamCommsSettings(); + /** @brief clear transmissionMissingPackets and transmissionMissingWriteAckPackets */ + void clearRetransmissionLists(); + + void resendReadWriteRequests(); + + void emitParameterChanged(int compId, const QString& key, QVariant& value); + signals: void parameterChanged(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 7600d15768..c7b75939ad 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -450,100 +450,6 @@ void QGCParamWidget::writeParameters() } } -/** - * @param component the subsystem which has the parameter - * @param parameterName name of the parameter, as delivered by the system - * @param value value of the parameter - */ -//void QGCParamWidget::setParameter(int component, QString parameterName, QVariant value) -//{ - -// if (parameterName.isEmpty()) { -// return; -// } - -// double dblValue = value.toDouble(); - -// if (paramDataModel->isValueLessThanParamMin(parameterName,dblValue)) { -// statusLabel->setText(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); -// return; -// } -// if (paramDataModel->isValueGreaterThanParamMax(parameterName,dblValue)) { -// statusLabel->setText(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); -// return; -// } -// QVariant onboardVal; -// paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); -// if (onboardVal == value) { -// statusLabel->setText(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue)); -// return; -// } - -// //int paramType = (int)onboardParameters.value(component)->value(parameterName).type(); -// int paramType = (int)value.type(); -// switch (paramType) -// { -// case QVariant::Char: -// { -// QVariant fixedValue(QChar((unsigned char)value.toInt())); -// emit parameterChanged(component, parameterName, fixedValue); -// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; -// } -// break; -// case QVariant::Int: -// { -// QVariant fixedValue(value.toInt()); -// emit parameterChanged(component, parameterName, fixedValue); -// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; -// } -// break; -// case QVariant::UInt: -// { -// QVariant fixedValue(value.toUInt()); -// emit parameterChanged(component, parameterName, fixedValue); -// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; -// } -// break; -// case QMetaType::Float: -// { -// QVariant fixedValue(value.toFloat()); -// emit parameterChanged(component, parameterName, fixedValue); -// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; -// } -// break; -// default: -// qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE"; -// return; -// } - -// // Wait for parameter to be written back -// // mark it therefore as missing -// if (!transmissionMissingWriteAckPackets.contains(component)) -// { -// transmissionMissingWriteAckPackets.insert(component, new QMap()); -// } - -// // Insert it in missing write ACK list -// transmissionMissingWriteAckPackets.value(component)->insert(parameterName, value); - -// // Set timeouts -// if (transmissionActive) -// { -// transmissionTimeout += rewriteTimeout; -// } -// else -// { -// quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + rewriteTimeout; -// if (newTransmissionTimeout > transmissionTimeout) -// { -// transmissionTimeout = newTransmissionTimeout; -// } -// transmissionActive = true; -// } - -// // Enable guard / reset timeouts -// paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO -//} void QGCParamWidget::readParameters() { -- GitLab From 6a173001afa7a31213a2dfb0031499538664761b Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 23:22:41 -0700 Subject: [PATCH 184/460] reset timeout timer every time we receive a param --- src/uas/UASParameterCommsMgr.cc | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 712cd9b1cb..3c9818d4a4 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -495,15 +495,31 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para emit parameterListUpToDate(); } else { - qDebug() << "missCount:" << missCount << "missWriteCount:" << missWriteCount; + //reset the timeout timer since we received one + setRetransmissionGuardEnabled(true); - if (missCount < 4) { - foreach (int key, transmissionMissingPackets.keys()) { - QList* list = transmissionMissingPackets.value(key); - qDebug() << "Component" << key << "missing params:" << list ; - } - } - setRetransmissionGuardEnabled(true); //reset the timeout timer since we received one + //qDebug() << "missCount:" << missCount << "missWriteCount:" << missWriteCount; + //if (missCount < 4) { + // foreach (int key, transmissionMissingPackets.keys()) { + // QList* list = transmissionMissingPackets.value(key); + + // if (list && list->count()) { + // QString yazza = QString().sprintf("Component %d missing %d: ",key,list->count()); + + // for (int i = 0; i < list->count(); i++) { + // int val = list->at(i); + // yazza.append( QString().sprintf("%d,",val) ); + // } + + // qDebug() << yazza; + // } + // else { + // //very suspicious...no actual missing items?? + // transmissionMissingPackets.remove(key); + // break; + // } + // } + //} } } -- GitLab From 3dd5866fff17ef6fb583cf8ef537299725332b0d Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 23:46:58 -0700 Subject: [PATCH 185/460] refresh tree display after list recv --- src/ui/QGCParamWidget.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index c7b75939ad..d5f769b088 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -202,6 +202,21 @@ void QGCParamWidget::handleParameterUpdate(int componentId, const QString& param void QGCParamWidget::handleParameterListUpToDate() { + tree->collapseAll(); + + //rewrite the component item tree after receiving the full list + QMap*>::iterator i; + QMap*>* onboardParams = paramDataModel->getOnboardParameters(); + + for (i = onboardParams->begin(); i != onboardParams->end(); ++i) { + int compId = i.key(); + QMap* paramPairs = onboardParams->value(compId); + QMap::iterator j; + for (j = paramPairs->begin(); j != paramPairs->end(); j++) { + updateParameterDisplay(compId, j.key(),j.value()); + } + } + // Expand visual tree tree->expandItem(tree->topLevelItem(0)); } -- GitLab From d862ec870f37e55fec79ebd3d81a9ab5d4ba6301 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 00:03:13 -0700 Subject: [PATCH 186/460] rm totalOnboardParameters --- src/uas/QGCUASParamManager.cc | 23 +++-------------------- src/uas/UASParameterDataModel.cc | 3 ++- src/uas/UASParameterDataModel.h | 2 -- src/ui/designer/QGCParamSlider.cc | 3 +++ 4 files changed, 8 insertions(+), 23 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 1dd6050c57..c1b29e88f1 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -8,7 +8,9 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : QWidget(parent), - mav(uas) + mav(uas), + paramDataModel(NULL), + paramCommsMgr(NULL) { paramDataModel = uas->getParamDataModel(); paramCommsMgr = uas->getParamCommsMgr(); @@ -18,25 +20,6 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : loadParamMetaInfoCSV(); -// // Connect retransmission guard -// connect(this, SIGNAL(parameterUpdateRequested(int,QString)), -// this, SLOT(requestParameterUpdate(int,QString))); - -// //TODO connect in paramCommsMgr instead -// connect(this, SIGNAL(parameterUpdateRequestedById(int,int)), -// mav, SLOT(requestParameter(int,int))); - - // New parameters from UAS - - void parameterUpdated(int compId, QString paramName, QVariant value); - - -// connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), -// this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); - - - - } diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 9815ce7779..96d7479f0b 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -11,7 +11,8 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : QObject(parent) { - + onboardParameters.clear(); + pendingParameters.clear(); } diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 219eff900b..535cc03082 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -14,7 +14,6 @@ public: explicit UASParameterDataModel(QObject *parent = 0); - int getTotalOnboardParams() { return totalOnboardParameters; } //Parameter meta info bool isParamMinKnown(const QString& param) { return paramMin.contains(param); } virtual bool isValueLessThanParamMin(const QString& param, double dblVal); @@ -97,7 +96,6 @@ protected: int uasId; ///< The UAS / MAV to which this data model pertains QMap* > pendingParameters; ///< Changed values that have not yet been transmitted to the UAS, by component ID QMap* > onboardParameters; ///< All parameters confirmed to be stored onboard the UAS, by component ID - int totalOnboardParameters;///< The known count of onboard parameters, may not match onboardParameters until all params are received // Tooltip data structures QMap paramDescriptions; ///< Tooltip values diff --git a/src/ui/designer/QGCParamSlider.cc b/src/ui/designer/QGCParamSlider.cc index e927dea032..32b236a4b8 100644 --- a/src/ui/designer/QGCParamSlider.cc +++ b/src/ui/designer/QGCParamSlider.cc @@ -175,6 +175,9 @@ void QGCParamSlider::selectParameter(int paramIndex) { // Set name parameterName = ui->editSelectParamComboBox->itemText(paramIndex); + if (parameterName.isEmpty()) { + return; + } // Update min and max values if available if (uas) { -- GitLab From 5a1bd9b9005800cbc70a0ace5e40e744db009d3b Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 07:15:03 -0700 Subject: [PATCH 187/460] fix comm mgr -> data model wiring --- src/uas/UASParameterCommsMgr.cc | 10 ++- src/ui/QGCParamWidget.cc | 152 ++++++++++++++++---------------- src/ui/QGCParamWidget.h | 1 + 3 files changed, 86 insertions(+), 77 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 3c9818d4a4..690851cbeb 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -30,7 +30,7 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), mav, SLOT(setParameter(int,QString,QVariant))); - // New parameters from UAS + // Received parameter updates from UAS connect(mav, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); @@ -177,7 +177,7 @@ void UASParameterCommsMgr::resendReadWriteRequests() QList* missingReadParams = transmissionMissingPackets.value(compId, NULL); foreach (int paramId, *missingReadParams) { if (requestedReadCount < retransmissionBurstRequestSize) { - qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << paramId << "FROM COMPONENT #" << compId; + //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << paramId << "FROM COMPONENT #" << compId; emit parameterUpdateRequestedById(compId, paramId); setParameterStatusMsg(tr("Requested retransmission of #%1").arg(paramId+1)); requestedReadCount++; @@ -385,6 +385,10 @@ void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg, ParamCommsS */ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value) { + Q_UNUSED(uas); //this object is assigned to one UAS only + + //notify the data model that we have an updated param + paramDataModel->handleParameterUpdate(compId,paramName,value); // Missing packets list has to be instantiated for all components if (!transmissionMissingPackets.contains(compId)) { @@ -402,7 +406,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para transmissionListSizeKnown.insert(compId, true); qDebug() << "Mark all parameters as missing: " << paramCount; - for (int i = 0; i < paramCount; ++i) { + for (int i = 1; i < paramCount; ++i) { //TODO check: param Id 0 is "all parameters" ? if (!compXmitMissing->contains(i)) { compXmitMissing->append(i); } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index d5f769b088..a141ec4ea8 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -54,6 +54,36 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : componentItems(new QMap()) { + layoutWidget(); + + // Connect signals/slots + + // Listen for edits to the tree UI + connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), + this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); + + // Listen to updated param signals from the data model + connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), + this, SLOT(handleParameterUpdate(int,QString,QVariant))); + + // Listen for param list reload finished + connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), + this, SLOT(handleParameterListUpToDate())); + + // Listen to communications status messages so we can display them + connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), + this, SLOT(handleParamStatusMsgUpdate(QString , int ))); + + // Ensure we're receiving the list of params + requestAllParamsUpdate(); + +} + + + + +void QGCParamWidget::layoutWidget() +{ // Create tree widget tree = new QTreeWidget(this); statusLabel = new QLabel(); @@ -77,7 +107,6 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : statusLabel->setText(tr("Click refresh to download parameters")); horizontalLayout->addWidget(statusLabel, 1, 0, 1, 3); - // BUTTONS QPushButton* refreshButton = new QPushButton(tr("Get")); refreshButton->setToolTip(tr("Load parameters currently in non-permanent memory of aircraft.")); @@ -130,61 +159,35 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : headerItems.append("Value"); tree->setHeaderLabels(headerItems); tree->setColumnCount(2); + tree->setColumnWidth(0,120); + tree->setColumnWidth(1,120); tree->setExpandsOnDoubleClick(true); - // Connect signals/slots -// connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), -// mav, SLOT(setParameter(int,QString,QVariant))); - connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), - this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); - -// // New parameters from UAS -// connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); - - -// connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); -// connect(this, SIGNAL(requestParameter(int,QString)), uas, SLOT(requestParameter(int,QString))); -// connect(this, SIGNAL(requestParameter(int,int)), uas, SLOT(requestParameter(int,int))); - - - connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), - this, SLOT(handleParameterUpdate(int,QString,QVariant))); - - // Listen for param list reload finished - connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), - this, SLOT(handleParameterListUpToDate())); - - connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), - this, SLOT(handleParamStatusMsgUpdate(QString , int ))); - - // Get parameters - if (uas) { - requestAllParamsUpdate(); - } + tree->setVisible(true); } - - - - - void QGCParamWidget::addComponentItem( int compId, QString compName) { + QString compLine = QString("%1 (#%2)").arg(compName).arg(compId); + + QString ptrStr.sprintf("%8p", this); + qDebug() << "QGCParamWidget" << ptrStr << "addComponentItem:" << compLine; + if (componentItems->contains(compId)) { - // Update existing - componentItems->value(compId)->setData(0, Qt::DisplayRole, QString("%1 (#%2)").arg(compName).arg(compId)); + // Update existing component item + componentItems->value(compId)->setData(0, Qt::DisplayRole, compLine); //components->value(component)->setData(1, Qt::DisplayRole, QString::number(component)); componentItems->value(compId)->setFirstColumnSpanned(true); } else { - // Add new - QStringList list(QString("%1 (#%2)").arg(compName).arg(compId)); - QTreeWidgetItem* comp = new QTreeWidgetItem(list); - comp->setFirstColumnSpanned(true); - componentItems->insert(compId, comp); - // Create grouping and update maps + // Add new component item + QStringList list(compLine); + QTreeWidgetItem* compItem = new QTreeWidgetItem(list); + compItem->setFirstColumnSpanned(true); + componentItems->insert(compId, compItem); + // Create parameter grouping for this component and update maps paramGroups.insert(compId, new QMap()); - tree->addTopLevelItem(comp); + tree->addTopLevelItem(compItem); tree->update(); } @@ -202,7 +205,10 @@ void QGCParamWidget::handleParameterUpdate(int componentId, const QString& param void QGCParamWidget::handleParameterListUpToDate() { - tree->collapseAll(); +// tree->collapseAll(); + + //turn off updates while we refresh the entire list + tree->setUpdatesEnabled(false); //rewrite the component item tree after receiving the full list QMap*>::iterator i; @@ -219,44 +225,38 @@ void QGCParamWidget::handleParameterListUpToDate() // Expand visual tree tree->expandItem(tree->topLevelItem(0)); + tree->setUpdatesEnabled(true); + tree->update(); + } void QGCParamWidget::updateParameterDisplay(int componentId, QString parameterName, QVariant value) { +// qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName; -// QString ptrStr; -// ptrStr.sprintf("%8p", this); -// qDebug() << "QGCParamWidget " << ptrStr << " got param" << parameterName; // Reference to item in tree QTreeWidgetItem* parameterItem = NULL; - // Get component + // Add component item if necessary if (!componentItems->contains(componentId)) { QString componentName = tr("Component #%1").arg(componentId); addComponentItem(componentId, componentName); } - //TODO this should be bubbling up from the model, not vice-versa, right? -// // Replace value in data model -// paramDataModel->handleParameterUpdate(componentId,parameterName,value); - - QString splitToken = "_"; // Check if auto-grouping can work - if (parameterName.contains(splitToken)) - { + if (parameterName.contains(splitToken)) { QString parent = parameterName.section(splitToken, 0, 0, QString::SectionSkipEmpty); QMap* compParamGroups = paramGroups.value(componentId); - if (!compParamGroups->contains(parent)) - { + if (!compParamGroups->contains(parent)) { // Insert group item QStringList glist; glist.append(parent); - QTreeWidgetItem* item = new QTreeWidgetItem(glist); - compParamGroups->insert(parent, item); - componentItems->value(componentId)->addChild(item); + QTreeWidgetItem* groupItem = new QTreeWidgetItem(glist); + compParamGroups->insert(parent, groupItem); + componentItems->value(componentId)->addChild(groupItem); } // Append child to group @@ -322,26 +322,30 @@ void QGCParamWidget::updateParameterDisplay(int componentId, QString parameterNa componentItems->value(componentId)->addChild(parameterItem); parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); } - //tree->expandAll(); } + // Reset background color parameterItem->setBackground(0, Qt::NoBrush); parameterItem->setBackground(1, Qt::NoBrush); + + parameterItem->setTextColor(0, QGC::colorDarkWhite); + parameterItem->setTextColor(1, QGC::colorDarkWhite); + // Add tooltip QString paramDesc = paramDataModel->getParamDescription(parameterName); - QString tooltipFormat; - if (paramDataModel->isParamDefaultKnown(parameterName)) { - tooltipFormat = tr("Default: %1, %2"); - double paramDefValue = paramDataModel->getParamDefault(parameterName); - tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc); - } - else { - tooltipFormat = paramDesc; + if (!paramDesc.isEmpty()) { + QString tooltipFormat; + if (paramDataModel->isParamDefaultKnown(parameterName)) { + tooltipFormat = tr("Default: %1, %2"); + double paramDefValue = paramDataModel->getParamDefault(parameterName); + tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc); + } + else { + tooltipFormat = paramDesc; + } + parameterItem->setToolTip(0, tooltipFormat); + parameterItem->setToolTip(1, tooltipFormat); } - parameterItem->setToolTip(0, tooltipFormat); - parameterItem->setToolTip(1, tooltipFormat); - - //paramDataModel->handleParameterUpdate(componentId,parameterName,value); } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 5a356b722b..85794966d5 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -51,6 +51,7 @@ public: protected: virtual void setParameterStatusMsg(const QString& msg); + virtual void layoutWidget(); signals: /** @brief A parameter was changed in the widget, NOT onboard */ -- GitLab From 3db98d95653e53626afa3076287a39772778f11a Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 07:16:18 -0700 Subject: [PATCH 188/460] propagate error signal on too many link errs reduce serial link logging; clear transmit buffer on disconnect --- src/comm/SerialLink.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 07807e550a..1e19bc2a80 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -176,7 +176,9 @@ void SerialLink::run() } if (isConnected() && (linkErrorCount > 100)) { + qDebug() << "linkErrorCount too high: disconnecting!"; linkErrorCount = 0; + communicationError("SerialLink", tr("Disconnecting on too many link errors")); disconnect(); } @@ -210,7 +212,7 @@ void SerialLink::run() } } else { linkErrorCount++; - qDebug() << "Wait read response timeout" << QTime::currentTime().toString(); + //qDebug() << "Wait read response timeout" << QTime::currentTime().toString(); } if (bytes != m_bytesRead) // i.e things are good and data is being read. @@ -370,6 +372,8 @@ bool SerialLink::disconnect() return true; } + m_transmitBuffer.clear(); //clear the output buffer to avoid sending garbage at next connect + qDebug() << "already disconnected"; return true; } -- GitLab From b2773acd3523b6eab81aff4e7eafac1661e5e227 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 07:17:17 -0700 Subject: [PATCH 189/460] fix typo --- src/ui/QGCParamWidget.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index a141ec4ea8..025e68f5e4 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -171,7 +171,7 @@ void QGCParamWidget::addComponentItem( int compId, QString compName) { QString compLine = QString("%1 (#%2)").arg(compName).arg(compId); - QString ptrStr.sprintf("%8p", this); + QString ptrStr = QString().sprintf("%8p", this); qDebug() << "QGCParamWidget" << ptrStr << "addComponentItem:" << compLine; if (componentItems->contains(compId)) { -- GitLab From 7037ca90adeb53b53a4566b437c8928283cd322f Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 09:11:42 -0700 Subject: [PATCH 190/460] move sendPendingParams --- src/uas/QGCUASParamManager.cc | 6 ++++ src/uas/QGCUASParamManager.h | 3 ++ src/uas/UASParameterCommsMgr.cc | 36 ++++++++++++---------- src/uas/UASParameterCommsMgr.h | 2 +- src/ui/QGCParamWidget.cc | 53 ++++++++++++++++----------------- src/ui/QGCParamWidget.h | 6 +--- 6 files changed, 56 insertions(+), 50 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index c1b29e88f1..6796ef0b49 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -70,6 +70,12 @@ void QGCUASParamManager::setParameter(int component, QString parameterName, QVar paramCommsMgr->setParameter(component,parameterName,value); } +void QGCUASParamManager::sendPendingParameters() +{ + paramCommsMgr->sendPendingParameters(); +} + + void QGCUASParamManager::loadParamMetaInfoCSV() { diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index a5c4b40f2f..9836de2d10 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -46,6 +46,9 @@ public slots: /** @brief Send one parameter to the MAV: changes value in transient memory of MAV */ virtual void setParameter(int component, QString parameterName, QVariant value); + /** @brief Send all pending parameters to the MAV, for storage in transient (RAM) memory */ + virtual void sendPendingParameters(); + /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 690851cbeb..e92ef2ed9c 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -100,25 +100,23 @@ void UASParameterCommsMgr::requestParameterList() Empty read retransmission list Empty write retransmission list */ -void UASParameterCommsMgr::clearRetransmissionLists() +void UASParameterCommsMgr::clearRetransmissionLists(int& missingReadCount, int& missingWriteCount ) { qDebug() << __FILE__ << __LINE__ << "clearRetransmissionLists"; - int missingReadCount = 0; + missingReadCount = 0; QList readKeys = transmissionMissingPackets.keys(); foreach (int component, readKeys) { missingReadCount += transmissionMissingPackets.value(component)->count(); transmissionMissingPackets.value(component)->clear(); } - int missingWriteCount = 0; + missingWriteCount = 0; QList writeKeys = transmissionMissingWriteAckPackets.keys(); foreach (int component, writeKeys) { missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); transmissionMissingWriteAckPackets.value(component)->clear(); } - setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount), - ParamCommsStatusLevel_Warning); } @@ -230,7 +228,6 @@ void UASParameterCommsMgr::retransmissionGuardTick() return; } - qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; // Check for timeout // stop retransmission attempts on timeout @@ -238,10 +235,17 @@ void UASParameterCommsMgr::retransmissionGuardTick() setRetransmissionGuardEnabled(false); transmissionActive = false; transmissionListMode = false; - clearRetransmissionLists(); + int missingReadCount, missingWriteCount; + clearRetransmissionLists(missingReadCount,missingWriteCount); + if ((missingReadCount > 0) || (missingWriteCount > 0)) { + setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount), + ParamCommsStatusLevel_Warning); + } + return; } + qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; resendReadWriteRequests(); } else { @@ -544,15 +548,15 @@ void UASParameterCommsMgr::sendPendingParameters() QMap*>::iterator i; for (i = changedValues->begin(); i != changedValues->end(); ++i) { // Iterate through the parameters of the component - int compid = i.key(); - QMap* comp = i.value(); - { - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) { - //TODO mavlink command for "set parameter list" ? - setParameter(compid, j.key(), j.value()); - parametersSent++; - } + int compId = i.key(); + QMap* paramList = i.value(); + QMap::iterator j; + setParameterStatusMsg(tr("%1 pending params for component %2").arg(paramList->count()).arg(compId)); + + for (j = paramList->begin(); j != paramList->end(); ++j) { + //TODO mavlink command for "set parameter list" ? + setParameter(compId, j.key(), j.value()); + parametersSent++; } } diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 327d99a94b..b36dc7fb83 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -39,7 +39,7 @@ protected: void loadParamCommsSettings(); /** @brief clear transmissionMissingPackets and transmissionMissingWriteAckPackets */ - void clearRetransmissionLists(); + void clearRetransmissionLists(int& missingReadCount, int& missingWriteCount ); void resendReadWriteRequests(); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 025e68f5e4..6818856401 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -88,7 +88,6 @@ void QGCParamWidget::layoutWidget() tree = new QTreeWidget(this); statusLabel = new QLabel(); statusLabel->setAutoFillBackground(true); - tree->setColumnWidth(70, 30); // Set tree widget as widget onto this component QGridLayout* horizontalLayout; @@ -117,7 +116,8 @@ void QGCParamWidget::layoutWidget() QPushButton* setButton = new QPushButton(tr("Set")); setButton->setToolTip(tr("Set current parameters in non-permanent onboard memory")); setButton->setWhatsThis(tr("Set current parameters in non-permanent onboard memory")); - connect(setButton, SIGNAL(clicked()), this, SLOT(setParameters())); + connect(setButton, SIGNAL(clicked()), + this, SLOT(sendPendingParameters())); horizontalLayout->addWidget(setButton, 2, 1); QPushButton* writeButton = new QPushButton(tr("Write (ROM)")); @@ -159,7 +159,7 @@ void QGCParamWidget::layoutWidget() headerItems.append("Value"); tree->setHeaderLabels(headerItems); tree->setColumnCount(2); - tree->setColumnWidth(0,120); + tree->setColumnWidth(0,200); tree->setColumnWidth(1,120); tree->setExpandsOnDoubleClick(true); @@ -167,8 +167,9 @@ void QGCParamWidget::layoutWidget() } -void QGCParamWidget::addComponentItem( int compId, QString compName) +void QGCParamWidget::addComponentItem(int compId, QString compName) { + QString compLine = QString("%1 (#%2)").arg(compName).arg(compId); QString ptrStr = QString().sprintf("%8p", this); @@ -231,37 +232,41 @@ void QGCParamWidget::handleParameterListUpToDate() } -void QGCParamWidget::updateParameterDisplay(int componentId, QString parameterName, QVariant value) +void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, QVariant value) { // qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName; - // Reference to item in tree QTreeWidgetItem* parameterItem = NULL; // Add component item if necessary - if (!componentItems->contains(componentId)) { - QString componentName = tr("Component #%1").arg(componentId); - addComponentItem(componentId, componentName); + if (!componentItems->contains(compId)) { + QString componentName = tr("Component #%1").arg(compId); + addComponentItem(compId, componentName); } QString splitToken = "_"; // Check if auto-grouping can work if (parameterName.contains(splitToken)) { - QString parent = parameterName.section(splitToken, 0, 0, QString::SectionSkipEmpty); - QMap* compParamGroups = paramGroups.value(componentId); - if (!compParamGroups->contains(parent)) { + QString parentStr = parameterName.section(splitToken, 0, 0, QString::SectionSkipEmpty); + QMap* compParamGroups = paramGroups.value(compId); + if (!compParamGroups->contains(parentStr)) { // Insert group item QStringList glist; - glist.append(parent); + glist.append(parentStr); QTreeWidgetItem* groupItem = new QTreeWidgetItem(glist); - compParamGroups->insert(parent, groupItem); - componentItems->value(componentId)->addChild(groupItem); + + compParamGroups->insert(parentStr, groupItem); + + // insert new group alphabetized + QList groupKeys = compParamGroups->uniqueKeys(); + int insertIdx = groupKeys.indexOf(parentStr); + componentItems->value(compId)->insertChild(insertIdx,groupItem); } // Append child to group bool found = false; - QTreeWidgetItem* parentItem = compParamGroups->value(parent); + QTreeWidgetItem* parentItem = compParamGroups->value(parentStr); for (int i = 0; i < parentItem->childCount(); i++) { QTreeWidgetItem* child = parentItem->child(i); QString key = child->data(0, Qt::DisplayRole).toString(); @@ -292,13 +297,13 @@ void QGCParamWidget::updateParameterDisplay(int componentId, QString parameterNa parameterItem->setData(1, Qt::DisplayRole, value); } - compParamGroups->value(parent)->addChild(parameterItem); + compParamGroups->value(parentStr)->addChild(parameterItem); parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); } } else { bool found = false; - QTreeWidgetItem* parent = componentItems->value(componentId); + QTreeWidgetItem* parent = componentItems->value(compId); for (int i = 0; i < parent->childCount(); i++) { QTreeWidgetItem* child = parent->child(i); QString key = child->data(0, Qt::DisplayRole).toString(); @@ -319,7 +324,7 @@ void QGCParamWidget::updateParameterDisplay(int componentId, QString parameterNa // CONFIGURE PARAMETER ITEM parameterItem->setData(1, Qt::DisplayRole, value); - componentItems->value(componentId)->addChild(parameterItem); + componentItems->value(compId)->addChild(parameterItem); parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); } } @@ -434,14 +439,6 @@ void QGCParamWidget::requestAllParamsUpdate() -/** - * Set all parameter in the parameter tree on the MAV - */ -void QGCParamWidget::setParameters() -{ - paramCommsMgr->sendPendingParameters(); -} - /** * Write the current onboard parameters from RAM into * permanent storage, e.g. EEPROM or harddisk @@ -454,7 +451,7 @@ void QGCParamWidget::writeParameters() QMap*>* changedValues = paramDataModel->getPendingParameters(); for (i = changedValues->begin(); (i != changedValues->end()) && (0 == changedParamCount); ++i) { - // Iterate through the parameters of the component + // Iterate through the pending parameters of the component, break on the first changed parameter QMap* compPending = i.value(); changedParamCount += compPending->count(); } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 85794966d5..2176b5b4a5 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -77,10 +77,7 @@ public slots: void updateParameterDisplay(int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ void requestAllParamsUpdate(); - /** @brief Set one parameter, changes value in RAM of MAV */ -// virtual void setParameter(int component, QString parameterName, QVariant value); - /** @brief Set all parameters, changes the value in RAM of MAV */ - void setParameters(); + /** @brief Write the current parameters to permanent storage (EEPROM/HDD) */ void writeParameters(); /** @brief Read the parameters from permanent storage to RAM */ @@ -103,7 +100,6 @@ protected: QMap* componentItems; ///< The tree of component items, stored by component ID QMap* > paramGroups; ///< Parameter groups to organize component items - }; #endif // QGCPARAMWIDGET_H -- GitLab From 5f00489feb544cfed3480ea3b101ea7be70ccf37 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 09:40:04 -0700 Subject: [PATCH 191/460] clear guard timer when list mode done --- src/uas/UASParameterCommsMgr.cc | 42 ++++++++----- src/uas/UASParameterCommsMgr.h | 1 + src/ui/QGCParamWidget.cc | 101 +++++++++++++++++++++++--------- 3 files changed, 99 insertions(+), 45 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index e92ef2ed9c..c2655dc046 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -106,16 +106,16 @@ void UASParameterCommsMgr::clearRetransmissionLists(int& missingReadCount, int& missingReadCount = 0; QList readKeys = transmissionMissingPackets.keys(); - foreach (int component, readKeys) { - missingReadCount += transmissionMissingPackets.value(component)->count(); - transmissionMissingPackets.value(component)->clear(); + foreach (int compId, readKeys) { + missingReadCount += transmissionMissingPackets.value(compId)->count(); + transmissionMissingPackets.value(compId)->clear(); } missingWriteCount = 0; QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); - transmissionMissingWriteAckPackets.value(component)->clear(); + foreach (int compId, writeKeys) { + missingWriteCount += transmissionMissingWriteAckPackets.value(compId)->count(); + transmissionMissingWriteAckPackets.value(compId)->clear(); } } @@ -209,10 +209,26 @@ void UASParameterCommsMgr::resendReadWriteRequests() if ((0 == requestedWriteCount) && (0 == requestedReadCount) ) { qDebug() << __FILE__ << __LINE__ << "NO re-read or rewrite requests??"; - //setRetransmissionGuardEnabled(false); + if (!transmissionListMode) { + setRetransmissionGuardEnabled(false); + transmissionActive = false; + } } } +void UASParameterCommsMgr::resetAfterListReceive() +{ + transmissionListMode = false; + transmissionListSizeKnown.clear(); + + //TODO we shouldn't clear missingPackets because other transactions might be using them? + //for list reception we only clear receive packets? +// foreach (int key, transmissionMissingPackets.keys()) { +// transmissionMissingPackets.value(key)->clear(); +// } + +} + void UASParameterCommsMgr::retransmissionGuardTick() { if (transmissionActive) { @@ -233,8 +249,8 @@ void UASParameterCommsMgr::retransmissionGuardTick() // stop retransmission attempts on timeout if (QGC::groundTimeMilliseconds() > transmissionTimeout) { setRetransmissionGuardEnabled(false); - transmissionActive = false; - transmissionListMode = false; + resetAfterListReceive(); + int missingReadCount, missingWriteCount; clearRetransmissionLists(missingReadCount,missingWriteCount); if ((missingReadCount > 0) || (missingWriteCount > 0)) { @@ -491,13 +507,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para // Check if last parameter was received if (missCount == 0 && missWriteCount == 0) { - this->transmissionActive = false; - this->transmissionListMode = false; - transmissionListSizeKnown.clear(); - foreach (int key, transmissionMissingPackets.keys()) { - transmissionMissingPackets.value(key)->clear(); - } - + resetAfterListReceive(); setRetransmissionGuardEnabled(false); //all parameters have been received, broadcast to UI emit parameterListUpToDate(); diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index b36dc7fb83..b1ece5fa18 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -42,6 +42,7 @@ protected: void clearRetransmissionLists(int& missingReadCount, int& missingWriteCount ); void resendReadWriteRequests(); + void resetAfterListReceive(); void emitParameterChanged(int compId, const QString& key, QVariant& value); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 6818856401..069e4cd60e 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -245,6 +245,9 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q addComponentItem(compId, componentName); } + //default parent item for this parameter widget item will be the top level component item + QTreeWidgetItem* parentItem = componentItems->value(compId); + QString splitToken = "_"; // Check if auto-grouping can work if (parameterName.contains(splitToken)) { @@ -265,8 +268,75 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q } // Append child to group + //bool found = false; + //parent item for this tree widget item will be a group widget item + parentItem = compParamGroups->value(parentStr); + +// for (int i = 0; i < parentItem->childCount(); i++) { +// QTreeWidgetItem* child = parentItem->child(i); +// QString key = child->data(0, Qt::DisplayRole).toString(); +// if (key == parameterName) { +// //qDebug() << "UPDATED CHILD"; +// parameterItem = child; +// if (value.type() == QVariant::Char) { +// parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); +// } +// else { +// parameterItem->setData(1, Qt::DisplayRole, value); +// } +// found = true; +// } +// } + +// if (!found) { +// // Insert parameter into map +// QStringList plist; +// plist.append(parameterName); +// // CREATE PARAMETER ITEM +// parameterItem = new QTreeWidgetItem(plist); +// // CONFIGURE PARAMETER ITEM +// if (value.type() == QVariant::Char) { +// parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); +// } +// else { +// parameterItem->setData(1, Qt::DisplayRole, value); +// } +// parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); + +// parentItem->addChild(parameterItem); +// } + } + else { + //bool found = false; + parentItem = componentItems->value(compId); + +// for (int i = 0; i < parent->childCount(); i++) { +// QTreeWidgetItem* child = parent->child(i); +// QString key = child->data(0, Qt::DisplayRole).toString(); +// if (key == parameterName) { +// //qDebug() << "UPDATED CHILD"; +// parameterItem = child; +// parameterItem->setData(1, Qt::DisplayRole, value); +// found = true; +// } +// } + +// if (!found) { +// // Insert parameter into map +// QStringList plist; +// plist.append(parameterName); +// // CREATE PARAMETER ITEM +// parameterItem = new QTreeWidgetItem(plist); +// // CONFIGURE PARAMETER ITEM +// parameterItem->setData(1, Qt::DisplayRole, value); + +// componentItems->value(compId)->addChild(parameterItem); +// parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); +// } + } + + if (parentItem) { bool found = false; - QTreeWidgetItem* parentItem = compParamGroups->value(parentStr); for (int i = 0; i < parentItem->childCount(); i++) { QTreeWidgetItem* child = parentItem->child(i); QString key = child->data(0, Qt::DisplayRole).toString(); @@ -296,36 +366,9 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q else { parameterItem->setData(1, Qt::DisplayRole, value); } - - compParamGroups->value(parentStr)->addChild(parameterItem); parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); - } - } - else { - bool found = false; - QTreeWidgetItem* parent = componentItems->value(compId); - for (int i = 0; i < parent->childCount(); i++) { - QTreeWidgetItem* child = parent->child(i); - QString key = child->data(0, Qt::DisplayRole).toString(); - if (key == parameterName) { - //qDebug() << "UPDATED CHILD"; - parameterItem = child; - parameterItem->setData(1, Qt::DisplayRole, value); - found = true; - } - } - if (!found) { - // Insert parameter into map - QStringList plist; - plist.append(parameterName); - // CREATE PARAMETER ITEM - parameterItem = new QTreeWidgetItem(plist); - // CONFIGURE PARAMETER ITEM - parameterItem->setData(1, Qt::DisplayRole, value); - - componentItems->value(compId)->addChild(parameterItem); - parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); + parentItem->addChild(parameterItem); } } -- GitLab From 15355644f60b72a847c543941942f7c0ce8c934a Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 11:09:20 -0700 Subject: [PATCH 192/460] fix change checking for params; better pending status indication --- src/uas/UASParameterDataModel.cc | 16 +++--- src/uas/UASParameterDataModel.h | 2 +- src/ui/QGCParamWidget.cc | 86 +++++--------------------------- 3 files changed, 20 insertions(+), 84 deletions(-) diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 96d7479f0b..a4f6976ee6 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -18,25 +18,21 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : -bool UASParameterDataModel::checkParameterChanged(int componentId, const QString& key, const QVariant &value) +bool UASParameterDataModel::checkParameterChanged(int compId, const QString& key, const QVariant& value) { bool changed = true; - addComponent(componentId); - QMap* existParams = getOnbardParametersForComponent(componentId); + //ensure we have this component in our onboard and pending lists already + addComponent(compId); + QMap* existParams = getOnbardParametersForComponent(compId); if (existParams->contains(key)) { QVariant existValue = existParams->value(key); - QMap* pendParams = getPendingParametersForComponent(componentId); - if (pendParams->contains(key)) { - QVariant pendValue = pendParams->value(key); - if (existValue == pendValue) { - changed = false; - } + if (existValue == value) { + changed = false; } } return changed; - } bool UASParameterDataModel::addPendingIfParameterChanged(int componentId, QString& key, QVariant &value) diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 535cc03082..57dbc8f0af 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -45,7 +45,7 @@ public: virtual void forgetAllOnboardParameters(); /** - * @return true if the parameter has changed + * @return true if the given value for the parameter is different from the existing value */ virtual bool checkParameterChanged(int componentId, const QString& key, const QVariant &value); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 069e4cd60e..484d61d5de 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -267,72 +267,12 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q componentItems->value(compId)->insertChild(insertIdx,groupItem); } - // Append child to group - //bool found = false; - //parent item for this tree widget item will be a group widget item + //parent item for this parameter item will be a group widget item parentItem = compParamGroups->value(parentStr); - -// for (int i = 0; i < parentItem->childCount(); i++) { -// QTreeWidgetItem* child = parentItem->child(i); -// QString key = child->data(0, Qt::DisplayRole).toString(); -// if (key == parameterName) { -// //qDebug() << "UPDATED CHILD"; -// parameterItem = child; -// if (value.type() == QVariant::Char) { -// parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); -// } -// else { -// parameterItem->setData(1, Qt::DisplayRole, value); -// } -// found = true; -// } -// } - -// if (!found) { -// // Insert parameter into map -// QStringList plist; -// plist.append(parameterName); -// // CREATE PARAMETER ITEM -// parameterItem = new QTreeWidgetItem(plist); -// // CONFIGURE PARAMETER ITEM -// if (value.type() == QVariant::Char) { -// parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); -// } -// else { -// parameterItem->setData(1, Qt::DisplayRole, value); -// } -// parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); - -// parentItem->addChild(parameterItem); -// } } else { - //bool found = false; + //parent item for this parameter will be the top level component widget item parentItem = componentItems->value(compId); - -// for (int i = 0; i < parent->childCount(); i++) { -// QTreeWidgetItem* child = parent->child(i); -// QString key = child->data(0, Qt::DisplayRole).toString(); -// if (key == parameterName) { -// //qDebug() << "UPDATED CHILD"; -// parameterItem = child; -// parameterItem->setData(1, Qt::DisplayRole, value); -// found = true; -// } -// } - -// if (!found) { -// // Insert parameter into map -// QStringList plist; -// plist.append(parameterName); -// // CREATE PARAMETER ITEM -// parameterItem = new QTreeWidgetItem(plist); -// // CONFIGURE PARAMETER ITEM -// parameterItem->setData(1, Qt::DisplayRole, value); - -// componentItems->value(compId)->addChild(parameterItem); -// parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); -// } } if (parentItem) { @@ -367,7 +307,7 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q parameterItem->setData(1, Qt::DisplayRole, value); } parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); - + //TODO insert alphabetically parentItem->addChild(parameterItem); } } @@ -411,25 +351,25 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) QString key = current->data(0, Qt::DisplayRole).toString(); QVariant value = current->data(1, Qt::DisplayRole); - // Set parameter on changed list to be transmitted to MAV - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorOrange); - statusLabel->setPalette(pal); - statusLabel->setText(tr("Transmit pend. %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); - //qDebug() << "PARAM CHANGED: COMP:" << key << "KEY:" << str << "VALUE:" << value; - // Changed values list bool changed = paramDataModel->addPendingIfParameterChanged(componentId,key,value); // If the value was numerically changed, display it differently if (changed) { + + // Set parameter on changed list to be transmitted to MAV + statusLabel->setText(tr("Transmit pend. %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); + + if (current == tree->currentItem()) { + //need to unset current item to clear highlighting (green by default) + tree->setCurrentItem(NULL); //clear the selected line + } current->setBackground(0, QBrush(QColor(QGC::colorOrange))); current->setBackground(1, QBrush(QColor(QGC::colorOrange))); - - //TODO this seems incorrect-- we're pre-updating the onboard value before we've received confirmation - //paramDataModel->setOnboardParameterWithType(componentId,key,value); + tree->update(); } + } } -- GitLab From 6bc50564cfd92b55e65da4d1e460fe1c228ee72c Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 12:25:17 -0700 Subject: [PATCH 193/460] fix pending parameter change check --- src/uas/QGCUASParamManager.cc | 2 +- src/uas/UASParameterCommsMgr.cc | 11 +++-- src/uas/UASParameterDataModel.cc | 83 +++++++++++++++----------------- src/uas/UASParameterDataModel.h | 40 +++++++-------- src/ui/QGCParamWidget.cc | 26 +++++----- 5 files changed, 80 insertions(+), 82 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 6796ef0b49..fcc78a6cb6 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -26,7 +26,7 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : bool QGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const { - return paramDataModel->getOnboardParameterValue(component,parameter,value); + return paramDataModel->getOnboardParamValue(component,parameter,value); } diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index c2655dc046..47ec654b3f 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -168,7 +168,6 @@ void UASParameterCommsMgr::resendReadWriteRequests() // Re-request at maximum retransmissionBurstRequestSize parameters at once // to prevent link flooding' int requestedReadCount = 0; - compIds = transmissionMissingPackets.keys(); foreach (compId, compIds) { // Request n parameters from this component (at maximum) @@ -214,6 +213,10 @@ void UASParameterCommsMgr::resendReadWriteRequests() transmissionActive = false; } } + else { + //restart the timer now that we've sent + setRetransmissionGuardEnabled(true); + } } void UASParameterCommsMgr::resetAfterListReceive() @@ -354,7 +357,7 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV } QVariant onboardVal; - paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); + paramDataModel->getOnboardParamValue(component,parameterName,onboardVal); if (onboardVal == value) { setParameterStatusMsg(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue), ParamCommsStatusLevel_Warning @@ -408,7 +411,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para Q_UNUSED(uas); //this object is assigned to one UAS only //notify the data model that we have an updated param - paramDataModel->handleParameterUpdate(compId,paramName,value); + paramDataModel->handleParamUpdate(compId,paramName,value); // Missing packets list has to be instantiated for all components if (!transmissionMissingPackets.contains(compId)) { @@ -554,7 +557,7 @@ void UASParameterCommsMgr::sendPendingParameters() { // Iterate through all components, through all pending parameters and send them to UAS int parametersSent = 0; - QMap*>* changedValues = paramDataModel->getPendingParameters(); + QMap*>* changedValues = paramDataModel->getAllPendingParams(); QMap*>::iterator i; for (i = changedValues->begin(); i != changedValues->end(); ++i) { // Iterate through the parameters of the component diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index a4f6976ee6..c942b4437b 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -18,53 +18,58 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : -bool UASParameterDataModel::checkParameterChanged(int compId, const QString& key, const QVariant& value) + + +bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key, QVariant& value) { - bool changed = true; + bool pending = true; //ensure we have this component in our onboard and pending lists already addComponent(compId); - QMap* existParams = getOnbardParametersForComponent(compId); + QMap* existParams = getOnboardParamsForComponent(compId); if (existParams->contains(key)) { QVariant existValue = existParams->value(key); if (existValue == value) { - changed = false; + pending = false; } } - return changed; -} + if (pending) { + setPendingParam(compId,key,value); + } + else { + removePendingParam(compId,key); + } -bool UASParameterDataModel::addPendingIfParameterChanged(int componentId, QString& key, QVariant &value) + return pending; +} +void UASParameterDataModel::removePendingParam(int compId, QString& key) { - bool changed = checkParameterChanged(componentId,key,value); - - if (changed ) { - setPendingParameter(componentId,key,value); + QMap *params = getPendingParamsForComponent(compId); + if (params) { + params->remove(key); } - - return changed; } -void UASParameterDataModel::setPendingParameter(int componentId, QString& key, const QVariant &value) +void UASParameterDataModel::setPendingParam(int compId, QString& key, const QVariant &value) { //ensure we have a placeholder map for this component - addComponent(componentId); - QMap *params = getPendingParametersForComponent(componentId); + addComponent(compId); + QMap *params = getPendingParamsForComponent(compId); params->insert(key,value); } -void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, const QVariant& value) +void UASParameterDataModel::setOnboardParam(int compId, QString& key, const QVariant& value) { //ensure we have a placeholder map for this component - addComponent(componentId); - QMap *params = getOnbardParametersForComponent(componentId); + addComponent(compId); + QMap *params = getOnboardParamsForComponent(compId); params->insert(key,value); } -void UASParameterDataModel::setOnboardParameterWithType(int componentId, QString& key, QVariant& value) +void UASParameterDataModel::setOnboardParamWithType(int compId, QString& key, QVariant& value) { // switch ((int)onboardParameters.value(componentId)->value(key).type()) @@ -73,25 +78,25 @@ void UASParameterDataModel::setOnboardParameterWithType(int componentId, QString case QVariant::Int: { QVariant fixedValue(value.toInt()); - onboardParameters.value(componentId)->insert(key, fixedValue); + onboardParameters.value(compId)->insert(key, fixedValue); } break; case QVariant::UInt: { QVariant fixedValue(value.toUInt()); - onboardParameters.value(componentId)->insert(key, fixedValue); + onboardParameters.value(compId)->insert(key, fixedValue); } break; case QMetaType::Float: { QVariant fixedValue(value.toFloat()); - onboardParameters.value(componentId)->insert(key, fixedValue); + onboardParameters.value(compId)->insert(key, fixedValue); } break; case QMetaType::QChar: { QVariant fixedValue(QChar((unsigned char)value.toUInt())); - onboardParameters.value(componentId)->insert(key, fixedValue); + onboardParameters.value(compId)->insert(key, fixedValue); } break; default: @@ -111,7 +116,7 @@ void UASParameterDataModel::addComponent(int compId) } -void UASParameterDataModel::handleParameterUpdate(int compId, QString& key, QVariant& value) +void UASParameterDataModel::handleParamUpdate(int compId, QString& key, QVariant& value) { //verify that the value requested by the user matches the set value //if it doesn't match, leave the pending parameter in the pending list! @@ -128,13 +133,13 @@ void UASParameterDataModel::handleParameterUpdate(int compId, QString& key, QVar } } - setOnboardParameter(compId,key,value); + setOnboardParam(compId,key,value); emit parameterUpdated(compId,key,value); } -bool UASParameterDataModel::getOnboardParameterValue(int componentId, const QString& key, QVariant& value) const +bool UASParameterDataModel::getOnboardParamValue(int componentId, const QString& key, QVariant& value) const { if (onboardParameters.contains(componentId)) { @@ -147,14 +152,13 @@ bool UASParameterDataModel::getOnboardParameterValue(int componentId, const QStr return false; } -void UASParameterDataModel::forgetAllOnboardParameters() +void UASParameterDataModel::forgetAllOnboardParams() { onboardParameters.clear(); } -void UASParameterDataModel::readUpdateParametersFromStream( QTextStream& stream) +void UASParameterDataModel::readUpdateParamsFromStream( QTextStream& stream) { - bool userWarned = false; while (!stream.atEnd()) { @@ -165,7 +169,7 @@ void UASParameterDataModel::readUpdateParametersFromStream( QTextStream& stream) if (wpParams.size() == 5) { // Only load parameters for right mav if (!userWarned && (uasId != lineMavId)) { - //TODO warn the user somehow + //TODO warn the user somehow ?? QString msg = tr("The parameters in the stream have been saved from system %1, but the currently selected system has the ID %2.").arg(lineMavId).arg(uasId); // MainWindow::instance()->showCriticalMessage( // tr("Parameter loading warning"), @@ -199,26 +203,17 @@ void UASParameterDataModel::readUpdateParametersFromStream( QTextStream& stream) switch (paramType) { case MAV_PARAM_TYPE_REAL32: - //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toFloat()); - setPendingParameter(componentId,key,QVariant(valStr.toFloat())); - //setParameter(componentId, key, valStr.toFloat()); + setPendingParam(componentId,key,QVariant(valStr.toFloat())); break; case MAV_PARAM_TYPE_UINT32: - //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toUInt()); - setPendingParameter(componentId,key, QVariant(valStr.toUInt())); - //setParameter(componentId, key, QVariant(valStr.toUInt())); + setPendingParam(componentId,key, QVariant(valStr.toUInt())); break; case MAV_PARAM_TYPE_INT32: - //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toInt()); - setPendingParameter(componentId,key,QVariant(valStr.toInt())); - //setParameter(componentId, key, QVariant(valStr.toInt())); + setPendingParam(componentId,key,QVariant(valStr.toInt())); break; default: qDebug() << "FAILED LOADING PARAM" << key << "UNKNOWN DATA TYPE"; } - - //TODO update display - } @@ -228,7 +223,7 @@ void UASParameterDataModel::readUpdateParametersFromStream( QTextStream& stream) } -void UASParameterDataModel::writeOnboardParametersToStream( QTextStream &stream, const QString& name) +void UASParameterDataModel::writeOnboardParamsToStream( QTextStream &stream, const QString& name) { stream << "# Onboard parameters for system " << name << "\n"; stream << "#\n"; diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 57dbc8f0af..6ae4f685cd 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -35,55 +35,51 @@ public: virtual void addComponent(int compId); /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ - virtual void setPendingParameter(int componentId, QString& key, const QVariant& value); - virtual void setOnboardParameter(int componentId, QString& key, const QVariant& value); + virtual void setPendingParam(int componentId, QString& key, const QVariant& value); + + virtual void removePendingParam(int compId, QString& key); /** @brief Save the onboard parameter with a the type specified in the QVariant as fixed */ - virtual void setOnboardParameterWithType(int componentId, QString& key, QVariant& value); + virtual void setOnboardParamWithType(int componentId, QString& key, QVariant& value); /** @brief clears every parameter for every loaded component */ - virtual void forgetAllOnboardParameters(); - - /** - * @return true if the given value for the parameter is different from the existing value - */ - virtual bool checkParameterChanged(int componentId, const QString& key, const QVariant &value); + virtual void forgetAllOnboardParams(); /** @brief add this parameter to pending list iff it has changed from onboard value - * @return true if the parameter has changed + * @return true if the parameter is now pending */ - virtual bool addPendingIfParameterChanged(int componentId, QString& key, QVariant& value); - + virtual bool updatePendingParamWithValue(int componentId, QString& key, QVariant& value); + virtual void handleParamUpdate(int componentId, QString& key, QVariant& value); + virtual bool getOnboardParamValue(int componentId, const QString& key, QVariant& value) const; - virtual void handleParameterUpdate(int componentId, QString& key, QVariant& value); - - virtual bool getOnboardParameterValue(int componentId, const QString& key, QVariant& value) const; - - QMap* getPendingParametersForComponent(int componentId) { + QMap* getPendingParamsForComponent(int componentId) { return pendingParameters.value(componentId); } - QMap* getOnbardParametersForComponent(int componentId) { + QMap* getOnboardParamsForComponent(int componentId) { return onboardParameters.value(componentId); } - QMap* >* getPendingParameters() { + QMap* >* getAllPendingParams() { return &pendingParameters; } - QMap* >* getOnboardParameters() { + QMap* >* getAllOnboardParams() { return &onboardParameters; } - virtual void writeOnboardParametersToStream(QTextStream &stream, const QString& uasName); - virtual void readUpdateParametersFromStream(QTextStream &stream); + virtual void writeOnboardParamsToStream(QTextStream &stream, const QString& uasName); + virtual void readUpdateParamsFromStream(QTextStream &stream); virtual void loadParamMetaInfoFromStream(QTextStream& stream); void setUASID(int anId) { this->uasId = anId; } +protected: + virtual void setOnboardParam(int componentId, QString& key, const QVariant& value); + signals: /** @brief We've received an update of a parameter's value */ diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 484d61d5de..7f18df8c93 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -213,7 +213,7 @@ void QGCParamWidget::handleParameterListUpToDate() //rewrite the component item tree after receiving the full list QMap*>::iterator i; - QMap*>* onboardParams = paramDataModel->getOnboardParameters(); + QMap*>* onboardParams = paramDataModel->getAllOnboardParams(); for (i = onboardParams->begin(); i != onboardParams->end(); ++i) { int compId = i.key(); @@ -352,13 +352,12 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) QString key = current->data(0, Qt::DisplayRole).toString(); QVariant value = current->data(1, Qt::DisplayRole); - bool changed = paramDataModel->addPendingIfParameterChanged(componentId,key,value); - - // If the value was numerically changed, display it differently - if (changed) { + bool pending = paramDataModel->updatePendingParamWithValue(componentId,key,value); + // If the value will result in an update + if (pending) { // Set parameter on changed list to be transmitted to MAV - statusLabel->setText(tr("Transmit pend. %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); + statusLabel->setText(tr("Pending: %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); if (current == tree->currentItem()) { //need to unset current item to clear highlighting (green by default) @@ -366,9 +365,14 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) } current->setBackground(0, QBrush(QColor(QGC::colorOrange))); current->setBackground(1, QBrush(QColor(QGC::colorOrange))); - tree->update(); } - + else { + QMap* pendingParams = paramDataModel->getOnboardParamsForComponent(componentId); + int pendingCount = pendingParams->count(); + statusLabel->setText(tr("Pending items: %1").arg(pendingCount)); + current->setBackground(0, Qt::NoBrush); + current->setBackground(1, Qt::NoBrush); + } } } @@ -385,7 +389,7 @@ void QGCParamWidget::saveParametersToFile() } QTextStream outstream(&file); - paramDataModel->writeOnboardParametersToStream(outstream,mav->getUASName()); + paramDataModel->writeOnboardParamsToStream(outstream,mav->getUASName()); file.close(); } @@ -399,7 +403,7 @@ void QGCParamWidget::loadParametersFromFile() return; QTextStream in(&file); - paramDataModel->readUpdateParametersFromStream(in); + paramDataModel->readUpdateParamsFromStream(in); file.close(); } @@ -431,7 +435,7 @@ void QGCParamWidget::writeParameters() int changedParamCount = 0; QMap*>::iterator i; - QMap*>* changedValues = paramDataModel->getPendingParameters(); + QMap*>* changedValues = paramDataModel->getAllPendingParams(); for (i = changedValues->begin(); (i != changedValues->end()) && (0 == changedParamCount); ++i) { // Iterate through the pending parameters of the component, break on the first changed parameter -- GitLab From dae59cf7e2e884e32ac23cd569304c39dd259ec6 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 13:01:39 -0700 Subject: [PATCH 194/460] workaround for premature timer firing bug --- src/uas/UASParameterCommsMgr.cc | 26 ++++++++++++++++---------- src/uas/UASParameterCommsMgr.h | 5 +---- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 47ec654b3f..18b31ec3c8 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -234,23 +234,33 @@ void UASParameterCommsMgr::resetAfterListReceive() void UASParameterCommsMgr::retransmissionGuardTick() { + quint64 curTime = QGC::groundTimeMilliseconds(); + + //Workaround for an apparent Qt bug that causes retransmission guard timer to fire prematurely (350ms) + quint64 elapsed = (curTime = lastTimerReset); + if (elapsed < transmissionTimeout) { + qDebug() << "retransmissionGuardTick elapsed:" << (curTime - lastTimerReset); + //reset the guard timer: it fired prematurely + setRetransmissionGuardEnabled(true); + return; + } + if (transmissionActive) { if (transmissionListMode && transmissionListSizeKnown.isEmpty() ) { //we are still waitin for the first parameter list response - if (QGC::groundTimeMilliseconds() > this->listRecvTimeout) { + if (curTime > this->listRecvTimeout) { //re-request parameters setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); - listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; + listRecvTimeout = curTime + 10000; mav->requestParameters(); } return; } - // Check for timeout // stop retransmission attempts on timeout - if (QGC::groundTimeMilliseconds() > transmissionTimeout) { + if (curTime > transmissionTimeout) { setRetransmissionGuardEnabled(false); resetAfterListReceive(); @@ -285,10 +295,9 @@ void UASParameterCommsMgr::retransmissionGuardTick() void UASParameterCommsMgr::setRetransmissionGuardEnabled(bool enabled) { -// qDebug() << "setRetransmissionGuardEnabled: " << enabled; - if (enabled) { retransmissionTimer.start(retransmissionTimeout); + lastTimerReset = QGC::groundTimeMilliseconds() ; } else { retransmissionTimer.stop(); } @@ -429,7 +438,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para transmissionListSizeKnown.insert(compId, true); qDebug() << "Mark all parameters as missing: " << paramCount; - for (int i = 1; i < paramCount; ++i) { //TODO check: param Id 0 is "all parameters" ? + for (int i = 1; i < paramCount; ++i) { //TODO check: param Id 0 is "all parameters" and not valid ? if (!compXmitMissing->contains(i)) { compXmitMissing->append(i); } @@ -444,9 +453,6 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para } } - // Start retransmission guard - // or reset timer - setRetransmissionGuardEnabled(true); } // Mark this parameter as received in read list diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index b1ece5fa18..006d45d83f 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -84,10 +84,6 @@ public slots: virtual void receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value); -//protected slots: -// void receivedParameterChange(int uas, int component, QString parameterName, QVariant value); -// void receivedParameterListChange(int uas, int component, int parameterCount, int parameterId, QString parameterName, QVariant value); - protected: UASInterface* mav; ///< The MAV we're talking to @@ -103,6 +99,7 @@ protected: bool transmissionActive; ///< Missing packets, working on list? quint64 transmissionTimeout; ///< Timeout QTimer retransmissionTimer; ///< Timer handling parameter retransmission + quint64 lastTimerReset; ///< Last time the guard timer was reset, to prevent premature firing int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds int rewriteTimeout; ///< Write request timeout, in milliseconds int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst -- GitLab From 08f2de63f6316e5c8e23d202d8f4c2f6e6d45ffd Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 13:57:21 -0700 Subject: [PATCH 195/460] propagate pending list updates fix pending items indicator --- src/uas/UASParameterDataModel.cc | 6 ++ src/uas/UASParameterDataModel.h | 3 + src/ui/QGCParamWidget.cc | 130 +++++++++++++++++++------------ src/ui/QGCParamWidget.h | 11 +-- 4 files changed, 95 insertions(+), 55 deletions(-) diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index c942b4437b..1806ec23fc 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -49,6 +49,10 @@ void UASParameterDataModel::removePendingParam(int compId, QString& key) QMap *params = getPendingParamsForComponent(compId); if (params) { params->remove(key); + //broadcast the existing value + QVariant existVal; + bool ok = getOnboardParamValue(compId,key,existVal); + emit pendingParamUpdate(compId, key,existVal, false); } } @@ -59,6 +63,8 @@ void UASParameterDataModel::setPendingParam(int compId, QString& key, const QVa addComponent(compId); QMap *params = getPendingParamsForComponent(compId); params->insert(key,value); + emit pendingParamUpdate(compId, key, value, true); + } void UASParameterDataModel::setOnboardParam(int compId, QString& key, const QVariant& value) diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 6ae4f685cd..fde760b703 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -85,6 +85,9 @@ signals: /** @brief We've received an update of a parameter's value */ void parameterUpdated(int compId, QString paramName, QVariant value); + /** @brief Notifies listeners that a param was added to or removed from the pending list */ + void pendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); + public slots: diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 7f18df8c93..ce20a29d67 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -66,6 +66,9 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), this, SLOT(handleParameterUpdate(int,QString,QVariant))); + connect(paramDataModel, SIGNAL(pendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending)), + this, SLOT(handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending))); + // Listen for param list reload finished connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), this, SLOT(handleParameterListUpToDate())); @@ -197,6 +200,19 @@ void QGCParamWidget::addComponentItem(int compId, QString compName) } +void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) +{ + QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); + if (isPending) { + paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); + paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); + } + else { + paramItem->setBackground(0, Qt::NoBrush); + paramItem->setBackground(1, Qt::NoBrush); + } + +} void QGCParamWidget::handleParameterUpdate(int componentId, const QString& paramName, QVariant value) { @@ -206,7 +222,6 @@ void QGCParamWidget::handleParameterUpdate(int componentId, const QString& param void QGCParamWidget::handleParameterListUpToDate() { -// tree->collapseAll(); //turn off updates while we refresh the entire list tree->setUpdatesEnabled(false); @@ -231,27 +246,30 @@ void QGCParamWidget::handleParameterListUpToDate() } - -void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, QVariant value) +QTreeWidgetItem* QGCParamWidget::findChildWidgetItemForParam(QTreeWidgetItem* parentItem, const QString& paramName) { -// qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName; - - // Reference to item in tree - QTreeWidgetItem* parameterItem = NULL; - - // Add component item if necessary - if (!componentItems->contains(compId)) { - QString componentName = tr("Component #%1").arg(compId); - addComponentItem(compId, componentName); + QTreeWidgetItem* childItem = NULL; + + for (int i = 0; i < parentItem->childCount(); i++) { + QTreeWidgetItem* child = parentItem->child(i); + QString key = child->data(0, Qt::DisplayRole).toString(); + if (key == paramName) { + childItem = child; + break; + } } - //default parent item for this parameter widget item will be the top level component item + return childItem; +} + +QTreeWidgetItem* QGCParamWidget::getParentWidgetItemForParam(int compId, const QString& paramName) +{ QTreeWidgetItem* parentItem = componentItems->value(compId); QString splitToken = "_"; // Check if auto-grouping can work - if (parameterName.contains(splitToken)) { - QString parentStr = parameterName.section(splitToken, 0, 0, QString::SectionSkipEmpty); + if (paramName.contains(splitToken)) { + QString parentStr = paramName.section(splitToken, 0, 0, QString::SectionSkipEmpty); QMap* compParamGroups = paramGroups.value(compId); if (!compParamGroups->contains(parentStr)) { // Insert group item @@ -271,29 +289,31 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q parentItem = compParamGroups->value(parentStr); } else { - //parent item for this parameter will be the top level component widget item + //parent item for this parameter will be the top level (component) widget item parentItem = componentItems->value(compId); } - if (parentItem) { - bool found = false; - for (int i = 0; i < parentItem->childCount(); i++) { - QTreeWidgetItem* child = parentItem->child(i); - QString key = child->data(0, Qt::DisplayRole).toString(); - if (key == parameterName) { - //qDebug() << "UPDATED CHILD"; - parameterItem = child; - if (value.type() == QVariant::Char) { - parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); - } - else { - parameterItem->setData(1, Qt::DisplayRole, value); - } - found = true; - } - } + return parentItem; +} + +QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, QVariant value) +{ +// qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName; + + // Reference to item in tree + QTreeWidgetItem* parameterItem = NULL; - if (!found) { + // Add component item if necessary + if (!componentItems->contains(compId)) { + QString componentName = tr("Component #%1").arg(compId); + addComponentItem(compId, componentName); + } + + //default parent item for this parameter widget item will be the top level component item + QTreeWidgetItem* parentItem = getParentWidgetItemForParam(compId,parameterName); + if (parentItem) { + parameterItem = findChildWidgetItemForParam(parentItem,parameterName); + if (!parameterItem) { // Insert parameter into map QStringList plist; plist.append(parameterName); @@ -309,6 +329,30 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); //TODO insert alphabetically parentItem->addChild(parameterItem); + + //only add the tooltip when the parameter item is first added + QString paramDesc = paramDataModel->getParamDescription(parameterName); + if (!paramDesc.isEmpty()) { + QString tooltipFormat; + if (paramDataModel->isParamDefaultKnown(parameterName)) { + tooltipFormat = tr("Default: %1, %2"); + double paramDefValue = paramDataModel->getParamDefault(parameterName); + tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc); + } + else { + tooltipFormat = paramDesc; + } + parameterItem->setToolTip(0, tooltipFormat); + parameterItem->setToolTip(1, tooltipFormat); + } + } + + //update the parameterItem's data + if (value.type() == QVariant::Char) { + parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); + } + else { + parameterItem->setData(1, Qt::DisplayRole, value); } } @@ -319,21 +363,7 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q parameterItem->setTextColor(0, QGC::colorDarkWhite); parameterItem->setTextColor(1, QGC::colorDarkWhite); - // Add tooltip - QString paramDesc = paramDataModel->getParamDescription(parameterName); - if (!paramDesc.isEmpty()) { - QString tooltipFormat; - if (paramDataModel->isParamDefaultKnown(parameterName)) { - tooltipFormat = tr("Default: %1, %2"); - double paramDefValue = paramDataModel->getParamDefault(parameterName); - tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc); - } - else { - tooltipFormat = paramDesc; - } - parameterItem->setToolTip(0, tooltipFormat); - parameterItem->setToolTip(1, tooltipFormat); - } + return parameterItem; } @@ -367,7 +397,7 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) current->setBackground(1, QBrush(QColor(QGC::colorOrange))); } else { - QMap* pendingParams = paramDataModel->getOnboardParamsForComponent(componentId); + QMap* pendingParams = paramDataModel->getPendingParamsForComponent(componentId); int pendingCount = pendingParams->count(); statusLabel->setText(tr("Pending items: %1").arg(pendingCount)); current->setBackground(0, Qt::NoBrush); diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 2176b5b4a5..33df32200b 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -52,10 +52,11 @@ public: protected: virtual void setParameterStatusMsg(const QString& msg); virtual void layoutWidget(); + virtual QTreeWidgetItem* getParentWidgetItemForParam(int compId, const QString& paramName); + virtual QTreeWidgetItem* findChildWidgetItemForParam(QTreeWidgetItem* parentItem, const QString& paramName); + signals: - /** @brief A parameter was changed in the widget, NOT onboard */ - //void parameterChanged(int component, QString parametername, float value); // defined in QGCUASParamManager already public slots: @@ -65,16 +66,16 @@ public slots: */ void addComponentItem(int compId, QString compName); - /** @brief Add a parameter to the list with retransmission / safety checks */ -// void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); virtual void handleParameterUpdate(int component,const QString& parameterName, QVariant value); + virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); + virtual void handleParameterListUpToDate(); virtual void handleParamStatusMsgUpdate(QString msg, int level); /** @brief Ensure that view of parameter matches data in the model */ - void updateParameterDisplay(int component, QString parameterName, QVariant value); + QTreeWidgetItem* updateParameterDisplay(int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ void requestAllParamsUpdate(); -- GitLab From ceffc7a60d730a00402b1af252aa934a40cb6280 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 16:57:02 -0700 Subject: [PATCH 196/460] fix lastTimerReset bug --- src/uas/UASParameterCommsMgr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 18b31ec3c8..5e04a92ffa 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -237,7 +237,7 @@ void UASParameterCommsMgr::retransmissionGuardTick() quint64 curTime = QGC::groundTimeMilliseconds(); //Workaround for an apparent Qt bug that causes retransmission guard timer to fire prematurely (350ms) - quint64 elapsed = (curTime = lastTimerReset); + quint64 elapsed = (curTime - lastTimerReset); if (elapsed < transmissionTimeout) { qDebug() << "retransmissionGuardTick elapsed:" << (curTime - lastTimerReset); //reset the guard timer: it fired prematurely -- GitLab From 330f067d2cf6fc468c21321351a4d32b0c33de33 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 17:19:51 -0700 Subject: [PATCH 197/460] fix timeout checker --- src/uas/UASParameterCommsMgr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 5e04a92ffa..c80b6e522b 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -238,7 +238,7 @@ void UASParameterCommsMgr::retransmissionGuardTick() //Workaround for an apparent Qt bug that causes retransmission guard timer to fire prematurely (350ms) quint64 elapsed = (curTime - lastTimerReset); - if (elapsed < transmissionTimeout) { + if (elapsed < retransmissionTimeout) { qDebug() << "retransmissionGuardTick elapsed:" << (curTime - lastTimerReset); //reset the guard timer: it fired prematurely setRetransmissionGuardEnabled(true); -- GitLab From 8f165fa48973a13c7b8ac79029110641ac4fd17a Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 17:24:45 -0700 Subject: [PATCH 198/460] fix slot wiring; debounce echo from data model --- src/uas/UASParameterCommsMgr.cc | 6 +----- src/ui/QGCParamWidget.cc | 31 +++++++++++++++++++------------ src/ui/QGCParamWidget.h | 1 + 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index c80b6e522b..ec1395041c 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -224,11 +224,7 @@ void UASParameterCommsMgr::resetAfterListReceive() transmissionListMode = false; transmissionListSizeKnown.clear(); - //TODO we shouldn't clear missingPackets because other transactions might be using them? - //for list reception we only clear receive packets? -// foreach (int key, transmissionMissingPackets.keys()) { -// transmissionMissingPackets.value(key)->clear(); -// } + //We shouldn't clear missingPackets because other transactions might be using them? } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index ce20a29d67..52bfc208c1 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -66,8 +66,8 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), this, SLOT(handleParameterUpdate(int,QString,QVariant))); - connect(paramDataModel, SIGNAL(pendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending)), - this, SLOT(handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending))); + connect(paramDataModel, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), + this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); // Listen for param list reload finished connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), @@ -348,6 +348,7 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para } //update the parameterItem's data + updatedLineItem_weak = parameterItem; //keep a temporary ref to the item that's being updated if (value.type() == QVariant::Char) { parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); } @@ -363,24 +364,30 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para parameterItem->setTextColor(0, QGC::colorDarkWhite); parameterItem->setTextColor(1, QGC::colorDarkWhite); + updatedLineItem_weak = NULL; return parameterItem; } -void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) +void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column) { - if (current && column > 0) { - QTreeWidgetItem* parent = current->parent(); + if (paramItem && column > 0) { + if (paramItem == updatedLineItem_weak) { + //ignore updates reflected back from the data model, to avoid infinite loop + return; + } + + QTreeWidgetItem* parent = paramItem->parent(); while (parent->parent() != NULL) { parent = parent->parent(); } // Parent is now top-level component int componentId = componentItems->key(parent); - QString key = current->data(0, Qt::DisplayRole).toString(); - QVariant value = current->data(1, Qt::DisplayRole); + QString key = paramItem->data(0, Qt::DisplayRole).toString(); + QVariant value = paramItem->data(1, Qt::DisplayRole); bool pending = paramDataModel->updatePendingParamWithValue(componentId,key,value); @@ -389,19 +396,19 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) // Set parameter on changed list to be transmitted to MAV statusLabel->setText(tr("Pending: %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); - if (current == tree->currentItem()) { + if (paramItem == tree->currentItem()) { //need to unset current item to clear highlighting (green by default) tree->setCurrentItem(NULL); //clear the selected line } - current->setBackground(0, QBrush(QColor(QGC::colorOrange))); - current->setBackground(1, QBrush(QColor(QGC::colorOrange))); + paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); + paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); } else { QMap* pendingParams = paramDataModel->getPendingParamsForComponent(componentId); int pendingCount = pendingParams->count(); statusLabel->setText(tr("Pending items: %1").arg(pendingCount)); - current->setBackground(0, Qt::NoBrush); - current->setBackground(1, Qt::NoBrush); + paramItem->setBackground(0, Qt::NoBrush); + paramItem->setBackground(1, Qt::NoBrush); } } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 33df32200b..d0e6f96c39 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -100,6 +100,7 @@ protected: QLabel* statusLabel; ///< User-facing parameter status label QMap* componentItems; ///< The tree of component items, stored by component ID QMap* > paramGroups; ///< Parameter groups to organize component items + QTreeWidgetItem* updatedLineItem_weak;///< weak ref to user-edited line }; -- GitLab From 11e1379a07b9af868eb92b8e183786afe7558e57 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 18:28:10 -0700 Subject: [PATCH 199/460] Begin to connect separate param widgets via data model still some remaining issues with pending line items bouncing back from data model --- src/uas/UASParameterCommsMgr.cc | 8 ++++++-- src/ui/QGCParamWidget.cc | 35 +++++++++++++++++++++++++-------- src/ui/QGCParamWidget.h | 1 + 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index ec1395041c..27ee774faf 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -50,6 +50,7 @@ void UASParameterCommsMgr::loadParamCommsSettings() int val = settings.value("PARAMETER_RETRANSMISSION_TIMEOUT", retransmissionTimeout).toInt(&ok); if (ok) { retransmissionTimeout = val; + qDebug() << "retransmissionTimeout" << retransmissionTimeout; } val = settings.value("PARAMETER_REWRITE_TIMEOUT", rewriteTimeout).toInt(&ok); if (ok) { @@ -240,6 +241,8 @@ void UASParameterCommsMgr::retransmissionGuardTick() setRetransmissionGuardEnabled(true); return; } + qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE after" << elapsed; + if (transmissionActive) { @@ -250,6 +253,8 @@ void UASParameterCommsMgr::retransmissionGuardTick() setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); listRecvTimeout = curTime + 10000; mav->requestParameters(); + //reset the timer + setRetransmissionGuardEnabled(true); } return; } @@ -270,7 +275,6 @@ void UASParameterCommsMgr::retransmissionGuardTick() return; } - qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; resendReadWriteRequests(); } else { @@ -443,7 +447,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para // There is only one transmission timeout for all components // since components do not manage their transmission, // the longest timeout is safe for all components. - quint64 thisTransmissionTimeout = QGC::groundTimeMilliseconds() + ((paramCount)*retransmissionTimeout); + quint64 thisTransmissionTimeout = QGC::groundTimeMilliseconds() + (paramCount*retransmissionTimeout); if (thisTransmissionTimeout > transmissionTimeout) { transmissionTimeout = thisTransmissionTimeout; } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 52bfc208c1..2f7f8ca541 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -202,7 +202,20 @@ void QGCParamWidget::addComponentItem(int compId, QString compName) void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) { + qDebug() << "handlePendingParamUpdate:" << paramName << "with updatedLineItem_weak:" << updatedLineItem_weak; + + if (updatedLineItem_weak) { + QString key = updatedLineItem_weak->data(0, Qt::DisplayRole).toString(); + if (paramName == key) { + //debounce echo from data model + return; + } + } + QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); + if (updatedLineItem_weak == NULL) { + updatedLineItem_weak = paramItem; + } if (isPending) { paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); @@ -327,6 +340,8 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para parameterItem->setData(1, Qt::DisplayRole, value); } parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); + updatedLineItem_weak = parameterItem; //keep a temporary ref to the item that's being updated + //TODO insert alphabetically parentItem->addChild(parameterItem); @@ -347,8 +362,9 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para } } - //update the parameterItem's data updatedLineItem_weak = parameterItem; //keep a temporary ref to the item that's being updated + + //update the parameterItem's data if (value.type() == QVariant::Char) { parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); } @@ -357,14 +373,16 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para } } - // Reset background color - parameterItem->setBackground(0, Qt::NoBrush); - parameterItem->setBackground(1, Qt::NoBrush); + if (parameterItem) { + // Reset background color + parameterItem->setBackground(0, Qt::NoBrush); + parameterItem->setBackground(1, Qt::NoBrush); - parameterItem->setTextColor(0, QGC::colorDarkWhite); - parameterItem->setTextColor(1, QGC::colorDarkWhite); + parameterItem->setTextColor(0, QGC::colorDarkWhite); + parameterItem->setTextColor(1, QGC::colorDarkWhite); - updatedLineItem_weak = NULL; + updatedLineItem_weak = NULL; + } return parameterItem; } @@ -374,7 +392,8 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column) { if (paramItem && column > 0) { - if (paramItem == updatedLineItem_weak) { + + if (!paramItem->isSelected() || (paramItem == updatedLineItem_weak)) { //ignore updates reflected back from the data model, to avoid infinite loop return; } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index d0e6f96c39..5779b2e4b2 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -101,6 +101,7 @@ protected: QMap* componentItems; ///< The tree of component items, stored by component ID QMap* > paramGroups; ///< Parameter groups to organize component items QTreeWidgetItem* updatedLineItem_weak;///< weak ref to user-edited line +// QTreeWidgetItem* updatedPendingItem_weak;///< weak ref to pending-modified line }; -- GitLab From e02f9ec092d1c84e8a3bebd1983e7e0b7518e7c6 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 12 Aug 2013 14:08:00 -0700 Subject: [PATCH 200/460] Better data model update debouncing --- src/ui/QGCParamWidget.cc | 44 ++++++++++++++++++++++------------------ src/ui/QGCParamWidget.h | 3 +-- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 2f7f8ca541..5fa7727093 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -51,7 +51,8 @@ This file is part of the QGROUNDCONTROL project */ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QGCUASParamManager(uas, parent), - componentItems(new QMap()) + componentItems(new QMap()), + updatingParamNameLock("") { layoutWidget(); @@ -202,20 +203,17 @@ void QGCParamWidget::addComponentItem(int compId, QString compName) void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) { - qDebug() << "handlePendingParamUpdate:" << paramName << "with updatedLineItem_weak:" << updatedLineItem_weak; + qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; - if (updatedLineItem_weak) { - QString key = updatedLineItem_weak->data(0, Qt::DisplayRole).toString(); - if (paramName == key) { - //debounce echo from data model - return; - } + if (updatingParamNameLock == paramName) { + qDebug() << "ignoring bounce from " << paramName; + return; + } + else { + updatingParamNameLock = paramName; } QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); - if (updatedLineItem_weak == NULL) { - updatedLineItem_weak = paramItem; - } if (isPending) { paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); @@ -225,17 +223,20 @@ void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramNa paramItem->setBackground(1, Qt::NoBrush); } + updatingParamNameLock.clear(); + } void QGCParamWidget::handleParameterUpdate(int componentId, const QString& paramName, QVariant value) { + updatingParamNameLock = paramName; updateParameterDisplay(componentId, paramName, value); + updatingParamNameLock.clear(); } void QGCParamWidget::handleParameterListUpToDate() { - //turn off updates while we refresh the entire list tree->setUpdatesEnabled(false); @@ -340,7 +341,6 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para parameterItem->setData(1, Qt::DisplayRole, value); } parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); - updatedLineItem_weak = parameterItem; //keep a temporary ref to the item that's being updated //TODO insert alphabetically parentItem->addChild(parameterItem); @@ -362,8 +362,6 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para } } - updatedLineItem_weak = parameterItem; //keep a temporary ref to the item that's being updated - //update the parameterItem's data if (value.type() == QVariant::Char) { parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); @@ -381,7 +379,6 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para parameterItem->setTextColor(0, QGC::colorDarkWhite); parameterItem->setTextColor(1, QGC::colorDarkWhite); - updatedLineItem_weak = NULL; } return parameterItem; @@ -391,12 +388,19 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column) { + if (paramItem && column > 0) { - if (!paramItem->isSelected() || (paramItem == updatedLineItem_weak)) { - //ignore updates reflected back from the data model, to avoid infinite loop + QString key = paramItem->data(0, Qt::DisplayRole).toString(); + qDebug() << "parameterItemChanged:" << key << "with updatingParamNameLock:" << updatingParamNameLock; + + if (key == updatingParamNameLock) { + qDebug() << "ignoring parameterItemChanged" << key; return; } + else { + updatingParamNameLock = key; + } QTreeWidgetItem* parent = paramItem->parent(); while (parent->parent() != NULL) { @@ -404,10 +408,9 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column } // Parent is now top-level component int componentId = componentItems->key(parent); - - QString key = paramItem->data(0, Qt::DisplayRole).toString(); QVariant value = paramItem->data(1, Qt::DisplayRole); + bool pending = paramDataModel->updatePendingParamWithValue(componentId,key,value); // If the value will result in an update @@ -430,6 +433,7 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column paramItem->setBackground(1, Qt::NoBrush); } + updatingParamNameLock.clear(); } } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 5779b2e4b2..3578ed04ba 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -100,8 +100,7 @@ protected: QLabel* statusLabel; ///< User-facing parameter status label QMap* componentItems; ///< The tree of component items, stored by component ID QMap* > paramGroups; ///< Parameter groups to organize component items - QTreeWidgetItem* updatedLineItem_weak;///< weak ref to user-edited line -// QTreeWidgetItem* updatedPendingItem_weak;///< weak ref to pending-modified line + QString updatingParamNameLock; ///< Name of param currently being updated-- used for reducing echo on param change }; -- GitLab From 918bdf6ba03780897607c9243f17ebb317ec3500 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 12 Aug 2013 14:59:58 -0700 Subject: [PATCH 201/460] more strict locking of currently updating parameter --- src/ui/QGCParamWidget.cc | 53 +++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 5fa7727093..ab8624c64f 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -249,7 +249,9 @@ void QGCParamWidget::handleParameterListUpToDate() QMap* paramPairs = onboardParams->value(compId); QMap::iterator j; for (j = paramPairs->begin(); j != paramPairs->end(); j++) { + updatingParamNameLock = j.key(); updateParameterDisplay(compId, j.key(),j.value()); + updatingParamNameLock.clear(); } } @@ -315,7 +317,7 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para // qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName; // Reference to item in tree - QTreeWidgetItem* parameterItem = NULL; + QTreeWidgetItem* paramItem = NULL; // Add component item if necessary if (!componentItems->contains(compId)) { @@ -326,24 +328,24 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para //default parent item for this parameter widget item will be the top level component item QTreeWidgetItem* parentItem = getParentWidgetItemForParam(compId,parameterName); if (parentItem) { - parameterItem = findChildWidgetItemForParam(parentItem,parameterName); - if (!parameterItem) { + paramItem = findChildWidgetItemForParam(parentItem,parameterName); + if (!paramItem) { // Insert parameter into map QStringList plist; plist.append(parameterName); // CREATE PARAMETER ITEM - parameterItem = new QTreeWidgetItem(plist); + paramItem = new QTreeWidgetItem(plist); // CONFIGURE PARAMETER ITEM if (value.type() == QVariant::Char) { - parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); + paramItem->setData(1, Qt::DisplayRole, value.toUInt()); } else { - parameterItem->setData(1, Qt::DisplayRole, value); + paramItem->setData(1, Qt::DisplayRole, value); } - parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); + paramItem->setFlags(paramItem->flags() | Qt::ItemIsEditable); //TODO insert alphabetically - parentItem->addChild(parameterItem); + parentItem->addChild(paramItem); //only add the tooltip when the parameter item is first added QString paramDesc = paramDataModel->getParamDescription(parameterName); @@ -357,30 +359,35 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para else { tooltipFormat = paramDesc; } - parameterItem->setToolTip(0, tooltipFormat); - parameterItem->setToolTip(1, tooltipFormat); + paramItem->setToolTip(0, tooltipFormat); + paramItem->setToolTip(1, tooltipFormat); } } //update the parameterItem's data if (value.type() == QVariant::Char) { - parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); + paramItem->setData(1, Qt::DisplayRole, value.toUInt()); } else { - parameterItem->setData(1, Qt::DisplayRole, value); + paramItem->setData(1, Qt::DisplayRole, value); } } - if (parameterItem) { + if (paramItem) { // Reset background color - parameterItem->setBackground(0, Qt::NoBrush); - parameterItem->setBackground(1, Qt::NoBrush); + paramItem->setBackground(0, Qt::NoBrush); + paramItem->setBackground(1, Qt::NoBrush); - parameterItem->setTextColor(0, QGC::colorDarkWhite); - parameterItem->setTextColor(1, QGC::colorDarkWhite); + paramItem->setTextColor(0, QGC::colorDarkWhite); + paramItem->setTextColor(1, QGC::colorDarkWhite); + + if (paramItem == tree->currentItem()) { + //need to unset current item to clear highlighting (green by default) + tree->setCurrentItem(NULL); //clear the selected line + } } - return parameterItem; + return paramItem; } @@ -418,10 +425,6 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column // Set parameter on changed list to be transmitted to MAV statusLabel->setText(tr("Pending: %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); - if (paramItem == tree->currentItem()) { - //need to unset current item to clear highlighting (green by default) - tree->setCurrentItem(NULL); //clear the selected line - } paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); } @@ -433,6 +436,12 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column paramItem->setBackground(1, Qt::NoBrush); } + + if (paramItem == tree->currentItem()) { + //need to unset current item to clear highlighting (green by default) + tree->setCurrentItem(NULL); //clear the selected line + } + updatingParamNameLock.clear(); } } -- GitLab From 31482062d74da50e5a5b24ce3001920e7c976dfe Mon Sep 17 00:00:00 2001 From: gefink Date: Mon, 12 Aug 2013 16:42:00 -0600 Subject: [PATCH 202/460] Fixed RC calibration trim problem. Trim was not being set because setTrimPositions() was never being called. --- src/ui/QGCVehicleConfig.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ui/QGCVehicleConfig.cc b/src/ui/QGCVehicleConfig.cc index b99535bccb..5282d32aa4 100644 --- a/src/ui/QGCVehicleConfig.cc +++ b/src/ui/QGCVehicleConfig.cc @@ -929,6 +929,8 @@ void QGCVehicleConfig::writeCalibrationRC() { if (!mav) return; + setTrimPositions(); + QString minTpl("RC%1_MIN"); QString maxTpl("RC%1_MAX"); QString trimTpl("RC%1_TRIM"); -- GitLab From 1617064813d2abeaea08ae2cadac97ec89aadd99 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 12 Aug 2013 17:10:22 -0700 Subject: [PATCH 203/460] cleanup cruft --- src/uas/QGCUASParamManager.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 9836de2d10..5612334e6e 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -29,7 +29,7 @@ public: UASInterface* getUAS(); protected: - //TODO decouple this UI message display further + //TODO decouple this UI message display further? virtual void setParameterStatusMsg(const QString& msg); /** @brief Load parameter meta information from appropriate CSV file */ virtual void loadParamMetaInfoCSV(); @@ -38,9 +38,6 @@ protected: signals: void parameterChanged(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); -// void parameterUpdateRequested(int component, const QString& parameter); -// void parameterUpdateRequestedById(int componentId, int paramId); - public slots: /** @brief Send one parameter to the MAV: changes value in transient memory of MAV */ @@ -62,8 +59,8 @@ public slots: protected: // Parameter data model - UASInterface* mav; ///< The MAV this widget is controlling - UASParameterDataModel* paramDataModel;///< Shared data model of parameters + UASInterface* mav; ///< The MAV this manager is controlling + UASParameterDataModel* paramDataModel;///< Shared data model of parameters UASParameterCommsMgr* paramCommsMgr; ///< Shared comms mgr for parameters // Status -- GitLab From c7d4af260faf5d8380ad5771c7bf9c546d1d3c86 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 12 Aug 2013 18:13:45 -0700 Subject: [PATCH 204/460] prelim extraction of read-only pending params widget --- qgroundcontrol.pro | 6 +- src/uas/QGCUASParamManager.cc | 8 +- src/uas/QGCUASParamManager.h | 2 + src/ui/ParameterInterface.cc | 1 + src/ui/QGCPX4VehicleConfig.cc | 8 +- src/ui/QGCPX4VehicleConfig.h | 1 + src/ui/QGCPX4VehicleConfig.ui | 24 +++++- src/ui/QGCParamWidget.cc | 19 +++-- src/ui/QGCParamWidget.h | 4 +- src/ui/QGCPendingParamWidget.cc | 33 +++++++++ src/ui/QGCPendingParamWidget.h | 26 +++++++ src/ui/designer/QGCComboBox.cc | 23 ++---- src/ui/designer/QGCComboBox.h | 4 +- src/ui/designer/QGCParamSlider.cc | 117 ++++++++++++++---------------- src/ui/designer/QGCParamSlider.h | 4 +- 15 files changed, 173 insertions(+), 107 deletions(-) create mode 100644 src/ui/QGCPendingParamWidget.cc create mode 100644 src/ui/QGCPendingParamWidget.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 6f0f51ca48..cf714d579c 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -470,7 +470,8 @@ HEADERS += src/MG.h \ src/ui/configuration/ApmHighlighter.h \ src/ui/configuration/ApmFirmwareConfig.h \ src/uas/UASParameterDataModel.h \ - src/uas/UASParameterCommsMgr.h + src/uas/UASParameterCommsMgr.h \ + src/ui/QGCPendingParamWidget.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -687,7 +688,8 @@ SOURCES += src/main.cc \ src/ui/configuration/ApmHighlighter.cc \ src/ui/configuration/ApmFirmwareConfig.cc \ src/uas/UASParameterDataModel.cc \ - src/uas/UASParameterCommsMgr.cc + src/uas/UASParameterCommsMgr.cc \ + src/ui/QGCPendingParamWidget.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index fcc78a6cb6..f1fd085bff 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -18,9 +18,6 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : // Load default values and tooltips loadParamMetaInfoCSV(); - - - } @@ -75,6 +72,11 @@ void QGCUASParamManager::sendPendingParameters() paramCommsMgr->sendPendingParameters(); } +void QGCUASParamManager::setPendingParam(int compId, QString& paramName, const QVariant& value) +{ + paramDataModel->setPendingParam(compId,paramName,value); +} + void QGCUASParamManager::loadParamMetaInfoCSV() diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 5612334e6e..6c910509cd 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -49,6 +49,8 @@ public slots: /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); + virtual void setPendingParam(int componentId, QString& key, const QVariant& value); + /** @brief Request a single parameter by name from the MAV */ virtual void requestParameterUpdate(int component, const QString& parameter); diff --git a/src/ui/ParameterInterface.cc b/src/ui/ParameterInterface.cc index c7d5f811b3..93624d50ea 100644 --- a/src/ui/ParameterInterface.cc +++ b/src/ui/ParameterInterface.cc @@ -98,6 +98,7 @@ void ParameterInterface::addUAS(UASInterface* uas) } QGCParamWidget* param = new QGCParamWidget(uas, this); + param->init(); QString ptrStr; ptrStr.sprintf("QGCParamWidget %8p (parent %8p)", param,this); qDebug() << "Created " << ptrStr << " for UAS id: " << uasId << " count: " << paramWidgets->count(); diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 177a5e0660..e28569335b 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -15,6 +15,7 @@ #include "QGCPX4VehicleConfig.h" #include "QGC.h" +#include "QGCPendingParamWidget.h" #include "QGCToolWidget.h" #include "UASManager.h" #include "UASParameterCommsMgr.h" @@ -82,7 +83,9 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(ui->rcModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setRCModeIndex(int))); //connect(ui->setTrimButton, SIGNAL(clicked()), this, SLOT(setTrimPositions())); - + //TODO connect buttons here to save/clear actions? + ui->pendingCommitsWidget->init(); + ui->pendingCommitsWidget->update(); //TODO the following methods are not yet implemented @@ -301,7 +304,6 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) } // Generate widgets for the Advanced tab. - left = true; foreach (QString file,vehicledir.entryList(QDir::Files | QDir::NoDotAndDotDot)) { if (file.toLower().endsWith(".qgw")) { @@ -1232,8 +1234,6 @@ void QGCPX4VehicleConfig::handleRcParameterChange(QString parameterName, QVarian void QGCPX4VehicleConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { - Q_UNUSED(uas); - Q_UNUSED(component); if (!doneLoadingConfig) { //We do not want to attempt to generate any UI elements until loading of the config file is complete. //We should re-request params later if needed, that is not implemented yet. diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index 93761d52f2..a242fcf9d3 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -187,6 +187,7 @@ protected: QTimer updateTimer; ///< Controls update intervals enum RC_MODE rc_mode; ///< Mode of the remote control, according to usual convention QList toolWidgets; ///< Configurable widgets + QMap toolWidgetsByName; ///< bool calibrationEnabled; ///< calibration mode on / off QMap paramToWidgetMap; ///< Holds the current active MAV's parameter widgets. diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 8607a55643..da0ddfd9b1 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -138,7 +138,7 @@ Config - 0 + 3 @@ -1035,8 +1035,8 @@ p, li { white-space: pre-wrap; } 0 0 - 16 - 16 + 597 + 569 @@ -1168,7 +1168,17 @@ p, li { white-space: pre-wrap; } 0 - + + + + 0 + 30 + + + + true + + @@ -1259,6 +1269,12 @@ p, li { white-space: pre-wrap; }
ui/designer/QGCRadioChannelDisplay.h
1 + + QGCPendingParamWidget + QWidget +
/ui/QGCPendingParamWidget.h
+ 1 +
diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index ab8624c64f..1f4889603d 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -55,9 +55,19 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : updatingParamNameLock("") { +} + +void QGCParamWidget::init() +{ layoutWidget(); + connectSignalsAndSlots(); + + // Ensure we're receiving the list of params + requestAllParamsUpdate(); +} - // Connect signals/slots +void QGCParamWidget::connectSignalsAndSlots() +{ // Listen for edits to the tree UI connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), @@ -77,15 +87,8 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : // Listen to communications status messages so we can display them connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), this, SLOT(handleParamStatusMsgUpdate(QString , int ))); - - // Ensure we're receiving the list of params - requestAllParamsUpdate(); - } - - - void QGCParamWidget::layoutWidget() { // Create tree widget diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 3578ed04ba..f23a627d33 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -48,10 +48,12 @@ class QGCParamWidget : public QGCUASParamManager Q_OBJECT public: QGCParamWidget(UASInterface* uas, QWidget *parent = 0); + virtual void init(); ///< Two-stage construction: initialize the object protected: virtual void setParameterStatusMsg(const QString& msg); - virtual void layoutWidget(); + virtual void layoutWidget();///< Layout the appearance of this widget + virtual void connectSignalsAndSlots();///< Connect signals/slots as needed virtual QTreeWidgetItem* getParentWidgetItemForParam(int compId, const QString& paramName); virtual QTreeWidgetItem* findChildWidgetItemForParam(QTreeWidgetItem* parentItem, const QString& paramName); diff --git a/src/ui/QGCPendingParamWidget.cc b/src/ui/QGCPendingParamWidget.cc new file mode 100644 index 0000000000..800ca354e0 --- /dev/null +++ b/src/ui/QGCPendingParamWidget.cc @@ -0,0 +1,33 @@ +#include "QGCPendingParamWidget.h" + +#include "UASManager.h" +#include "UASParameterCommsMgr.h" + + +QGCPendingParamWidget::QGCPendingParamWidget(QObject *parent) : + QGCParamWidget(UASManager::instance()->getActiveUAS(),(QWidget*)parent) +{ +} + + +void QGCPendingParamWidget::init() +{ + //we override a lot of the super's init methods + layoutWidget(); + connectSignalsAndSlots(); + + //don't request update params here...assume that everything we need is in the data model +} + +void QGCPendingParamWidget::connectSignalsAndSlots() +{ + // Listing for pending list update + connect(paramDataModel, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), + this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); + + // Listen to communications status messages so we can display them + connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), + this, SLOT(handleParamStatusMsgUpdate(QString , int ))); +} + + diff --git a/src/ui/QGCPendingParamWidget.h b/src/ui/QGCPendingParamWidget.h new file mode 100644 index 0000000000..91f08a522f --- /dev/null +++ b/src/ui/QGCPendingParamWidget.h @@ -0,0 +1,26 @@ +#ifndef QGCPENDINGPARAMWIDGET_H +#define QGCPENDINGPARAMWIDGET_H + + +#include "QGCParamWidget.h" + +class QGCPendingParamWidget : public QGCParamWidget +{ + Q_OBJECT + +public: + explicit QGCPendingParamWidget(QObject* parent); + virtual void init(); ///< Two-stage construction: initialize the object + +protected: + virtual void connectSignalsAndSlots(); + + + +signals: + +public slots: + +}; + +#endif // QGCPENDINGPARAMWIDGET_H diff --git a/src/ui/designer/QGCComboBox.cc b/src/ui/designer/QGCComboBox.cc index 91f9dfc21b..01ca3881b8 100644 --- a/src/ui/designer/QGCComboBox.cc +++ b/src/ui/designer/QGCComboBox.cc @@ -48,7 +48,7 @@ QGCComboBox::QGCComboBox(QWidget *parent) : connect(ui->editRemoveItemButton,SIGNAL(clicked()),this,SLOT(delButtonClicked())); // Sending actions - connect(ui->writeButton, SIGNAL(clicked()), this, SLOT(sendParameter())); + connect(ui->writeButton, SIGNAL(clicked()), this, SLOT(setParamPending())); connect(ui->editSelectComponentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectComponent(int))); connect(ui->editSelectParamComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectParameter(int))); //connect(ui->valueSlider, SIGNAL(valueChanged(int)), this, SLOT(setSliderValue(int))); @@ -233,24 +233,13 @@ void QGCComboBox::endEditMode() emit editingFinished(); } -void QGCComboBox::sendParameter() +void QGCComboBox::setParamPending() { - if (uas) - { - // Set value, param manager handles retransmission - if (uas->getParamManager()) - { - qDebug() << "Sending param:" << parameterName << "to component" << component << "with a value of" << parameterValue; - uas->getParamManager()->setParameter(component, parameterName, parameterValue); - } - else - { - qDebug() << "UAS HAS NO PARAM MANAGER, DOING NOTHING"; - } + if (uas) { + uas->getParamManager()->setPendingParam(component, parameterName, parameterValue); } - else - { - qDebug() << __FILE__ << __LINE__ << "NO UAS SET, DOING NOTHING"; + else { + qWarning() << __FILE__ << __LINE__ << "NO UAS SET, DOING NOTHING"; } } diff --git a/src/ui/designer/QGCComboBox.h b/src/ui/designer/QGCComboBox.h index 4c5491580e..ecc71126b5 100644 --- a/src/ui/designer/QGCComboBox.h +++ b/src/ui/designer/QGCComboBox.h @@ -23,8 +23,8 @@ public: public slots: void startEditMode(); void endEditMode(); - /** @brief Send the parameter to the MAV */ - void sendParameter(); + /** @brief Queue parameter for sending to the MAV (add to pending list)*/ + void setParamPending(); /** @brief Update the UI with the new parameter value */ void setParameterValue(int uas, int component, int paramCount, int paramIndex, QString parameterName, const QVariant value); void writeSettings(QSettings& settings); diff --git a/src/ui/designer/QGCParamSlider.cc b/src/ui/designer/QGCParamSlider.cc index 32b236a4b8..54b3bd723e 100644 --- a/src/ui/designer/QGCParamSlider.cc +++ b/src/ui/designer/QGCParamSlider.cc @@ -47,20 +47,31 @@ QGCParamSlider::QGCParamSlider(QWidget *parent) : connect(ui->editDoneButton, SIGNAL(clicked()), this, SLOT(endEditMode())); // Sending actions - connect(ui->writeButton, SIGNAL(clicked()), this, SLOT(sendParameter())); - connect(ui->editSelectComponentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectComponent(int))); - connect(ui->editSelectParamComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectParameter(int))); - connect(ui->valueSlider, SIGNAL(valueChanged(int)), this, SLOT(setSliderValue(int))); - connect(ui->doubleValueSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setParamValue(double))); - connect(ui->intValueSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setParamValue(int))); - connect(ui->editNameLabel, SIGNAL(textChanged(QString)), ui->nameLabel, SLOT(setText(QString))); + connect(ui->writeButton, SIGNAL(clicked()), + this, SLOT(setParamPending())); + connect(ui->editSelectComponentComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(selectComponent(int))); + connect(ui->editSelectParamComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(selectParameter(int))); + connect(ui->valueSlider, SIGNAL(valueChanged(int)), + this, SLOT(setSliderValue(int))); + connect(ui->doubleValueSpinBox, SIGNAL(valueChanged(double)), + this, SLOT(setParamValue(double))); + connect(ui->intValueSpinBox, SIGNAL(valueChanged(int)), + this, SLOT(setParamValue(int))); + connect(ui->editNameLabel, SIGNAL(textChanged(QString)), + ui->nameLabel, SLOT(setText(QString))); connect(ui->readButton, SIGNAL(clicked()), this, SLOT(requestParameter())); - connect(ui->editRefreshParamsButton, SIGNAL(clicked()), this, SLOT(refreshParamList())); - connect(ui->editInfoCheckBox, SIGNAL(clicked(bool)), this, SLOT(showInfo(bool))); + connect(ui->editRefreshParamsButton, SIGNAL(clicked()), + this, SLOT(refreshParamList())); + connect(ui->editInfoCheckBox, SIGNAL(clicked(bool)), + this, SLOT(showInfo(bool))); // connect to self - connect(ui->infoLabel, SIGNAL(released()), this, SLOT(showTooltip())); + connect(ui->infoLabel, SIGNAL(released()), + this, SLOT(showTooltip())); // Set the current UAS if present - connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); + connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), + this, SLOT(setActiveUAS(UASInterface*))); } QGCParamSlider::~QGCParamSlider() @@ -83,8 +94,7 @@ void QGCParamSlider::refreshParamList() { ui->editSelectParamComboBox->setEnabled(true); ui->editSelectComponentComboBox->setEnabled(true); - if (uas) - { + if (uas) { uas->getParamManager()->requestParameterList(); ui->editStatusLabel->setText(tr("Parameter list updating..")); } @@ -122,9 +132,8 @@ void QGCParamSlider::setActiveUAS(UASInterface* activeUas) void QGCParamSlider::requestParameter() { - if (!parameterName.isEmpty() && uas) - { - uas->getParamManager()->requestParameterUpdate(this->component, this->parameterName); + if (uas && !parameterName.isEmpty()) { + uas->getParamManager()->requestParameterUpdate(component, parameterName); } } @@ -268,23 +277,13 @@ void QGCParamSlider::endEditMode() emit editingFinished(); } -void QGCParamSlider::sendParameter() +void QGCParamSlider::setParamPending() { - if (uas) - { - // Set value, param manager handles retransmission - if (uas->getParamManager()) - { - uas->getParamManager()->setParameter(component, parameterName, parameterValue); - } - else - { - qDebug() << "UAS HAS NO PARAM MANAGER, DOING NOTHING"; - } + if (uas) { + uas->getParamManager()->setPendingParam(component, parameterName, parameterValue); } - else - { - qDebug() << __FILE__ << __LINE__ << "NO UAS SET, DOING NOTHING"; + else { + qWarning() << __FILE__ << __LINE__ << "NO UAS SET, DOING NOTHING"; } } @@ -329,55 +328,48 @@ void QGCParamSlider::setSliderValue(int sliderValue) * @brief parameterName Key/name of the parameter * @brief value Value of the parameter */ -void QGCParamSlider::setParameterValue(int uas, int component, int paramCount, int paramIndex, QString parameterName, QVariant value) +void QGCParamSlider::setParameterValue(int uasId, int compId, int paramCount, int paramIndex, QString paramName, QVariant value) { Q_UNUSED(paramCount); - if (ui->nameLabel->text() == "Name") - { - ui->nameLabel->setText(parameterName); + if (uasId != this->uas->getUASID()) { + return; + } + + if (ui->nameLabel->text() == "Name") { + ui->nameLabel->setText(paramName); } // Check if this component and parameter are part of the list bool found = false; - for (int i = 0; i< ui->editSelectComponentComboBox->count(); ++i) - { - if (component == ui->editSelectComponentComboBox->itemData(i).toInt()) - { + for (int i = 0; i< ui->editSelectComponentComboBox->count(); ++i) { + if (compId == ui->editSelectComponentComboBox->itemData(i).toInt()) { found = true; } } - if (!found) - { - ui->editSelectComponentComboBox->addItem(tr("Component #%1").arg(component), component); + if (!found) { + ui->editSelectComponentComboBox->addItem(tr("Component #%1").arg(compId), compId); } // Parameter checking found = false; - for (int i = 0; i < ui->editSelectParamComboBox->count(); ++i) - { - if (parameterName == ui->editSelectParamComboBox->itemText(i)) - { + for (int i = 0; i < ui->editSelectParamComboBox->count(); ++i) { + if (paramName == ui->editSelectParamComboBox->itemText(i)) { found = true; } } - if (!found) - { - ui->editSelectParamComboBox->addItem(parameterName, paramIndex); + if (!found) { + ui->editSelectParamComboBox->addItem(paramName, paramIndex); } - if (visibleParam != "") - { - if (parameterName == visibleParam) - { - if (visibleVal == value.toInt()) - { - this->uas->requestParameter(this->component,this->parameterName); + if (visibleParam != "") { + if (paramName == visibleParam) { + if (visibleVal == value.toInt()) { + uas->getParamManager()->requestParameterUpdate(compId,paramName); visibleEnabled = true; this->show(); } - else - { + else { //Disable the component here. ui->valueSlider->setEnabled(false); ui->intValueSpinBox->setEnabled(false); @@ -388,10 +380,8 @@ void QGCParamSlider::setParameterValue(int uas, int component, int paramCount, i } } Q_UNUSED(uas); - if (component == this->component && parameterName == this->parameterName) - { - if (!visibleEnabled) - { + if (compId == this->component && paramName == this->parameterName) { + if (!visibleEnabled) { return; } parameterValue = value; @@ -460,8 +450,7 @@ void QGCParamSlider::setParameterValue(int uas, int component, int paramCount, i parameterMin = ui->editMinSpinBox->value(); } - if (paramIndex == paramCount - 1) - { + if (paramIndex == paramCount - 1) { ui->editStatusLabel->setText(tr("Complete parameter list received.")); } } diff --git a/src/ui/designer/QGCParamSlider.h b/src/ui/designer/QGCParamSlider.h index 7160cd937e..3ef78fdf71 100644 --- a/src/ui/designer/QGCParamSlider.h +++ b/src/ui/designer/QGCParamSlider.h @@ -23,8 +23,8 @@ public: public slots: void startEditMode(); void endEditMode(); - /** @brief Send the parameter to the MAV */ - void sendParameter(); + /** @brief Queue parameter for sending to the MAV (add to pending list)*/ + void setParamPending(); /** @brief Set the slider value as parameter value */ void setSliderValue(int sliderValue); /** @brief Update the UI with the new parameter value */ -- GitLab From 6b1801a8daf35367ca21d7faeea9583d31ca3a98 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 13 Aug 2013 11:50:50 -0700 Subject: [PATCH 205/460] fix counting of written params; fix wiring of pend param widget to model --- src/uas/QGCUASParamManager.cc | 7 +-- src/uas/UASParameterCommsMgr.cc | 77 ++++++++++++++++---------------- src/uas/UASParameterCommsMgr.h | 6 +-- src/uas/UASParameterDataModel.cc | 77 ++++++++++++++++++++++++-------- src/uas/UASParameterDataModel.h | 13 ++++-- src/ui/QGCParamWidget.cc | 17 ++++--- src/ui/QGCPendingParamWidget.cc | 29 ++++++++++++ src/ui/QGCPendingParamWidget.h | 3 +- 8 files changed, 157 insertions(+), 72 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index f1fd085bff..569daebb67 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -62,9 +62,10 @@ void QGCUASParamManager::setParamDescriptions(const QMap& param } -void QGCUASParamManager::setParameter(int component, QString parameterName, QVariant value) +void QGCUASParamManager::setParameter(int compId, QString paramName, QVariant value) { - paramCommsMgr->setParameter(component,parameterName,value); + //paramCommsMgr->setParameter(compId,paramName,value); + paramDataModel->updatePendingParamWithValue(compId,paramName,value); } void QGCUASParamManager::sendPendingParameters() @@ -74,7 +75,7 @@ void QGCUASParamManager::sendPendingParameters() void QGCUASParamManager::setPendingParam(int compId, QString& paramName, const QVariant& value) { - paramDataModel->setPendingParam(compId,paramName,value); + paramDataModel->updatePendingParamWithValue(compId,paramName,value); } diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 27ee774faf..63ccac4839 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -27,7 +27,7 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : mav, SLOT(requestParameter(int,int))); // Sending params to the UAS - connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), + connect(this, SIGNAL(commitPendingParameter(int,QString,QVariant)), mav, SLOT(setParameter(int,QString,QVariant))); // Received parameter updates from UAS @@ -113,16 +113,16 @@ void UASParameterCommsMgr::clearRetransmissionLists(int& missingReadCount, int& } missingWriteCount = 0; - QList writeKeys = transmissionMissingWriteAckPackets.keys(); + QList writeKeys = missingWriteAckPackets.keys(); foreach (int compId, writeKeys) { - missingWriteCount += transmissionMissingWriteAckPackets.value(compId)->count(); - transmissionMissingWriteAckPackets.value(compId)->clear(); + missingWriteCount += missingWriteAckPackets.value(compId)->count(); + missingWriteAckPackets.value(compId)->clear(); } } -void UASParameterCommsMgr::emitParameterChanged(int compId, const QString& key, QVariant& value) +void UASParameterCommsMgr::emitPendingParameterCommit(int compId, const QString& key, QVariant& value) { int paramType = (int)value.type(); switch (paramType) @@ -130,25 +130,25 @@ void UASParameterCommsMgr::emitParameterChanged(int compId, const QString& key, case QVariant::Char: { QVariant fixedValue(QChar((unsigned char)value.toInt())); - emit parameterChanged(compId, key, fixedValue); + emit commitPendingParameter(compId, key, fixedValue); } break; case QVariant::Int: { QVariant fixedValue(value.toInt()); - emit parameterChanged(compId, key, fixedValue); + emit commitPendingParameter(compId, key, fixedValue); } break; case QVariant::UInt: { QVariant fixedValue(value.toUInt()); - emit parameterChanged(compId, key, fixedValue); + emit commitPendingParameter(compId, key, fixedValue); } break; case QMetaType::Float: { QVariant fixedValue(value.toFloat()); - emit parameterChanged(compId, key, fixedValue); + emit commitPendingParameter(compId, key, fixedValue); } break; default: @@ -190,14 +190,14 @@ void UASParameterCommsMgr::resendReadWriteRequests() // Re-request at maximum retransmissionBurstRequestSize parameters at once // to prevent write-request link flooding int requestedWriteCount = 0; - compIds = transmissionMissingWriteAckPackets.keys(); + compIds = missingWriteAckPackets.keys(); foreach (compId, compIds) { - QMap * missingParams = transmissionMissingWriteAckPackets.value(compId); + QMap * missingParams = missingWriteAckPackets.value(compId); foreach (QString key, missingParams->keys()) { if (requestedWriteCount < retransmissionBurstRequestSize) { // Re-request write operation QVariant value = missingParams->value(key); - emitParameterChanged(compId, key, value); + emitPendingParameterCommit(compId, key, value); requestedWriteCount++; } else { @@ -234,7 +234,7 @@ void UASParameterCommsMgr::retransmissionGuardTick() quint64 curTime = QGC::groundTimeMilliseconds(); //Workaround for an apparent Qt bug that causes retransmission guard timer to fire prematurely (350ms) - quint64 elapsed = (curTime - lastTimerReset); + int elapsed = (int)(curTime - lastTimerReset); if (elapsed < retransmissionTimeout) { qDebug() << "retransmissionGuardTick elapsed:" << (curTime - lastTimerReset); //reset the guard timer: it fired prematurely @@ -374,16 +374,16 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV return; } - emitParameterChanged(component, parameterName, value); + emitPendingParameterCommit(component, parameterName, value); // Wait for parameter to be written back // mark it therefore as missing - if (!transmissionMissingWriteAckPackets.contains(component)) { - transmissionMissingWriteAckPackets.insert(component, new QMap()); + if (!missingWriteAckPackets.contains(component)) { + missingWriteAckPackets.insert(component, new QMap()); } // Insert it in missing write ACK list - transmissionMissingWriteAckPackets.value(component)->insert(parameterName, value); + missingWriteAckPackets.value(component)->insert(parameterName, value); // Set timeouts if (transmissionActive) { @@ -466,42 +466,42 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para bool writeMismatch = false; // Mark this parameter as received in write ACK list - QMap* map = transmissionMissingWriteAckPackets.value(compId); + QMap* map = missingWriteAckPackets.value(compId); if (map && map->contains(paramName)) { justWritten = true; - QVariant newval = map->value(paramName); if (map->value(paramName) != value) { writeMismatch = true; } map->remove(paramName); } - int missCount = 0; + int missReadCount = 0; foreach (int key, transmissionMissingPackets.keys()) { - missCount += transmissionMissingPackets.value(key)->count(); + missReadCount += transmissionMissingPackets.value(key)->count(); } int missWriteCount = 0; - foreach (int key, transmissionMissingWriteAckPackets.keys()) { - missWriteCount += transmissionMissingWriteAckPackets.value(key)->count(); + foreach (int key, missingWriteAckPackets.keys()) { + missWriteCount += missingWriteAckPackets.value(key)->count(); } //TODO simplify this if-else tree - if (justWritten && !writeMismatch && missWriteCount == 0) { - // Just wrote one and count went to 0 - this was the last missing write parameter - setParameterStatusMsg(tr("SUCCESS: WROTE ALL PARAMETERS")); - } - else if (justWritten && !writeMismatch) { - setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount)); - } - else if (justWritten && writeMismatch) { - // Mismatch, tell user - setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(map->value(paramName).toDouble()).arg(value.toDouble()), - ParamCommsStatusLevel_Warning); + if (justWritten) { + if (!writeMismatch) { + setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount)); + if (0 == missWriteCount) { + setParameterStatusMsg(tr("SUCCESS: WROTE ALL PARAMETERS")); + paramDataModel->commitAllPendingParams(); + } + } + else { + // Mismatch, tell user + setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(map->value(paramName).toDouble()).arg(value.toDouble()), + ParamCommsStatusLevel_Warning); + } } else { - QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); - if (missCount == 0) { + if (missReadCount == 0) { // Transmission done QTime time = QTime::currentTime(); QString timeString = time.toString(); @@ -509,13 +509,14 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para } else { // Transmission in progress - setParameterStatusMsg(tr("OK: %1 %2 (%3/%4)").arg(paramName).arg(val).arg(paramCount-missCount).arg(paramCount), + QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); + setParameterStatusMsg(tr("OK: %1 %2 (%3/%4)").arg(paramName).arg(val).arg(paramCount-missReadCount).arg(paramCount), ParamCommsStatusLevel_Warning); } } // Check if last parameter was received - if (missCount == 0 && missWriteCount == 0) { + if (missReadCount == 0 && missWriteCount == 0) { resetAfterListReceive(); setRetransmissionGuardEnabled(false); //all parameters have been received, broadcast to UI diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 006d45d83f..d554e0021a 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -44,10 +44,10 @@ protected: void resendReadWriteRequests(); void resetAfterListReceive(); - void emitParameterChanged(int compId, const QString& key, QVariant& value); + void emitPendingParameterCommit(int compId, const QString& key, QVariant& value); signals: - void parameterChanged(int component, QString parameter, QVariant value); + void commitPendingParameter(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); void parameterValueConfirmed(int uas, int component,int paramCount, int paramId, QString parameter, QVariant value); @@ -93,7 +93,7 @@ protected: // Communications management QVector receivedParamsList; ///< Successfully received parameters QMap* > transmissionMissingPackets; ///< Missing packets - QMap* > transmissionMissingWriteAckPackets; ///< Missing write ACK packets + QMap* > missingWriteAckPackets; ///< Missing write ACK packets bool transmissionListMode; ///< Currently requesting list QMap transmissionListSizeKnown; ///< List size initialized? bool transmissionActive; ///< Missing packets, working on list? diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 1806ec23fc..ab444d4962 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -18,9 +18,42 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : +int UASParameterDataModel::countPendingParams() +{ + int totalPending = 0; + QMap*>::iterator i; + for (i = pendingParameters.begin(); i != pendingParameters.end(); ++i) { + // Iterate through the parameters of the component + QMap* paramList = i.value(); + totalPending += paramList->count(); + } + + return totalPending; +} + +void UASParameterDataModel::commitAllPendingParams() +{ + qDebug() << "commitAllPendingParams:" << countPendingParams(); + + QList allCompIds = pendingParameters.keys(); + foreach (int compId, allCompIds) { + // Iterate through the parameters of the component + QMap* compParams = pendingParameters.value(compId); + QList paramNames = compParams->keys(); + qDebug() << paramNames.count() << "committed params for component" << compId; + + foreach (QString paramName, paramNames) { + QVariant value = compParams->value(paramName); + setOnboardParamWithType( compId, paramName, value);//update the onboard value to match pending value + emit pendingParamUpdate(compId,paramName,value,false); //no longer pending + emit parameterUpdated(compId,paramName,value);//ensure the new onboard value is broadcast + } + + } +} -bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key, QVariant& value) +bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key, const QVariant& value) { bool pending = true; //ensure we have this component in our onboard and pending lists already @@ -44,27 +77,36 @@ bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key return pending; } -void UASParameterDataModel::removePendingParam(int compId, QString& key) + +bool UASParameterDataModel::isParamChangePending(int compId, const QString& key) { - QMap *params = getPendingParamsForComponent(compId); - if (params) { - params->remove(key); - //broadcast the existing value - QVariant existVal; - bool ok = getOnboardParamValue(compId,key,existVal); - emit pendingParamUpdate(compId, key,existVal, false); - } + QMap* pendingParms = getPendingParamsForComponent(compId); + return ((NULL != pendingParms) && pendingParms->contains(key)); } - void UASParameterDataModel::setPendingParam(int compId, QString& key, const QVariant &value) { //ensure we have a placeholder map for this component addComponent(compId); - QMap *params = getPendingParamsForComponent(compId); - params->insert(key,value); - emit pendingParamUpdate(compId, key, value, true); + QMap *pendParams = getPendingParamsForComponent(compId); + if (pendParams) { + pendParams->insert(key,value); + emit pendingParamUpdate(compId, key, value, true); + } +} +void UASParameterDataModel::removePendingParam(int compId, QString& key) +{ + qDebug() << "removePendingParam:" << key; + + QMap *pendParams = getPendingParamsForComponent(compId); + if (pendParams) { + pendParams->remove(key); + //broadcast the existing value + QVariant existVal; + getOnboardParamValue(compId,key,existVal); + emit pendingParamUpdate(compId, key,existVal, false); + } } void UASParameterDataModel::setOnboardParam(int compId, QString& key, const QVariant& value) @@ -78,7 +120,6 @@ void UASParameterDataModel::setOnboardParam(int compId, QString& key, const QVa void UASParameterDataModel::setOnboardParamWithType(int compId, QString& key, QVariant& value) { -// switch ((int)onboardParameters.value(componentId)->value(key).type()) switch ((int)value.type()) { case QVariant::Int: @@ -209,13 +250,13 @@ void UASParameterDataModel::readUpdateParamsFromStream( QTextStream& stream) switch (paramType) { case MAV_PARAM_TYPE_REAL32: - setPendingParam(componentId,key,QVariant(valStr.toFloat())); + updatePendingParamWithValue(componentId,key,QVariant(valStr.toFloat())); break; case MAV_PARAM_TYPE_UINT32: - setPendingParam(componentId,key, QVariant(valStr.toUInt())); + updatePendingParamWithValue(componentId,key, QVariant(valStr.toUInt())); break; case MAV_PARAM_TYPE_INT32: - setPendingParam(componentId,key,QVariant(valStr.toInt())); + updatePendingParamWithValue(componentId,key,QVariant(valStr.toInt())); break; default: qDebug() << "FAILED LOADING PARAM" << key << "UNKNOWN DATA TYPE"; diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index fde760b703..f3da12f199 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -34,10 +34,9 @@ public: */ virtual void addComponent(int compId); - /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ - virtual void setPendingParam(int componentId, QString& key, const QVariant& value); virtual void removePendingParam(int compId, QString& key); + virtual void commitAllPendingParams();///< Called by eg params comms mgr when all pending params have been sent & acked /** @brief Save the onboard parameter with a the type specified in the QVariant as fixed */ virtual void setOnboardParamWithType(int componentId, QString& key, QVariant& value); @@ -49,10 +48,12 @@ public: /** @brief add this parameter to pending list iff it has changed from onboard value * @return true if the parameter is now pending */ - virtual bool updatePendingParamWithValue(int componentId, QString& key, QVariant& value); + virtual bool updatePendingParamWithValue(int componentId, QString& key, const QVariant &value); virtual void handleParamUpdate(int componentId, QString& key, QVariant& value); virtual bool getOnboardParamValue(int componentId, const QString& key, QVariant& value) const; + virtual bool isParamChangePending(int componentId,const QString& key); + QMap* getPendingParamsForComponent(int componentId) { return pendingParameters.value(componentId); } @@ -79,6 +80,10 @@ public: protected: virtual void setOnboardParam(int componentId, QString& key, const QVariant& value); + /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ + virtual void setPendingParam(int componentId, QString& key, const QVariant& value); + + int countPendingParams(); signals: @@ -88,6 +93,8 @@ signals: /** @brief Notifies listeners that a param was added to or removed from the pending list */ void pendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); + void allPendingParamsCommitted(); ///< All pending params have been committed to the MAV + public slots: diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 1f4889603d..571283d2d3 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -206,10 +206,10 @@ void QGCParamWidget::addComponentItem(int compId, QString compName) void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) { - qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; + // qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; if (updatingParamNameLock == paramName) { - qDebug() << "ignoring bounce from " << paramName; + //qDebug() << "ignoring bounce from " << paramName; return; } else { @@ -230,10 +230,15 @@ void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramNa } -void QGCParamWidget::handleParameterUpdate(int componentId, const QString& paramName, QVariant value) +void QGCParamWidget::handleParameterUpdate(int compId, const QString& paramName, QVariant value) { +// qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; + if (paramName == updatingParamNameLock) { + qDebug() << "handlePendingParamUpdate ignoring bounce from " << paramName; + return; + } updatingParamNameLock = paramName; - updateParameterDisplay(componentId, paramName, value); + updateParameterDisplay(compId, paramName, value); updatingParamNameLock.clear(); } @@ -402,10 +407,10 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column if (paramItem && column > 0) { QString key = paramItem->data(0, Qt::DisplayRole).toString(); - qDebug() << "parameterItemChanged:" << key << "with updatingParamNameLock:" << updatingParamNameLock; + //qDebug() << "parameterItemChanged:" << key << "with updatingParamNameLock:" << updatingParamNameLock; if (key == updatingParamNameLock) { - qDebug() << "ignoring parameterItemChanged" << key; + //qDebug() << "parameterItemChanged ignoring parameterItemChanged" << key; return; } else { diff --git a/src/ui/QGCPendingParamWidget.cc b/src/ui/QGCPendingParamWidget.cc index 800ca354e0..57ee57d5db 100644 --- a/src/ui/QGCPendingParamWidget.cc +++ b/src/ui/QGCPendingParamWidget.cc @@ -30,4 +30,33 @@ void QGCPendingParamWidget::connectSignalsAndSlots() this, SLOT(handleParamStatusMsgUpdate(QString , int ))); } +void QGCPendingParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) +{ + // qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; + + if (updatingParamNameLock == paramName) { + //qDebug() << "ignoring bounce from " << paramName; + return; + } + else { + updatingParamNameLock = paramName; + } + + QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); + + if (isPending) { + QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); + paramItem->setFlags(paramItem->flags() & ~Qt::ItemIsEditable); //disallow editing + paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); + paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); + tree->expandAll(); + } + else { + //we don't display non-pending items + paramItem->parent()->removeChild(paramItem); + } + + updatingParamNameLock.clear(); + +} diff --git a/src/ui/QGCPendingParamWidget.h b/src/ui/QGCPendingParamWidget.h index 91f08a522f..4c6e7370c4 100644 --- a/src/ui/QGCPendingParamWidget.h +++ b/src/ui/QGCPendingParamWidget.h @@ -20,7 +20,8 @@ protected: signals: public slots: - + virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); + }; #endif // QGCPENDINGPARAMWIDGET_H -- GitLab From 1fad00a10d5cac9c849a74506002124c8f012a92 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 13 Aug 2013 13:00:57 -0700 Subject: [PATCH 206/460] fix updating of pending param list after transmit --- src/uas/UASParameterCommsMgr.cc | 50 +++++++++++++++++--------------- src/uas/UASParameterCommsMgr.h | 2 +- src/uas/UASParameterDataModel.cc | 38 ++++++------------------ src/uas/UASParameterDataModel.h | 10 +++++-- src/ui/QGCParamWidget.cc | 13 ++------- 5 files changed, 45 insertions(+), 68 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 63ccac4839..db74186114 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -80,8 +80,8 @@ void UASParameterCommsMgr::requestParameterList() transmissionListSizeKnown.clear(); transmissionListMode = true; - foreach (int key, transmissionMissingPackets.keys()) { - transmissionMissingPackets.value(key)->clear(); + foreach (int key, missingReadPackets.keys()) { + missingReadPackets.value(key)->clear(); } transmissionActive = true; @@ -106,10 +106,10 @@ void UASParameterCommsMgr::clearRetransmissionLists(int& missingReadCount, int& qDebug() << __FILE__ << __LINE__ << "clearRetransmissionLists"; missingReadCount = 0; - QList readKeys = transmissionMissingPackets.keys(); + QList readKeys = missingReadPackets.keys(); foreach (int compId, readKeys) { - missingReadCount += transmissionMissingPackets.value(compId)->count(); - transmissionMissingPackets.value(compId)->clear(); + missingReadCount += missingReadPackets.value(compId)->count(); + missingReadPackets.value(compId)->clear(); } missingWriteCount = 0; @@ -169,10 +169,11 @@ void UASParameterCommsMgr::resendReadWriteRequests() // Re-request at maximum retransmissionBurstRequestSize parameters at once // to prevent link flooding' int requestedReadCount = 0; - compIds = transmissionMissingPackets.keys(); + compIds = missingReadPackets.keys(); foreach (compId, compIds) { // Request n parameters from this component (at maximum) - QList* missingReadParams = transmissionMissingPackets.value(compId, NULL); + QList* missingReadParams = missingReadPackets.value(compId, NULL); + qDebug() << "missingReadParams:" << missingReadParams->count(); foreach (int paramId, *missingReadParams) { if (requestedReadCount < retransmissionBurstRequestSize) { //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << paramId << "FROM COMPONENT #" << compId; @@ -423,11 +424,11 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para paramDataModel->handleParamUpdate(compId,paramName,value); // Missing packets list has to be instantiated for all components - if (!transmissionMissingPackets.contains(compId)) { - transmissionMissingPackets.insert(compId, new QList()); + if (!missingReadPackets.contains(compId)) { + missingReadPackets.insert(compId, new QList()); } - QList* compXmitMissing = transmissionMissingPackets.value(compId); + QList* compMissReadPackets = missingReadPackets.value(compId); // List mode is different from single parameter transfers if (transmissionListMode) { @@ -439,8 +440,8 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para qDebug() << "Mark all parameters as missing: " << paramCount; for (int i = 1; i < paramCount; ++i) { //TODO check: param Id 0 is "all parameters" and not valid ? - if (!compXmitMissing->contains(i)) { - compXmitMissing->append(i); + if (!compMissReadPackets->contains(i)) { + compMissReadPackets->append(i); } } @@ -456,28 +457,27 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para } // Mark this parameter as received in read list - int index = compXmitMissing->indexOf(paramId); - // If the MAV sent the parameter without request, it wont be in missing list + int index = compMissReadPackets->indexOf(paramId); if (index != -1) { - compXmitMissing->removeAt(index); + compMissReadPackets->removeAt(index); } bool justWritten = false; bool writeMismatch = false; // Mark this parameter as received in write ACK list - QMap* map = missingWriteAckPackets.value(compId); - if (map && map->contains(paramName)) { + QMap* compMissWritePackets = missingWriteAckPackets.value(compId); + if (compMissWritePackets && compMissWritePackets->contains(paramName)) { justWritten = true; - if (map->value(paramName) != value) { + if (compMissWritePackets->value(paramName) != value) { writeMismatch = true; } - map->remove(paramName); + compMissWritePackets->remove(paramName); } int missReadCount = 0; - foreach (int key, transmissionMissingPackets.keys()) { - missReadCount += transmissionMissingPackets.value(key)->count(); + foreach (int key, missingReadPackets.keys()) { + missReadCount += missingReadPackets.value(key)->count(); } int missWriteCount = 0; @@ -488,15 +488,14 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para //TODO simplify this if-else tree if (justWritten) { if (!writeMismatch) { - setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount)); + setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3 [%5]").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount).arg(missWriteCount)); if (0 == missWriteCount) { setParameterStatusMsg(tr("SUCCESS: WROTE ALL PARAMETERS")); - paramDataModel->commitAllPendingParams(); } } else { // Mismatch, tell user - setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(map->value(paramName).toDouble()).arg(value.toDouble()), + setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(compMissWritePackets->value(paramName).toDouble()).arg(value.toDouble()), ParamCommsStatusLevel_Warning); } } @@ -512,6 +511,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); setParameterStatusMsg(tr("OK: %1 %2 (%3/%4)").arg(paramName).arg(val).arg(paramCount-missReadCount).arg(paramCount), ParamCommsStatusLevel_Warning); + //transmissionMissingPackets } } @@ -598,6 +598,8 @@ void UASParameterCommsMgr::sendPendingParameters() } // Enable guard setRetransmissionGuardEnabled(true); + + qDebug() << "Pending parameters now:" << paramDataModel->countPendingParams(); } } diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index d554e0021a..acdab75a86 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -92,7 +92,7 @@ protected: // Communications management QVector receivedParamsList; ///< Successfully received parameters - QMap* > transmissionMissingPackets; ///< Missing packets + QMap* > missingReadPackets; ///< Missing packets QMap* > missingWriteAckPackets; ///< Missing write ACK packets bool transmissionListMode; ///< Currently requesting list QMap transmissionListSizeKnown; ///< List size initialized? diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index ab444d4962..66b847e88e 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -31,27 +31,6 @@ int UASParameterDataModel::countPendingParams() return totalPending; } -void UASParameterDataModel::commitAllPendingParams() -{ - qDebug() << "commitAllPendingParams:" << countPendingParams(); - - QList allCompIds = pendingParameters.keys(); - foreach (int compId, allCompIds) { - // Iterate through the parameters of the component - QMap* compParams = pendingParameters.value(compId); - QList paramNames = compParams->keys(); - qDebug() << paramNames.count() << "committed params for component" << compId; - - foreach (QString paramName, paramNames) { - QVariant value = compParams->value(paramName); - setOnboardParamWithType( compId, paramName, value);//update the onboard value to match pending value - emit pendingParamUpdate(compId,paramName,value,false); //no longer pending - emit parameterUpdated(compId,paramName,value);//ensure the new onboard value is broadcast - } - - } -} - bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key, const QVariant& value) { @@ -163,26 +142,27 @@ void UASParameterDataModel::addComponent(int compId) } -void UASParameterDataModel::handleParamUpdate(int compId, QString& key, QVariant& value) +void UASParameterDataModel::handleParamUpdate(int compId, QString& paramName, QVariant& value) { //verify that the value requested by the user matches the set value //if it doesn't match, leave the pending parameter in the pending list! if (pendingParameters.contains(compId)) { QMap *pendingParams = pendingParameters.value(compId); - if ((NULL != pendingParams) && pendingParams->contains(key)) { - QVariant reqVal = pendingParams->value(key); + if ((NULL != pendingParams) && pendingParams->contains(paramName)) { + QVariant reqVal = pendingParams->value(paramName); if (reqVal == value) { - pendingParams->remove(key); + //notify everyone that this item is being removed from the pending parameters list since it's now confirmed + emit pendingParamUpdate(compId, paramName, value, false); + pendingParams->remove(paramName); } else { - qDebug() << "Pending commit for " << key << " want: " << reqVal << " got: " << value; + qDebug() << "Pending commit for " << paramName << " want: " << reqVal << " got: " << value; } } } - setOnboardParam(compId,key,value); - - emit parameterUpdated(compId,key,value); + emit parameterUpdated(compId,paramName,value); + setOnboardParam(compId,paramName,value); } diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index f3da12f199..2ca97965d8 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -35,8 +35,6 @@ public: virtual void addComponent(int compId); - virtual void removePendingParam(int compId, QString& key); - virtual void commitAllPendingParams();///< Called by eg params comms mgr when all pending params have been sent & acked /** @brief Save the onboard parameter with a the type specified in the QVariant as fixed */ virtual void setOnboardParamWithType(int componentId, QString& key, QVariant& value); @@ -70,6 +68,9 @@ public: return &onboardParameters; } + /** @brief return a count of all pending parameters */ + int countPendingParams(); + virtual void writeOnboardParamsToStream(QTextStream &stream, const QString& uasName); virtual void readUpdateParamsFromStream(QTextStream &stream); @@ -79,11 +80,14 @@ public: void setUASID(int anId) { this->uasId = anId; } protected: + /** @brief set the confirmed value of a parameter in the onboard params list */ virtual void setOnboardParam(int componentId, QString& key, const QVariant& value); + /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ virtual void setPendingParam(int componentId, QString& key, const QVariant& value); + /** @brief remove a parameter from the pending list */ + virtual void removePendingParam(int compId, QString& key); - int countPendingParams(); signals: diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 571283d2d3..f2fc58073e 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -509,16 +509,7 @@ void QGCParamWidget::requestAllParamsUpdate() */ void QGCParamWidget::writeParameters() { - int changedParamCount = 0; - - QMap*>::iterator i; - QMap*>* changedValues = paramDataModel->getAllPendingParams(); - - for (i = changedValues->begin(); (i != changedValues->end()) && (0 == changedParamCount); ++i) { - // Iterate through the pending parameters of the component, break on the first changed parameter - QMap* compPending = i.value(); - changedParamCount += compPending->count(); - } + int changedParamCount = paramDataModel->countPendingParams(); if (changedParamCount > 0) { QMessageBox msgBox; @@ -534,7 +525,7 @@ void QGCParamWidget::writeParameters() void QGCParamWidget::readParameters() { if (!mav) return; - mav->readParametersFromStorage(); + mav->readParametersFromStorage(); //TODO use data model / mgr instead? } /** -- GitLab From 548a0097ec5a3271ad18b40b01dc6f852c22c3a5 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 2 Aug 2013 21:50:32 -0700 Subject: [PATCH 207/460] wip decoupling the UI (view) from the param data model --- qgroundcontrol.pro | 6 +- src/uas/QGCUASParamManager.cc | 1 + src/uas/QGCUASParamManager.h | 8 +- src/uas/UAS.cc | 3 + src/uas/UAS.h | 12 +++ src/uas/UASInterface.h | 6 ++ src/uas/UASParameterDataModel.cc | 26 ++++++ src/uas/UASParameterDataModel.h | 42 +++++++++ src/ui/QGCParamWidget.cc | 148 +++++++++++++++++-------------- src/ui/QGCParamWidget.h | 10 ++- 10 files changed, 189 insertions(+), 73 deletions(-) create mode 100644 src/uas/UASParameterDataModel.cc create mode 100644 src/uas/UASParameterDataModel.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 263586226c..fd4df5e5b5 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -468,7 +468,8 @@ HEADERS += src/MG.h \ src/ui/configuration/SerialSettingsDialog.h \ src/ui/configuration/terminalconsole.h \ src/ui/configuration/ApmHighlighter.h \ - src/ui/configuration/ApmFirmwareConfig.h + src/ui/configuration/ApmFirmwareConfig.h \ + src/uas/UASParameterDataModel.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -683,7 +684,8 @@ SOURCES += src/main.cc \ src/ui/configuration/console.cpp \ src/ui/configuration/SerialSettingsDialog.cc \ src/ui/configuration/ApmHighlighter.cc \ - src/ui/configuration/ApmFirmwareConfig.cc + src/ui/configuration/ApmFirmwareConfig.cc \ + src/uas/UASParameterDataModel.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 6e137b6329..7193bce82f 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -12,6 +12,7 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : retransmissionBurstRequestSize(5) { uas->setParamManager(this); + paramDataModel = uas->getParamDataModel(); } diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 69dee9eb44..d7f8adf976 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -7,6 +7,7 @@ #include class UASInterface; +class UASParameterDataModel; class QGCUASParamManager : public QWidget { @@ -62,9 +63,14 @@ public slots: virtual void requestParameterList() = 0; protected: + + //Parameter data model UASInterface* mav; ///< The MAV this widget is controlling - QMap* > changedValues; ///< Changed values +// QMap* > changedValues; ///< Changed values QMap* > parameters; ///< All parameters + UASParameterDataModel* paramDataModel;///< Shared data model of parameters + + // Communications management QVector received; ///< Successfully received parameters QMap* > transmissionMissingPackets; ///< Missing packets QMap* > transmissionMissingWriteAckPackets; ///< Missing write ACK packets diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 8dd3395506..8a8ef7539f 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -131,6 +131,7 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), paramsOnceRequested(false), paramManager(NULL), + paramDataModel(NULL), simulation(0), @@ -151,6 +152,8 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), componentMulti[i] = false; } + paramDataModel->setUASID(this->getUASID()); + // Store a list of available actions for this UAS. // Basically everything exposted as a SLOT with no return value or arguments. diff --git a/src/uas/UAS.h b/src/uas/UAS.h index b1c027bd1f..c8b9a604c7 100644 --- a/src/uas/UAS.h +++ b/src/uas/UAS.h @@ -492,6 +492,7 @@ protected: //COMMENTS FOR TEST UNIT QMap* > parameters; ///< All parameters bool paramsOnceRequested; ///< If the parameter list has been read at least once QGCUASParamManager* paramManager; ///< Parameter manager class + UASParameterDataModel* paramDataModel; ///< The parameter data model for this UAS /// SIMULATION QGCHilLink* simulation; ///< Hardware in the loop simulation link @@ -519,10 +520,20 @@ public: QGCUASParamManager* getParamManager() const { return paramManager; } + + /** @brief Get reference to the parameter data model (same one shared with the parameter manager) **/ + UASParameterDataModel* getParamDataModel() { + return paramDataModel; + } + + /** @brief Get the HIL simulation */ QGCHilLink* getHILSimulation() const { return simulation; } + + + // TODO Will be removed /** @brief Set reference to the param manager **/ void setParamManager(QGCUASParamManager* manager) { @@ -949,6 +960,7 @@ protected: quint64 lastSendTimeSensors; QList actions; ///< A list of actions that this UAS can perform. + protected slots: /** @brief Write settings to disk */ void writeSettings(); diff --git a/src/uas/UASInterface.h b/src/uas/UASInterface.h index 37382e3eb4..ed2aed28c8 100644 --- a/src/uas/UASInterface.h +++ b/src/uas/UASInterface.h @@ -40,6 +40,7 @@ This file is part of the QGROUNDCONTROL project #include "LinkInterface.h" #include "ProtocolInterface.h" +#include "UASParameterDataModel.h" #include "UASWaypointManager.h" #include "QGCUASParamManager.h" #include "RadioCalibration/RadioCalibrationData.h" @@ -152,8 +153,13 @@ public: /** @brief Get reference to the waypoint manager **/ virtual UASWaypointManager* getWaypointManager(void) = 0; + + /** @brief Access the parameter data model for this UAS (sans widget). This is the same parameter data model used by the parameter manager. **/ + virtual UASParameterDataModel* getParamDataModel() = 0; + /** @brief Get reference to the param manager **/ virtual QGCUASParamManager* getParamManager() const = 0; + // TODO Will be removed /** @brief Set reference to the param manager **/ virtual void setParamManager(QGCUASParamManager* manager) = 0; diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc new file mode 100644 index 0000000000..8effd144ce --- /dev/null +++ b/src/uas/UASParameterDataModel.cc @@ -0,0 +1,26 @@ +#include "UASParameterDataModel.h" + +#include + +UASParameterDataModel::UASParameterDataModel(QObject *parent) : + QObject(parent) +{ + + + + + +} + + +void UASParameterDataModel::setPendingParameter(int componentId, QString& key, QVariant &value) +{ + QMap *compPendingParams = pendingParameters.value(componentId); + //TODO insert blank map if necessary + if (NULL == compPendingParams) { + pendingParameters.insert(componentId,new QMap()); + compPendingParams = pendingParameters.value(componentId); + } + + compPendingParams->insert(key,value); +} diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h new file mode 100644 index 0000000000..5c1d67d486 --- /dev/null +++ b/src/uas/UASParameterDataModel.h @@ -0,0 +1,42 @@ +#ifndef UASPARAMETERDATAMODEL_H +#define UASPARAMETERDATAMODEL_H + +#include +#include +#include + +class UASParameterDataModel : public QObject +{ + Q_OBJECT +public: + explicit UASParameterDataModel(QObject *parent = 0); + + + /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ + virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue) = 0; + + QMap* > getPendingParameters() { + return pendingParameters; + } + + QMap* > getOnboardParameters() { + return onboardParameters; + } + + + void setUASID(int anId) { this->uasId = anId; } + +signals: + +public slots: + + +protected: + int uasId; ///< The UAS / MAV to which this data model pertains + QMap* > pendingParameters; ///< Changed values that have not yet been transmitted to the UAS, by component ID + QMap* > onboardParameters; ///< All parameters confirmed to be stored onboard the UAS, by component ID + + +}; + +#endif // UASPARAMETERDATAMODEL_H diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 94e1697b52..abd1e913d5 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -105,13 +105,13 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QPushButton* loadFileButton = new QPushButton(tr("Load File")); loadFileButton->setToolTip(tr("Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them.")); loadFileButton->setWhatsThis(tr("Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them.")); - connect(loadFileButton, SIGNAL(clicked()), this, SLOT(loadParameters())); + connect(loadFileButton, SIGNAL(clicked()), this, SLOT(loadParametersFromFile())); horizontalLayout->addWidget(loadFileButton, 3, 0); QPushButton* saveFileButton = new QPushButton(tr("Save File")); saveFileButton->setToolTip(tr("Save parameters in this view to a file on this computer.")); saveFileButton->setWhatsThis(tr("Save parameters in this view to a file on this computer.")); - connect(saveFileButton, SIGNAL(clicked()), this, SLOT(saveParameters())); + connect(saveFileButton, SIGNAL(clicked()), this, SLOT(saveParametersToFile())); horizontalLayout->addWidget(saveFileButton, 3, 1); QPushButton* readButton = new QPushButton(tr("Read (ROM)")); @@ -142,7 +142,7 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); // New parameters from UAS - connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(addParameter(int,int,int,int,QString,QVariant))); + connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); // Connect retransmission guard connect(this, SIGNAL(requestParameter(int,QString)), uas, SLOT(requestParameter(int,QString))); @@ -335,10 +335,10 @@ void QGCParamWidget::addComponent(int uas, int component, QString componentName) if (!parameters.contains(component)) { parameters.insert(component, new QMap()); } - // Create map in changed parameters - if (!changedValues.contains(component)) { - changedValues.insert(component, new QMap()); - } +// // Create map in changed parameters +// if (!changedValues.contains(component)) { +// changedValues.insert(component, new QMap()); +// } } } @@ -347,9 +347,9 @@ void QGCParamWidget::addComponent(int uas, int component, QString componentName) * @param component id of the component * @param parameterName human friendly name of the parameter */ -void QGCParamWidget::addParameter(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) +void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) { - addParameter(uas, component, parameterName, value); + receivedParameterUpdate(uas, component, parameterName, value); // Missing packets list has to be instantiated for all components if (!transmissionMissingPackets.contains(component)) { @@ -494,7 +494,7 @@ void QGCParamWidget::addParameter(int uas, int component, int paramCount, int pa * @param component id of the component * @param parameterName human friendly name of the parameter */ -void QGCParamWidget::addParameter(int uas, int component, QString parameterName, QVariant value) +void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value) { //qDebug() << "PARAM WIDGET GOT PARAM:" << value; Q_UNUSED(uas); @@ -636,8 +636,18 @@ void QGCParamWidget::addParameter(int uas, int component, QString parameterName, parameterItem->setToolTip(0, tooltipFormat); parameterItem->setToolTip(1, tooltipFormat); - //tree->update(); - if (changedValues.contains(component)) changedValues.value(component)->remove(parameterName); + //verify that the value requested by the user matches the set value + //if it doesn't match, leave the pending parameter in the pending list! + QMap *> changedValues = this->paramDataModel->getPendingParameters(); + if (changedValues.contains(component)) { + QMap *compReqVals = changedValues.value(component); + if ((NULL != compReqVals) && compReqVals->contains(parameterName)) { + QVariant reqVal = compReqVals->value(parameterName); + if (reqVal == value) { + compReqVals->remove(parameterName); + } + } + } } /** @@ -682,9 +692,14 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) } // Parent is now top-level component int key = components->key(parent); + + //ensure we have a placeholder map for this component + QMap *> changedValues = this->paramDataModel->getPendingParameters(); if (!changedValues.contains(key)) { changedValues.insert(key, new QMap()); } + + //insert the changed value into the map QMap* map = changedValues.value(key, NULL); if (map) { QString str = current->data(0, Qt::DisplayRole).toString(); @@ -739,7 +754,7 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) } } -void QGCParamWidget::saveParameters() +void QGCParamWidget::saveParametersToFile() { if (!mav) return; QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "./parameters.txt", tr("Parameter File (*.txt)")); @@ -794,7 +809,47 @@ void QGCParamWidget::saveParameters() file.close(); } -void QGCParamWidget::loadParameters() + +void QGCParamWidget::loadedParameterForComponent(int componentId, QStringList& wpParams ) +{ + // Set parameter value + + QMap *> changedValues = this->paramDataModel->getPendingParameters(); + + // Create changed values data structure if necessary + if (!changedValues.contains(componentId)) { + changedValues.insert(componentId, new QMap()); + } + + // Add to changed values + if (changedValues.value(componentId)->contains(wpParams.at(2))) { + changedValues.value(componentId)->remove(wpParams.at(2)); + } + + switch (wpParams.at(4).toUInt()) + { + case (int)MAV_PARAM_TYPE_REAL32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toFloat()); + changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toFloat()); + setParameter(componentId, wpParams.at(2), wpParams.at(3).toFloat()); + break; + case (int)MAV_PARAM_TYPE_UINT32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toUInt()); + changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toUInt()); + setParameter(componentId, wpParams.at(2), QVariant(wpParams.at(3).toUInt())); + break; + case (int)MAV_PARAM_TYPE_INT32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toInt()); + changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toInt()); + setParameter(componentId, wpParams.at(2), QVariant(wpParams.at(3).toInt())); + break; + default: + qDebug() << "FAILED LOADING PARAM" << wpParams.at(2) << "NO KNOWN DATA TYPE"; + } + +} + +void QGCParamWidget::loadParametersFromFile() { if (!mav) return; QString fileName = QFileDialog::getOpenFileName(this, tr("Load File"), ".", tr("Parameter file (*.txt)")); @@ -817,59 +872,18 @@ void QGCParamWidget::loadParameters() } bool changed = false; - int component = wpParams.at(1).toInt(); + int componentId = wpParams.at(1).toInt(); QString parameterName = wpParams.at(2); - if (!parameters.contains(component) || - fabs((static_cast(parameters.value(component)->value(parameterName, wpParams.at(3).toDouble()).toDouble())) - (wpParams.at(3).toDouble())) > 2.0f * FLT_EPSILON) { + if (!parameters.contains(componentId) || + fabs((static_cast(parameters.value(componentId)->value(parameterName, wpParams.at(3).toDouble()).toDouble())) - (wpParams.at(3).toDouble())) > 2.0f * FLT_EPSILON) { changed = true; qDebug() << "Changed" << parameterName << "VAL" << wpParams.at(3).toDouble(); } - // Set parameter value - - // Create changed values data structure if necessary - if (changed && !changedValues.contains(wpParams.at(1).toInt())) { - changedValues.insert(wpParams.at(1).toInt(), new QMap()); - } - - // Add to changed values - if (changed && changedValues.value(wpParams.at(1).toInt())->contains(wpParams.at(2))) { - changedValues.value(wpParams.at(1).toInt())->remove(wpParams.at(2)); - } - - switch (wpParams.at(4).toUInt()) - { - case (int)MAV_PARAM_TYPE_REAL32: - addParameter(wpParams.at(0).toInt(), wpParams.at(1).toInt(), wpParams.at(2), wpParams.at(3).toFloat()); - if (changed) { - changedValues.value(wpParams.at(1).toInt())->insert(wpParams.at(2), wpParams.at(3).toFloat()); - setParameter(wpParams.at(1).toInt(), wpParams.at(2), wpParams.at(3).toFloat()); - qDebug() << "FLOAT PARAM CHANGED"; - } - break; - case (int)MAV_PARAM_TYPE_UINT32: - addParameter(wpParams.at(0).toInt(), wpParams.at(1).toInt(), wpParams.at(2), wpParams.at(3).toUInt()); - if (changed) { - changedValues.value(wpParams.at(1).toInt())->insert(wpParams.at(2), wpParams.at(3).toUInt()); - setParameter(wpParams.at(1).toInt(), wpParams.at(2), QVariant(wpParams.at(3).toUInt())); - } - break; - case (int)MAV_PARAM_TYPE_INT32: - addParameter(wpParams.at(0).toInt(), wpParams.at(1).toInt(), wpParams.at(2), wpParams.at(3).toInt()); - if (changed) { - changedValues.value(wpParams.at(1).toInt())->insert(wpParams.at(2), wpParams.at(3).toInt()); - setParameter(wpParams.at(1).toInt(), wpParams.at(2), QVariant(wpParams.at(3).toInt())); - } - break; - default: - qDebug() << "FAILED LOADING PARAM" << wpParams.at(2) << "NO KNOWN DATA TYPE"; + if (changed) { + loadedParameterForComponent(componentId,wpParams); } - //qDebug() << "MARKING COMP" << wpParams.at(1).toInt() << "PARAM" << wpParams.at(2) << "VALUE" << (float)wpParams.at(3).toDouble() << "AS CHANGED"; - - // Mark in UI - - } } } @@ -1098,6 +1112,7 @@ void QGCParamWidget::setParameters() { // Iterate through all components, through all parameters and emit them int parametersSent = 0; + QMap*> changedValues = paramDataModel->getPendingParameters(); QMap*>::iterator i; for (i = changedValues.begin(); i != changedValues.end(); ++i) { // Iterate through the parameters of the component @@ -1144,16 +1159,17 @@ void QGCParamWidget::writeParameters() int changedParamCount = 0; QMap*>::iterator i; - for (i = changedValues.begin(); i != changedValues.end(); ++i) + QMap*> changedValues = paramDataModel->getPendingParameters(); + + for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) { // Iterate through the parameters of the component QMap* comp = i.value(); + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) { - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) - { - changedParamCount++; - } + changedParamCount++; + break;//it only takes one changed param to warrant warning the user } } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index f62227d015..5b48fffb22 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -71,9 +71,9 @@ public slots: /** @brief Add a component to the list */ void addComponent(int uas, int component, QString componentName); /** @brief Add a parameter to the list with retransmission / safety checks */ - void addParameter(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); + void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); /** @brief Add a parameter to the list */ - void addParameter(int uas, int component, QString parameterName, QVariant value); + void receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ void requestParameterList(); /** @brief Request one single parameter */ @@ -92,9 +92,11 @@ public slots: void parameterItemChanged(QTreeWidgetItem* prev, int column); /** @brief Store parameters to a file */ - void saveParameters(); + void saveParametersToFile(); /** @brief Load parameters from a file */ - void loadParameters(); + void loadParametersFromFile(); + + void loadedParameterForComponent(int componentId, QStringList& wpParams ); /** @brief Check for missing parameters */ void retransmissionGuardTick(); -- GitLab From 3713adf2fee1fdea8981473934cafb9862fad818 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 5 Aug 2013 17:56:59 -0700 Subject: [PATCH 208/460] fix null ptr exception --- src/uas/UAS.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 8a8ef7539f..597472af5a 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -152,6 +152,7 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), componentMulti[i] = false; } + paramDataModel = new UASParameterDataModel(this); paramDataModel->setUASID(this->getUASID()); // Store a list of available actions for this UAS. -- GitLab From f020b6412114a5f6334ce79cb335cf9dc1b4fc54 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 5 Aug 2013 17:57:51 -0700 Subject: [PATCH 209/460] remove pure virtual --- src/uas/UASParameterDataModel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 5c1d67d486..60bfbbfa80 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -13,7 +13,7 @@ public: /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ - virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue) = 0; + virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue); QMap* > getPendingParameters() { return pendingParameters; -- GitLab From 4d77bfedfe625c3baf5f9f7792166d03d96302a5 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 2 Aug 2013 21:50:32 -0700 Subject: [PATCH 210/460] wip decoupling the UI (view) from the param data model --- src/uas/UASParameterDataModel.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 60bfbbfa80..c120770392 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -15,6 +15,7 @@ public: /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue); + QMap* > getPendingParameters() { return pendingParameters; } -- GitLab From 132795551b91fbfe14d61e4ac2a4d40cbc0535de Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 5 Aug 2013 17:57:51 -0700 Subject: [PATCH 211/460] remove pure virtual --- src/uas/UASParameterDataModel.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index c120770392..60bfbbfa80 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -15,7 +15,6 @@ public: /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue); - QMap* > getPendingParameters() { return pendingParameters; } -- GitLab From 0be24ebc42ae8519ac101e42dbc446f3d591083b Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 5 Aug 2013 18:20:28 -0700 Subject: [PATCH 212/460] rename parameters --- src/uas/QGCUASParamManager.h | 15 +++++++-------- src/ui/QGCParamWidget.cc | 36 ++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index d7f8adf976..130e9a18cb 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -16,23 +16,23 @@ public: QGCUASParamManager(UASInterface* uas, QWidget *parent = 0); QList getParameterNames(int component) const { - return parameters.value(component)->keys(); + return onboardParameters.value(component)->keys(); } QList getParameterValues(int component) const { - return parameters.value(component)->values(); + return onboardParameters.value(component)->values(); } bool getParameterValue(int component, const QString& parameter, QVariant& value) const { - if (!parameters.contains(component)) + if (!onboardParameters.contains(component)) { return false; } - if (!parameters.value(component)->contains(parameter)) + if (!onboardParameters.value(component)->contains(parameter)) { return false; } - value = parameters.value(component)->value(parameter); + value = onboardParameters.value(component)->value(parameter); return true; } @@ -64,10 +64,9 @@ public slots: protected: - //Parameter data model + // Parameter data model UASInterface* mav; ///< The MAV this widget is controlling -// QMap* > changedValues; ///< Changed values - QMap* > parameters; ///< All parameters + QMap* > onboardParameters; ///< All parameters UASParameterDataModel* paramDataModel;///< Shared data model of parameters // Communications management diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index abd1e913d5..fb1e6eb964 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -332,8 +332,8 @@ void QGCParamWidget::addComponent(int uas, int component, QString componentName) tree->addTopLevelItem(comp); tree->update(); // Create map in parameters - if (!parameters.contains(component)) { - parameters.insert(component, new QMap()); + if (!onboardParameters.contains(component)) { + onboardParameters.insert(component, new QMap()); } // // Create map in changed parameters // if (!changedValues.contains(component)) { @@ -524,8 +524,8 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString par // Replace value in map // FIXME - if (parameters.value(component)->contains(parameterName)) parameters.value(component)->remove(parameterName); - parameters.value(component)->insert(parameterName, value); + if (onboardParameters.value(component)->contains(parameterName)) onboardParameters.value(component)->remove(parameterName); + onboardParameters.value(component)->insert(parameterName, value); QString splitToken = "_"; @@ -666,7 +666,7 @@ void QGCParamWidget::requestParameterList() // Clear view and request param list clear(); - parameters.clear(); + onboardParameters.clear(); received.clear(); // Clear transmission state transmissionListMode = true; @@ -715,35 +715,35 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) map->insert(str, value); // Check if the value was numerically changed - if (!parameters.value(key)->contains(str) || parameters.value(key)->value(str, value.toDouble()-1) != value) { + if (!onboardParameters.value(key)->contains(str) || onboardParameters.value(key)->value(str, value.toDouble()-1) != value) { current->setBackground(0, QBrush(QColor(QGC::colorOrange))); current->setBackground(1, QBrush(QColor(QGC::colorOrange))); } - switch ((int)parameters.value(key)->value(str).type()) + switch ((int)onboardParameters.value(key)->value(str).type()) { case QVariant::Int: { QVariant fixedValue(value.toInt()); - parameters.value(key)->insert(str, fixedValue); + onboardParameters.value(key)->insert(str, fixedValue); } break; case QVariant::UInt: { QVariant fixedValue(value.toUInt()); - parameters.value(key)->insert(str, fixedValue); + onboardParameters.value(key)->insert(str, fixedValue); } break; case QMetaType::Float: { QVariant fixedValue(value.toFloat()); - parameters.value(key)->insert(str, fixedValue); + onboardParameters.value(key)->insert(str, fixedValue); } break; case QMetaType::QChar: { QVariant fixedValue(QChar((unsigned char)value.toUInt())); - parameters.value(key)->insert(str, fixedValue); + onboardParameters.value(key)->insert(str, fixedValue); } break; default: @@ -771,7 +771,7 @@ void QGCParamWidget::saveParametersToFile() // Iterate through all components, through all parameters and emit them QMap*>::iterator i; - for (i = parameters.begin(); i != parameters.end(); ++i) { + for (i = onboardParameters.begin(); i != onboardParameters.end(); ++i) { // Iterate through the parameters of the component int compid = i.key(); QMap* comp = i.value(); @@ -874,8 +874,8 @@ void QGCParamWidget::loadParametersFromFile() bool changed = false; int componentId = wpParams.at(1).toInt(); QString parameterName = wpParams.at(2); - if (!parameters.contains(componentId) || - fabs((static_cast(parameters.value(componentId)->value(parameterName, wpParams.at(3).toDouble()).toDouble())) - (wpParams.at(3).toDouble())) > 2.0f * FLT_EPSILON) { + if (!onboardParameters.contains(componentId) || + fabs((static_cast(onboardParameters.value(componentId)->value(parameterName, wpParams.at(3).toDouble()).toDouble())) - (wpParams.at(3).toDouble())) > 2.0f * FLT_EPSILON) { changed = true; qDebug() << "Changed" << parameterName << "VAL" << wpParams.at(3).toDouble(); } @@ -940,7 +940,7 @@ void QGCParamWidget::retransmissionGuardTick() // Re-request at maximum retransmissionBurstRequestSize parameters at once // to prevent link flooding QMap*>::iterator i; - for (i = parameters.begin(); i != parameters.end(); ++i) { + for (i = onboardParameters.begin(); i != onboardParameters.end(); ++i) { // Iterate through the parameters of the component int component = i.key(); // Request n parameters from this component (at maximum) @@ -971,7 +971,7 @@ void QGCParamWidget::retransmissionGuardTick() if (count < retransmissionBurstRequestSize) { // Re-request write operation QVariant value = missingParams->value(key); - switch ((int)parameters.value(component)->value(key).type()) + switch ((int)onboardParameters.value(component)->value(key).type()) { case QVariant::Int: { @@ -1035,13 +1035,13 @@ void QGCParamWidget::setParameter(int component, QString parameterName, QVariant statusLabel->setText(tr("REJ. %1 > max").arg(value.toDouble())); return; } - if (parameters.value(component)->value(parameterName) == value) + if (onboardParameters.value(component)->value(parameterName) == value) { statusLabel->setText(tr("REJ. %1 > max").arg(value.toDouble())); return; } - switch ((int)parameters.value(component)->value(parameterName).type()) + switch ((int)onboardParameters.value(component)->value(parameterName).type()) { case QVariant::Char: { -- GitLab From ca20853343109bf52424d3db8a46458fb5c95942 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 5 Aug 2013 21:29:48 -0700 Subject: [PATCH 213/460] utility methods for data model --- src/uas/UASParameterDataModel.cc | 40 +++++++++++++++++++++++++------- src/uas/UASParameterDataModel.h | 15 ++++++++++++ 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 8effd144ce..8396594e17 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -7,20 +7,44 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : { +} +void UASParameterDataModel::addPendingIfParameterChanged(int componentId, QString& key, QVariant &value) +{ + addComponent(componentId); + QMap *existParams = getOnbardParametersForComponent(componentId); + QMap *pendParams = getPendingParametersForComponent(componentId); + + QVariant existValue = existParams->value(key); + QVariant pendValue = pendParams->value(key); + if (!(existValue == pendValue)) { + setPendingParameter(componentId,key,value); + } +} +void UASParameterDataModel::setPendingParameter(int componentId, QString& key, QVariant &value) +{ + //ensure we have a placeholder map for this component + addComponent(componentId); + QMap *params = getPendingParametersForComponent(componentId); + params->insert(key,value); } +void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, QVariant &value) +{ + //ensure we have a placeholder map for this component + addComponent(componentId); + QMap *params = getOnbardParametersForComponent(componentId); + params->insert(key,value); +} -void UASParameterDataModel::setPendingParameter(int componentId, QString& key, QVariant &value) +void UASParameterDataModel::addComponent(int componentId) { - QMap *compPendingParams = pendingParameters.value(componentId); - //TODO insert blank map if necessary - if (NULL == compPendingParams) { - pendingParameters.insert(componentId,new QMap()); - compPendingParams = pendingParameters.value(componentId); + if (!onboardParameters.contains(componentId)) { + onboardParameters.insert(componentId, new QMap()); + } + if (!pendingParameters.contains(componentId)) { + pendingParameters.insert(componentId, new QMap()); } - - compPendingParams->insert(key,value); } diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 60bfbbfa80..7122d523eb 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -12,8 +12,23 @@ public: explicit UASParameterDataModel(QObject *parent = 0); + virtual void addComponent(int componentId); + /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue); + virtual void setOnboardParameter(int componentId, QString& key, QVariant &value); + + /** @brief add this parameter to pending list iff it has changed from onboard value */ + virtual void addPendingIfParameterChanged(int componentId, QString& key, QVariant &value); + + + QMap* getPendingParametersForComponent(int componentId) { + return pendingParameters.value(componentId); + } + + QMap* getOnbardParametersForComponent(int componentId) { + return onboardParameters.value(componentId); + } QMap* > getPendingParameters() { return pendingParameters; -- GitLab From ea5e80afebf812bc7972db31e6be9335f8a8b29c Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 5 Aug 2013 21:43:24 -0700 Subject: [PATCH 214/460] Move handleParameterUpdate into data model class --- src/uas/UASParameterDataModel.cc | 24 +++++++++++++++++++++++- src/uas/UASParameterDataModel.h | 2 ++ src/ui/QGCParamWidget.cc | 14 ++------------ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 8396594e17..dbf4610601 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -1,5 +1,6 @@ #include "UASParameterDataModel.h" +#include #include UASParameterDataModel::UASParameterDataModel(QObject *parent) : @@ -31,7 +32,7 @@ void UASParameterDataModel::setPendingParameter(int componentId, QString& key, params->insert(key,value); } -void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, QVariant &value) +void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, QVariant& value) { //ensure we have a placeholder map for this component addComponent(componentId); @@ -48,3 +49,24 @@ void UASParameterDataModel::addComponent(int componentId) pendingParameters.insert(componentId, new QMap()); } } + + +void UASParameterDataModel::handleParameterUpdate(int componentId, QString& key, QVariant& value) +{ + //verify that the value requested by the user matches the set value + //if it doesn't match, leave the pending parameter in the pending list! + if (pendingParameters.contains(componentId)) { + QMap *pendingParams = pendingParameters.value(componentId); + if ((NULL != pendingParams) && pendingParams->contains(key)) { + QVariant reqVal = pendingParams->value(key); + if (reqVal == value) { + pendingParams->remove(key); + } + else { + qDebug() << "Pending commit for " << key << " want: " << reqVal << " got: " << value; + } + } + } + + setOnboardParameter(componentId,key, value); +} diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 7122d523eb..b3e56b7a74 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -22,6 +22,8 @@ public: virtual void addPendingIfParameterChanged(int componentId, QString& key, QVariant &value); + void handleParameterUpdate(int componentId, QString& key, QVariant& value); + QMap* getPendingParametersForComponent(int componentId) { return pendingParameters.value(componentId); } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index fb1e6eb964..0e415d8bd9 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -636,18 +636,8 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString par parameterItem->setToolTip(0, tooltipFormat); parameterItem->setToolTip(1, tooltipFormat); - //verify that the value requested by the user matches the set value - //if it doesn't match, leave the pending parameter in the pending list! - QMap *> changedValues = this->paramDataModel->getPendingParameters(); - if (changedValues.contains(component)) { - QMap *compReqVals = changedValues.value(component); - if ((NULL != compReqVals) && compReqVals->contains(parameterName)) { - QVariant reqVal = compReqVals->value(parameterName); - if (reqVal == value) { - compReqVals->remove(parameterName); - } - } - } + paramDataModel->handleParameterUpdate(component,parameterName,value); + } /** -- GitLab From 9a9913bb27c6224336861ede8eae99d004286152 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 07:42:05 -0700 Subject: [PATCH 215/460] remove unused methods --- src/uas/QGCUASParamManager.cc | 3 +++ src/uas/QGCUASParamManager.h | 23 +---------------------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 7193bce82f..ee42aa9684 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -24,4 +24,7 @@ void QGCUASParamManager::requestParameterListUpdate(int component) Q_UNUSED(component); } +bool QGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const { + return paramDataModel->getOnboardParameterValue(component,parameter,value); +} diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 130e9a18cb..7f970ef6dc 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -15,27 +15,7 @@ class QGCUASParamManager : public QWidget public: QGCUASParamManager(UASInterface* uas, QWidget *parent = 0); - QList getParameterNames(int component) const { - return onboardParameters.value(component)->keys(); - } - QList getParameterValues(int component) const { - return onboardParameters.value(component)->values(); - } - bool getParameterValue(int component, const QString& parameter, QVariant& value) const { - if (!onboardParameters.contains(component)) - { - return false; - } - - if (!onboardParameters.value(component)->contains(parameter)) - { - return false; - } - - value = onboardParameters.value(component)->value(parameter); - - return true; - } + virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; virtual bool isParamMinKnown(const QString& param) = 0; virtual bool isParamMaxKnown(const QString& param) = 0; @@ -66,7 +46,6 @@ protected: // Parameter data model UASInterface* mav; ///< The MAV this widget is controlling - QMap* > onboardParameters; ///< All parameters UASParameterDataModel* paramDataModel;///< Shared data model of parameters // Communications management -- GitLab From eee3e8fe1c8a6f4ba012d4363596415e7f0a0d55 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 07:43:45 -0700 Subject: [PATCH 216/460] Move more model code into the model class --- src/uas/UASParameterDataModel.cc | 218 +++++++++++++++++++++++++++++-- src/uas/UASParameterDataModel.h | 31 ++++- 2 files changed, 236 insertions(+), 13 deletions(-) diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index dbf4610601..3269efd185 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -1,8 +1,13 @@ #include "UASParameterDataModel.h" +#include + #include +#include #include +#include "QGCMAVLink.h" + UASParameterDataModel::UASParameterDataModel(QObject *parent) : QObject(parent) { @@ -10,21 +15,43 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : } -void UASParameterDataModel::addPendingIfParameterChanged(int componentId, QString& key, QVariant &value) + + +bool UASParameterDataModel::checkParameterChanged(int componentId, const QString& key, const QVariant &value) { + bool changed = true; addComponent(componentId); - QMap *existParams = getOnbardParametersForComponent(componentId); - QMap *pendParams = getPendingParametersForComponent(componentId); + QMap* existParams = getOnbardParametersForComponent(componentId); + + if (existParams->contains(key)) { + QVariant existValue = existParams->value(key); + QMap* pendParams = getPendingParametersForComponent(componentId); + if (pendParams->contains(key)) { + QVariant pendValue = pendParams->value(key); + if (existValue == pendValue) { + changed = false; + } + } + } - QVariant existValue = existParams->value(key); - QVariant pendValue = pendParams->value(key); - if (!(existValue == pendValue)) { + return changed; + +} + +bool UASParameterDataModel::addPendingIfParameterChanged(int componentId, QString& key, QVariant &value) + +{ + bool changed = checkParameterChanged(componentId,key,value); + + if (changed ) { setPendingParameter(componentId,key,value); } + + return changed; } -void UASParameterDataModel::setPendingParameter(int componentId, QString& key, QVariant &value) +void UASParameterDataModel::setPendingParameter(int componentId, QString& key, const QVariant &value) { //ensure we have a placeholder map for this component addComponent(componentId); @@ -32,7 +59,7 @@ void UASParameterDataModel::setPendingParameter(int componentId, QString& key, params->insert(key,value); } -void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, QVariant& value) +void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, const QVariant& value) { //ensure we have a placeholder map for this component addComponent(componentId); @@ -40,6 +67,42 @@ void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, params->insert(key,value); } +void UASParameterDataModel::setOnboardParameterWithType(int componentId, QString& key, QVariant& value) +{ + +// switch ((int)onboardParameters.value(componentId)->value(key).type()) + switch ((int)value.type()) + { + case QVariant::Int: + { + QVariant fixedValue(value.toInt()); + onboardParameters.value(componentId)->insert(key, fixedValue); + } + break; + case QVariant::UInt: + { + QVariant fixedValue(value.toUInt()); + onboardParameters.value(componentId)->insert(key, fixedValue); + } + break; + case QMetaType::Float: + { + QVariant fixedValue(value.toFloat()); + onboardParameters.value(componentId)->insert(key, fixedValue); + } + break; + case QMetaType::QChar: + { + QVariant fixedValue(QChar((unsigned char)value.toUInt())); + onboardParameters.value(componentId)->insert(key, fixedValue); + } + break; + default: + qCritical() << "ABORTED PARAM UPDATE, NO VALID QVARIANT TYPE"; + return; + } +} + void UASParameterDataModel::addComponent(int componentId) { if (!onboardParameters.contains(componentId)) { @@ -70,3 +133,142 @@ void UASParameterDataModel::handleParameterUpdate(int componentId, QString& key, setOnboardParameter(componentId,key, value); } + +bool UASParameterDataModel::getOnboardParameterValue(int componentId, const QString& key, QVariant& value) const +{ + + if (onboardParameters.contains(componentId)) { + if (onboardParameters.value(componentId)->contains(key)) { + value = onboardParameters.value(componentId)->value(key); + return true; + } + } + + return false; +} + +void UASParameterDataModel::forgetAllOnboardParameters() +{ + onboardParameters.clear(); +} + +void UASParameterDataModel::readUpdateParametersFromStream(QTextStream& stream) +{ + + bool userWarned = false; + + while (!stream.atEnd()) { + QString line = stream.readLine(); + if (!line.startsWith("#")) { + QStringList wpParams = line.split("\t"); + int lineMavId = wpParams.at(0).toInt(); + if (wpParams.size() == 5) { + // Only load parameters for right mav + if (!userWarned && (uasId != lineMavId)) { + //TODO warn the user somehow + QString msg = tr("The parameters in the stream have been saved from system %1, but the currently selected system has the ID %2.").arg(lineMavId).arg(uasId); +// MainWindow::instance()->showCriticalMessage( +// tr("Parameter loading warning"), +// tr("The parameters from the file %1 have been saved from system %2, but the currently selected system has the ID %3. If this is unintentional, please click on to revert to the parameters that are currently onboard").arg(fileName).arg(wpParams.at(0).toInt()).arg(mav->getUASID())); + userWarned = true; + return; + } + + bool changed = false; + int componentId = wpParams.at(1).toInt(); + QString key = wpParams.at(2); + QString valStr = wpParams.at(3); + double dblVal = wpParams.at(3).toDouble(); + uint paramType = wpParams.at(4).toUInt(); + + + if (!onboardParameters.contains(componentId)) { + addComponent(componentId); + changed = true; + } + else { + if (fabs((static_cast(onboardParameters.value(componentId)->value(key, dblVal).toDouble())) - (dblVal)) > + 2.0f * FLT_EPSILON) { + changed = true; + qDebug() << "Changed" << key << "VAL" << dblVal; + } + } + + + if (changed) { + switch (paramType) + { + case MAV_PARAM_TYPE_REAL32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toFloat()); + setPendingParameter(componentId,key,QVariant(valStr.toFloat())); + //setParameter(componentId, key, valStr.toFloat()); + break; + case MAV_PARAM_TYPE_UINT32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toUInt()); + setPendingParameter(componentId,key, QVariant(valStr.toUInt())); + //setParameter(componentId, key, QVariant(valStr.toUInt())); + break; + case MAV_PARAM_TYPE_INT32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toInt()); + setPendingParameter(componentId,key,QVariant(valStr.toInt())); + //setParameter(componentId, key, QVariant(valStr.toInt())); + break; + default: + qDebug() << "FAILED LOADING PARAM" << key << "UNKNOWN DATA TYPE"; + } + + //TODO update display + + } + + + } + } + } + +} + +void UASParameterDataModel::writeOnboardParametersToStream(QTextStream& stream, const QString& name) +{ + stream << "# Onboard parameters for system " << name << "\n"; + stream << "#\n"; + stream << "# MAV ID COMPONENT ID PARAM NAME VALUE (FLOAT)\n"; + + // Iterate through all components, through all parameters and emit them + QMap*>::iterator i; + for (i = onboardParameters.begin(); i != onboardParameters.end(); ++i) { + // Iterate through the parameters of the component + int compid = i.key(); + QMap* comp = i.value(); + { + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) + { + QString paramValue("%1"); + QString paramType("%1"); + switch ((int)j.value().type()) + { + case QVariant::Int: + paramValue = paramValue.arg(j.value().toInt()); + paramType = paramType.arg(MAV_PARAM_TYPE_INT32); + break; + case QVariant::UInt: + paramValue = paramValue.arg(j.value().toUInt()); + paramType = paramType.arg(MAV_PARAM_TYPE_UINT32); + break; + case QMetaType::Float: + // We store parameters as floats, with only 6 digits of precision guaranteed for decimal string conversion + // (see IEEE 754, 32 bit single-precision) + paramValue = paramValue.arg((double)j.value().toFloat(), 25, 'g', 6); + paramType = paramType.arg(MAV_PARAM_TYPE_REAL32); + break; + default: + qCritical() << "ABORTED PARAM WRITE TO FILE, NO VALID QVARIANT TYPE" << j.value(); + return; + } + stream << this->uasId << "\t" << compid << "\t" << j.key() << "\t" << paramValue << "\t" << paramType << "\n"; + stream.flush(); + } + } + } +} diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index b3e56b7a74..e38e06c8c4 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -5,6 +5,8 @@ #include #include +class QTextStream; + class UASParameterDataModel : public QObject { Q_OBJECT @@ -15,14 +17,30 @@ public: virtual void addComponent(int componentId); /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ - virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue); - virtual void setOnboardParameter(int componentId, QString& key, QVariant &value); + virtual void setPendingParameter(int componentId, QString& key, const QVariant& value); + virtual void setOnboardParameter(int componentId, QString& key, const QVariant& value); + + /** @brief Save the onboard parameter with a the type specified in the QVariant as fixed */ + virtual void setOnboardParameterWithType(int componentId, QString& key, QVariant& value); + + /** @brief clears every parameter for every loaded component */ + virtual void forgetAllOnboardParameters(); + + /** + * @return true if the parameter has changed + */ + virtual bool checkParameterChanged(int componentId, const QString& key, const QVariant &value); - /** @brief add this parameter to pending list iff it has changed from onboard value */ - virtual void addPendingIfParameterChanged(int componentId, QString& key, QVariant &value); + /** @brief add this parameter to pending list iff it has changed from onboard value + * @return true if the parameter has changed + */ + virtual bool addPendingIfParameterChanged(int componentId, QString& key, QVariant& value); - void handleParameterUpdate(int componentId, QString& key, QVariant& value); + + virtual void handleParameterUpdate(int componentId, QString& key, QVariant& value); + + virtual bool getOnboardParameterValue(int componentId, const QString& key, QVariant& value) const; QMap* getPendingParametersForComponent(int componentId) { return pendingParameters.value(componentId); @@ -41,6 +59,9 @@ public: } + virtual void writeOnboardParametersToStream(QTextStream& stream, const QString& uasName); + virtual void readUpdateParametersFromStream(QTextStream& stream); + void setUASID(int anId) { this->uasId = anId; } signals: -- GitLab From c70d99207a2c52bdeb37d995fa0b9f177e5f4cb3 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 07:52:25 -0700 Subject: [PATCH 217/460] cleanupt paramInfo (tooltips) --- src/ui/QGCParamWidget.cc | 244 +++++++++------------------------------ src/ui/QGCParamWidget.h | 4 +- 2 files changed, 55 insertions(+), 193 deletions(-) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 0e415d8bd9..07c948457b 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -165,6 +165,15 @@ void QGCParamWidget::loadSettings() settings.endGroup(); } + +void QGCParamWidget::setParamInfo(const QMap& paramInfo) { + if (paramInfo.isEmpty()) { + qDebug() << << __FILE__ << ":" << __LINE__ << "setParamInfo with empty"; + } + paramToolTips = paramInfo; +} + + void QGCParamWidget::loadParameterInfoCSV(const QString& autopilot, const QString& airframe) { Q_UNUSED(airframe); @@ -331,15 +340,10 @@ void QGCParamWidget::addComponent(int uas, int component, QString componentName) paramGroups.insert(component, new QMap()); tree->addTopLevelItem(comp); tree->update(); - // Create map in parameters - if (!onboardParameters.contains(component)) { - onboardParameters.insert(component, new QMap()); - } -// // Create map in changed parameters -// if (!changedValues.contains(component)) { -// changedValues.insert(component, new QMap()); -// } } + + paramDataModel->addComponent(component); + } /** @@ -496,7 +500,7 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCo */ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value) { - //qDebug() << "PARAM WIDGET GOT PARAM:" << value; + qDebug() << "PARAM WIDGET GOT PARAM:" << parameterName; Q_UNUSED(uas); // Reference to item in tree QTreeWidgetItem* parameterItem = NULL; @@ -523,9 +527,7 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString par // Replace value in map - // FIXME - if (onboardParameters.value(component)->contains(parameterName)) onboardParameters.value(component)->remove(parameterName); - onboardParameters.value(component)->insert(parameterName, value); + paramDataModel->setOnboardParameter(component,parameterName,value); QString splitToken = "_"; @@ -656,7 +658,7 @@ void QGCParamWidget::requestParameterList() // Clear view and request param list clear(); - onboardParameters.clear(); + paramDataModel->forgetAllOnboardParameters(); received.clear(); // Clear transmission state transmissionListMode = true; @@ -681,69 +683,34 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) parent = parent->parent(); } // Parent is now top-level component - int key = components->key(parent); + int componentId = components->key(parent); - //ensure we have a placeholder map for this component - QMap *> changedValues = this->paramDataModel->getPendingParameters(); - if (!changedValues.contains(key)) { - changedValues.insert(key, new QMap()); - } + QString key = current->data(0, Qt::DisplayRole).toString(); + QVariant value = current->data(1, Qt::DisplayRole); + // Set parameter on changed list to be transmitted to MAV + QPalette pal = statusLabel->palette(); + pal.setColor(backgroundRole(), QGC::colorOrange); + statusLabel->setPalette(pal); + statusLabel->setText(tr("Transmit pend. %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); + //qDebug() << "PARAM CHANGED: COMP:" << key << "KEY:" << str << "VALUE:" << value; + // Changed values list - //insert the changed value into the map - QMap* map = changedValues.value(key, NULL); - if (map) { - QString str = current->data(0, Qt::DisplayRole).toString(); - QVariant value = current->data(1, Qt::DisplayRole); - // Set parameter on changed list to be transmitted to MAV - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorOrange); - statusLabel->setPalette(pal); - statusLabel->setText(tr("Transmit pend. %1:%2: %3").arg(key).arg(str).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); - //qDebug() << "PARAM CHANGED: COMP:" << key << "KEY:" << str << "VALUE:" << value; - // Changed values list - if (map->contains(str)) map->remove(str); - map->insert(str, value); - - // Check if the value was numerically changed - if (!onboardParameters.value(key)->contains(str) || onboardParameters.value(key)->value(str, value.toDouble()-1) != value) { - current->setBackground(0, QBrush(QColor(QGC::colorOrange))); - current->setBackground(1, QBrush(QColor(QGC::colorOrange))); - } + bool changed = paramDataModel->addPendingIfParameterChanged(componentId,key,value); - switch ((int)onboardParameters.value(key)->value(str).type()) - { - case QVariant::Int: - { - QVariant fixedValue(value.toInt()); - onboardParameters.value(key)->insert(str, fixedValue); - } - break; - case QVariant::UInt: - { - QVariant fixedValue(value.toUInt()); - onboardParameters.value(key)->insert(str, fixedValue); - } - break; - case QMetaType::Float: - { - QVariant fixedValue(value.toFloat()); - onboardParameters.value(key)->insert(str, fixedValue); - } - break; - case QMetaType::QChar: - { - QVariant fixedValue(QChar((unsigned char)value.toUInt())); - onboardParameters.value(key)->insert(str, fixedValue); - } - break; - default: - qCritical() << "ABORTED PARAM UPDATE, NO VALID QVARIANT TYPE"; - return; - } + // If the value was numerically changed, display it differently + if (changed) { + current->setBackground(0, QBrush(QColor(QGC::colorOrange))); + current->setBackground(1, QBrush(QColor(QGC::colorOrange))); + + //TODO this seems incorrect-- we're pre-updating the onboard value before we've received confirmation + paramDataModel->setOnboardParameterWithType(componentId,key,value); } + } } + + void QGCParamWidget::saveParametersToFile() { if (!mav) return; @@ -753,92 +720,12 @@ void QGCParamWidget::saveParametersToFile() return; } - QTextStream in(&file); - - in << "# Onboard parameters for system " << mav->getUASName() << "\n"; - in << "#\n"; - in << "# MAV ID COMPONENT ID PARAM NAME VALUE (FLOAT)\n"; - - // Iterate through all components, through all parameters and emit them - QMap*>::iterator i; - for (i = onboardParameters.begin(); i != onboardParameters.end(); ++i) { - // Iterate through the parameters of the component - int compid = i.key(); - QMap* comp = i.value(); - { - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) - { - QString paramValue("%1"); - QString paramType("%1"); - switch ((int)j.value().type()) - { - case QVariant::Int: - paramValue = paramValue.arg(j.value().toInt()); - paramType = paramType.arg(MAV_PARAM_TYPE_INT32); - break; - case QVariant::UInt: - paramValue = paramValue.arg(j.value().toUInt()); - paramType = paramType.arg(MAV_PARAM_TYPE_UINT32); - break; - case QMetaType::Float: - // We store parameters as floats, with only 6 digits of precision guaranteed for decimal string conversion - // (see IEEE 754, 32 bit single-precision) - paramValue = paramValue.arg((double)j.value().toFloat(), 25, 'g', 6); - paramType = paramType.arg(MAV_PARAM_TYPE_REAL32); - break; - default: - qCritical() << "ABORTED PARAM WRITE TO FILE, NO VALID QVARIANT TYPE" << j.value(); - return; - } - in << mav->getUASID() << "\t" << compid << "\t" << j.key() << "\t" << paramValue << "\t" << paramType << "\n"; - in.flush(); - } - } - } + QTextStream outstream(&file); + paramDataModel->writeOnboardParametersToStream(outstream,mav->getUASName()); file.close(); } -void QGCParamWidget::loadedParameterForComponent(int componentId, QStringList& wpParams ) -{ - // Set parameter value - - QMap *> changedValues = this->paramDataModel->getPendingParameters(); - - // Create changed values data structure if necessary - if (!changedValues.contains(componentId)) { - changedValues.insert(componentId, new QMap()); - } - - // Add to changed values - if (changedValues.value(componentId)->contains(wpParams.at(2))) { - changedValues.value(componentId)->remove(wpParams.at(2)); - } - - switch (wpParams.at(4).toUInt()) - { - case (int)MAV_PARAM_TYPE_REAL32: - //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toFloat()); - changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toFloat()); - setParameter(componentId, wpParams.at(2), wpParams.at(3).toFloat()); - break; - case (int)MAV_PARAM_TYPE_UINT32: - //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toUInt()); - changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toUInt()); - setParameter(componentId, wpParams.at(2), QVariant(wpParams.at(3).toUInt())); - break; - case (int)MAV_PARAM_TYPE_INT32: - //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, wpParams.at(2), wpParams.at(3).toInt()); - changedValues.value(componentId)->insert(wpParams.at(2), wpParams.at(3).toInt()); - setParameter(componentId, wpParams.at(2), QVariant(wpParams.at(3).toInt())); - break; - default: - qDebug() << "FAILED LOADING PARAM" << wpParams.at(2) << "NO KNOWN DATA TYPE"; - } - -} - void QGCParamWidget::loadParametersFromFile() { if (!mav) return; @@ -847,36 +734,8 @@ void QGCParamWidget::loadParametersFromFile() if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return; - bool userWarned = false; - QTextStream in(&file); - while (!in.atEnd()) { - QString line = in.readLine(); - if (!line.startsWith("#")) { - QStringList wpParams = line.split("\t"); - if (wpParams.size() == 5) { - // Only load parameters for right mav - if (!userWarned && (mav->getUASID() != wpParams.at(0).toInt())) { - MainWindow::instance()->showCriticalMessage(tr("Parameter loading warning"), tr("The parameters from the file %1 have been saved from system %2, but the currently selected system has the ID %3. If this is unintentional, please click on to revert to the parameters that are currently onboard").arg(fileName).arg(wpParams.at(0).toInt()).arg(mav->getUASID())); - userWarned = true; - } - - bool changed = false; - int componentId = wpParams.at(1).toInt(); - QString parameterName = wpParams.at(2); - if (!onboardParameters.contains(componentId) || - fabs((static_cast(onboardParameters.value(componentId)->value(parameterName, wpParams.at(3).toDouble()).toDouble())) - (wpParams.at(3).toDouble())) > 2.0f * FLT_EPSILON) { - changed = true; - qDebug() << "Changed" << parameterName << "VAL" << wpParams.at(3).toDouble(); - } - - if (changed) { - loadedParameterForComponent(componentId,wpParams); - } - - } - } - } + paramDataModel->readUpdateParametersFromStream(in); file.close(); } @@ -930,7 +789,8 @@ void QGCParamWidget::retransmissionGuardTick() // Re-request at maximum retransmissionBurstRequestSize parameters at once // to prevent link flooding QMap*>::iterator i; - for (i = onboardParameters.begin(); i != onboardParameters.end(); ++i) { + QMap*> onboardParams = paramDataModel->getOnboardParameters(); + for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { // Iterate through the parameters of the component int component = i.key(); // Request n parameters from this component (at maximum) @@ -961,7 +821,7 @@ void QGCParamWidget::retransmissionGuardTick() if (count < retransmissionBurstRequestSize) { // Re-request write operation QVariant value = missingParams->value(key); - switch ((int)onboardParameters.value(component)->value(key).type()) + switch ((int)onboardParams.value(component)->value(key).type()) { case QVariant::Int: { @@ -1015,23 +875,27 @@ void QGCParamWidget::requestParameterUpdate(int component, const QString& parame */ void QGCParamWidget::setParameter(int component, QString parameterName, QVariant value) { - if (paramMin.contains(parameterName) && value.toDouble() < paramMin.value(parameterName)) + double dblValue = value.toDouble(); + if (paramMin.contains(parameterName) && dblValue < paramMin.value(parameterName)) { - statusLabel->setText(tr("REJ. %1 < min").arg(value.toDouble())); + statusLabel->setText(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); return; } - if (paramMax.contains(parameterName) && value.toDouble() > paramMax.value(parameterName)) + if (paramMax.contains(parameterName) && dblValue > paramMax.value(parameterName)) { - statusLabel->setText(tr("REJ. %1 > max").arg(value.toDouble())); + statusLabel->setText(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); return; } - if (onboardParameters.value(component)->value(parameterName) == value) - { - statusLabel->setText(tr("REJ. %1 > max").arg(value.toDouble())); + QVariant onboardVal; + paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); + if (onboardVal == value) { + statusLabel->setText(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue)); return; } - switch ((int)onboardParameters.value(component)->value(parameterName).type()) + //int paramType = (int)onboardParameters.value(component)->value(parameterName).type(); + int paramType = (int)value.type(); + switch (paramType) { case QVariant::Char: { diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 5b48fffb22..0b810bc5bd 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -58,7 +58,7 @@ public: double getParamMax(const QString& param) { return paramMax.value(param, 0.0f); } double getParamDefault(const QString& param) { return paramDefault.value(param, 0.0f); } QString getParamInfo(const QString& param) { return paramToolTips.value(param, ""); } - void setParamInfo(const QMap& param) { paramToolTips = param; } + void setParamInfo(const QMap& paramInfo); signals: /** @brief A parameter was changed in the widget, NOT onboard */ @@ -96,8 +96,6 @@ public slots: /** @brief Load parameters from a file */ void loadParametersFromFile(); - void loadedParameterForComponent(int componentId, QStringList& wpParams ); - /** @brief Check for missing parameters */ void retransmissionGuardTick(); -- GitLab From d5d0563b70b5e99823b18ebc29f69cecdfb79bfd Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 07:54:25 -0700 Subject: [PATCH 218/460] fix debug str --- src/ui/QGCParamWidget.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 07c948457b..95b58eadd1 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -168,7 +168,7 @@ void QGCParamWidget::loadSettings() void QGCParamWidget::setParamInfo(const QMap& paramInfo) { if (paramInfo.isEmpty()) { - qDebug() << << __FILE__ << ":" << __LINE__ << "setParamInfo with empty"; + qDebug() << __FILE__ << ":" << __LINE__ << "setParamInfo with empty"; } paramToolTips = paramInfo; } -- GitLab From 79e103568162b23e8781eff61508412ec592d6db Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 08:05:47 -0700 Subject: [PATCH 219/460] ignoring UAS updates while slider has no param name --- src/ui/designer/QGCParamSlider.cc | 42 +++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/ui/designer/QGCParamSlider.cc b/src/ui/designer/QGCParamSlider.cc index edba2c78cd..6733c5790a 100644 --- a/src/ui/designer/QGCParamSlider.cc +++ b/src/ui/designer/QGCParamSlider.cc @@ -92,29 +92,29 @@ void QGCParamSlider::refreshParamList() void QGCParamSlider::setActiveUAS(UASInterface* activeUas) { - if (activeUas) - { - if (uas) - { - disconnect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant))); - } - - // Connect buttons and signals - connect(activeUas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant)), Qt::UniqueConnection); - uas = activeUas; - // Update current param value - //requestParameter(); + if (activeUas) { // Set param info - QString text = uas->getParamManager()->getParamInfo(parameterName); - if (text != "") - { - ui->infoLabel->setToolTip(text); - ui->infoLabel->show(); + if (!parameterName.isEmpty()) { + //disconnect from any existing uas signals + if (uas != activeUas) { + disconnect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant))); + connect(activeUas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant)), Qt::UniqueConnection); + uas = activeUas; + } + + QString text = uas->getParamManager()->getParamInfo(parameterName); + if (text != "") { + ui->infoLabel->setToolTip(text); + ui->infoLabel->show(); + } + // Force-uncheck and hide label if no description is available + if (ui->editInfoCheckBox->isChecked()) { + showInfo((text.length() > 0)); + } } - // Force-uncheck and hide label if no description is available - if (ui->editInfoCheckBox->isChecked()) - { - showInfo((text.length() > 0)); + else { + //when parameter widgets are first loaded, they are disconnected from any parameter? + qWarning() << __FILE__ << ":" << __LINE__ << "slider has no parameterName??"; } } } -- GitLab From 2eac0e2e58780faea8fcff1c945ef930d60a8ba4 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 08:45:59 -0700 Subject: [PATCH 220/460] Refactoring comms code --- src/uas/QGCUASParamManager.cc | 154 ++++++++++++++++ src/uas/QGCUASParamManager.h | 16 +- src/ui/QGCParamWidget.cc | 324 +++++++++++----------------------- src/ui/QGCParamWidget.h | 16 +- 4 files changed, 278 insertions(+), 232 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index ee42aa9684..2bbe1fb610 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -28,3 +28,157 @@ bool QGCUASParamManager::getParameterValue(int component, const QString& paramet return paramDataModel->getOnboardParameterValue(component,parameter,value); } + + + + +/** + * Send a request to deliver the list of onboard parameters + * to the MAV. + */ +void QGCUASParamManager::requestParameterList() +{ + if (!mav) { + return; + } + + paramDataModel->forgetAllOnboardParameters(); + received.clear(); + // Clear transmission state + transmissionListMode = true; + transmissionListSizeKnown.clear(); + foreach (int key, transmissionMissingPackets.keys()) + { + transmissionMissingPackets.value(key)->clear(); + } + transmissionActive = true; + + setParameterStatusMsg(tr("Requested param list.. waiting")); + mav->requestParameters(); + +} + + +/** + * Enabling the retransmission guard enables the parameter widget to track + * dropped parameters and to re-request them. This works for both individual + * parameter reads as well for whole list requests. + * + * @param enabled True if retransmission checking should be enabled, false else + */ +void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) +{ + if (enabled) { + retransmissionTimer.start(retransmissionTimeout); + } else { + retransmissionTimer.stop(); + } +} + +void QGCUASParamManager::setParameterStatusMsg(const QString& msg) +{ + parameterStatusMsg = msg; +} + +void QGCUASParamManager::retransmissionGuardTick() +{ + if (transmissionActive) { + //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; + + // Check for timeout + // stop retransmission attempts on timeout + if (QGC::groundTimeMilliseconds() > transmissionTimeout) { + setRetransmissionGuardEnabled(false); + transmissionActive = false; + + // Empty read retransmission list + // Empty write retransmission list + int missingReadCount = 0; + QList readKeys = transmissionMissingPackets.keys(); + foreach (int component, readKeys) { + missingReadCount += transmissionMissingPackets.value(component)->count(); + transmissionMissingPackets.value(component)->clear(); + } + + // Empty write retransmission list + int missingWriteCount = 0; + QList writeKeys = transmissionMissingWriteAckPackets.keys(); + foreach (int component, writeKeys) { + missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); + transmissionMissingWriteAckPackets.value(component)->clear(); + } + setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); + } + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent link flooding + QMap*>::iterator i; + QMap*> onboardParams = paramDataModel->getOnboardParameters(); + for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { + // Iterate through the parameters of the component + int component = i.key(); + // Request n parameters from this component (at maximum) + QList * paramList = transmissionMissingPackets.value(component, NULL); + if (paramList) { + int count = 0; + foreach (int id, *paramList) { + if (count < retransmissionBurstRequestSize) { + //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; + //TODO mavlink msg type for "request parameter set" ? + emit requestParameter(component, id); + setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); + count++; + } else { + break; + } + } + } + } + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent write-request link flooding + // Empty write retransmission list + QList writeKeys = transmissionMissingWriteAckPackets.keys(); + foreach (int component, writeKeys) { + int count = 0; + QMap * missingParams = transmissionMissingWriteAckPackets.value(component); + foreach (QString key, missingParams->keys()) { + if (count < retransmissionBurstRequestSize) { + // Re-request write operation + QVariant value = missingParams->value(key); + switch ((int)onboardParams.value(component)->value(key).type()) + { + case QVariant::Int: + { + QVariant fixedValue(value.toInt()); + emit parameterChanged(component, key, fixedValue); + } + break; + case QVariant::UInt: + { + QVariant fixedValue(value.toUInt()); + emit parameterChanged(component, key, fixedValue); + } + break; + case QMetaType::Float: + { + QVariant fixedValue(value.toFloat()); + emit parameterChanged(component, key, fixedValue); + } + break; + default: + //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; + return; + } + setParameterStatusMsg(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); + count++; + } else { + break; + } + } + } + } else { + //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; + setRetransmissionGuardEnabled(false); + } +} diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 7f970ef6dc..c6351a6c38 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -31,16 +31,29 @@ public: /** @brief Request an update for this specific parameter */ virtual void requestParameterUpdate(int component, const QString& parameter) = 0; +protected: + /** @brief Check for missing parameters */ + virtual void retransmissionGuardTick(); + /** @brief Activate / deactivate parameter retransmission */ + virtual void setRetransmissionGuardEnabled(bool enabled); + + //TODO decouple this UI message display further + virtual void setParameterStatusMsg(const QString& msg); + signals: void parameterChanged(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); void parameterListUpToDate(int component); + /** @brief Request a single parameter */ + void requestParameter(int component, int parameter); + /** @brief Request a single parameter by name */ + void requestParameter(int component, const QString& parameter); public slots: /** @brief Write one parameter to the MAV */ virtual void setParameter(int component, QString parameterName, QVariant value) = 0; /** @brief Request list of parameters from MAV */ - virtual void requestParameterList() = 0; + virtual void requestParameterList(); protected: @@ -60,6 +73,7 @@ protected: int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds int rewriteTimeout; ///< Write request timeout, in milliseconds int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst + QString parameterStatusMsg; }; diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 95b58eadd1..40fc49195a 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -87,7 +87,7 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QPushButton* refreshButton = new QPushButton(tr("Get")); refreshButton->setToolTip(tr("Load parameters currently in non-permanent memory of aircraft.")); refreshButton->setWhatsThis(tr("Load parameters currently in non-permanent memory of aircraft.")); - connect(refreshButton, SIGNAL(clicked()), this, SLOT(requestParameterList())); + connect(refreshButton, SIGNAL(clicked()), this, SLOT(requestParameterListUpdate())); horizontalLayout->addWidget(refreshButton, 2, 0); QPushButton* setButton = new QPushButton(tr("Set")); @@ -150,9 +150,12 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); // Get parameters - if (uas) requestParameterList(); + if (uas) { + requestParameterListUpdate(); + } } + void QGCParamWidget::loadSettings() { QSettings settings; @@ -642,38 +645,7 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString par } -/** - * Send a request to deliver the list of onboard parameters - * to the MAV. - */ -void QGCParamWidget::requestParameterList() -{ - if (!mav) return; - // FIXME This call does not belong here - // Once the comm handling is moved to a new - // Param manager class the settings can be directly - // loaded from MAVLink protocol - loadSettings(); - // End of FIXME - - // Clear view and request param list - clear(); - paramDataModel->forgetAllOnboardParameters(); - received.clear(); - // Clear transmission state - transmissionListMode = true; - transmissionListSizeKnown.clear(); - foreach (int key, transmissionMissingPackets.keys()) - { - transmissionMissingPackets.value(key)->clear(); - } - transmissionActive = true; - - // Set status text - statusLabel->setText(tr("Requested param list.. waiting")); - mav->requestParameters(); -} void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) { @@ -740,133 +712,122 @@ void QGCParamWidget::loadParametersFromFile() } -/** - * Enabling the retransmission guard enables the parameter widget to track - * dropped parameters and to re-request them. This works for both individual - * parameter reads as well for whole list requests. - * - * @param enabled True if retransmission checking should be enabled, false else - */ -void QGCParamWidget::setRetransmissionGuardEnabled(bool enabled) +void QGCParamWidget::setParameterStatusMsg(const QString& msg) { - if (enabled) { - retransmissionTimer.start(retransmissionTimeout); - } else { - retransmissionTimer.stop(); + statusLabel->setText(msg); +} + + + +void QGCParamWidget::requestParameterListUpdate() +{ + if (!mav) { + return; } + + // FIXME This call does not belong here + // Once the comm handling is moved to a new + // Param manager class the settings can be directly + // loaded from MAVLink protocol + loadSettings(); + // End of FIXME + + // Clear view and request param list + clear(); + + requestParameterList(); } -void QGCParamWidget::retransmissionGuardTick() +/** + * The .. signal is emitted + */ +void QGCParamWidget::requestParameterUpdate(int component, const QString& parameter) { - if (transmissionActive) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; - - // Check for timeout - // stop retransmission attempts on timeout - if (QGC::groundTimeMilliseconds() > transmissionTimeout) { - setRetransmissionGuardEnabled(false); - transmissionActive = false; - - // Empty read retransmission list - // Empty write retransmission list - int missingReadCount = 0; - QList readKeys = transmissionMissingPackets.keys(); - foreach (int component, readKeys) { - missingReadCount += transmissionMissingPackets.value(component)->count(); - transmissionMissingPackets.value(component)->clear(); - } + if (mav) mav->requestParameter(component, parameter); +} - // Empty write retransmission list - int missingWriteCount = 0; - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); - transmissionMissingWriteAckPackets.value(component)->clear(); - } - statusLabel->setText(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); - } - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent link flooding - QMap*>::iterator i; - QMap*> onboardParams = paramDataModel->getOnboardParameters(); - for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { - // Iterate through the parameters of the component - int component = i.key(); - // Request n parameters from this component (at maximum) - QList * paramList = transmissionMissingPackets.value(component, NULL); - if (paramList) { - int count = 0; - foreach (int id, *paramList) { - if (count < retransmissionBurstRequestSize) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; - emit requestParameter(component, id); - statusLabel->setText(tr("Requested retransmission of #%1").arg(id+1)); - count++; - } else { - break; - } - } + +/** + * Set all parameter in the parameter tree on the MAV + */ +void QGCParamWidget::setParameters() +{ + // Iterate through all components, through all parameters and emit them + int parametersSent = 0; + QMap*> changedValues = paramDataModel->getPendingParameters(); + QMap*>::iterator i; + for (i = changedValues.begin(); i != changedValues.end(); ++i) { + // Iterate through the parameters of the component + int compid = i.key(); + QMap* comp = i.value(); + { + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) { + setParameter(compid, j.key(), j.value()); + parametersSent++; } } + } - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent write-request link flooding - // Empty write retransmission list - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - int count = 0; - QMap * missingParams = transmissionMissingWriteAckPackets.value(component); - foreach (QString key, missingParams->keys()) { - if (count < retransmissionBurstRequestSize) { - // Re-request write operation - QVariant value = missingParams->value(key); - switch ((int)onboardParams.value(component)->value(key).type()) - { - case QVariant::Int: - { - QVariant fixedValue(value.toInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QVariant::UInt: - { - QVariant fixedValue(value.toUInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QMetaType::Float: - { - QVariant fixedValue(value.toFloat()); - emit parameterChanged(component, key, fixedValue); - } - break; - default: - //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; - return; - } - statusLabel->setText(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); - count++; - } else { - break; - } + // Change transmission status if necessary + if (parametersSent == 0) { + statusLabel->setText(tr("No transmission: No changed values.")); + } else { + statusLabel->setText(tr("Transmitting %1 parameters.").arg(parametersSent)); + // Set timeouts + if (transmissionActive) + { + transmissionTimeout += parametersSent*rewriteTimeout; + } + else + { + transmissionActive = true; + quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + parametersSent*rewriteTimeout; + if (newTransmissionTimeout > transmissionTimeout) { + transmissionTimeout = newTransmissionTimeout; } } - } else { - //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; - setRetransmissionGuardEnabled(false); + // Enable guard + setRetransmissionGuardEnabled(true); } } - /** - * The .. signal is emitted + * Write the current onboard parameters from RAM into + * permanent storage, e.g. EEPROM or harddisk */ -void QGCParamWidget::requestParameterUpdate(int component, const QString& parameter) +void QGCParamWidget::writeParameters() { - if (mav) mav->requestParameter(component, parameter); -} + int changedParamCount = 0; + + QMap*>::iterator i; + QMap*> changedValues = paramDataModel->getPendingParameters(); + + for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) + { + // Iterate through the parameters of the component + QMap* comp = i.value(); + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) + { + changedParamCount++; + break;//it only takes one changed param to warrant warning the user + } + } + if (changedParamCount > 0) + { + QMessageBox msgBox; + msgBox.setText(tr("There are locally changed parameters. Please transmit them first () or update them with the onboard values () before storing onboard from RAM to ROM.")); + msgBox.exec(); + } + else + { + if (!mav) return; + mav->writeParametersToStorage(); + } +} /** * @param component the subsystem which has the parameter @@ -959,87 +920,6 @@ void QGCParamWidget::setParameter(int component, QString parameterName, QVariant setRetransmissionGuardEnabled(true); } -/** - * Set all parameter in the parameter tree on the MAV - */ -void QGCParamWidget::setParameters() -{ - // Iterate through all components, through all parameters and emit them - int parametersSent = 0; - QMap*> changedValues = paramDataModel->getPendingParameters(); - QMap*>::iterator i; - for (i = changedValues.begin(); i != changedValues.end(); ++i) { - // Iterate through the parameters of the component - int compid = i.key(); - QMap* comp = i.value(); - { - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) { - setParameter(compid, j.key(), j.value()); - parametersSent++; - } - } - } - - // Change transmission status if necessary - if (parametersSent == 0) { - statusLabel->setText(tr("No transmission: No changed values.")); - } else { - statusLabel->setText(tr("Transmitting %1 parameters.").arg(parametersSent)); - // Set timeouts - if (transmissionActive) - { - transmissionTimeout += parametersSent*rewriteTimeout; - } - else - { - transmissionActive = true; - quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + parametersSent*rewriteTimeout; - if (newTransmissionTimeout > transmissionTimeout) { - transmissionTimeout = newTransmissionTimeout; - } - } - // Enable guard - setRetransmissionGuardEnabled(true); - } -} - -/** - * Write the current onboard parameters from RAM into - * permanent storage, e.g. EEPROM or harddisk - */ -void QGCParamWidget::writeParameters() -{ - int changedParamCount = 0; - - QMap*>::iterator i; - QMap*> changedValues = paramDataModel->getPendingParameters(); - - for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) - { - // Iterate through the parameters of the component - QMap* comp = i.value(); - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) - { - changedParamCount++; - break;//it only takes one changed param to warrant warning the user - } - } - - if (changedParamCount > 0) - { - QMessageBox msgBox; - msgBox.setText(tr("There are locally changed parameters. Please transmit them first () or update them with the onboard values () before storing onboard from RAM to ROM.")); - msgBox.exec(); - } - else - { - if (!mav) return; - mav->writeParametersToStorage(); - } -} - void QGCParamWidget::readParameters() { if (!mav) return; diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 0b810bc5bd..c49f5a55cb 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -60,13 +60,13 @@ public: QString getParamInfo(const QString& param) { return paramToolTips.value(param, ""); } void setParamInfo(const QMap& paramInfo); +protected: + virtual void setParameterStatusMsg(const QString& msg); + signals: /** @brief A parameter was changed in the widget, NOT onboard */ //void parameterChanged(int component, QString parametername, float value); // defined in QGCUASParamManager already - /** @brief Request a single parameter */ - void requestParameter(int component, int parameter); - /** @brief Request a single parameter by name */ - void requestParameter(int component, const QString& parameter); + public slots: /** @brief Add a component to the list */ void addComponent(int uas, int component, QString componentName); @@ -75,7 +75,7 @@ public slots: /** @brief Add a parameter to the list */ void receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ - void requestParameterList(); + void requestParameterListUpdate(); /** @brief Request one single parameter */ void requestParameterUpdate(int component, const QString& parameter); /** @brief Set one parameter, changes value in RAM of MAV */ @@ -96,8 +96,7 @@ public slots: /** @brief Load parameters from a file */ void loadParametersFromFile(); - /** @brief Check for missing parameters */ - void retransmissionGuardTick(); + protected: QTreeWidget* tree; ///< The parameter tree @@ -112,8 +111,7 @@ protected: QMap paramDefault; ///< Default param values QMap paramMax; ///< Minimum param values - /** @brief Activate / deactivate parameter retransmission */ - void setRetransmissionGuardEnabled(bool enabled); + /** @brief Load settings */ void loadSettings(); /** @brief Load meta information from CSV */ -- GitLab From 6157344e1b2d31b8a0b674bfedd9a60510062561 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 08:54:27 -0700 Subject: [PATCH 221/460] more comms refactoring --- src/uas/QGCUASParamManager.cc | 6 ++++-- src/uas/QGCUASParamManager.h | 2 +- src/ui/QGCParamWidget.cc | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 2bbe1fb610..af62e3916e 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -43,10 +43,12 @@ void QGCUASParamManager::requestParameterList() } paramDataModel->forgetAllOnboardParameters(); - received.clear(); + // Clear transmission state - transmissionListMode = true; + receivedParamsList.clear(); transmissionListSizeKnown.clear(); + + transmissionListMode = true; foreach (int key, transmissionMissingPackets.keys()) { transmissionMissingPackets.value(key)->clear(); diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index c6351a6c38..f16be9f7b2 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -62,7 +62,7 @@ protected: UASParameterDataModel* paramDataModel;///< Shared data model of parameters // Communications management - QVector received; ///< Successfully received parameters + QVector receivedParamsList; ///< Successfully received parameters QMap* > transmissionMissingPackets; ///< Missing packets QMap* > transmissionMissingWriteAckPackets; ///< Missing write ACK packets bool transmissionListMode; ///< Currently requesting list diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 40fc49195a..1cb641fdde 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -764,6 +764,7 @@ void QGCParamWidget::setParameters() { QMap::iterator j; for (j = comp->begin(); j != comp->end(); ++j) { + //TODO mavlink command for "set parameter list" ? setParameter(compid, j.key(), j.value()); parametersSent++; } -- GitLab From 31855837729e41124f00f717e0ac88a072c4e372 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 10:25:33 -0700 Subject: [PATCH 222/460] move parameter meta info into param data model --- src/uas/QGCUASParamManager.cc | 8 +- src/uas/QGCUASParamManager.h | 12 +-- src/uas/UASParameterDataModel.cc | 144 ++++++++++++++++++++++++++++- src/uas/UASParameterDataModel.h | 29 +++++- src/ui/QGCPX4VehicleConfig.cc | 4 +- src/ui/QGCParamWidget.cc | 146 ++++-------------------------- src/ui/QGCParamWidget.h | 17 +--- src/ui/QGCVehicleConfig.cc | 4 +- src/ui/designer/QGCComboBox.cc | 31 +++---- src/ui/designer/QGCParamSlider.cc | 30 ++---- 10 files changed, 225 insertions(+), 200 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index af62e3916e..06774ec25d 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -11,8 +11,8 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : rewriteTimeout(500), retransmissionBurstRequestSize(5) { - uas->setParamManager(this); paramDataModel = uas->getParamDataModel(); + uas->setParamManager(this); } @@ -82,6 +82,12 @@ void QGCUASParamManager::setParameterStatusMsg(const QString& msg) parameterStatusMsg = msg; } +void QGCUASParamManager::setParamDescriptions(const QMap& paramInfo) { + paramDataModel->setParamDescriptions(paramInfo); +} + + + void QGCUASParamManager::retransmissionGuardTick() { if (transmissionActive) { diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index f16be9f7b2..2a0165959a 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -17,20 +17,14 @@ public: virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; - virtual bool isParamMinKnown(const QString& param) = 0; - virtual bool isParamMaxKnown(const QString& param) = 0; - virtual bool isParamDefaultKnown(const QString& param) = 0; - virtual double getParamMin(const QString& param) = 0; - virtual double getParamMax(const QString& param) = 0; - virtual double getParamDefault(const QString& param) = 0; - virtual QString getParamInfo(const QString& param) = 0; - virtual void setParamInfo(const QMap& param) = 0; - /** @brief Request an update for the parameter list */ void requestParameterListUpdate(int component = 0); /** @brief Request an update for this specific parameter */ virtual void requestParameterUpdate(int component, const QString& parameter) = 0; + /** @brief Provide tooltips / user-visible descriptions for parameters */ + virtual void setParamDescriptions(const QMap& paramDescs); + protected: /** @brief Check for missing parameters */ virtual void retransmissionGuardTick(); diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 3269efd185..d678385dcf 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -152,7 +152,7 @@ void UASParameterDataModel::forgetAllOnboardParameters() onboardParameters.clear(); } -void UASParameterDataModel::readUpdateParametersFromStream(QTextStream& stream) +void UASParameterDataModel::readUpdateParametersFromStream( QTextStream& stream) { bool userWarned = false; @@ -228,7 +228,7 @@ void UASParameterDataModel::readUpdateParametersFromStream(QTextStream& stream) } -void UASParameterDataModel::writeOnboardParametersToStream(QTextStream& stream, const QString& name) +void UASParameterDataModel::writeOnboardParametersToStream( QTextStream &stream, const QString& name) { stream << "# Onboard parameters for system " << name << "\n"; stream << "#\n"; @@ -272,3 +272,143 @@ void UASParameterDataModel::writeOnboardParametersToStream(QTextStream& stream, } } } + + +void UASParameterDataModel::loadParamMetaInfoFromStream(QTextStream& stream) +{ + + // First line is header + // there might be more lines, but the first + // line is assumed to be at least header + QString header = stream.readLine(); + + // Ignore top-level comment lines + while (header.startsWith('#') || header.startsWith('/') + || header.startsWith('=') || header.startsWith('^')) + { + header = stream.readLine(); + } + + bool charRead = false; + QString separator = ""; + QList sepCandidates; + sepCandidates << '\t'; + sepCandidates << ','; + sepCandidates << ';'; + //sepCandidates << ' '; + sepCandidates << '~'; + sepCandidates << '|'; + + // Iterate until separator is found + // or full header is parsed + for (int i = 0; i < header.length(); i++) + { + if (sepCandidates.contains(header.at(i))) + { + // Separator found + if (charRead) + { + separator += header[i]; + } + } + else + { + // Char found + charRead = true; + // If the separator is not empty, this char + // has been read after a separator, so detection + // is now complete + if (separator != "") break; + } + } + + bool stripFirstSeparator = false; + bool stripLastSeparator = false; + + // Figure out if the lines start with the separator (e.g. wiki syntax) + if (header.startsWith(separator)) stripFirstSeparator = true; + + // Figure out if the lines end with the separator (e.g. wiki syntax) + if (header.endsWith(separator)) stripLastSeparator = true; + + QString out = separator; + out.replace("\t", ""); + //qDebug() << " Separator: \"" << out << "\""; + //qDebug() << "READING CSV:" << header; + + + // Read data + while (!stream.atEnd()) + { + QString line = stream.readLine(); + + //qDebug() << "LINE PRE-STRIP" << line; + + // Strip separtors if necessary + if (stripFirstSeparator) line.remove(0, separator.length()); + if (stripLastSeparator) line.remove(line.length()-separator.length(), line.length()-1); + + //qDebug() << "LINE POST-STRIP" << line; + + // Keep empty parts here - we still have to act on them + QStringList parts = line.split(separator, QString::KeepEmptyParts); + + // Each line is: + // variable name, Min, Max, Default, Multiplier, Enabled (0 = no, 1 = yes), Comment + + + // Fill in min, max and default values + if (parts.count() > 1) + { + // min + paramMin.insert(parts.at(0).trimmed(), parts.at(1).toDouble()); + } + if (parts.count() > 2) + { + // max + paramMax.insert(parts.at(0).trimmed(), parts.at(2).toDouble()); + } + if (parts.count() > 3) + { + // default + paramDefault.insert(parts.at(0).trimmed(), parts.at(3).toDouble()); + } + // IGNORING 4 and 5 for now + if (parts.count() > 6) + { + // tooltip + paramDescriptions.insert(parts.at(0).trimmed(), parts.at(6).trimmed()); + qDebug() << "PARAM META:" << parts.at(0).trimmed(); + } + } +} + + void UASParameterDataModel::setParamDescriptions(const QMap& paramInfo) +{ + if (paramInfo.isEmpty()) { + qDebug() << __FILE__ << ":" << __LINE__ << "setParamDescriptions with empty"; + } + + paramDescriptions = paramInfo; +} + +bool UASParameterDataModel::isValueGreaterThanParamMax(const QString& paramName, double dblVal) +{ + if (paramMax.contains(paramName)) { + if (dblVal > paramMax.value(paramName)) + return true; + } + + return false; +} + +bool UASParameterDataModel::isValueLessThanParamMin(const QString& paramName, double dblVal) +{ + if (paramMin.contains(paramName)) { + if (dblVal < paramMin.value(paramName)) + return true; + } + + return false; + } + diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index e38e06c8c4..0f89ed4365 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -14,6 +14,21 @@ public: explicit UASParameterDataModel(QObject *parent = 0); + //Parameter meta info + bool isParamMinKnown(const QString& param) { return paramMin.contains(param); } + virtual bool isValueLessThanParamMin(const QString& param, double dblVal); + + bool isParamMaxKnown(const QString& param) { return paramMax.contains(param); } + virtual bool isValueGreaterThanParamMax(const QString& param, double dblVal); + + bool isParamDefaultKnown(const QString& param) { return paramDefault.contains(param); } + double getParamMin(const QString& param) { return paramMin.value(param, 0.0f); } + double getParamMax(const QString& param) { return paramMax.value(param, 0.0f); } + double getParamDefault(const QString& param) { return paramDefault.value(param, 0.0f); } + virtual QString getParamDescription(const QString& param) { return paramDescriptions.value(param, ""); } + virtual void setParamDescriptions(const QMap& paramInfo); + + virtual void addComponent(int componentId); /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ @@ -59,8 +74,10 @@ public: } - virtual void writeOnboardParametersToStream(QTextStream& stream, const QString& uasName); - virtual void readUpdateParametersFromStream(QTextStream& stream); + virtual void writeOnboardParametersToStream(QTextStream &stream, const QString& uasName); + virtual void readUpdateParametersFromStream(QTextStream &stream); + + virtual void loadParamMetaInfoFromStream(QTextStream& stream); void setUASID(int anId) { this->uasId = anId; } @@ -74,6 +91,14 @@ protected: QMap* > pendingParameters; ///< Changed values that have not yet been transmitted to the UAS, by component ID QMap* > onboardParameters; ///< All parameters confirmed to be stored onboard the UAS, by component ID + // Tooltip data structures + QMap paramDescriptions; ///< Tooltip values + + // Min / Default / Max data structures + QMap paramMin; ///< Minimum param values + QMap paramDefault; ///< Default param values + QMap paramMax; ///< Minimum param values + }; diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 3ea93d914b..f43f20a881 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -793,7 +793,7 @@ void QGCPX4VehicleConfig::loadConfig() xml.readNext(); } - mav->getParamManager()->setParamInfo(paramTooltips); + mav->getParamManager()->setParamDescriptions(paramTooltips); doneLoadingConfig = true; mav->requestParameters(); //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. } @@ -892,7 +892,7 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) if (!paramTooltips.isEmpty()) { - mav->getParamManager()->setParamInfo(paramTooltips); + mav->getParamManager()->setParamDescriptions(paramTooltips); } qDebug() << "CALIBRATION!! System Type Name:" << mav->getSystemTypeName(); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 1cb641fdde..7b6f333011 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -55,9 +55,9 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : loadSettings(); // Load default values and tooltips - QString hey(uas->getAutopilotTypeName()); - QString hey2(uas->getSystemTypeName()); - loadParameterInfoCSV(hey, hey2); + QString autoPilotName(uas->getAutopilotTypeName()); + QString sysTypeName(uas->getSystemTypeName()); + loadParamMetaInfoCSV(autoPilotName, sysTypeName); // Create tree widget tree = new QTreeWidget(this); @@ -169,15 +169,9 @@ void QGCParamWidget::loadSettings() } -void QGCParamWidget::setParamInfo(const QMap& paramInfo) { - if (paramInfo.isEmpty()) { - qDebug() << __FILE__ << ":" << __LINE__ << "setParamInfo with empty"; - } - paramToolTips = paramInfo; -} -void QGCParamWidget::loadParameterInfoCSV(const QString& autopilot, const QString& airframe) +void QGCParamWidget::loadParamMetaInfoCSV(const QString& autopilot, const QString& airframe) { Q_UNUSED(airframe); @@ -198,116 +192,11 @@ void QGCParamWidget::loadParameterInfoCSV(const QString& autopilot, const QStrin return; } - // Extract header - // Read in values - // Find all keys QTextStream in(¶mMetaFile); + paramDataModel->loadParamMetaInfoFromStream(in); + paramMetaFile.close(); - // First line is header - // there might be more lines, but the first - // line is assumed to be at least header - QString header = in.readLine(); - - // Ignore top-level comment lines - while (header.startsWith('#') || header.startsWith('/') - || header.startsWith('=') || header.startsWith('^')) - { - header = in.readLine(); - } - - bool charRead = false; - QString separator = ""; - QList sepCandidates; - sepCandidates << '\t'; - sepCandidates << ','; - sepCandidates << ';'; - //sepCandidates << ' '; - sepCandidates << '~'; - sepCandidates << '|'; - - // Iterate until separator is found - // or full header is parsed - for (int i = 0; i < header.length(); i++) - { - if (sepCandidates.contains(header.at(i))) - { - // Separator found - if (charRead) - { - separator += header[i]; - } - } - else - { - // Char found - charRead = true; - // If the separator is not empty, this char - // has been read after a separator, so detection - // is now complete - if (separator != "") break; - } - } - - bool stripFirstSeparator = false; - bool stripLastSeparator = false; - - // Figure out if the lines start with the separator (e.g. wiki syntax) - if (header.startsWith(separator)) stripFirstSeparator = true; - - // Figure out if the lines end with the separator (e.g. wiki syntax) - if (header.endsWith(separator)) stripLastSeparator = true; - - QString out = separator; - out.replace("\t", ""); - //qDebug() << " Separator: \"" << out << "\""; - //qDebug() << "READING CSV:" << header; - - - // Read data - while (!in.atEnd()) - { - QString line = in.readLine(); - - //qDebug() << "LINE PRE-STRIP" << line; - - // Strip separtors if necessary - if (stripFirstSeparator) line.remove(0, separator.length()); - if (stripLastSeparator) line.remove(line.length()-separator.length(), line.length()-1); - - //qDebug() << "LINE POST-STRIP" << line; - - // Keep empty parts here - we still have to act on them - QStringList parts = line.split(separator, QString::KeepEmptyParts); - - // Each line is: - // variable name, Min, Max, Default, Multiplier, Enabled (0 = no, 1 = yes), Comment - - - // Fill in min, max and default values - if (parts.count() > 1) - { - // min - paramMin.insert(parts.at(0).trimmed(), parts.at(1).toDouble()); - } - if (parts.count() > 2) - { - // max - paramMax.insert(parts.at(0).trimmed(), parts.at(2).toDouble()); - } - if (parts.count() > 3) - { - // default - paramDefault.insert(parts.at(0).trimmed(), parts.at(3).toDouble()); - } - // IGNORING 4 and 5 for now - if (parts.count() > 6) - { - // tooltip - paramToolTips.insert(parts.at(0).trimmed(), parts.at(6).trimmed()); - qDebug() << "PARAM META:" << parts.at(0).trimmed(); - } - } } /** @@ -628,15 +517,15 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString par parameterItem->setBackground(0, Qt::NoBrush); parameterItem->setBackground(1, Qt::NoBrush); // Add tooltip + QString paramDesc = paramDataModel->getParamDescription(parameterName); QString tooltipFormat; - if (paramDefault.contains(parameterName)) - { + if (paramDataModel->isParamDefaultKnown(parameterName)) { tooltipFormat = tr("Default: %1, %2"); - tooltipFormat = tooltipFormat.arg(paramDefault.value(parameterName, 0.0f)).arg(paramToolTips.value(parameterName, "")); + double paramDefValue = paramDataModel->getParamDefault(parameterName); + tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc); } - else - { - tooltipFormat = paramToolTips.value(parameterName, ""); + else { + tooltipFormat = paramDesc; } parameterItem->setToolTip(0, tooltipFormat); parameterItem->setToolTip(1, tooltipFormat); @@ -837,14 +726,17 @@ void QGCParamWidget::writeParameters() */ void QGCParamWidget::setParameter(int component, QString parameterName, QVariant value) { + if (parameterName.isEmpty()) { + return; + } + double dblValue = value.toDouble(); - if (paramMin.contains(parameterName) && dblValue < paramMin.value(parameterName)) - { + + if (paramDataModel->isValueLessThanParamMin(parameterName,dblValue)) { statusLabel->setText(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); return; } - if (paramMax.contains(parameterName) && dblValue > paramMax.value(parameterName)) - { + if (paramDataModel->isValueGreaterThanParamMax(parameterName,dblValue)) { statusLabel->setText(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); return; } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index c49f5a55cb..9b34813b06 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -51,14 +51,6 @@ public: /** @brief Get the UAS of this widget */ UASInterface* getUAS(); - bool isParamMinKnown(const QString& param) { return paramMin.contains(param); } - bool isParamMaxKnown(const QString& param) { return paramMax.contains(param); } - bool isParamDefaultKnown(const QString& param) { return paramDefault.contains(param); } - double getParamMin(const QString& param) { return paramMin.value(param, 0.0f); } - double getParamMax(const QString& param) { return paramMax.value(param, 0.0f); } - double getParamDefault(const QString& param) { return paramDefault.value(param, 0.0f); } - QString getParamInfo(const QString& param) { return paramToolTips.value(param, ""); } - void setParamInfo(const QMap& paramInfo); protected: virtual void setParameterStatusMsg(const QString& msg); @@ -104,18 +96,13 @@ protected: QMap* components; ///< The list of components QMap* > paramGroups; ///< Parameter groups - // Tooltip data structures - QMap paramToolTips; ///< Tooltip values - // Min / Default / Max data structures - QMap paramMin; ///< Minimum param values - QMap paramDefault; ///< Default param values - QMap paramMax; ///< Minimum param values + /** @brief Load settings */ void loadSettings(); /** @brief Load meta information from CSV */ - void loadParameterInfoCSV(const QString& autopilot, const QString& airframe); + void loadParamMetaInfoCSV(const QString& autopilot, const QString& airframe); }; #endif // QGCPARAMWIDGET_H diff --git a/src/ui/QGCVehicleConfig.cc b/src/ui/QGCVehicleConfig.cc index d94076dbd4..dd2c769a7a 100644 --- a/src/ui/QGCVehicleConfig.cc +++ b/src/ui/QGCVehicleConfig.cc @@ -786,7 +786,7 @@ void QGCVehicleConfig::loadConfig() xml.readNext(); } - mav->getParamManager()->setParamInfo(paramTooltips); + mav->getParamManager()->setParamDescriptions(paramTooltips); doneLoadingConfig = true; mav->requestParameters(); //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. } @@ -888,7 +888,7 @@ void QGCVehicleConfig::setActiveUAS(UASInterface* active) if (!paramTooltips.isEmpty()) { - mav->getParamManager()->setParamInfo(paramTooltips); + mav->getParamManager()->setParamDescriptions(paramTooltips); } qDebug() << "CALIBRATION!! System Type Name:" << mav->getSystemTypeName(); diff --git a/src/ui/designer/QGCComboBox.cc b/src/ui/designer/QGCComboBox.cc index 21d86f6795..91f9dfc21b 100644 --- a/src/ui/designer/QGCComboBox.cc +++ b/src/ui/designer/QGCComboBox.cc @@ -108,15 +108,14 @@ void QGCComboBox::setActiveUAS(UASInterface* activeUas) // Update current param value //requestParameter(); // Set param info - QString text = uas->getParamManager()->getParamInfo(parameterName); - if (text != "") - { + + QString text = uas->getParamDataModel()->getParamDescription(parameterName); + if (!text.isEmpty()) { ui->infoLabel->setToolTip(text); ui->infoLabel->show(); } // Force-uncheck and hide label if no description is available - if (ui->editInfoCheckBox->isChecked()) - { + if (ui->editInfoCheckBox->isChecked()) { showInfo((text.length() > 0)); } } @@ -147,27 +146,21 @@ void QGCComboBox::selectParameter(int paramIndex) parameterName = ui->editSelectParamComboBox->itemText(paramIndex); // Update min and max values if available - if (uas) - { - if (uas->getParamManager()) - { - // Current value - //uas->getParamManager()->requestParameterUpdate(component, parameterName); - + if (uas) { + UASParameterDataModel* dataModel = uas->getParamDataModel(); + if (dataModel) { // Minimum - if (uas->getParamManager()->isParamMinKnown(parameterName)) - { - parameterMin = uas->getParamManager()->getParamMin(parameterName); + if (dataModel->isParamMinKnown(parameterName)) { + parameterMin = dataModel->getParamMin(parameterName); } // Maximum - if (uas->getParamManager()->isParamMaxKnown(parameterName)) - { - parameterMax = uas->getParamManager()->getParamMax(parameterName); + if (dataModel->isParamMaxKnown(parameterName)) { + parameterMax = dataModel->getParamMax(parameterName); } // Description - QString text = uas->getParamManager()->getParamInfo(parameterName); + QString text = dataModel->getParamDescription(parameterName); //ui->infoLabel->setText(text); showInfo(!(text.length() > 0)); } diff --git a/src/ui/designer/QGCParamSlider.cc b/src/ui/designer/QGCParamSlider.cc index 6733c5790a..7f76759424 100644 --- a/src/ui/designer/QGCParamSlider.cc +++ b/src/ui/designer/QGCParamSlider.cc @@ -102,8 +102,8 @@ void QGCParamSlider::setActiveUAS(UASInterface* activeUas) uas = activeUas; } - QString text = uas->getParamManager()->getParamInfo(parameterName); - if (text != "") { + QString text = uas->getParamDataModel()->getParamDescription(parameterName); + if (!text.isEmpty()) { ui->infoLabel->setToolTip(text); ui->infoLabel->show(); } @@ -176,32 +176,20 @@ void QGCParamSlider::selectParameter(int paramIndex) parameterName = ui->editSelectParamComboBox->itemText(paramIndex); // Update min and max values if available - if (uas) - { - if (uas->getParamManager()) - { - // Current value - //uas->getParamManager()->requestParameterUpdate(component, parameterName); - + if (uas) { + UASParameterDataModel* dataModel = uas->getParamDataModel(); + if (dataModel) { // Minimum - if (uas->getParamManager()->isParamMinKnown(parameterName)) - { - parameterMin = uas->getParamManager()->getParamMin(parameterName); + if (dataModel->isParamMinKnown(parameterName)) { + parameterMin = dataModel->getParamMin(parameterName); ui->editMinSpinBox->setValue(parameterMin); } // Maximum - if (uas->getParamManager()->isParamMaxKnown(parameterName)) - { - parameterMax = uas->getParamManager()->getParamMax(parameterName); + if (dataModel->isParamMaxKnown(parameterName)) { + parameterMax = dataModel->getParamMax(parameterName); ui->editMaxSpinBox->setValue(parameterMax); } - - // Description - //QString text = uas->getParamManager()->getParamInfo(parameterName); - //ui->infoLabel->setText(text); - - //showInfo(!(text.length() > 0)); } } } -- GitLab From 9bcd3ed364c4c065b3b91f4757a3ef6e5541b0f6 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 10:49:52 -0700 Subject: [PATCH 223/460] debugging retransmission of read param list --- src/uas/QGCUASParamManager.cc | 6 ++++-- src/uas/QGCUASParamManager.h | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 06774ec25d..3e61077310 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -49,8 +49,7 @@ void QGCUASParamManager::requestParameterList() transmissionListSizeKnown.clear(); transmissionListMode = true; - foreach (int key, transmissionMissingPackets.keys()) - { + foreach (int key, transmissionMissingPackets.keys()) { transmissionMissingPackets.value(key)->clear(); } transmissionActive = true; @@ -70,6 +69,8 @@ void QGCUASParamManager::requestParameterList() */ void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) { + qDebug() << "setRetransmissionGuardEnabled: " << enabled; + if (enabled) { retransmissionTimer.start(retransmissionTimeout); } else { @@ -79,6 +80,7 @@ void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) void QGCUASParamManager::setParameterStatusMsg(const QString& msg) { + qDebug() << "parameterStatusMsg: " << msg; parameterStatusMsg = msg; } diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 2a0165959a..6e3927b085 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -26,8 +26,6 @@ public: virtual void setParamDescriptions(const QMap& paramDescs); protected: - /** @brief Check for missing parameters */ - virtual void retransmissionGuardTick(); /** @brief Activate / deactivate parameter retransmission */ virtual void setRetransmissionGuardEnabled(bool enabled); @@ -48,6 +46,8 @@ public slots: virtual void setParameter(int component, QString parameterName, QVariant value) = 0; /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); + /** @brief Check for missing parameters */ + virtual void retransmissionGuardTick(); protected: @@ -67,6 +67,8 @@ protected: int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds int rewriteTimeout; ///< Write request timeout, in milliseconds int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst + + // Status QString parameterStatusMsg; }; -- GitLab From 5e211bb9b29a94d22f931bc2538b8deddcde6927 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 13:02:28 -0700 Subject: [PATCH 224/460] debug multiple parameter widgets creation --- src/uas/QGCUASParamManager.cc | 13 ++----------- src/uas/QGCUASParamManager.h | 2 -- src/uas/UAS.cc | 2 +- src/ui/ParameterInterface.cc | 12 +++++++++++- src/ui/QGCParamWidget.cc | 25 +++++++++++++++---------- src/ui/QGCParamWidget.h | 4 ++-- 6 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 3e61077310..532efe813a 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -16,22 +16,13 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : } -/** - * The .. signal is emitted - */ -void QGCUASParamManager::requestParameterListUpdate(int component) -{ - Q_UNUSED(component); -} + bool QGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const { return paramDataModel->getOnboardParameterValue(component,parameter,value); } - - - /** * Send a request to deliver the list of onboard parameters * to the MAV. @@ -69,7 +60,7 @@ void QGCUASParamManager::requestParameterList() */ void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) { - qDebug() << "setRetransmissionGuardEnabled: " << enabled; +// qDebug() << "setRetransmissionGuardEnabled: " << enabled; if (enabled) { retransmissionTimer.start(retransmissionTimeout); diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 6e3927b085..3607552df2 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -17,8 +17,6 @@ public: virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; - /** @brief Request an update for the parameter list */ - void requestParameterListUpdate(int component = 0); /** @brief Request an update for this specific parameter */ virtual void requestParameterUpdate(int component, const QString& parameter) = 0; diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 597472af5a..3e34dd48ab 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -1995,7 +1995,7 @@ void UAS::sendMessage(mavlink_message_t message) if (LinkManager::instance()->getLinks().contains(link)) { sendMessage(link, message); - qDebug() << "SENT MESSAGE!"; + qDebug() << "SENT MESSAGE id" << message.msgid; } else { diff --git a/src/ui/ParameterInterface.cc b/src/ui/ParameterInterface.cc index e387a20938..8ad4a450ca 100644 --- a/src/ui/ParameterInterface.cc +++ b/src/ui/ParameterInterface.cc @@ -89,8 +89,18 @@ void ParameterInterface::selectUAS(int index) */ void ParameterInterface::addUAS(UASInterface* uas) { + int uasId = uas->getUASID(); + if (paramWidgets->contains(uasId) ) { + qDebug() << "Already have QGCParamWidget for: " << uasId ; + return; + } + QGCParamWidget* param = new QGCParamWidget(uas, this); - paramWidgets->insert(uas->getUASID(), param); + QString ptrStr; + ptrStr.sprintf("%8p", param); + qDebug() << "Created QGCParamWidget " << ptrStr << "for UAS id: " << uasId << " count: " << paramWidgets->count(); + + paramWidgets->insert(uasId, param); m_ui->stackedWidget->addWidget(param); QGCSensorSettingsWidget* sensor = NULL; diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 7b6f333011..b26348be63 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -87,7 +87,7 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QPushButton* refreshButton = new QPushButton(tr("Get")); refreshButton->setToolTip(tr("Load parameters currently in non-permanent memory of aircraft.")); refreshButton->setWhatsThis(tr("Load parameters currently in non-permanent memory of aircraft.")); - connect(refreshButton, SIGNAL(clicked()), this, SLOT(requestParameterListUpdate())); + connect(refreshButton, SIGNAL(clicked()), this, SLOT(requestAllParamsUpdate())); horizontalLayout->addWidget(refreshButton, 2, 0); QPushButton* setButton = new QPushButton(tr("Set")); @@ -151,7 +151,7 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : // Get parameters if (uas) { - requestParameterListUpdate(); + requestAllParamsUpdate(); } } @@ -245,7 +245,8 @@ void QGCParamWidget::addComponent(int uas, int component, QString componentName) */ void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) { - receivedParameterUpdate(uas, component, parameterName, value); + + updateParameterDisplay(uas, component, parameterName, value); // Missing packets list has to be instantiated for all components if (!transmissionMissingPackets.contains(component)) { @@ -390,10 +391,15 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCo * @param component id of the component * @param parameterName human friendly name of the parameter */ -void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value) +void QGCParamWidget::updateParameterDisplay(int uas, int component, QString parameterName, QVariant value) { - qDebug() << "PARAM WIDGET GOT PARAM:" << parameterName; Q_UNUSED(uas); + + + QString ptrStr; + ptrStr.sprintf("%8p", this); + qDebug() << "QGCParamWidget " << ptrStr << " got param" << parameterName; + // Reference to item in tree QTreeWidgetItem* parameterItem = NULL; @@ -417,9 +423,8 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, QString par addComponent(uas, component, componentName); } - // Replace value in map - - paramDataModel->setOnboardParameter(component,parameterName,value); + // Replace value in data model + paramDataModel->handleParameterUpdate(component,parameterName,value); QString splitToken = "_"; @@ -564,7 +569,7 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) current->setBackground(1, QBrush(QColor(QGC::colorOrange))); //TODO this seems incorrect-- we're pre-updating the onboard value before we've received confirmation - paramDataModel->setOnboardParameterWithType(componentId,key,value); + //paramDataModel->setOnboardParameterWithType(componentId,key,value); } } @@ -608,7 +613,7 @@ void QGCParamWidget::setParameterStatusMsg(const QString& msg) -void QGCParamWidget::requestParameterListUpdate() +void QGCParamWidget::requestAllParamsUpdate() { if (!mav) { return; diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 9b34813b06..48edbb3103 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -65,9 +65,9 @@ public slots: /** @brief Add a parameter to the list with retransmission / safety checks */ void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); /** @brief Add a parameter to the list */ - void receivedParameterUpdate(int uas, int component, QString parameterName, QVariant value); + void updateParameterDisplay(int uas, int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ - void requestParameterListUpdate(); + void requestAllParamsUpdate(); /** @brief Request one single parameter */ void requestParameterUpdate(int component, const QString& parameter); /** @brief Set one parameter, changes value in RAM of MAV */ -- GitLab From e87b4ca5bd3fd2381ee61e7b44d8c19c7e10f5a8 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 15:30:49 -0700 Subject: [PATCH 225/460] consolidating comms-related methods --- src/uas/QGCUASParamManager.cc | 12 ++++-- src/uas/QGCUASParamManager.h | 10 ++--- src/ui/ParameterInterface.cc | 5 ++- src/ui/QGCParamWidget.cc | 69 ++++++++++++----------------------- src/ui/QGCParamWidget.h | 6 +-- 5 files changed, 42 insertions(+), 60 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 532efe813a..dc11769a90 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -16,13 +16,19 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : } - - -bool QGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const { +bool QGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const +{ return paramDataModel->getOnboardParameterValue(component,parameter,value); } +void QGCUASParamManager::requestParameterUpdate(int component, const QString& parameter) +{ + if (mav) { + mav->requestParameter(component, parameter); + } +} + /** * Send a request to deliver the list of onboard parameters * to the MAV. diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 3607552df2..872273c522 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -17,9 +17,6 @@ public: virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; - /** @brief Request an update for this specific parameter */ - virtual void requestParameterUpdate(int component, const QString& parameter) = 0; - /** @brief Provide tooltips / user-visible descriptions for parameters */ virtual void setParamDescriptions(const QMap& paramDescs); @@ -36,8 +33,7 @@ signals: void parameterListUpToDate(int component); /** @brief Request a single parameter */ void requestParameter(int component, int parameter); - /** @brief Request a single parameter by name */ - void requestParameter(int component, const QString& parameter); + public slots: /** @brief Write one parameter to the MAV */ @@ -47,6 +43,10 @@ public slots: /** @brief Check for missing parameters */ virtual void retransmissionGuardTick(); + + /** @brief Request one single parameter */ + virtual void requestParameterUpdate(int component, const QString& parameter); + protected: // Parameter data model diff --git a/src/ui/ParameterInterface.cc b/src/ui/ParameterInterface.cc index 8ad4a450ca..2936394cec 100644 --- a/src/ui/ParameterInterface.cc +++ b/src/ui/ParameterInterface.cc @@ -72,6 +72,7 @@ ParameterInterface::ParameterInterface(QWidget *parent) : ParameterInterface::~ParameterInterface() { + delete paramWidgets; delete m_ui; } @@ -97,8 +98,8 @@ void ParameterInterface::addUAS(UASInterface* uas) QGCParamWidget* param = new QGCParamWidget(uas, this); QString ptrStr; - ptrStr.sprintf("%8p", param); - qDebug() << "Created QGCParamWidget " << ptrStr << "for UAS id: " << uasId << " count: " << paramWidgets->count(); + ptrStr.sprintf("QGCParamWidget %8p (parent %8p)", param,this); + qDebug() << "Created " << ptrStr << " for UAS id: " << uasId << " count: " << paramWidgets->count(); paramWidgets->insert(uasId, param); m_ui->stackedWidget->addWidget(param); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index b26348be63..6b10632b7e 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -49,7 +49,7 @@ This file is part of the QGROUNDCONTROL project */ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QGCUASParamManager(uas, parent), - components(new QMap()) + componentItems(new QMap()) { // Load settings loadSettings(); @@ -145,8 +145,8 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); // Connect retransmission guard - connect(this, SIGNAL(requestParameter(int,QString)), uas, SLOT(requestParameter(int,QString))); - connect(this, SIGNAL(requestParameter(int,int)), uas, SLOT(requestParameter(int,int))); + connect(this, SIGNAL(requestParameterByName(int,QString)), uas, SLOT(requestParameterByName(int,QString))); + connect(this, SIGNAL(requestParameterByName(int,int)), uas, SLOT(requestParameterByName(int,int))); connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); // Get parameters @@ -214,20 +214,20 @@ UASInterface* QGCParamWidget::getUAS() * @param component id of the component * @param componentName human friendly name of the component */ -void QGCParamWidget::addComponent(int uas, int component, QString componentName) +void QGCParamWidget::addComponentItem(int uas, int component, QString componentName) { Q_UNUSED(uas); - if (components->contains(component)) { + if (componentItems->contains(component)) { // Update existing - components->value(component)->setData(0, Qt::DisplayRole, QString("%1 (#%2)").arg(componentName).arg(component)); + componentItems->value(component)->setData(0, Qt::DisplayRole, QString("%1 (#%2)").arg(componentName).arg(component)); //components->value(component)->setData(1, Qt::DisplayRole, QString::number(component)); - components->value(component)->setFirstColumnSpanned(true); + componentItems->value(component)->setFirstColumnSpanned(true); } else { // Add new QStringList list(QString("%1 (#%2)").arg(componentName).arg(component)); QTreeWidgetItem* comp = new QTreeWidgetItem(list); comp->setFirstColumnSpanned(true); - components->insert(component, comp); + componentItems->insert(component, comp); // Create grouping and update maps paramGroups.insert(component, new QMap()); tree->addTopLevelItem(comp); @@ -391,40 +391,26 @@ void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCo * @param component id of the component * @param parameterName human friendly name of the parameter */ -void QGCParamWidget::updateParameterDisplay(int uas, int component, QString parameterName, QVariant value) +void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString parameterName, QVariant value) { Q_UNUSED(uas); - QString ptrStr; - ptrStr.sprintf("%8p", this); - qDebug() << "QGCParamWidget " << ptrStr << " got param" << parameterName; +// QString ptrStr; +// ptrStr.sprintf("%8p", this); +// qDebug() << "QGCParamWidget " << ptrStr << " got param" << parameterName; // Reference to item in tree QTreeWidgetItem* parameterItem = NULL; // Get component - if (!components->contains(component)) - { - // QString componentName; - // switch (component) - // { - // case MAV_COMP_ID_CAMERA: - // componentName = tr("Camera (#%1)").arg(component); - // break; - // case MAV_COMP_ID_IMU: - // componentName = tr("IMU (#%1)").arg(component); - // break; - // default: - // componentName = tr("Component #").arg(component); - // break; - // } - QString componentName = tr("Component #%1").arg(component); - addComponent(uas, component, componentName); + if (!componentItems->contains(componentId)) { + QString componentName = tr("Component #%1").arg(componentId); + addComponentItem(uas, componentId, componentName); } // Replace value in data model - paramDataModel->handleParameterUpdate(component,parameterName,value); + paramDataModel->handleParameterUpdate(componentId,parameterName,value); QString splitToken = "_"; @@ -432,7 +418,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int component, QString para if (parameterName.contains(splitToken)) { QString parent = parameterName.section(splitToken, 0, 0, QString::SectionSkipEmpty); - QMap* compParamGroups = paramGroups.value(component); + QMap* compParamGroups = paramGroups.value(componentId); if (!compParamGroups->contains(parent)) { // Insert group item @@ -440,7 +426,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int component, QString para glist.append(parent); QTreeWidgetItem* item = new QTreeWidgetItem(glist); compParamGroups->insert(parent, item); - components->value(component)->addChild(item); + componentItems->value(componentId)->addChild(item); } // Append child to group @@ -489,7 +475,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int component, QString para else { bool found = false; - QTreeWidgetItem* parent = components->value(component); + QTreeWidgetItem* parent = componentItems->value(componentId); for (int i = 0; i < parent->childCount(); i++) { QTreeWidgetItem* child = parent->child(i); @@ -513,7 +499,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int component, QString para // CONFIGURE PARAMETER ITEM parameterItem->setData(1, Qt::DisplayRole, value); - components->value(component)->addChild(parameterItem); + componentItems->value(componentId)->addChild(parameterItem); parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); } //tree->expandAll(); @@ -535,7 +521,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int component, QString para parameterItem->setToolTip(0, tooltipFormat); parameterItem->setToolTip(1, tooltipFormat); - paramDataModel->handleParameterUpdate(component,parameterName,value); + paramDataModel->handleParameterUpdate(componentId,parameterName,value); } @@ -549,7 +535,7 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) parent = parent->parent(); } // Parent is now top-level component - int componentId = components->key(parent); + int componentId = componentItems->key(parent); QString key = current->data(0, Qt::DisplayRole).toString(); QVariant value = current->data(1, Qt::DisplayRole); @@ -603,7 +589,6 @@ void QGCParamWidget::loadParametersFromFile() QTextStream in(&file); paramDataModel->readUpdateParametersFromStream(in); file.close(); - } void QGCParamWidget::setParameterStatusMsg(const QString& msg) @@ -632,14 +617,6 @@ void QGCParamWidget::requestAllParamsUpdate() requestParameterList(); } -/** - * The .. signal is emitted - */ -void QGCParamWidget::requestParameterUpdate(int component, const QString& parameter) -{ - if (mav) mav->requestParameter(component, parameter); -} - /** @@ -830,5 +807,5 @@ void QGCParamWidget::readParameters() void QGCParamWidget::clear() { tree->clear(); - components->clear(); + componentItems->clear(); } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 48edbb3103..06a15b83bb 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -61,15 +61,13 @@ signals: public slots: /** @brief Add a component to the list */ - void addComponent(int uas, int component, QString componentName); + void addComponentItem(int uas, int component, QString componentName); /** @brief Add a parameter to the list with retransmission / safety checks */ void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); /** @brief Add a parameter to the list */ void updateParameterDisplay(int uas, int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ void requestAllParamsUpdate(); - /** @brief Request one single parameter */ - void requestParameterUpdate(int component, const QString& parameter); /** @brief Set one parameter, changes value in RAM of MAV */ void setParameter(int component, QString parameterName, QVariant value); /** @brief Set all parameters, changes the value in RAM of MAV */ @@ -93,7 +91,7 @@ public slots: protected: QTreeWidget* tree; ///< The parameter tree QLabel* statusLabel; ///< Parameter transmission label - QMap* components; ///< The list of components + QMap* componentItems; ///< The list of component items, stored by component ID QMap* > paramGroups; ///< Parameter groups -- GitLab From 77aaf4d015fe2ebc407215ed5b5ba4e00e0e4384 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 16:50:08 -0700 Subject: [PATCH 226/460] Fixing inter-object wiring --- src/uas/QGCUASParamManager.cc | 12 +++++++++++- src/uas/QGCUASParamManager.h | 8 ++++---- src/uas/UASManager.cc | 1 + src/ui/ParameterInterface.cc | 3 ++- src/ui/QGCParamWidget.cc | 10 +++++++--- src/ui/QGCParamWidget.h | 3 ++- 6 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index dc11769a90..9103a2b437 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -13,6 +13,12 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : { paramDataModel = uas->getParamDataModel(); uas->setParamManager(this); + + // Connect retransmission guard + connect(this, SIGNAL(parameterUpdateRequested(int,QString)), this, SLOT(requestParameterUpdate(int,QString))); + connect(this, SIGNAL(parameterUpdateRequestedById(int,int)), mav, SLOT(requestParameter(int,int))); + + } @@ -29,6 +35,10 @@ void QGCUASParamManager::requestParameterUpdate(int component, const QString& pa } } + + + + /** * Send a request to deliver the list of onboard parameters * to the MAV. @@ -132,7 +142,7 @@ void QGCUASParamManager::retransmissionGuardTick() if (count < retransmissionBurstRequestSize) { //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; //TODO mavlink msg type for "request parameter set" ? - emit requestParameter(component, id); + emit parameterUpdateRequestedById(component, id); setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); count++; } else { diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 872273c522..6a87ba7632 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -27,12 +27,13 @@ protected: //TODO decouple this UI message display further virtual void setParameterStatusMsg(const QString& msg); + signals: void parameterChanged(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); void parameterListUpToDate(int component); - /** @brief Request a single parameter */ - void requestParameter(int component, int parameter); + void parameterUpdateRequested(int component, const QString& parameter); + void parameterUpdateRequestedById(int componentId, int paramId); public slots: @@ -43,8 +44,7 @@ public slots: /** @brief Check for missing parameters */ virtual void retransmissionGuardTick(); - - /** @brief Request one single parameter */ + /** @brief Request a single parameter by name */ virtual void requestParameterUpdate(int component, const QString& parameter); protected: diff --git a/src/uas/UASManager.cc b/src/uas/UASManager.cc index 072c7aea7a..8ee92242db 100644 --- a/src/uas/UASManager.cc +++ b/src/uas/UASManager.cc @@ -280,6 +280,7 @@ void UASManager::addUAS(UASInterface* uas) // Only execute if there is no UAS at this index if (!systems.contains(uas)) { + qDebug() << "Add new UAS: " << uas->getUASID(); systems.append(uas); // Set home position on UAV if set in UI // - this is done on a per-UAV basis diff --git a/src/ui/ParameterInterface.cc b/src/ui/ParameterInterface.cc index 2936394cec..c7d5f811b3 100644 --- a/src/ui/ParameterInterface.cc +++ b/src/ui/ParameterInterface.cc @@ -91,8 +91,9 @@ void ParameterInterface::selectUAS(int index) void ParameterInterface::addUAS(UASInterface* uas) { int uasId = uas->getUASID(); + qDebug() << "ParameterInterface::addUAS : " << uasId ; + if (paramWidgets->contains(uasId) ) { - qDebug() << "Already have QGCParamWidget for: " << uasId ; return; } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 6b10632b7e..4c973cd2aa 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -144,11 +144,15 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : // New parameters from UAS connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); - // Connect retransmission guard - connect(this, SIGNAL(requestParameterByName(int,QString)), uas, SLOT(requestParameterByName(int,QString))); - connect(this, SIGNAL(requestParameterByName(int,int)), uas, SLOT(requestParameterByName(int,int))); + connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); + +// connect(this, SIGNAL(requestParameter(int,QString)), uas, SLOT(requestParameter(int,QString))); +// connect(this, SIGNAL(requestParameter(int,int)), uas, SLOT(requestParameter(int,int))); + + + // Get parameters if (uas) { requestAllParamsUpdate(); diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 06a15b83bb..af58eabf3f 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -59,6 +59,7 @@ signals: /** @brief A parameter was changed in the widget, NOT onboard */ //void parameterChanged(int component, QString parametername, float value); // defined in QGCUASParamManager already + public slots: /** @brief Add a component to the list */ void addComponentItem(int uas, int component, QString componentName); @@ -69,7 +70,7 @@ public slots: /** @brief Request list of parameters from MAV */ void requestAllParamsUpdate(); /** @brief Set one parameter, changes value in RAM of MAV */ - void setParameter(int component, QString parameterName, QVariant value); + virtual void setParameter(int component, QString parameterName, QVariant value); /** @brief Set all parameters, changes the value in RAM of MAV */ void setParameters(); /** @brief Write the current parameters to permanent storage (EEPROM/HDD) */ -- GitLab From 1bf69c0a707f68018ee3db4280a182b609cfe089 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 19:52:30 -0700 Subject: [PATCH 227/460] start moving comms mgmt code to a separate class --- qgroundcontrol.pro | 6 +- src/uas/QGCUASParamManager.cc | 63 ++++---- src/uas/UASParameterCommsMgr.cc | 278 ++++++++++++++++++++++++++++++++ src/uas/UASParameterCommsMgr.h | 72 +++++++++ 4 files changed, 386 insertions(+), 33 deletions(-) create mode 100644 src/uas/UASParameterCommsMgr.cc create mode 100644 src/uas/UASParameterCommsMgr.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index fd4df5e5b5..6f0f51ca48 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -469,7 +469,8 @@ HEADERS += src/MG.h \ src/ui/configuration/terminalconsole.h \ src/ui/configuration/ApmHighlighter.h \ src/ui/configuration/ApmFirmwareConfig.h \ - src/uas/UASParameterDataModel.h + src/uas/UASParameterDataModel.h \ + src/uas/UASParameterCommsMgr.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -685,7 +686,8 @@ SOURCES += src/main.cc \ src/ui/configuration/SerialSettingsDialog.cc \ src/ui/configuration/ApmHighlighter.cc \ src/ui/configuration/ApmFirmwareConfig.cc \ - src/uas/UASParameterDataModel.cc + src/uas/UASParameterDataModel.cc \ + src/uas/UASParameterCommsMgr.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 9103a2b437..de1d19afd1 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -66,37 +66,6 @@ void QGCUASParamManager::requestParameterList() } - -/** - * Enabling the retransmission guard enables the parameter widget to track - * dropped parameters and to re-request them. This works for both individual - * parameter reads as well for whole list requests. - * - * @param enabled True if retransmission checking should be enabled, false else - */ -void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) -{ -// qDebug() << "setRetransmissionGuardEnabled: " << enabled; - - if (enabled) { - retransmissionTimer.start(retransmissionTimeout); - } else { - retransmissionTimer.stop(); - } -} - -void QGCUASParamManager::setParameterStatusMsg(const QString& msg) -{ - qDebug() << "parameterStatusMsg: " << msg; - parameterStatusMsg = msg; -} - -void QGCUASParamManager::setParamDescriptions(const QMap& paramInfo) { - paramDataModel->setParamDescriptions(paramInfo); -} - - - void QGCUASParamManager::retransmissionGuardTick() { if (transmissionActive) { @@ -199,3 +168,35 @@ void QGCUASParamManager::retransmissionGuardTick() setRetransmissionGuardEnabled(false); } } + + + +/** + * Enabling the retransmission guard enables the parameter widget to track + * dropped parameters and to re-request them. This works for both individual + * parameter reads as well for whole list requests. + * + * @param enabled True if retransmission checking should be enabled, false else + */ +void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) +{ +// qDebug() << "setRetransmissionGuardEnabled: " << enabled; + + if (enabled) { + retransmissionTimer.start(retransmissionTimeout); + } else { + retransmissionTimer.stop(); + } +} + +void QGCUASParamManager::setParameterStatusMsg(const QString& msg) +{ + qDebug() << "parameterStatusMsg: " << msg; + parameterStatusMsg = msg; +} + +void QGCUASParamManager::setParamDescriptions(const QMap& paramInfo) { + paramDataModel->setParamDescriptions(paramInfo); +} + + diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc new file mode 100644 index 0000000000..9f0d60e051 --- /dev/null +++ b/src/uas/UASParameterCommsMgr.cc @@ -0,0 +1,278 @@ +#include "UASParameterCommsMgr.h" + +#include "QGCUASParamManager.h" +#include "UASInterface.h" + +UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : + QObject(parent) +{ + mav = uas; + + // Sending params to the UAS + connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), mav, SLOT(setParameter(int,QString,QVariant))); + + // New parameters from UAS + connect(mav, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); + +} + + +/** + * Send a request to deliver the list of onboard parameters + * from the MAV. + */ +void UASParameterCommsMgr::requestParameterList() +{ + if (!mav) { + return; + } + + //TODO check: no need to cause datamodel to forget params here? +// paramDataModel->forgetAllOnboardParameters(); + + // Clear transmission state + receivedParamsList.clear(); + transmissionListSizeKnown.clear(); + + transmissionListMode = true; + foreach (int key, transmissionMissingPackets.keys()) { + transmissionMissingPackets.value(key)->clear(); + } + transmissionActive = true; + + setParameterStatusMsg(tr("Requested param list.. waiting")); + mav->requestParameters(); + +} + + +void UASParameterCommsMgr::retransmissionGuardTick() +{ + if (transmissionActive) { + //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; + + // Check for timeout + // stop retransmission attempts on timeout + if (QGC::groundTimeMilliseconds() > transmissionTimeout) { + setRetransmissionGuardEnabled(false); + transmissionActive = false; + + // Empty read retransmission list + // Empty write retransmission list + int missingReadCount = 0; + QList readKeys = transmissionMissingPackets.keys(); + foreach (int component, readKeys) { + missingReadCount += transmissionMissingPackets.value(component)->count(); + transmissionMissingPackets.value(component)->clear(); + } + + // Empty write retransmission list + int missingWriteCount = 0; + QList writeKeys = transmissionMissingWriteAckPackets.keys(); + foreach (int component, writeKeys) { + missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); + transmissionMissingWriteAckPackets.value(component)->clear(); + } + setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); + } + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent link flooding + QMap*>::iterator i; + QMap*> onboardParams = paramDataModel->getOnboardParameters(); + for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { + // Iterate through the parameters of the component + int component = i.key(); + // Request n parameters from this component (at maximum) + QList * paramList = transmissionMissingPackets.value(component, NULL); + if (paramList) { + int count = 0; + foreach (int id, *paramList) { + if (count < retransmissionBurstRequestSize) { + //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; + //TODO mavlink msg type for "request parameter set" ? + emit parameterUpdateRequestedById(component, id); + setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); + count++; + } else { + break; + } + } + } + } + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent write-request link flooding + // Empty write retransmission list + QList writeKeys = transmissionMissingWriteAckPackets.keys(); + foreach (int component, writeKeys) { + int count = 0; + QMap * missingParams = transmissionMissingWriteAckPackets.value(component); + foreach (QString key, missingParams->keys()) { + if (count < retransmissionBurstRequestSize) { + // Re-request write operation + QVariant value = missingParams->value(key); + switch ((int)onboardParams.value(component)->value(key).type()) + { + case QVariant::Int: + { + QVariant fixedValue(value.toInt()); + emit parameterChanged(component, key, fixedValue); + } + break; + case QVariant::UInt: + { + QVariant fixedValue(value.toUInt()); + emit parameterChanged(component, key, fixedValue); + } + break; + case QMetaType::Float: + { + QVariant fixedValue(value.toFloat()); + emit parameterChanged(component, key, fixedValue); + } + break; + default: + //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; + return; + } + setParameterStatusMsg(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); + count++; + } else { + break; + } + } + } + } else { + //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; + setRetransmissionGuardEnabled(false); + } +} + + + +/** + * Enabling the retransmission guard enables the parameter widget to track + * dropped parameters and to re-request them. This works for both individual + * parameter reads as well for whole list requests. + * + * @param enabled True if retransmission checking should be enabled, false else + */ + +void UASParameterCommsMgr::setRetransmissionGuardEnabled(bool enabled) +{ +// qDebug() << "setRetransmissionGuardEnabled: " << enabled; + + if (enabled) { + retransmissionTimer.start(retransmissionTimeout); + } else { + retransmissionTimer.stop(); + } +} + +void UASParameterCommsMgr::requestParameterUpdate(int component, const QString& parameter) +{ + if (mav) { + mav->requestParameter(component, parameter); + } +} + +/** + * @param component the subsystem which has the parameter + * @param parameterName name of the parameter, as delivered by the system + * @param value value of the parameter + */ +void UASParameterCommsMgr::setParameter(int component, QString parameterName, QVariant value) +{ + if (parameterName.isEmpty()) { + return; + } + + double dblValue = value.toDouble(); + + if (paramDataModel->isValueLessThanParamMin(parameterName,dblValue)) { + setParameterStatusMsg(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); + return; + } + if (paramDataModel->isValueGreaterThanParamMax(parameterName,dblValue)) { + setParameterStatusMsg(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); + return; + } + QVariant onboardVal; + paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); + if (onboardVal == value) { + setParameterStatusMsg(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue)); + return; + } + + //int paramType = (int)onboardParameters.value(component)->value(parameterName).type(); + int paramType = (int)value.type(); + switch (paramType) + { + case QVariant::Char: + { + QVariant fixedValue(QChar((unsigned char)value.toInt())); + emit parameterChanged(component, parameterName, fixedValue); + //qDebug() << "PARAM WIDGET SENT:" << fixedValue; + } + break; + case QVariant::Int: + { + QVariant fixedValue(value.toInt()); + emit parameterChanged(component, parameterName, fixedValue); + //qDebug() << "PARAM WIDGET SENT:" << fixedValue; + } + break; + case QVariant::UInt: + { + QVariant fixedValue(value.toUInt()); + emit parameterChanged(component, parameterName, fixedValue); + //qDebug() << "PARAM WIDGET SENT:" << fixedValue; + } + break; + case QMetaType::Float: + { + QVariant fixedValue(value.toFloat()); + emit parameterChanged(component, parameterName, fixedValue); + //qDebug() << "PARAM WIDGET SENT:" << fixedValue; + } + break; + default: + qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE"; + return; + } + + // Wait for parameter to be written back + // mark it therefore as missing + if (!transmissionMissingWriteAckPackets.contains(component)) + { + transmissionMissingWriteAckPackets.insert(component, new QMap()); + } + + // Insert it in missing write ACK list + transmissionMissingWriteAckPackets.value(component)->insert(parameterName, value); + + // Set timeouts + if (transmissionActive) + { + transmissionTimeout += rewriteTimeout; + } + else + { + quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + rewriteTimeout; + if (newTransmissionTimeout > transmissionTimeout) + { + transmissionTimeout = newTransmissionTimeout; + } + transmissionActive = true; + } + + // Enable guard / reset timeouts + setRetransmissionGuardEnabled(true); +} + +void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg) +{ + qDebug() << "parameterStatusMsg: " << msg; + parameterStatusMsg = msg; +} diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h new file mode 100644 index 0000000000..72da05d8f8 --- /dev/null +++ b/src/uas/UASParameterCommsMgr.h @@ -0,0 +1,72 @@ +#ifndef UASPARAMETERCOMMSMGR_H +#define UASPARAMETERCOMMSMGR_H + +#include +#include +#include +#include +#include + +class UASInterface; +class UASParameterDataModel; + +class UASParameterCommsMgr : public QObject +{ + Q_OBJECT +public: + explicit UASParameterCommsMgr(QObject *parent = 0, UASInterface* uas = NULL); + + +protected: + /** @brief Activate / deactivate parameter retransmission */ + virtual void setRetransmissionGuardEnabled(bool enabled); + + virtual void setParameterStatusMsg(const QString& msg); + +signals: + void parameterChanged(int component, QString parameter, QVariant value); + void parameterChanged(int component, int parameterIndex, QVariant value); + void parameterValueConfirmed(int component, QString parameter, QVariant value); + + void parameterListUpToDate(int component); + void parameterUpdateRequested(int component, const QString& parameter); + void parameterUpdateRequestedById(int componentId, int paramId); + + +public slots: + /** @brief Write one parameter to the MAV */ + virtual void setParameter(int component, QString parameterName, QVariant value); + /** @brief Request list of parameters from MAV */ + virtual void requestParameterList(); + /** @brief Check for missing parameters */ + virtual void retransmissionGuardTick(); + + /** @brief Request a single parameter update by name */ + virtual void requestParameterUpdate(int component, const QString& parameter); + +protected: + + UASInterface* mav; ///< The MAV we're talking to + + UASParameterDataModel* paramDataModel; + + // Communications management + QVector receivedParamsList; ///< Successfully received parameters + QMap* > transmissionMissingPackets; ///< Missing packets + QMap* > transmissionMissingWriteAckPackets; ///< Missing write ACK packets + bool transmissionListMode; ///< Currently requesting list + QMap transmissionListSizeKnown; ///< List size initialized? + bool transmissionActive; ///< Missing packets, working on list? + quint64 transmissionTimeout; ///< Timeout + QTimer retransmissionTimer; ///< Timer handling parameter retransmission + int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds + int rewriteTimeout; ///< Write request timeout, in milliseconds + int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst + + // Status + QString parameterStatusMsg; + +}; + + +#endif // UASPARAMETERCOMMSMGR_H -- GitLab From 3af4958cb8b6e8813865a0b606a387f24e5071fa Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 7 Aug 2013 17:40:32 -0700 Subject: [PATCH 228/460] wip-- more mvc refactoring --- src/uas/QGCUASParamManager.cc | 337 ++++++++++++--------- src/uas/QGCUASParamManager.h | 38 ++- src/uas/UAS.cc | 4 + src/uas/UAS.h | 6 + src/uas/UASInterface.h | 3 + src/uas/UASParameterCommsMgr.cc | 217 ++++++++++++- src/uas/UASParameterCommsMgr.h | 31 +- src/uas/UASParameterDataModel.cc | 10 +- src/uas/UASParameterDataModel.h | 11 +- src/ui/QGCParamWidget.cc | 505 ++++++++++++------------------- src/ui/QGCParamWidget.h | 33 +- 11 files changed, 686 insertions(+), 509 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index de1d19afd1..79b03d2059 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -1,22 +1,43 @@ #include "QGCUASParamManager.h" #include "UASInterface.h" +#include "UASParameterCommsMgr.h" + QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : QWidget(parent), - mav(uas), - transmissionListMode(false), - transmissionActive(false), - transmissionTimeout(0), - retransmissionTimeout(350), - rewriteTimeout(500), - retransmissionBurstRequestSize(5) + mav(uas) { paramDataModel = uas->getParamDataModel(); - uas->setParamManager(this); + paramCommsMgr = uas->getParamCommsMgr(); + mav->setParamManager(this); + + // Load default values and tooltips + loadParamMetaInfoCSV(); + // Connect retransmission guard - connect(this, SIGNAL(parameterUpdateRequested(int,QString)), this, SLOT(requestParameterUpdate(int,QString))); - connect(this, SIGNAL(parameterUpdateRequestedById(int,int)), mav, SLOT(requestParameter(int,int))); + connect(this, SIGNAL(parameterUpdateRequested(int,QString)), + this, SLOT(requestParameterUpdate(int,QString))); + +// //TODO connect in paramCommsMgr instead +// connect(this, SIGNAL(parameterUpdateRequestedById(int,int)), +// mav, SLOT(requestParameter(int,int))); + + // New parameters from UAS + + void parameterUpdated(int compId, int paramId, QString paramName, QVariant value); + + connect(paramDataModel, SIGNAL(parameterUpdated(int, int, QString , QVariant )), + this, SLOT(handleParameterUpdate(int,int,int,QString,QVariant)); + +// connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), +// this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); + + + // Listen for param list reload finished + connect(paramCommsMgr, SIGNAL(parameterListUpToDate(int)), + this, SLOT(handleParameterListUpToDate(int)))); + } @@ -31,14 +52,12 @@ bool QGCUASParamManager::getParameterValue(int component, const QString& paramet void QGCUASParamManager::requestParameterUpdate(int component, const QString& parameter) { if (mav) { - mav->requestParameter(component, parameter); + paramCommsMgr->requestParameterUpdate(component,parameter); } } - - /** * Send a request to deliver the list of onboard parameters * to the MAV. @@ -48,146 +67,133 @@ void QGCUASParamManager::requestParameterList() if (!mav) { return; } - - paramDataModel->forgetAllOnboardParameters(); - - // Clear transmission state - receivedParamsList.clear(); - transmissionListSizeKnown.clear(); - - transmissionListMode = true; - foreach (int key, transmissionMissingPackets.keys()) { - transmissionMissingPackets.value(key)->clear(); - } - transmissionActive = true; - + //paramDataModel->forgetAllOnboardParameters(); //TODO really?? setParameterStatusMsg(tr("Requested param list.. waiting")); - mav->requestParameters(); - -} - -void QGCUASParamManager::retransmissionGuardTick() -{ - if (transmissionActive) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; - - // Check for timeout - // stop retransmission attempts on timeout - if (QGC::groundTimeMilliseconds() > transmissionTimeout) { - setRetransmissionGuardEnabled(false); - transmissionActive = false; - - // Empty read retransmission list - // Empty write retransmission list - int missingReadCount = 0; - QList readKeys = transmissionMissingPackets.keys(); - foreach (int component, readKeys) { - missingReadCount += transmissionMissingPackets.value(component)->count(); - transmissionMissingPackets.value(component)->clear(); - } - - // Empty write retransmission list - int missingWriteCount = 0; - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); - transmissionMissingWriteAckPackets.value(component)->clear(); - } - setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); - } - - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent link flooding - QMap*>::iterator i; - QMap*> onboardParams = paramDataModel->getOnboardParameters(); - for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { - // Iterate through the parameters of the component - int component = i.key(); - // Request n parameters from this component (at maximum) - QList * paramList = transmissionMissingPackets.value(component, NULL); - if (paramList) { - int count = 0; - foreach (int id, *paramList) { - if (count < retransmissionBurstRequestSize) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; - //TODO mavlink msg type for "request parameter set" ? - emit parameterUpdateRequestedById(component, id); - setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); - count++; - } else { - break; - } - } - } - } - - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent write-request link flooding - // Empty write retransmission list - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - int count = 0; - QMap * missingParams = transmissionMissingWriteAckPackets.value(component); - foreach (QString key, missingParams->keys()) { - if (count < retransmissionBurstRequestSize) { - // Re-request write operation - QVariant value = missingParams->value(key); - switch ((int)onboardParams.value(component)->value(key).type()) - { - case QVariant::Int: - { - QVariant fixedValue(value.toInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QVariant::UInt: - { - QVariant fixedValue(value.toUInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QMetaType::Float: - { - QVariant fixedValue(value.toFloat()); - emit parameterChanged(component, key, fixedValue); - } - break; - default: - //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; - return; - } - setParameterStatusMsg(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); - count++; - } else { - break; - } - } - } - } else { - //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; - setRetransmissionGuardEnabled(false); - } + paramCommsMgr->requestParameterList(); } - - -/** - * Enabling the retransmission guard enables the parameter widget to track - * dropped parameters and to re-request them. This works for both individual - * parameter reads as well for whole list requests. - * - * @param enabled True if retransmission checking should be enabled, false else - */ -void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) -{ +//void QGCUASParamManager::retransmissionGuardTick() +//{ +// if (transmissionActive) { +// //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; + +// // Check for timeout +// // stop retransmission attempts on timeout +// if (QGC::groundTimeMilliseconds() > transmissionTimeout) { +// setRetransmissionGuardEnabled(false); +// transmissionActive = false; + +// // Empty read retransmission list +// // Empty write retransmission list +// int missingReadCount = 0; +// QList readKeys = transmissionMissingPackets.keys(); +// foreach (int component, readKeys) { +// missingReadCount += transmissionMissingPackets.value(component)->count(); +// transmissionMissingPackets.value(component)->clear(); +// } + +// // Empty write retransmission list +// int missingWriteCount = 0; +// QList writeKeys = transmissionMissingWriteAckPackets.keys(); +// foreach (int component, writeKeys) { +// missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); +// transmissionMissingWriteAckPackets.value(component)->clear(); +// } +// setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); +// } + +// // Re-request at maximum retransmissionBurstRequestSize parameters at once +// // to prevent link flooding +// QMap*>::iterator i; +// QMap*> onboardParams = paramDataModel->getOnboardParameters(); +// for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { +// // Iterate through the parameters of the component +// int component = i.key(); +// // Request n parameters from this component (at maximum) +// QList * paramList = transmissionMissingPackets.value(component, NULL); +// if (paramList) { +// int count = 0; +// foreach (int id, *paramList) { +// if (count < retransmissionBurstRequestSize) { +// //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; +// //TODO mavlink msg type for "request parameter set" ? +// emit parameterUpdateRequestedById(component, id); +// setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); +// count++; +// } else { +// break; +// } +// } +// } +// } + +// // Re-request at maximum retransmissionBurstRequestSize parameters at once +// // to prevent write-request link flooding +// // Empty write retransmission list +// QList writeKeys = transmissionMissingWriteAckPackets.keys(); +// foreach (int component, writeKeys) { +// int count = 0; +// QMap * missingParams = transmissionMissingWriteAckPackets.value(component); +// foreach (QString key, missingParams->keys()) { +// if (count < retransmissionBurstRequestSize) { +// // Re-request write operation +// QVariant value = missingParams->value(key); +// switch ((int)onboardParams.value(component)->value(key).type()) +// { +// case QVariant::Int: +// { +// QVariant fixedValue(value.toInt()); +// emit parameterChanged(component, key, fixedValue); +// } +// break; +// case QVariant::UInt: +// { +// QVariant fixedValue(value.toUInt()); +// emit parameterChanged(component, key, fixedValue); +// } +// break; +// case QMetaType::Float: +// { +// QVariant fixedValue(value.toFloat()); +// emit parameterChanged(component, key, fixedValue); +// } +// break; +// default: +// //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; +// return; +// } +// setParameterStatusMsg(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); +// count++; +// } else { +// break; +// } +// } +// } +// } else { +// //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; +// setRetransmissionGuardEnabled(false); +// } +//} + + + +//* +// * Enabling the retransmission guard enables the parameter widget to track +// * dropped parameters and to re-request them. This works for both individual +// * parameter reads as well for whole list requests. +// * +// * @param enabled True if retransmission checking should be enabled, false else + +//void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) +//{ // qDebug() << "setRetransmissionGuardEnabled: " << enabled; - - if (enabled) { - retransmissionTimer.start(retransmissionTimeout); - } else { - retransmissionTimer.stop(); - } -} +// +// if (enabled) { +// retransmissionTimer.start(retransmissionTimeout); +// } else { +// retransmissionTimer.stop(); +// } +//} void QGCUASParamManager::setParameterStatusMsg(const QString& msg) { @@ -200,3 +206,36 @@ void QGCUASParamManager::setParamDescriptions(const QMap& param } + + +void QGCUASParamManager::loadParamMetaInfoCSV() +{ + // Load default values and tooltips + QString autopilot(mav->getAutopilotTypeName()); + + QDir appDir = QApplication::applicationDirPath(); + appDir.cd("files"); + QString fileName = QString("%1/%2/parameter_tooltips/tooltips.txt").arg(appDir.canonicalPath()).arg(autopilot.toLower()); + QFile paramMetaFile(fileName); + + qDebug() << "loadParamMetaInfoCSV for autopilot: " << autopilot << " from file: " << fileName; + + if (!paramMetaFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning() << "loadParamMetaInfoCSV couldn't open:" << fileName; + return; + } + + QTextStream in(¶mMetaFile); + paramDataModel->loadParamMetaInfoFromStream(in); + paramMetaFile.close(); + +} + +/** + * @return The MAV of this mgr. Unless the MAV object has been destroyed, this + * pointer is never zero. + */ +UASInterface* QGCUASParamManager::getUAS() +{ + return mav; +} diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 6a87ba7632..313c0927ad 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -6,7 +6,9 @@ #include #include +//forward declarations class UASInterface; +class UASParameterCommsMgr; class UASParameterDataModel; class QGCUASParamManager : public QWidget @@ -15,25 +17,29 @@ class QGCUASParamManager : public QWidget public: QGCUASParamManager(UASInterface* uas, QWidget *parent = 0); + /** @brief Get the known, confirmed value of a parameter */ virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; /** @brief Provide tooltips / user-visible descriptions for parameters */ virtual void setParamDescriptions(const QMap& paramDescs); -protected: - /** @brief Activate / deactivate parameter retransmission */ - virtual void setRetransmissionGuardEnabled(bool enabled); + /** @brief Get the UAS of this widget + * @return The MAV of this mgr. Unless the MAV object has been destroyed, this is never null. + */ + UASInterface* getUAS(); +protected: //TODO decouple this UI message display further virtual void setParameterStatusMsg(const QString& msg); + /** @brief Load parameter meta information from appropriate CSV file */ + virtual void loadParamMetaInfoCSV(); signals: void parameterChanged(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); - void parameterListUpToDate(int component); - void parameterUpdateRequested(int component, const QString& parameter); - void parameterUpdateRequestedById(int componentId, int paramId); +// void parameterUpdateRequested(int component, const QString& parameter); +// void parameterUpdateRequestedById(int componentId, int paramId); public slots: @@ -41,30 +47,20 @@ public slots: virtual void setParameter(int component, QString parameterName, QVariant value) = 0; /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); - /** @brief Check for missing parameters */ - virtual void retransmissionGuardTick(); /** @brief Request a single parameter by name */ virtual void requestParameterUpdate(int component, const QString& parameter); + virtual void handleParameterUpdate(int component, int paramCount, int paramId, const QString& parameterName, QVariant value) = 0; + virtual void handleParameterListUpToDate(int component) = 0; + + protected: // Parameter data model UASInterface* mav; ///< The MAV this widget is controlling UASParameterDataModel* paramDataModel;///< Shared data model of parameters - - // Communications management - QVector receivedParamsList; ///< Successfully received parameters - QMap* > transmissionMissingPackets; ///< Missing packets - QMap* > transmissionMissingWriteAckPackets; ///< Missing write ACK packets - bool transmissionListMode; ///< Currently requesting list - QMap transmissionListSizeKnown; ///< List size initialized? - bool transmissionActive; ///< Missing packets, working on list? - quint64 transmissionTimeout; ///< Timeout - QTimer retransmissionTimer; ///< Timer handling parameter retransmission - int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds - int rewriteTimeout; ///< Write request timeout, in milliseconds - int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst + UASParameterCommsMgr* paramCommsMgr; ///< Shared comms mgr for parameters // Status QString parameterStatusMsg; diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 3e34dd48ab..772341413c 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -26,6 +26,7 @@ #include "QGCMAVLink.h" #include "LinkManager.h" #include "SerialLink.h" +#include "UASParameterCommsMgr.h" #include #ifdef QGC_PROTOBUF_ENABLED @@ -132,6 +133,7 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), paramsOnceRequested(false), paramManager(NULL), paramDataModel(NULL), + paramCommsMgr(NULL), simulation(0), @@ -155,6 +157,8 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), paramDataModel = new UASParameterDataModel(this); paramDataModel->setUASID(this->getUASID()); + paramCommsMgr = new UASParameterCommsMgr(this,this); + // Store a list of available actions for this UAS. // Basically everything exposted as a SLOT with no return value or arguments. diff --git a/src/uas/UAS.h b/src/uas/UAS.h index c8b9a604c7..5acd2c9ef4 100644 --- a/src/uas/UAS.h +++ b/src/uas/UAS.h @@ -41,6 +41,7 @@ This file is part of the QGROUNDCONTROL project #include "QGCJSBSimLink.h" #include "QGCXPlaneLink.h" + /** * @brief A generic MAVLINK-connected MAV/UAV * @@ -493,6 +494,7 @@ protected: //COMMENTS FOR TEST UNIT bool paramsOnceRequested; ///< If the parameter list has been read at least once QGCUASParamManager* paramManager; ///< Parameter manager class UASParameterDataModel* paramDataModel; ///< The parameter data model for this UAS + UASParameterCommsMgr* paramCommsMgr; /// SIMULATION QGCHilLink* simulation; ///< Hardware in the loop simulation link @@ -526,6 +528,10 @@ public: return paramDataModel; } + UASParameterCommsMgr* getParamCommsMgr() { + return paramCommsMgr; + } + /** @brief Get the HIL simulation */ QGCHilLink* getHILSimulation() const { diff --git a/src/uas/UASInterface.h b/src/uas/UASInterface.h index ed2aed28c8..6e6fe2fb33 100644 --- a/src/uas/UASInterface.h +++ b/src/uas/UASInterface.h @@ -157,6 +157,9 @@ public: /** @brief Access the parameter data model for this UAS (sans widget). This is the same parameter data model used by the parameter manager. **/ virtual UASParameterDataModel* getParamDataModel() = 0; + + virtual UASParameterCommsMgr* getParamCommsMgr() = 0; + /** @brief Get reference to the param manager **/ virtual QGCUASParamManager* getParamManager() const = 0; diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 9f0d60e051..22940e5fd3 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -4,9 +4,22 @@ #include "UASInterface.h" UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : - QObject(parent) + QObject(parent), + mav(uas), + transmissionListMode(false), + transmissionActive(false), + transmissionTimeout(0), + retransmissionTimeout(350), + rewriteTimeout(500), + retransmissionBurstRequestSize(5) { mav = uas; + loadParamCommsSettings(); + + + //Requesting parameters one-by-one from mav + connect(this, SIGNAL(parameterUpdateRequestedById(int,int)), + mav, SLOT(requestParameter(int,int))); // Sending params to the UAS connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), mav, SLOT(setParameter(int,QString,QVariant))); @@ -14,9 +27,29 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : // New parameters from UAS connect(mav, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); + //connecto retransmissionTimer + connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); + } + +void UASParameterCommsMgr::loadParamCommsSettings() +{ + QSettings settings; + settings.beginGroup("QGC_MAVLINK_PROTOCOL"); + bool valid; + int val = settings.value("PARAMETER_RETRANSMISSION_TIMEOUT", retransmissionTimeout).toInt(&ok); + if (valid) { + retransmissionTimeout = temp; + } + val = settings.value("PARAMETER_REWRITE_TIMEOUT", rewriteTimeout).toInt(&ok); + if (valid) { + rewriteTimeout = temp; + } + settings.endGroup(); +} + /** * Send a request to deliver the list of onboard parameters * from the MAV. @@ -271,8 +304,188 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV setRetransmissionGuardEnabled(true); } -void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg) +void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg, ParamCommsStatusLevel_t level) { qDebug() << "parameterStatusMsg: " << msg; parameterStatusMsg = msg; + + //TODO indicate OK status somehow (eg color) +// QPalette pal = statusLabel->palette(); +// pal.setColor(backgroundRole(), QGC::colorGreen); +// statusLabel->setPalette(pal); + +// pal.setColor(backgroundRole(), QGC::colorRed); + // pal.setColor(backgroundRole(), QGC::colorOrange); + + } + + +/** + * @param uas System which has the component + * @param component id of the component + * @param parameterName human friendly name of the parameter + */ +void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value) +{ + + // Missing packets list has to be instantiated for all components + if (!transmissionMissingPackets.contains(compId)) { + transmissionMissingPackets.insert(compId, new QList()); + } + + // List mode is different from single parameter transfers + if (transmissionListMode) { + // Only accept the list size once on the first packet from + // each component + if (!transmissionListSizeKnown.contains(compId)) { + // Mark list size as known + transmissionListSizeKnown.insert(compId, true); + + // Mark all parameters as missing + for (int i = 0; i < paramCount; ++i) { + if (!transmissionMissingPackets.value(compId)->contains(i)) { + transmissionMissingPackets.value(compId)->append(i); + } + } + + // There is only one transmission timeout for all components + // since components do not manage their transmission, + // the longest timeout is safe for all components. + quint64 thisTransmissionTimeout = QGC::groundTimeMilliseconds() + ((paramCount)*retransmissionTimeout); + if (thisTransmissionTimeout > transmissionTimeout) { + transmissionTimeout = thisTransmissionTimeout; + } + } + + // Start retransmission guard + // or reset timer + paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO + } + + // Mark this parameter as received in read list + int index = transmissionMissingPackets.value(compId)->indexOf(paramId); + // If the MAV sent the parameter without request, it wont be in missing list + if (index != -1) { + transmissionMissingPackets.value(compId)->removeAt(index); + } + + bool justWritten = false; + bool writeMismatch = false; + //bool lastWritten = false; + // Mark this parameter as received in write ACK list + QMap* map = transmissionMissingWriteAckPackets.value(compId); + if (map && map->contains(paramName)) { + justWritten = true; + QVariant newval = map->value(paramName); + if (map->value(paramName) != value) { + writeMismatch = true; + } + map->remove(paramName); + } + + int missCount = 0; + foreach (int key, transmissionMissingPackets.keys()) { + missCount += transmissionMissingPackets.value(key)->count(); + } + + int missWriteCount = 0; + foreach (int key, transmissionMissingWriteAckPackets.keys()) { + missWriteCount += transmissionMissingWriteAckPackets.value(key)->count(); + } + + //TODO simplify this if-else tree + if (justWritten && !writeMismatch && missWriteCount == 0) { + // Just wrote one and count went to 0 - this was the last missing write parameter + setParameterStatusMsg(tr("SUCCESS: WROTE ALL PARAMETERS")); + } + else if (justWritten && !writeMismatch) { + setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount)); + } + else if (justWritten && writeMismatch) { + // Mismatch, tell user + setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(map->value(paramName).toDouble()).arg(value.toDouble()), + ParamCommsStatusLevel_Warning); + } + else { + QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); + if (missCount == 0) { + // Transmission done + QTime time = QTime::currentTime(); + QString timeString = time.toString(); + setParameterStatusMsg(tr("All received. (updated at %1)").arg(timeString)); + } + else { + // Transmission in progress + setParameterStatusMsg(tr("OK: %1 %2 (%3/%4)").arg(paramName).arg(val).arg(paramCount-missCount).arg(paramCount), + ParamCommsStatusLevel_Warning); + } + } + + // Check if last parameter was received + if (missCount == 0 && missWriteCount == 0) { + this->transmissionActive = false; + this->transmissionListMode = false; + transmissionListSizeKnown.clear(); + foreach (int key, transmissionMissingPackets.keys()) { + transmissionMissingPackets.value(key)->clear(); + } + + //all parameters have been received, broadcast to UI + emit parameterListUpToDate(); + //TODO in UI + // Expand visual tree + //tree->expandItem(tree->topLevelItem(0)); + } +} + + +void UASParameterCommsMgr::writeParamsToPersistentStorage() +{ + if (mav) { + mav->writeParametersToStorage(); //TODO track timeout, retransmit etc? + } +} + + +void UASParameterCommsMgr::sendPendingParameters() +{ + // Iterate through all components, through all pending parameters and send them to UAS + int parametersSent = 0; + QMap*> changedValues = paramDataModel->getPendingParameters(); + QMap*>::iterator i; + for (i = changedValues.begin(); i != changedValues.end(); ++i) { + // Iterate through the parameters of the component + int compid = i.key(); + QMap* comp = i.value(); + { + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) { + //TODO mavlink command for "set parameter list" ? + setParameter(compid, j.key(), j.value()); + parametersSent++; + } + } + } + + // Change transmission status if necessary + if (parametersSent == 0) { + setParameterStatusMsg(tr("No transmission: No changed values."),ParamCommsStatusLevel_Warning); + } else { + setParameterStatusMsg(tr("Transmitting %1 parameters.").arg(parametersSent)); + // Set timeouts + if (transmissionActive) { + transmissionTimeout += parametersSent*rewriteTimeout; + } + else { + transmissionActive = true; + quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + parametersSent*rewriteTimeout; + if (newTransmissionTimeout > transmissionTimeout) { + transmissionTimeout = newTransmissionTimeout; + } + } + // Enable guard + setRetransmissionGuardEnabled(true); + } +} + diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 72da05d8f8..ff366c38e1 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -10,9 +10,19 @@ class UASInterface; class UASParameterDataModel; + + class UASParameterCommsMgr : public QObject { Q_OBJECT + +typedef enum ParamCommsStatusLevel { + ParamCommsStatusLevel_OK = 0, + ParamCommsStatusLevel_Warning = 2, + ParamCommsStatusLevel_Error = 4, + ParamCommsStatusLevel_Count +} ParamCommsStatusLevel_t; + public: explicit UASParameterCommsMgr(QObject *parent = 0, UASInterface* uas = NULL); @@ -21,19 +31,30 @@ protected: /** @brief Activate / deactivate parameter retransmission */ virtual void setRetransmissionGuardEnabled(bool enabled); - virtual void setParameterStatusMsg(const QString& msg); + virtual void setParameterStatusMsg(const QString& msg, ParamCommsStatusLevel_t level=ParamCommsStatusLevel_OK); + + /** @brief Load settings that control eg retransmission timeouts */ + void loadParamCommsSettings(); signals: void parameterChanged(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); - void parameterValueConfirmed(int component, QString parameter, QVariant value); + void parameterValueConfirmed(int uas, int component,int paramCount, int paramId, QString parameter, QVariant value); void parameterListUpToDate(int component); void parameterUpdateRequested(int component, const QString& parameter); void parameterUpdateRequestedById(int componentId, int paramId); + /** @brief We updated the parameter status message */ + void parameterStatusMsgUpdated(QString msg, ParamCommsStatusLevel_t level); public slots: + /** @brief Iterate through all components, through all pending parameters and send them to UAS */ + virtual void sendPendingParameters(); + + /** @brief Write the current onboard parameters from transient RAM into persistent storage, e.g. EEPROM or harddisk */ + virtual void writeParamsToPersistentStorage(); + /** @brief Write one parameter to the MAV */ virtual void setParameter(int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ @@ -44,6 +65,12 @@ public slots: /** @brief Request a single parameter update by name */ virtual void requestParameterUpdate(int component, const QString& parameter); + virtual void receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value); + +protected slots: + void receivedParameterChange(int uas, int component, QString parameterName, QVariant value); + void receivedParameterListChange(int uas, int component, int parameterCount, int parameterId, QString parameterName, QVariant value); + protected: UASInterface* mav; ///< The MAV we're talking to diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index d678385dcf..0a5f9d9724 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -103,13 +103,13 @@ void UASParameterDataModel::setOnboardParameterWithType(int componentId, QString } } -void UASParameterDataModel::addComponent(int componentId) +void UASParameterDataModel::addComponent(int compId) { - if (!onboardParameters.contains(componentId)) { - onboardParameters.insert(componentId, new QMap()); + if (!onboardParameters.contains(compId)) { + onboardParameters.insert(compId, new QMap()); } - if (!pendingParameters.contains(componentId)) { - pendingParameters.insert(componentId, new QMap()); + if (!pendingParameters.contains(compId)) { + pendingParameters.insert(compId, new QMap()); } } diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 0f89ed4365..240d375071 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -14,6 +14,7 @@ public: explicit UASParameterDataModel(QObject *parent = 0); + int getTotalOnboardParams() { return totalOnboardParameters; } //Parameter meta info bool isParamMinKnown(const QString& param) { return paramMin.contains(param); } virtual bool isValueLessThanParamMin(const QString& param, double dblVal); @@ -28,8 +29,11 @@ public: virtual QString getParamDescription(const QString& param) { return paramDescriptions.value(param, ""); } virtual void setParamDescriptions(const QMap& paramInfo); - - virtual void addComponent(int componentId); + //TODO make this method protected? + /** @brief Ensure that the data model is aware of this component + * @param compId Id of the component + */ + virtual void addComponent(int compId); /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ virtual void setPendingParameter(int componentId, QString& key, const QVariant& value); @@ -83,6 +87,8 @@ public: signals: + void parameterUpdated(int compId, int paramId, QString paramName, QVariant value); + public slots: @@ -90,6 +96,7 @@ protected: int uasId; ///< The UAS / MAV to which this data model pertains QMap* > pendingParameters; ///< Changed values that have not yet been transmitted to the UAS, by component ID QMap* > onboardParameters; ///< All parameters confirmed to be stored onboard the UAS, by component ID + int totalOnboardParameters;///< The known count of onboard parameters, may not match onboardParameters until all params are received // Tooltip data structures QMap paramDescriptions; ///< Tooltip values diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 4c973cd2aa..97e0d1eb31 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -36,12 +36,13 @@ This file is part of the QGROUNDCONTROL project #include #include #include +#include -#include "QGCParamWidget.h" -#include "UASInterface.h" #include "MainWindow.h" -#include #include "QGC.h" +#include "QGCParamWidget.h" +#include "UASInterface.h" +#include "UASParameterCommsMgr.h" /** * @param uas MAV to set the parameters on @@ -51,13 +52,6 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QGCUASParamManager(uas, parent), componentItems(new QMap()) { - // Load settings - loadSettings(); - - // Load default values and tooltips - QString autoPilotName(uas->getAutopilotTypeName()); - QString sysTypeName(uas->getSystemTypeName()); - loadParamMetaInfoCSV(autoPilotName, sysTypeName); // Create tree widget tree = new QTreeWidget(this); @@ -145,14 +139,10 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); - connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); - - +// connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); // connect(this, SIGNAL(requestParameter(int,QString)), uas, SLOT(requestParameter(int,QString))); // connect(this, SIGNAL(requestParameter(int,int)), uas, SLOT(requestParameter(int,int))); - - // Get parameters if (uas) { requestAllParamsUpdate(); @@ -160,245 +150,203 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : } -void QGCParamWidget::loadSettings() -{ - QSettings settings; - settings.beginGroup("QGC_MAVLINK_PROTOCOL"); - bool ok; - int temp = settings.value("PARAMETER_RETRANSMISSION_TIMEOUT", retransmissionTimeout).toInt(&ok); - if (ok) retransmissionTimeout = temp; - temp = settings.value("PARAMETER_REWRITE_TIMEOUT", rewriteTimeout).toInt(&ok); - if (ok) rewriteTimeout = temp; - settings.endGroup(); -} - - -void QGCParamWidget::loadParamMetaInfoCSV(const QString& autopilot, const QString& airframe) -{ - Q_UNUSED(airframe); - qDebug() << "ATTEMPTING TO LOAD CSV"; - QDir appDir = QApplication::applicationDirPath(); - appDir.cd("files"); - QString fileName = QString("%1/%2/parameter_tooltips/tooltips.txt").arg(appDir.canonicalPath()).arg(autopilot.toLower()); - QFile paramMetaFile(fileName); - qDebug() << "AUTOPILOT:" << autopilot; - qDebug() << "FILENAME: " << fileName; - - // Load CSV data - if (!paramMetaFile.open(QIODevice::ReadOnly | QIODevice::Text)) - { - //qDebug() << "COULD NOT OPEN PARAM META INFO FILE:" << fileName; - return; - } - - - QTextStream in(¶mMetaFile); - paramDataModel->loadParamMetaInfoFromStream(in); - paramMetaFile.close(); - -} - -/** - * @return The MAV of this widget. Unless the MAV object has been destroyed, this - * pointer is never zero. - */ -UASInterface* QGCParamWidget::getUAS() -{ - return mav; -} - -/** - * - * @param uas System which has the component - * @param component id of the component - * @param componentName human friendly name of the component - */ -void QGCParamWidget::addComponentItem(int uas, int component, QString componentName) +void QGCParamWidget::addComponentItem( int compId, QString compName) { - Q_UNUSED(uas); - if (componentItems->contains(component)) { + if (componentItems->contains(compId)) { // Update existing - componentItems->value(component)->setData(0, Qt::DisplayRole, QString("%1 (#%2)").arg(componentName).arg(component)); + componentItems->value(compId)->setData(0, Qt::DisplayRole, QString("%1 (#%2)").arg(compName).arg(compId)); //components->value(component)->setData(1, Qt::DisplayRole, QString::number(component)); - componentItems->value(component)->setFirstColumnSpanned(true); + componentItems->value(compId)->setFirstColumnSpanned(true); } else { // Add new - QStringList list(QString("%1 (#%2)").arg(componentName).arg(component)); + QStringList list(QString("%1 (#%2)").arg(compName).arg(compId)); QTreeWidgetItem* comp = new QTreeWidgetItem(list); comp->setFirstColumnSpanned(true); - componentItems->insert(component, comp); + componentItems->insert(compId, comp); // Create grouping and update maps - paramGroups.insert(component, new QMap()); + paramGroups.insert(compId, new QMap()); tree->addTopLevelItem(comp); tree->update(); } - paramDataModel->addComponent(component); + //TODO it seems unlikely that the UI would know about a component before the data model... + paramDataModel->addComponent(compId); } + + /** * @param uas System which has the component * @param component id of the component * @param parameterName human friendly name of the parameter */ -void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) +//void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) +//{ + +// updateParameterDisplay(component, parameterName, value); + +// // Missing packets list has to be instantiated for all components +// if (!transmissionMissingPackets.contains(component)) { +// transmissionMissingPackets.insert(component, new QList()); +// } + +// // List mode is different from single parameter transfers +// if (transmissionListMode) { +// // Only accept the list size once on the first packet from +// // each component +// if (!transmissionListSizeKnown.contains(component)) +// { +// // Mark list size as known +// transmissionListSizeKnown.insert(component, true); + +// // Mark all parameters as missing +// for (int i = 0; i < paramCount; ++i) +// { +// if (!transmissionMissingPackets.value(component)->contains(i)) +// { +// transmissionMissingPackets.value(component)->append(i); +// } +// } + +// // There is only one transmission timeout for all components +// // since components do not manage their transmission, +// // the longest timeout is safe for all components. +// quint64 thisTransmissionTimeout = QGC::groundTimeMilliseconds() + ((paramCount)*retransmissionTimeout); +// if (thisTransmissionTimeout > transmissionTimeout) +// { +// transmissionTimeout = thisTransmissionTimeout; +// } +// } + +// // Start retransmission guard +// // or reset timer +// paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO +// } + +// // Mark this parameter as received in read list +// int index = transmissionMissingPackets.value(component)->indexOf(paramId); +// // If the MAV sent the parameter without request, it wont be in missing list +// if (index != -1) transmissionMissingPackets.value(component)->removeAt(index); + +// bool justWritten = false; +// bool writeMismatch = false; +// //bool lastWritten = false; +// // Mark this parameter as received in write ACK list +// QMap* map = transmissionMissingWriteAckPackets.value(component); +// if (map && map->contains(parameterName)) +// { +// justWritten = true; +// QVariant newval = map->value(parameterName); +// if (map->value(parameterName) != value) +// { +// writeMismatch = true; +// } +// map->remove(parameterName); +// } + +// int missCount = 0; +// foreach (int key, transmissionMissingPackets.keys()) +// { +// missCount += transmissionMissingPackets.value(key)->count(); +// } + +// int missWriteCount = 0; +// foreach (int key, transmissionMissingWriteAckPackets.keys()) +// { +// missWriteCount += transmissionMissingWriteAckPackets.value(key)->count(); +// } + +// if (justWritten && !writeMismatch && missWriteCount == 0) +// { +// // Just wrote one and count went to 0 - this was the last missing write parameter +// statusLabel->setText(tr("SUCCESS: WROTE ALL PARAMETERS")); +// QPalette pal = statusLabel->palette(); +// pal.setColor(backgroundRole(), QGC::colorGreen); +// statusLabel->setPalette(pal); +// } else if (justWritten && !writeMismatch) +// { +// statusLabel->setText(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(parameterName).arg(value.toDouble()).arg(paramCount)); +// QPalette pal = statusLabel->palette(); +// pal.setColor(backgroundRole(), QGC::colorGreen); +// statusLabel->setPalette(pal); +// } else if (justWritten && writeMismatch) +// { +// // Mismatch, tell user +// QPalette pal = statusLabel->palette(); +// pal.setColor(backgroundRole(), QGC::colorRed); +// statusLabel->setPalette(pal); +// statusLabel->setText(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(parameterName).arg(map->value(parameterName).toDouble()).arg(value.toDouble())); +// } +// else +// { +// if (missCount > 0) +// { +// QPalette pal = statusLabel->palette(); +// pal.setColor(backgroundRole(), QGC::colorOrange); +// statusLabel->setPalette(pal); +// } +// else +// { +// QPalette pal = statusLabel->palette(); +// pal.setColor(backgroundRole(), QGC::colorGreen); +// statusLabel->setPalette(pal); +// } +// QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); +// //statusLabel->setText(tr("OK: %1 %2 #%3/%4, %5 miss").arg(parameterName).arg(val).arg(paramId+1).arg(paramCount).arg(missCount)); +// if (missCount == 0) +// { +// // Transmission done +// QTime time = QTime::currentTime(); +// QString timeString = time.toString(); +// statusLabel->setText(tr("All received. (updated at %1)").arg(timeString)); +// } +// else +// { +// // Transmission in progress +// statusLabel->setText(tr("OK: %1 %2 (%3/%4)").arg(parameterName).arg(val).arg(paramCount-missCount).arg(paramCount)); +// } +// } + +// // Check if last parameter was received +// if (missCount == 0 && missWriteCount == 0) +// { +// this->transmissionActive = false; +// this->transmissionListMode = false; +// transmissionListSizeKnown.clear(); +// foreach (int key, transmissionMissingPackets.keys()) +// { +// transmissionMissingPackets.value(key)->clear(); +// } + +// // Expand visual tree +// tree->expandItem(tree->topLevelItem(0)); +// } +//} + + +void QGCParamWidget::handleParameterUpdate(int componentId, int paramCount, int paramId, const QString& paramName, QVariant value) { + Q_UNUSED(paramCount); + Q_UNUSED(paramId); + updateParameterDisplay(componentId, paramName, value); +} - updateParameterDisplay(uas, component, parameterName, value); - - // Missing packets list has to be instantiated for all components - if (!transmissionMissingPackets.contains(component)) { - transmissionMissingPackets.insert(component, new QList()); - } - - // List mode is different from single parameter transfers - if (transmissionListMode) { - // Only accept the list size once on the first packet from - // each component - if (!transmissionListSizeKnown.contains(component)) - { - // Mark list size as known - transmissionListSizeKnown.insert(component, true); - - // Mark all parameters as missing - for (int i = 0; i < paramCount; ++i) - { - if (!transmissionMissingPackets.value(component)->contains(i)) - { - transmissionMissingPackets.value(component)->append(i); - } - } - - // There is only one transmission timeout for all components - // since components do not manage their transmission, - // the longest timeout is safe for all components. - quint64 thisTransmissionTimeout = QGC::groundTimeMilliseconds() + ((paramCount)*retransmissionTimeout); - if (thisTransmissionTimeout > transmissionTimeout) - { - transmissionTimeout = thisTransmissionTimeout; - } - } - - // Start retransmission guard - // or reset timer - setRetransmissionGuardEnabled(true); - } - - // Mark this parameter as received in read list - int index = transmissionMissingPackets.value(component)->indexOf(paramId); - // If the MAV sent the parameter without request, it wont be in missing list - if (index != -1) transmissionMissingPackets.value(component)->removeAt(index); - - bool justWritten = false; - bool writeMismatch = false; - //bool lastWritten = false; - // Mark this parameter as received in write ACK list - QMap* map = transmissionMissingWriteAckPackets.value(component); - if (map && map->contains(parameterName)) - { - justWritten = true; - QVariant newval = map->value(parameterName); - if (map->value(parameterName) != value) - { - writeMismatch = true; - } - map->remove(parameterName); - } - - int missCount = 0; - foreach (int key, transmissionMissingPackets.keys()) - { - missCount += transmissionMissingPackets.value(key)->count(); - } - - int missWriteCount = 0; - foreach (int key, transmissionMissingWriteAckPackets.keys()) - { - missWriteCount += transmissionMissingWriteAckPackets.value(key)->count(); - } - - if (justWritten && !writeMismatch && missWriteCount == 0) - { - // Just wrote one and count went to 0 - this was the last missing write parameter - statusLabel->setText(tr("SUCCESS: WROTE ALL PARAMETERS")); - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorGreen); - statusLabel->setPalette(pal); - } else if (justWritten && !writeMismatch) - { - statusLabel->setText(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(parameterName).arg(value.toDouble()).arg(paramCount)); - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorGreen); - statusLabel->setPalette(pal); - } else if (justWritten && writeMismatch) - { - // Mismatch, tell user - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorRed); - statusLabel->setPalette(pal); - statusLabel->setText(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(parameterName).arg(map->value(parameterName).toDouble()).arg(value.toDouble())); - } - else - { - if (missCount > 0) - { - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorOrange); - statusLabel->setPalette(pal); - } - else - { - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorGreen); - statusLabel->setPalette(pal); - } - QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); - //statusLabel->setText(tr("OK: %1 %2 #%3/%4, %5 miss").arg(parameterName).arg(val).arg(paramId+1).arg(paramCount).arg(missCount)); - if (missCount == 0) - { - // Transmission done - QTime time = QTime::currentTime(); - QString timeString = time.toString(); - statusLabel->setText(tr("All received. (updated at %1)").arg(timeString)); - } - else - { - // Transmission in progress - statusLabel->setText(tr("OK: %1 %2 (%3/%4)").arg(parameterName).arg(val).arg(paramCount-missCount).arg(paramCount)); - } - } - - // Check if last parameter was received - if (missCount == 0 && missWriteCount == 0) - { - this->transmissionActive = false; - this->transmissionListMode = false; - transmissionListSizeKnown.clear(); - foreach (int key, transmissionMissingPackets.keys()) - { - transmissionMissingPackets.value(key)->clear(); - } - // Expand visual tree - tree->expandItem(tree->topLevelItem(0)); - } +void QGCParamWidget::handleParameterListUpToDate(int component) +{ + // Expand visual tree + tree->expandItem(tree->topLevelItem(0)); } -/** - * @param uas System which has the component - * @param component id of the component - * @param parameterName human friendly name of the parameter - */ -void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString parameterName, QVariant value) -{ - Q_UNUSED(uas); +void QGCParamWidget::updateParameterDisplay(int componentId, QString parameterName, QVariant value) +{ // QString ptrStr; // ptrStr.sprintf("%8p", this); @@ -410,11 +358,12 @@ void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString pa // Get component if (!componentItems->contains(componentId)) { QString componentName = tr("Component #%1").arg(componentId); - addComponentItem(uas, componentId, componentName); + addComponentItem(componentId, componentName); } - // Replace value in data model - paramDataModel->handleParameterUpdate(componentId,parameterName,value); + //TODO this should be bubbling up from the model, not vice-versa, right? +// // Replace value in data model +// paramDataModel->handleParameterUpdate(componentId,parameterName,value); QString splitToken = "_"; @@ -439,36 +388,30 @@ void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString pa for (int i = 0; i < parentItem->childCount(); i++) { QTreeWidgetItem* child = parentItem->child(i); QString key = child->data(0, Qt::DisplayRole).toString(); - if (key == parameterName) - { + if (key == parameterName) { //qDebug() << "UPDATED CHILD"; parameterItem = child; - if (value.type() == QVariant::Char) - { + if (value.type() == QVariant::Char) { parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); } - else - { + else { parameterItem->setData(1, Qt::DisplayRole, value); } found = true; } } - if (!found) - { + if (!found) { // Insert parameter into map QStringList plist; plist.append(parameterName); // CREATE PARAMETER ITEM parameterItem = new QTreeWidgetItem(plist); // CONFIGURE PARAMETER ITEM - if (value.type() == QVariant::Char) - { + if (value.type() == QVariant::Char) { parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); } - else - { + else { parameterItem->setData(1, Qt::DisplayRole, value); } @@ -476,16 +419,13 @@ void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString pa parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); } } - else - { + else { bool found = false; QTreeWidgetItem* parent = componentItems->value(componentId); - for (int i = 0; i < parent->childCount(); i++) - { + for (int i = 0; i < parent->childCount(); i++) { QTreeWidgetItem* child = parent->child(i); QString key = child->data(0, Qt::DisplayRole).toString(); - if (key == parameterName) - { + if (key == parameterName) { //qDebug() << "UPDATED CHILD"; parameterItem = child; parameterItem->setData(1, Qt::DisplayRole, value); @@ -493,8 +433,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString pa } } - if (!found) - { + if (!found) { // Insert parameter into map QStringList plist; plist.append(parameterName); @@ -525,7 +464,7 @@ void QGCParamWidget::updateParameterDisplay(int uas, int componentId, QString pa parameterItem->setToolTip(0, tooltipFormat); parameterItem->setToolTip(1, tooltipFormat); - paramDataModel->handleParameterUpdate(componentId,parameterName,value); + //paramDataModel->handleParameterUpdate(componentId,parameterName,value); } @@ -600,21 +539,12 @@ void QGCParamWidget::setParameterStatusMsg(const QString& msg) statusLabel->setText(msg); } - - void QGCParamWidget::requestAllParamsUpdate() { if (!mav) { return; } - // FIXME This call does not belong here - // Once the comm handling is moved to a new - // Param manager class the settings can be directly - // loaded from MAVLink protocol - loadSettings(); - // End of FIXME - // Clear view and request param list clear(); @@ -628,45 +558,7 @@ void QGCParamWidget::requestAllParamsUpdate() */ void QGCParamWidget::setParameters() { - // Iterate through all components, through all parameters and emit them - int parametersSent = 0; - QMap*> changedValues = paramDataModel->getPendingParameters(); - QMap*>::iterator i; - for (i = changedValues.begin(); i != changedValues.end(); ++i) { - // Iterate through the parameters of the component - int compid = i.key(); - QMap* comp = i.value(); - { - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) { - //TODO mavlink command for "set parameter list" ? - setParameter(compid, j.key(), j.value()); - parametersSent++; - } - } - } - - // Change transmission status if necessary - if (parametersSent == 0) { - statusLabel->setText(tr("No transmission: No changed values.")); - } else { - statusLabel->setText(tr("Transmitting %1 parameters.").arg(parametersSent)); - // Set timeouts - if (transmissionActive) - { - transmissionTimeout += parametersSent*rewriteTimeout; - } - else - { - transmissionActive = true; - quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + parametersSent*rewriteTimeout; - if (newTransmissionTimeout > transmissionTimeout) { - transmissionTimeout = newTransmissionTimeout; - } - } - // Enable guard - setRetransmissionGuardEnabled(true); - } + paramCommsMgr->sendPendingParameters(); } /** @@ -680,28 +572,19 @@ void QGCParamWidget::writeParameters() QMap*>::iterator i; QMap*> changedValues = paramDataModel->getPendingParameters(); - for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) - { + for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) { // Iterate through the parameters of the component - QMap* comp = i.value(); - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) - { - changedParamCount++; - break;//it only takes one changed param to warrant warning the user - } + QMap* compPending = i.value(); + changedParamCount += compPending->count(); } - if (changedParamCount > 0) - { + if (changedParamCount > 0) { QMessageBox msgBox; msgBox.setText(tr("There are locally changed parameters. Please transmit them first () or update them with the onboard values () before storing onboard from RAM to ROM.")); msgBox.exec(); } - else - { - if (!mav) return; - mav->writeParametersToStorage(); + else { + paramCommsMgr->writeParamsToPersistentStorage(); } } @@ -796,7 +679,7 @@ void QGCParamWidget::setParameter(int component, QString parameterName, QVariant } // Enable guard / reset timeouts - setRetransmissionGuardEnabled(true); + paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO } void QGCParamWidget::readParameters() diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index af58eabf3f..0ada126d7e 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -48,9 +48,6 @@ class QGCParamWidget : public QGCUASParamManager Q_OBJECT public: QGCParamWidget(UASInterface* uas, QWidget *parent = 0); - /** @brief Get the UAS of this widget */ - UASInterface* getUAS(); - protected: virtual void setParameterStatusMsg(const QString& msg); @@ -61,12 +58,20 @@ signals: public slots: - /** @brief Add a component to the list */ - void addComponentItem(int uas, int component, QString componentName); + /** @brief Add a component to the list + * @param compId Component id of the component + * @param compName Human friendly name of the component + */ + void addComponentItem(int compId, QString compName); + /** @brief Add a parameter to the list with retransmission / safety checks */ - void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); - /** @brief Add a parameter to the list */ - void updateParameterDisplay(int uas, int component, QString parameterName, QVariant value); +// void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); + + virtual void handleParameterUpdate(int component, int paramCount, int paramId, const QString& parameterName, QVariant value); + virtual void handleParameterListUpToDate(int component); + + /** @brief Ensure that view of parameter matches data in the model */ + void updateParameterDisplay(int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ void requestAllParamsUpdate(); /** @brief Set one parameter, changes value in RAM of MAV */ @@ -91,17 +96,11 @@ public slots: protected: QTreeWidget* tree; ///< The parameter tree - QLabel* statusLabel; ///< Parameter transmission label - QMap* componentItems; ///< The list of component items, stored by component ID - QMap* > paramGroups; ///< Parameter groups - - + QLabel* statusLabel; ///< User-facing parameter status label + QMap* componentItems; ///< The tree of component items, stored by component ID + QMap* > paramGroups; ///< Parameter groups to organize component items - /** @brief Load settings */ - void loadSettings(); - /** @brief Load meta information from CSV */ - void loadParamMetaInfoCSV(const QString& autopilot, const QString& airframe); }; #endif // QGCPARAMWIDGET_H -- GitLab From 4e19c3a06e7ac96dda51c807c77686f8c8100ed2 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 7 Aug 2013 18:11:39 -0700 Subject: [PATCH 229/460] fix build --- src/uas/QGCUASParamManager.cc | 15 ++- src/uas/QGCUASParamManager.h | 9 +- src/uas/UASParameterCommsMgr.cc | 32 +++--- src/uas/UASParameterCommsMgr.h | 25 ++-- src/ui/QGCParamWidget.cc | 197 +++++++++++++++++--------------- src/ui/QGCParamWidget.h | 6 +- 6 files changed, 161 insertions(+), 123 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 79b03d2059..186bfac74b 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -1,6 +1,9 @@ #include "QGCUASParamManager.h" -#include "UASInterface.h" +#include > +#include + +#include "UASInterface.h" #include "UASParameterCommsMgr.h" QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : @@ -28,15 +31,15 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : void parameterUpdated(int compId, int paramId, QString paramName, QVariant value); connect(paramDataModel, SIGNAL(parameterUpdated(int, int, QString , QVariant )), - this, SLOT(handleParameterUpdate(int,int,int,QString,QVariant)); + this, SLOT(handleParameterUpdate(int,int,int,QString,QVariant))); // connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), // this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); // Listen for param list reload finished - connect(paramCommsMgr, SIGNAL(parameterListUpToDate(int)), - this, SLOT(handleParameterListUpToDate(int)))); + connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), + this, SLOT(handleParameterListUpToDate())); @@ -206,6 +209,10 @@ void QGCUASParamManager::setParamDescriptions(const QMap& param } +void QGCUASParamManager::setParameter(int component, QString parameterName, QVariant value) +{ + paramCommsMgr->setParameter(component,parameterName,value); +} void QGCUASParamManager::loadParamMetaInfoCSV() diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 313c0927ad..3c1fb7e78c 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -43,16 +43,17 @@ signals: public slots: - /** @brief Write one parameter to the MAV */ - virtual void setParameter(int component, QString parameterName, QVariant value) = 0; + /** @brief Send one parameter to the MAV: changes value in transient memory of MAV */ + virtual void setParameter(int component, QString parameterName, QVariant value); + /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); - /** @brief Request a single parameter by name */ + /** @brief Request a single parameter by name from the MAV */ virtual void requestParameterUpdate(int component, const QString& parameter); virtual void handleParameterUpdate(int component, int paramCount, int paramId, const QString& parameterName, QVariant value) = 0; - virtual void handleParameterListUpToDate(int component) = 0; + virtual void handleParameterListUpToDate() = 0; protected: diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 22940e5fd3..594e2447ec 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -1,5 +1,7 @@ #include "UASParameterCommsMgr.h" +#include + #include "QGCUASParamManager.h" #include "UASInterface.h" @@ -38,14 +40,14 @@ void UASParameterCommsMgr::loadParamCommsSettings() { QSettings settings; settings.beginGroup("QGC_MAVLINK_PROTOCOL"); - bool valid; + bool ok; int val = settings.value("PARAMETER_RETRANSMISSION_TIMEOUT", retransmissionTimeout).toInt(&ok); - if (valid) { - retransmissionTimeout = temp; + if (ok) { + retransmissionTimeout = val; } val = settings.value("PARAMETER_REWRITE_TIMEOUT", rewriteTimeout).toInt(&ok); - if (valid) { - rewriteTimeout = temp; + if (ok) { + rewriteTimeout = val; } settings.endGroup(); } @@ -224,17 +226,23 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV double dblValue = value.toDouble(); if (paramDataModel->isValueLessThanParamMin(parameterName,dblValue)) { - setParameterStatusMsg(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); + setParameterStatusMsg(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue), + ParamCommsStatusLevel_Error + ); return; } if (paramDataModel->isValueGreaterThanParamMax(parameterName,dblValue)) { - setParameterStatusMsg(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); + setParameterStatusMsg(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue), + ParamCommsStatusLevel_Error + ); return; } QVariant onboardVal; paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); if (onboardVal == value) { - setParameterStatusMsg(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue)); + setParameterStatusMsg(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue), + ParamCommsStatusLevel_Warning + ); return; } @@ -246,28 +254,24 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV { QVariant fixedValue(QChar((unsigned char)value.toInt())); emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; } break; case QVariant::Int: { QVariant fixedValue(value.toInt()); emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; } break; case QVariant::UInt: { QVariant fixedValue(value.toUInt()); emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; } break; case QMetaType::Float: { QVariant fixedValue(value.toFloat()); emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; } break; default: @@ -309,6 +313,8 @@ void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg, ParamCommsS qDebug() << "parameterStatusMsg: " << msg; parameterStatusMsg = msg; + emit parameterStatusMsgUpdated(msg,level); + //TODO indicate OK status somehow (eg color) // QPalette pal = statusLabel->palette(); // pal.setColor(backgroundRole(), QGC::colorGreen); @@ -360,7 +366,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para // Start retransmission guard // or reset timer - paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO + setRetransmissionGuardEnabled(true); //TODO } // Mark this parameter as received in read list diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index ff366c38e1..68c908bade 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -16,16 +16,16 @@ class UASParameterCommsMgr : public QObject { Q_OBJECT -typedef enum ParamCommsStatusLevel { - ParamCommsStatusLevel_OK = 0, - ParamCommsStatusLevel_Warning = 2, - ParamCommsStatusLevel_Error = 4, - ParamCommsStatusLevel_Count -} ParamCommsStatusLevel_t; public: explicit UASParameterCommsMgr(QObject *parent = 0, UASInterface* uas = NULL); - + typedef enum ParamCommsStatusLevel { + ParamCommsStatusLevel_OK = 0, + ParamCommsStatusLevel_Warning = 2, + ParamCommsStatusLevel_Error = 4, + ParamCommsStatusLevel_Count + } ParamCommsStatusLevel_t; + protected: /** @brief Activate / deactivate parameter retransmission */ @@ -41,7 +41,9 @@ signals: void parameterChanged(int component, int parameterIndex, QVariant value); void parameterValueConfirmed(int uas, int component,int paramCount, int paramId, QString parameter, QVariant value); - void parameterListUpToDate(int component); + /** @brief We have received a complete list of all parameters onboard the MAV */ + void parameterListUpToDate(); + void parameterUpdateRequested(int component, const QString& parameter); void parameterUpdateRequestedById(int componentId, int paramId); @@ -57,6 +59,7 @@ public slots: /** @brief Write one parameter to the MAV */ virtual void setParameter(int component, QString parameterName, QVariant value); + /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); /** @brief Check for missing parameters */ @@ -67,9 +70,9 @@ public slots: virtual void receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value); -protected slots: - void receivedParameterChange(int uas, int component, QString parameterName, QVariant value); - void receivedParameterListChange(int uas, int component, int parameterCount, int parameterId, QString parameterName, QVariant value); +//protected slots: +// void receivedParameterChange(int uas, int component, QString parameterName, QVariant value); +// void receivedParameterListChange(int uas, int component, int parameterCount, int parameterId, QString parameterName, QVariant value); protected: diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 97e0d1eb31..09ee9c970a 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -27,16 +27,17 @@ This file is part of the QGROUNDCONTROL project */ #include #include -#include -#include -#include +#include +#include #include +#include +#include + #include -#include -#include #include -#include -#include +#include +#include +#include #include "MainWindow.h" #include "QGC.h" @@ -338,7 +339,7 @@ void QGCParamWidget::handleParameterUpdate(int componentId, int paramCount, int } -void QGCParamWidget::handleParameterListUpToDate(int component) +void QGCParamWidget::handleParameterListUpToDate() { // Expand visual tree tree->expandItem(tree->topLevelItem(0)); @@ -593,94 +594,95 @@ void QGCParamWidget::writeParameters() * @param parameterName name of the parameter, as delivered by the system * @param value value of the parameter */ -void QGCParamWidget::setParameter(int component, QString parameterName, QVariant value) -{ - if (parameterName.isEmpty()) { - return; - } +//void QGCParamWidget::setParameter(int component, QString parameterName, QVariant value) +//{ - double dblValue = value.toDouble(); +// if (parameterName.isEmpty()) { +// return; +// } - if (paramDataModel->isValueLessThanParamMin(parameterName,dblValue)) { - statusLabel->setText(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); - return; - } - if (paramDataModel->isValueGreaterThanParamMax(parameterName,dblValue)) { - statusLabel->setText(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); - return; - } - QVariant onboardVal; - paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); - if (onboardVal == value) { - statusLabel->setText(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue)); - return; - } +// double dblValue = value.toDouble(); - //int paramType = (int)onboardParameters.value(component)->value(parameterName).type(); - int paramType = (int)value.type(); - switch (paramType) - { - case QVariant::Char: - { - QVariant fixedValue(QChar((unsigned char)value.toInt())); - emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; - } - break; - case QVariant::Int: - { - QVariant fixedValue(value.toInt()); - emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; - } - break; - case QVariant::UInt: - { - QVariant fixedValue(value.toUInt()); - emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; - } - break; - case QMetaType::Float: - { - QVariant fixedValue(value.toFloat()); - emit parameterChanged(component, parameterName, fixedValue); - //qDebug() << "PARAM WIDGET SENT:" << fixedValue; - } - break; - default: - qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE"; - return; - } +// if (paramDataModel->isValueLessThanParamMin(parameterName,dblValue)) { +// statusLabel->setText(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); +// return; +// } +// if (paramDataModel->isValueGreaterThanParamMax(parameterName,dblValue)) { +// statusLabel->setText(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); +// return; +// } +// QVariant onboardVal; +// paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); +// if (onboardVal == value) { +// statusLabel->setText(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue)); +// return; +// } - // Wait for parameter to be written back - // mark it therefore as missing - if (!transmissionMissingWriteAckPackets.contains(component)) - { - transmissionMissingWriteAckPackets.insert(component, new QMap()); - } +// //int paramType = (int)onboardParameters.value(component)->value(parameterName).type(); +// int paramType = (int)value.type(); +// switch (paramType) +// { +// case QVariant::Char: +// { +// QVariant fixedValue(QChar((unsigned char)value.toInt())); +// emit parameterChanged(component, parameterName, fixedValue); +// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; +// } +// break; +// case QVariant::Int: +// { +// QVariant fixedValue(value.toInt()); +// emit parameterChanged(component, parameterName, fixedValue); +// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; +// } +// break; +// case QVariant::UInt: +// { +// QVariant fixedValue(value.toUInt()); +// emit parameterChanged(component, parameterName, fixedValue); +// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; +// } +// break; +// case QMetaType::Float: +// { +// QVariant fixedValue(value.toFloat()); +// emit parameterChanged(component, parameterName, fixedValue); +// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; +// } +// break; +// default: +// qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE"; +// return; +// } - // Insert it in missing write ACK list - transmissionMissingWriteAckPackets.value(component)->insert(parameterName, value); +// // Wait for parameter to be written back +// // mark it therefore as missing +// if (!transmissionMissingWriteAckPackets.contains(component)) +// { +// transmissionMissingWriteAckPackets.insert(component, new QMap()); +// } - // Set timeouts - if (transmissionActive) - { - transmissionTimeout += rewriteTimeout; - } - else - { - quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + rewriteTimeout; - if (newTransmissionTimeout > transmissionTimeout) - { - transmissionTimeout = newTransmissionTimeout; - } - transmissionActive = true; - } +// // Insert it in missing write ACK list +// transmissionMissingWriteAckPackets.value(component)->insert(parameterName, value); - // Enable guard / reset timeouts - paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO -} +// // Set timeouts +// if (transmissionActive) +// { +// transmissionTimeout += rewriteTimeout; +// } +// else +// { +// quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + rewriteTimeout; +// if (newTransmissionTimeout > transmissionTimeout) +// { +// transmissionTimeout = newTransmissionTimeout; +// } +// transmissionActive = true; +// } + +// // Enable guard / reset timeouts +// paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO +//} void QGCParamWidget::readParameters() { @@ -696,3 +698,20 @@ void QGCParamWidget::clear() tree->clear(); componentItems->clear(); } + +void QGCParamWidget::handleParamStatusMsgUpdate(QString msg, int level) +{ + QColor bgColor = QGC::colorGreen; + if ((int)UASParameterCommsMgr::ParamCommsStatusLevel_Warning == level) { + bgColor = QGC::colorOrange; + } + else if ((int)UASParameterCommsMgr::ParamCommsStatusLevel_Error == level) { + bgColor = QGC::colorRed; + } + + QPalette pal = statusLabel->palette(); + pal.setColor(backgroundRole(), bgColor); + statusLabel->setPalette(pal); + statusLabel->setText(msg); + +} diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 0ada126d7e..3d2f7779eb 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -68,14 +68,16 @@ public slots: // void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); virtual void handleParameterUpdate(int component, int paramCount, int paramId, const QString& parameterName, QVariant value); - virtual void handleParameterListUpToDate(int component); + virtual void handleParameterListUpToDate(); + + virtual void handleParamStatusMsgUpdate(QString msg, int level); /** @brief Ensure that view of parameter matches data in the model */ void updateParameterDisplay(int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ void requestAllParamsUpdate(); /** @brief Set one parameter, changes value in RAM of MAV */ - virtual void setParameter(int component, QString parameterName, QVariant value); +// virtual void setParameter(int component, QString parameterName, QVariant value); /** @brief Set all parameters, changes the value in RAM of MAV */ void setParameters(); /** @brief Write the current parameters to permanent storage (EEPROM/HDD) */ -- GitLab From abed8afec83e34f9282b133290e0f1c6b4dbc563 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 7 Aug 2013 18:28:58 -0700 Subject: [PATCH 230/460] fixing signals / slots --- src/uas/QGCUASParamManager.cc | 12 ++++++------ src/uas/QGCUASParamManager.h | 2 +- src/uas/UASParameterDataModel.cc | 11 +++++++---- src/uas/UASParameterDataModel.h | 3 ++- src/ui/QGCParamWidget.cc | 3 +-- src/ui/QGCParamWidget.h | 2 +- src/ui/uas/UASListWidget.cc | 2 +- 7 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 186bfac74b..450fe79701 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -18,9 +18,9 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : loadParamMetaInfoCSV(); - // Connect retransmission guard - connect(this, SIGNAL(parameterUpdateRequested(int,QString)), - this, SLOT(requestParameterUpdate(int,QString))); +// // Connect retransmission guard +// connect(this, SIGNAL(parameterUpdateRequested(int,QString)), +// this, SLOT(requestParameterUpdate(int,QString))); // //TODO connect in paramCommsMgr instead // connect(this, SIGNAL(parameterUpdateRequestedById(int,int)), @@ -28,10 +28,10 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : // New parameters from UAS - void parameterUpdated(int compId, int paramId, QString paramName, QVariant value); + void parameterUpdated(int compId, QString paramName, QVariant value); - connect(paramDataModel, SIGNAL(parameterUpdated(int, int, QString , QVariant )), - this, SLOT(handleParameterUpdate(int,int,int,QString,QVariant))); + connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), + this, SLOT(handleParameterUpdate(int,QString,QVariant))); // connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), // this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 3c1fb7e78c..4cb6d446c1 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -52,7 +52,7 @@ public slots: /** @brief Request a single parameter by name from the MAV */ virtual void requestParameterUpdate(int component, const QString& parameter); - virtual void handleParameterUpdate(int component, int paramCount, int paramId, const QString& parameterName, QVariant value) = 0; + virtual void handleParameterUpdate(int component, int paramId, const QString& parameterName, QVariant value) = 0; virtual void handleParameterListUpToDate() = 0; diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 0a5f9d9724..9815ce7779 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -114,12 +114,12 @@ void UASParameterDataModel::addComponent(int compId) } -void UASParameterDataModel::handleParameterUpdate(int componentId, QString& key, QVariant& value) +void UASParameterDataModel::handleParameterUpdate(int compId, QString& key, QVariant& value) { //verify that the value requested by the user matches the set value //if it doesn't match, leave the pending parameter in the pending list! - if (pendingParameters.contains(componentId)) { - QMap *pendingParams = pendingParameters.value(componentId); + if (pendingParameters.contains(compId)) { + QMap *pendingParams = pendingParameters.value(compId); if ((NULL != pendingParams) && pendingParams->contains(key)) { QVariant reqVal = pendingParams->value(key); if (reqVal == value) { @@ -131,7 +131,10 @@ void UASParameterDataModel::handleParameterUpdate(int componentId, QString& key, } } - setOnboardParameter(componentId,key, value); + setOnboardParameter(compId,key,value); + + emit parameterUpdated(compId,key,value); + } bool UASParameterDataModel::getOnboardParameterValue(int componentId, const QString& key, QVariant& value) const diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 240d375071..352fb0eea6 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -87,7 +87,8 @@ public: signals: - void parameterUpdated(int compId, int paramId, QString paramName, QVariant value); + /** @brief We've received an update of a parameter's value */ + void parameterUpdated(int compId, QString paramName, QVariant value); public slots: diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 09ee9c970a..5b4b137239 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -331,9 +331,8 @@ void QGCParamWidget::addComponentItem( int compId, QString compName) //} -void QGCParamWidget::handleParameterUpdate(int componentId, int paramCount, int paramId, const QString& paramName, QVariant value) +void QGCParamWidget::handleParameterUpdate(int componentId, int paramId, const QString& paramName, QVariant value) { - Q_UNUSED(paramCount); Q_UNUSED(paramId); updateParameterDisplay(componentId, paramName, value); } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 3d2f7779eb..49ae507402 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -67,7 +67,7 @@ public slots: /** @brief Add a parameter to the list with retransmission / safety checks */ // void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); - virtual void handleParameterUpdate(int component, int paramCount, int paramId, const QString& parameterName, QVariant value); + virtual void handleParameterUpdate(int component, int paramId, const QString& parameterName, QVariant value); virtual void handleParameterListUpToDate(); virtual void handleParamStatusMsgUpdate(QString msg, int level); diff --git a/src/ui/uas/UASListWidget.cc b/src/ui/uas/UASListWidget.cc index d1cdde02eb..2b000d3769 100644 --- a/src/ui/uas/UASListWidget.cc +++ b/src/ui/uas/UASListWidget.cc @@ -149,7 +149,7 @@ void UASListWidget::addUAS(UASInterface* uas) QList* x = uas->getLinks(); if (x->size()) { - LinkInterface* li = x->at(0); + LinkInterface* li = x->first(); // Find an existing QGroupBox for this LinkInterface or create a // new one. -- GitLab From 6e84f136b4fad5f43d965d1719d30525cd1437ea Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 7 Aug 2013 18:45:50 -0700 Subject: [PATCH 231/460] More signal /slot fixes --- src/uas/QGCUASParamManager.cc | 5 ----- src/uas/QGCUASParamManager.h | 2 +- src/ui/QGCParamWidget.cc | 21 +++++++++++++++------ src/ui/QGCParamWidget.h | 2 +- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 450fe79701..f1cc5fd20c 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -30,16 +30,11 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : void parameterUpdated(int compId, QString paramName, QVariant value); - connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), - this, SLOT(handleParameterUpdate(int,QString,QVariant))); // connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), // this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); - // Listen for param list reload finished - connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), - this, SLOT(handleParameterListUpToDate())); diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 4cb6d446c1..a5c4b40f2f 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -52,7 +52,7 @@ public slots: /** @brief Request a single parameter by name from the MAV */ virtual void requestParameterUpdate(int component, const QString& parameter); - virtual void handleParameterUpdate(int component, int paramId, const QString& parameterName, QVariant value) = 0; + virtual void handleParameterUpdate(int component, const QString& parameterName, QVariant value) = 0; virtual void handleParameterListUpToDate() = 0; diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 5b4b137239..5ec85bceba 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -133,17 +133,27 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : tree->setExpandsOnDoubleClick(true); // Connect signals/slots - connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), mav, SLOT(setParameter(int,QString,QVariant))); - connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); +// connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), +// mav, SLOT(setParameter(int,QString,QVariant))); + connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), + this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); - // New parameters from UAS - connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); +// // New parameters from UAS +// connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); // connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); // connect(this, SIGNAL(requestParameter(int,QString)), uas, SLOT(requestParameter(int,QString))); // connect(this, SIGNAL(requestParameter(int,int)), uas, SLOT(requestParameter(int,int))); + + connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), + this, SLOT(handleParameterUpdate(int,QString,QVariant))); + + // Listen for param list reload finished + connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), + this, SLOT(handleParameterListUpToDate())); + // Get parameters if (uas) { requestAllParamsUpdate(); @@ -331,9 +341,8 @@ void QGCParamWidget::addComponentItem( int compId, QString compName) //} -void QGCParamWidget::handleParameterUpdate(int componentId, int paramId, const QString& paramName, QVariant value) +void QGCParamWidget::handleParameterUpdate(int componentId, const QString& paramName, QVariant value) { - Q_UNUSED(paramId); updateParameterDisplay(componentId, paramName, value); } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 49ae507402..5a356b722b 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -67,7 +67,7 @@ public slots: /** @brief Add a parameter to the list with retransmission / safety checks */ // void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); - virtual void handleParameterUpdate(int component, int paramId, const QString& parameterName, QVariant value); + virtual void handleParameterUpdate(int component,const QString& parameterName, QVariant value); virtual void handleParameterListUpToDate(); virtual void handleParamStatusMsgUpdate(QString msg, int level); -- GitLab From 764e22c92abc6981d52ca003281eac3f9202b562 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 06:37:44 -0700 Subject: [PATCH 232/460] fix setting of current mav in QGCConfigView --- src/ui/QGCConfigView.cc | 10 ++++++---- src/ui/QGCConfigView.h | 2 +- src/ui/QGCPX4VehicleConfig.cc | 17 ++++++++++------- src/ui/QGCVehicleConfig.cc | 1 + 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/ui/QGCConfigView.cc b/src/ui/QGCConfigView.cc index fb8f519b73..16fc3ecf94 100644 --- a/src/ui/QGCConfigView.cc +++ b/src/ui/QGCConfigView.cc @@ -8,7 +8,7 @@ QGCConfigView::QGCConfigView(QWidget *parent) : QWidget(parent), ui(new Ui::QGCConfigView), - currUAS(NULL) + mav(NULL) { ui->setupUi(this); @@ -26,7 +26,7 @@ QGCConfigView::~QGCConfigView() void QGCConfigView::activeUASChanged(UASInterface* uas) { - if (currUAS == uas) + if (mav == uas) return; //remove all child widgets since they could contain stale data @@ -41,11 +41,13 @@ void QGCConfigView::activeUASChanged(UASInterface* uas) } } - if (NULL != uas) { + mav = uas; + if (NULL != mav) { ui->gridLayout->removeWidget(ui->waitingLabel); ui->waitingLabel->setVisible(false); - switch (uas->getAutopilotType()) { + int autopilotType = mav->getAutopilotType(); + switch (autopilotType) { case MAV_AUTOPILOT_PX4: ui->gridLayout->addWidget(new QGCPX4VehicleConfig()); break; diff --git a/src/ui/QGCConfigView.h b/src/ui/QGCConfigView.h index 182d50c3b7..0c1bda9a57 100644 --- a/src/ui/QGCConfigView.h +++ b/src/ui/QGCConfigView.h @@ -21,7 +21,7 @@ public slots: private: Ui::QGCConfigView *ui; - UASInterface* currUAS; + UASInterface* mav; }; diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index f43f20a881..d526ed53b3 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -941,6 +941,7 @@ void QGCPX4VehicleConfig::writeCalibrationRC() // Do not write the RC type, as these values depend on this // active onboard parameter + //TODO consolidate RC param sending in the UAS comms mgr for (unsigned int i = 0; i < chanCount; ++i) { //qDebug() << "SENDING" << minTpl.arg(i+1) << rcMin[i]; @@ -975,7 +976,9 @@ void QGCPX4VehicleConfig::writeCalibrationRC() void QGCPX4VehicleConfig::requestCalibrationRC() { - if (!mav) return; + if (!mav ) { + return; + } QString minTpl("RC%1_MIN"); QString maxTpl("RC%1_MAX"); @@ -985,15 +988,15 @@ void QGCPX4VehicleConfig::requestCalibrationRC() // Do not request the RC type, as these values depend on this // active onboard parameter - for (unsigned int i = 0; i < chanMax; ++i) - { - mav->requestParameter(0, minTpl.arg(i+1)); + for (unsigned int i = 1; i < (chanMax+1); ++i) { + qDebug() << "Request RC " << i; + mav->requestParameter(0, minTpl.arg(i)); QGC::SLEEP::usleep(5000); - mav->requestParameter(0, trimTpl.arg(i+1)); + mav->requestParameter(0, trimTpl.arg(i)); QGC::SLEEP::usleep(5000); - mav->requestParameter(0, maxTpl.arg(i+1)); + mav->requestParameter(0, maxTpl.arg(i)); QGC::SLEEP::usleep(5000); - mav->requestParameter(0, revTpl.arg(i+1)); + mav->requestParameter(0, revTpl.arg(i)); QGC::SLEEP::usleep(5000); } } diff --git a/src/ui/QGCVehicleConfig.cc b/src/ui/QGCVehicleConfig.cc index dd2c769a7a..ce923ff49f 100644 --- a/src/ui/QGCVehicleConfig.cc +++ b/src/ui/QGCVehicleConfig.cc @@ -937,6 +937,7 @@ void QGCVehicleConfig::writeCalibrationRC() // Do not write the RC type, as these values depend on this // active onboard parameter + //TODO consolidate RC param sending in the UAS comms mgr for (unsigned int i = 0; i < chanCount; ++i) { //qDebug() << "SENDING" << minTpl.arg(i+1) << rcMin[i]; -- GitLab From d683fa331cc049ea1b2b140050feeacf30c840ec Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 06:56:38 -0700 Subject: [PATCH 233/460] Move requestCalibrationRC into commsmgr --- src/uas/UASParameterCommsMgr.cc | 31 +++++++++++++++++++++++++++++++ src/uas/UASParameterCommsMgr.h | 3 +++ src/ui/QGCPX4VehicleConfig.cc | 28 +++++----------------------- src/ui/QGCVehicleConfig.cc | 26 +++++--------------------- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 594e2447ec..25e772b3cc 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -5,6 +5,8 @@ #include "QGCUASParamManager.h" #include "UASInterface.h" +#define RC_CAL_CHAN_MAX 8 + UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : QObject(parent), mav(uas), @@ -212,6 +214,35 @@ void UASParameterCommsMgr::requestParameterUpdate(int component, const QString& } } +void UASParameterCommsMgr::requestRcCalibrationParamsUpdate() +{ + if (!transmissionListMode) { + QString minTpl("RC%1_MIN"); + QString maxTpl("RC%1_MAX"); + QString trimTpl("RC%1_TRIM"); + QString revTpl("RC%1_REV"); + + // Do not request the RC type, as these values depend on this + // active onboard parameter + + for (unsigned int i = 1; i < (RC_CAL_CHAN_MAX+1); ++i) { + qDebug() << "Request RC " << i; + mav->requestParameter(0, minTpl.arg(i)); + QGC::SLEEP::usleep(5000); + mav->requestParameter(0, trimTpl.arg(i)); + QGC::SLEEP::usleep(5000); + mav->requestParameter(0, maxTpl.arg(i)); + QGC::SLEEP::usleep(5000); + mav->requestParameter(0, revTpl.arg(i)); + QGC::SLEEP::usleep(5000); + } + } + else { + qDebug() << __FILE__ << __LINE__ << "Ignoring requestRcCalibrationParamsUpdate because we're receiving params list"; + } +} + + /** * @param component the subsystem which has the parameter * @param parameterName name of the parameter, as delivered by the system diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 68c908bade..03f24bb1d7 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -68,6 +68,9 @@ public slots: /** @brief Request a single parameter update by name */ virtual void requestParameterUpdate(int component, const QString& parameter); + /** @brief Request an update of RC parameters */ + virtual void requestRcCalibrationParamsUpdate(); + virtual void receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value); //protected slots: diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index d526ed53b3..708d5a0b7b 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -13,9 +13,11 @@ #include #include "QGCPX4VehicleConfig.h" -#include "UASManager.h" + #include "QGC.h" #include "QGCToolWidget.h" +#include "UASManager.h" +#include "UASParameterCommsMgr.h" #include "ui_QGCPX4VehicleConfig.h" @@ -976,28 +978,8 @@ void QGCPX4VehicleConfig::writeCalibrationRC() void QGCPX4VehicleConfig::requestCalibrationRC() { - if (!mav ) { - return; - } - - QString minTpl("RC%1_MIN"); - QString maxTpl("RC%1_MAX"); - QString trimTpl("RC%1_TRIM"); - QString revTpl("RC%1_REV"); - - // Do not request the RC type, as these values depend on this - // active onboard parameter - - for (unsigned int i = 1; i < (chanMax+1); ++i) { - qDebug() << "Request RC " << i; - mav->requestParameter(0, minTpl.arg(i)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, trimTpl.arg(i)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, maxTpl.arg(i)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, revTpl.arg(i)); - QGC::SLEEP::usleep(5000); + if (mav) { + mav->getParamCommsMgr()->requestRcCalibrationParamsUpdate(); } } diff --git a/src/ui/QGCVehicleConfig.cc b/src/ui/QGCVehicleConfig.cc index ce923ff49f..a296f28ff3 100644 --- a/src/ui/QGCVehicleConfig.cc +++ b/src/ui/QGCVehicleConfig.cc @@ -13,9 +13,11 @@ #include #include "QGCVehicleConfig.h" -#include "UASManager.h" + #include "QGC.h" #include "QGCToolWidget.h" +#include "UASManager.h" +#include "UASParameterCommsMgr.h" #include "ui_QGCVehicleConfig.h" QGCVehicleConfig::QGCVehicleConfig(QWidget *parent) : @@ -972,26 +974,8 @@ void QGCVehicleConfig::writeCalibrationRC() void QGCVehicleConfig::requestCalibrationRC() { - if (!mav) return; - - QString minTpl("RC%1_MIN"); - QString maxTpl("RC%1_MAX"); - QString trimTpl("RC%1_TRIM"); - QString revTpl("RC%1_REV"); - - // Do not request the RC type, as these values depend on this - // active onboard parameter - - for (unsigned int i = 0; i < chanMax; ++i) - { - mav->requestParameter(0, minTpl.arg(i+1)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, trimTpl.arg(i+1)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, maxTpl.arg(i+1)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, revTpl.arg(i+1)); - QGC::SLEEP::usleep(5000); + if (mav) { + mav->getParamCommsMgr()->requestRcCalibrationParamsUpdate(); } } -- GitLab From 7b81776c73e72830b9022076c639f72fd97dc63e Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 07:03:29 -0700 Subject: [PATCH 234/460] fix setActiveUAS; fix build warnings for enum switches --- src/ui/designer/QGCParamSlider.cc | 49 ++++++++++++++++--------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/ui/designer/QGCParamSlider.cc b/src/ui/designer/QGCParamSlider.cc index 7f76759424..e927dea032 100644 --- a/src/ui/designer/QGCParamSlider.cc +++ b/src/ui/designer/QGCParamSlider.cc @@ -92,31 +92,32 @@ void QGCParamSlider::refreshParamList() void QGCParamSlider::setActiveUAS(UASInterface* activeUas) { - if (activeUas) { - // Set param info - if (!parameterName.isEmpty()) { - //disconnect from any existing uas signals - if (uas != activeUas) { - disconnect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant))); - connect(activeUas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant)), Qt::UniqueConnection); - uas = activeUas; - } - QString text = uas->getParamDataModel()->getParamDescription(parameterName); - if (!text.isEmpty()) { - ui->infoLabel->setToolTip(text); - ui->infoLabel->show(); - } - // Force-uncheck and hide label if no description is available - if (ui->editInfoCheckBox->isChecked()) { - showInfo((text.length() > 0)); - } + if (uas != activeUas) { + if (uas) { + disconnect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), + this, SLOT(setParameterValue(int,int,int,int,QString,QVariant))); } - else { - //when parameter widgets are first loaded, they are disconnected from any parameter? - qWarning() << __FILE__ << ":" << __LINE__ << "slider has no parameterName??"; + if (activeUas) { + connect(activeUas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), + this, SLOT(setParameterValue(int,int,int,int,QString,QVariant)), Qt::UniqueConnection); } + uas = activeUas; } + + if (uas && !parameterName.isEmpty()) { + QString text = uas->getParamDataModel()->getParamDescription(parameterName); + if (!text.isEmpty()) { + ui->infoLabel->setToolTip(text); + ui->infoLabel->show(); + } + // Force-uncheck and hide label if no description is available + if (ui->editInfoCheckBox->isChecked()) { + showInfo((text.length() > 0)); + } + } + + } void QGCParamSlider::requestParameter() @@ -245,7 +246,7 @@ void QGCParamSlider::endEditMode() ui->writeButton->show(); ui->readButton->show(); ui->valueSlider->show(); - switch (parameterValue.type()) + switch ((int)parameterValue.type()) { case QVariant::Char: case QVariant::Int: @@ -289,7 +290,7 @@ void QGCParamSlider::setSliderValue(int sliderValue) if (!valueModLock && !valueModLockParam) { valueModLock = true; - switch (parameterValue.type()) + switch ((int)parameterValue.type()) { case QVariant::Char: parameterValue = QVariant(QChar((unsigned char)scaledIntToFloat(sliderValue))); @@ -393,7 +394,7 @@ void QGCParamSlider::setParameterValue(int uas, int component, int paramCount, i parameterValue = value; ui->valueSlider->setEnabled(true); valueModLockParam = true; - switch (value.type()) + switch ((int)value.type()) { case QVariant::Char: ui->intValueSpinBox->show(); -- GitLab From 959fc8faec0f16f26eec2dc74f5a4d2e4974257c Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 07:08:56 -0700 Subject: [PATCH 235/460] Fix miswired slot/signals --- src/ui/PrimaryFlightDisplay.cc | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/ui/PrimaryFlightDisplay.cc b/src/ui/PrimaryFlightDisplay.cc index d0070d2292..651500ea23 100644 --- a/src/ui/PrimaryFlightDisplay.cc +++ b/src/ui/PrimaryFlightDisplay.cc @@ -267,15 +267,24 @@ void PrimaryFlightDisplay::forgetUAS(UASInterface* uas) { if (this->uas != NULL && this->uas == uas) { // Disconnect any previously connected active MAV - disconnect(this->uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*, double, double, double, quint64))); - disconnect(this->uas, SIGNAL(attitudeChanged(UASInterface*,int,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*,int,double, double, double, quint64))); - disconnect(this->uas, SIGNAL(waypointSelected(int,int)), this, SLOT(selectWaypoint(int, int))); - disconnect(this->uas, SIGNAL(primarySpeedChanged(UASInterface*, double, quint64)), this, SLOT(updatePrimarySpeed(UASInterface*,double,quint64))); - disconnect(this->uas, SIGNAL(gpsSpeedChanged(UASInterface*, double, quint64)), this, SLOT(updateGPSSpeed(UASInterface*,double,quint64))); - disconnect(this->uas, SIGNAL(climbRateChanged(UASInterface*, double, quint64)), this, SLOT(updateClimbRate(UASInterface*, AltitudeMeasurementSource, double, quint64))); - disconnect(this->uas, SIGNAL(primaryAltitudeChanged(UASInterface*, double, quint64)), this, SLOT(updatePrimaryAltitude(UASInterface*, double, quint64))); - disconnect(this->uas, SIGNAL(gpsAltitudeChanged(UASInterface*, double, quint64)), this, SLOT(updateGPSAltitude(UASInterface*, double, quint64))); - disconnect(this->uas, SIGNAL(navigationControllerErrorsChanged(UASInterface*, double, double, double)), this, SLOT(updateNavigationControllerErrors(UASInterface*, double, double, double))); + disconnect(this->uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), + this, SLOT(updateAttitude(UASInterface*, double, double, double, quint64))); + disconnect(this->uas, SIGNAL(attitudeChanged(UASInterface*,int,double,double,double,quint64)), + this, SLOT(updateAttitude(UASInterface*,int,double, double, double, quint64))); + //disconnect(this->uas, SIGNAL(waypointSelected(int,int)), + // this, SLOT(selectWaypoint(int, int))); + disconnect(this->uas, SIGNAL(primarySpeedChanged(UASInterface*, double, quint64)), + this, SLOT(updatePrimarySpeed(UASInterface*,double,quint64))); + disconnect(this->uas, SIGNAL(gpsSpeedChanged(UASInterface*, double, quint64)), + this, SLOT(updateGPSSpeed(UASInterface*,double,quint64))); + disconnect(this->uas, SIGNAL(climbRateChanged(UASInterface*, double, quint64)), + this,SLOT(updateClimbRate(UASInterface*, double, quint64))); + disconnect(this->uas, SIGNAL(primaryAltitudeChanged(UASInterface*, double, quint64)), + this, SLOT(updatePrimaryAltitude(UASInterface*, double, quint64))); + disconnect(this->uas, SIGNAL(gpsAltitudeChanged(UASInterface*, double, quint64)), + this, SLOT(updateGPSAltitude(UASInterface*, double, quint64))); + disconnect(this->uas, SIGNAL(navigationControllerErrorsChanged(UASInterface*, double, double, double)), + this, SLOT(updateNavigationControllerErrors(UASInterface*, double, double, double))); //disconnect(this->uas, SIGNAL(batteryChanged(UASInterface*, double, double, double, int)), this, SLOT(updateBattery(UASInterface*, double, double, double, int))); //disconnect(this->uas, SIGNAL(statusChanged(UASInterface*,QString,QString)), this, SLOT(updateState(UASInterface*,QString))); @@ -314,10 +323,12 @@ void PrimaryFlightDisplay::setActiveUAS(UASInterface* uas) //connect(uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateLocalPosition(UASInterface*,double,double,double,quint64))); //connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64))); - connect(uas, SIGNAL(waypointSelected(int,int)), this, SLOT(selectWaypoint(int, int))); + //connect(uas, SIGNAL(waypointSelected(int,int)), this, + // SLOT(selectWaypoint(int, int))); connect(uas, SIGNAL(primarySpeedChanged(UASInterface*, double, quint64)), this, SLOT(updatePrimarySpeed(UASInterface*,double,quint64))); connect(uas, SIGNAL(gpsSpeedChanged(UASInterface*, double, quint64)), this, SLOT(updateGPSSpeed(UASInterface*,double,quint64))); - connect(uas, SIGNAL(climbRateChanged(UASInterface*, double, quint64)), this, SLOT(updateClimbRate(UASInterface*, AltitudeMeasurementSource, double, quint64))); + connect(uas, SIGNAL(climbRateChanged(UASInterface*, double, quint64)), this, + SLOT(updateClimbRate(UASInterface*, double, quint64))); connect(uas, SIGNAL(primaryAltitudeChanged(UASInterface*, double, quint64)), this, SLOT(updatePrimaryAltitude(UASInterface*, double, quint64))); connect(uas, SIGNAL(gpsAltitudeChanged(UASInterface*, double, quint64)), this, SLOT(updateGPSAltitude(UASInterface*, double, quint64))); connect(uas, SIGNAL(navigationControllerErrorsChanged(UASInterface*, double, double, double)), this, SLOT(updateNavigationControllerErrors(UASInterface*, double, double, double))); -- GitLab From ead568d8a309518dd4505da9813cfc9249b63823 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 07:24:24 -0700 Subject: [PATCH 236/460] Fix signal/slot mismatch; update formatting of some signal/slot wiring --- src/uas/UASParameterCommsMgr.cc | 9 ++-- src/ui/HSIDisplay.cc | 83 +++++++++++++++++++++------------ 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 25e772b3cc..26a5ce4da2 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -26,13 +26,16 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : mav, SLOT(requestParameter(int,int))); // Sending params to the UAS - connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), mav, SLOT(setParameter(int,QString,QVariant))); + connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), + mav, SLOT(setParameter(int,QString,QVariant))); // New parameters from UAS - connect(mav, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); + connect(mav, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), + this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); //connecto retransmissionTimer - connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); + connect(&retransmissionTimer, SIGNAL(timeout()), + this, SLOT(retransmissionGuardTick())); } diff --git a/src/ui/HSIDisplay.cc b/src/ui/HSIDisplay.cc index d3a2a9d2a3..8974032bfa 100644 --- a/src/ui/HSIDisplay.cc +++ b/src/ui/HSIDisplay.cc @@ -950,35 +950,60 @@ void HSIDisplay::setActiveUAS(UASInterface* uas) if (uas) { - connect(uas, SIGNAL(gpsSatelliteStatusChanged(int,int,float,float,float,bool)), this, SLOT(updateSatellite(int,int,float,float,float,bool))); - connect(uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateLocalPosition(UASInterface*,double,double,double,quint64))); - connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64))); - connect(uas, SIGNAL(attitudeThrustSetPointChanged(UASInterface*,double,double,double,double,quint64)), this, SLOT(updateAttitudeSetpoints(UASInterface*,double,double,double,double,quint64))); - connect(uas, SIGNAL(positionSetPointsChanged(int,float,float,float,float,quint64)), this, SLOT(updatePositionSetpoints(int,float,float,float,float,quint64))); - connect(uas, SIGNAL(userPositionSetPointsChanged(int,float,float,float,float)), this, SLOT(updateUserPositionSetpoints(int,float,float,float,float))); - connect(uas, SIGNAL(speedChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateSpeed(UASInterface*,double,double,double,quint64))); - connect(uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*,double,double,double,quint64))); - - connect(uas, SIGNAL(attitudeControlEnabled(bool)), this, SLOT(updateAttitudeControllerEnabled(bool))); - connect(uas, SIGNAL(positionXYControlEnabled(bool)), this, SLOT(updatePositionXYControllerEnabled(bool))); - connect(uas, SIGNAL(positionZControlEnabled(bool)), this, SLOT(updatePositionZControllerEnabled(bool))); - connect(uas, SIGNAL(positionYawControlEnabled(bool)), this, SLOT(updatePositionYawControllerEnabled(bool))); - - connect(uas, SIGNAL(localizationChanged(UASInterface*,int)), this, SLOT(updateLocalization(UASInterface*,int))); - connect(uas, SIGNAL(visionLocalizationChanged(UASInterface*,int)), this, SLOT(updateVisionLocalization(UASInterface*,int))); - connect(uas, SIGNAL(gpsLocalizationChanged(UASInterface*,int)), this, SLOT(updateGpsLocalization(UASInterface*,int))); - connect(uas, SIGNAL(irUltraSoundLocalizationChanged(UASInterface*,int)), this, SLOT(updateInfraredUltrasoundLocalization(UASInterface*,int))); - connect(uas, SIGNAL(objectDetected(uint,int,int,QString,int,float,float)), this, SLOT(updateObjectPosition(uint,int,int,QString,int,float,float))); - - connect(uas, SIGNAL(gyroStatusChanged(bool,bool,bool)), this, SLOT(updateGyroStatus(bool,bool,bool))); - connect(uas, SIGNAL(accelStatusChanged(bool,bool,bool)), this, SLOT(updateAccelStatus(bool,bool,bool))); - connect(uas, SIGNAL(magSensorStatusChanged(bool,bool,bool)), this, SLOT(updateMagSensorStatus(bool,bool,bool))); - connect(uas, SIGNAL(baroStatusChanged(bool,bool,bool)), this, SLOT(updateBaroStatus(bool,bool,bool))); - connect(uas, SIGNAL(airspeedStatusChanged(bool,bool,bool)), this, SLOT(updateAirspeedStatus(bool,bool,bool))); - connect(uas, SIGNAL(opticalFlowStatusChanged(bool,bool,bool)), this, SLOT(updateOpticalFlowStatus(bool,bool,bool))); - connect(uas, SIGNAL(laserStatusChanged(bool,bool,bool)), this, SLOT(updateLaserStatus(bool,bool,bool))); - connect(uas, SIGNAL(groundTruthSensorStatusChanged(bool,bool,bool)), this, SLOT(updateGroundTruthSensorStatus(bool,bool,bool))); - connect(uas, SIGNAL(actuatorStatusChanged(bool,bool,bool)), this, SLOT(updateActuatorStatus(bool,bool,bool))); + connect(uas, SIGNAL(gpsSatelliteStatusChanged(int,int,float,float,float,bool)), + this, SLOT(updateSatellite(int,int,float,float,float,bool))); + connect(uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), + this, SLOT(updateLocalPosition(UASInterface*,double,double,double,quint64))); + connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), + this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64))); + connect(uas, SIGNAL(attitudeThrustSetPointChanged(UASInterface*,double,double,double,double,quint64)), + this, SLOT(updateAttitudeSetpoints(UASInterface*,double,double,double,double,quint64))); + connect(uas, SIGNAL(positionSetPointsChanged(int,float,float,float,float,quint64)), + this, SLOT(updatePositionSetpoints(int,float,float,float,float,quint64))); + connect(uas, SIGNAL(userPositionSetPointsChanged(int,float,float,float,float)), + this, SLOT(updateUserPositionSetpoints(int,float,float,float,float))); + connect(uas, SIGNAL(velocityChanged_NED(UASInterface*,double,double,double,quint64)), + this, SLOT(updateSpeed(UASInterface*,double,double,double,quint64))); + connect(uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), + this, SLOT(updateAttitude(UASInterface*,double,double,double,quint64))); + connect(uas, SIGNAL(attitudeControlEnabled(bool)), + this, SLOT(updateAttitudeControllerEnabled(bool))); + connect(uas, SIGNAL(positionXYControlEnabled(bool)), + this, SLOT(updatePositionXYControllerEnabled(bool))); + connect(uas, SIGNAL(positionZControlEnabled(bool)), + this, SLOT(updatePositionZControllerEnabled(bool))); + connect(uas, SIGNAL(positionYawControlEnabled(bool)), + this, SLOT(updatePositionYawControllerEnabled(bool))); + + connect(uas, SIGNAL(localizationChanged(UASInterface*,int)), + this, SLOT(updateLocalization(UASInterface*,int))); + connect(uas, SIGNAL(visionLocalizationChanged(UASInterface*,int)), + this, SLOT(updateVisionLocalization(UASInterface*,int))); + connect(uas, SIGNAL(gpsLocalizationChanged(UASInterface*,int)), + this, SLOT(updateGpsLocalization(UASInterface*,int))); + connect(uas, SIGNAL(irUltraSoundLocalizationChanged(UASInterface*,int)), + this, SLOT(updateInfraredUltrasoundLocalization(UASInterface*,int))); + connect(uas, SIGNAL(objectDetected(uint,int,int,QString,int,float,float)), + this, SLOT(updateObjectPosition(uint,int,int,QString,int,float,float))); + + connect(uas, SIGNAL(gyroStatusChanged(bool,bool,bool)), + this, SLOT(updateGyroStatus(bool,bool,bool))); + connect(uas, SIGNAL(accelStatusChanged(bool,bool,bool)), + this, SLOT(updateAccelStatus(bool,bool,bool))); + connect(uas, SIGNAL(magSensorStatusChanged(bool,bool,bool)), + this, SLOT(updateMagSensorStatus(bool,bool,bool))); + connect(uas, SIGNAL(baroStatusChanged(bool,bool,bool)), + this, SLOT(updateBaroStatus(bool,bool,bool))); + connect(uas, SIGNAL(airspeedStatusChanged(bool,bool,bool)), + this, SLOT(updateAirspeedStatus(bool,bool,bool))); + connect(uas, SIGNAL(opticalFlowStatusChanged(bool,bool,bool)), + this, SLOT(updateOpticalFlowStatus(bool,bool,bool))); + connect(uas, SIGNAL(laserStatusChanged(bool,bool,bool)), + this, SLOT(updateLaserStatus(bool,bool,bool))); + connect(uas, SIGNAL(groundTruthSensorStatusChanged(bool,bool,bool)), + this, SLOT(updateGroundTruthSensorStatus(bool,bool,bool))); + connect(uas, SIGNAL(actuatorStatusChanged(bool,bool,bool)), + this, SLOT(updateActuatorStatus(bool,bool,bool))); statusClearTimer.start(3000); } else -- GitLab From 92843a3d209060ec2c4b3b588a2d272c682643ef Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 07:58:39 -0700 Subject: [PATCH 237/460] ignore duplicate request param list --- src/uas/UAS.cc | 2 +- src/uas/UASParameterCommsMgr.cc | 25 ++++++++++------- src/uas/UASParameterCommsMgr.h | 1 + src/ui/QGCPX4VehicleConfig.cc | 50 ++++++++++++++++----------------- src/ui/QGCPX4VehicleConfig.h | 3 ++ src/ui/QGCVehicleConfig.cc | 3 +- 6 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 772341413c..89f9d44e87 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -1999,7 +1999,7 @@ void UAS::sendMessage(mavlink_message_t message) if (LinkManager::instance()->getLinks().contains(link)) { sendMessage(link, message); - qDebug() << "SENT MESSAGE id" << message.msgid; + qDebug() << "SENT MESSAGE id" << message.msgid << "component" << message.compid; } else { diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 26a5ce4da2..e2231064db 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -70,18 +70,23 @@ void UASParameterCommsMgr::requestParameterList() //TODO check: no need to cause datamodel to forget params here? // paramDataModel->forgetAllOnboardParameters(); - // Clear transmission state - receivedParamsList.clear(); - transmissionListSizeKnown.clear(); + if (!transmissionListMode) { + // Clear transmission state + receivedParamsList.clear(); + transmissionListSizeKnown.clear(); - transmissionListMode = true; - foreach (int key, transmissionMissingPackets.keys()) { - transmissionMissingPackets.value(key)->clear(); - } - transmissionActive = true; + transmissionListMode = true; + foreach (int key, transmissionMissingPackets.keys()) { + transmissionMissingPackets.value(key)->clear(); + } + transmissionActive = true; - setParameterStatusMsg(tr("Requested param list.. waiting")); - mav->requestParameters(); + setParameterStatusMsg(tr("Requested param list.. waiting")); + mav->requestParameters(); + } + else { + qDebug() << __FILE__ << __LINE__ << "Ignoring requestParameterList because we're receiving params list"; + } } diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 03f24bb1d7..8f5a2eeb67 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -62,6 +62,7 @@ public slots: /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); + /** @brief Check for missing parameters */ virtual void retransmissionGuardTick(); diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 708d5a0b7b..177a5e0660 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -795,9 +795,12 @@ void QGCPX4VehicleConfig::loadConfig() xml.readNext(); } - mav->getParamManager()->setParamDescriptions(paramTooltips); + if (!paramTooltips.isEmpty()) { + mav->getParamManager()->setParamDescriptions(paramTooltips); + } doneLoadingConfig = true; - mav->requestParameters(); //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. + //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. + mav->getParamCommsMgr()->requestParameterList(); } void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) @@ -826,31 +829,28 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) // Disconnect old system disconnect(mav, SIGNAL(remoteControlChannelRawChanged(int,float)), this, SLOT(remoteControlChannelRawChanged(int,float))); + //TODO use paramCommsMgr instead disconnect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); - disconnect(ui->refreshButton,SIGNAL(clicked()),mav,SLOT(requestParameters())); + disconnect(ui->refreshButton,SIGNAL(clicked()), + paramCommsMgr,SLOT(requestParameterList())); // Delete all children from all fixed tabs. - foreach(QWidget* child, ui->generalLeftContents->findChildren()) - { + foreach(QWidget* child, ui->generalLeftContents->findChildren()) { child->deleteLater(); } - foreach(QWidget* child, ui->generalRightContents->findChildren()) - { + foreach(QWidget* child, ui->generalRightContents->findChildren()) { child->deleteLater(); } - foreach(QWidget* child, ui->advanceColumnContents->findChildren()) - { + foreach(QWidget* child, ui->advanceColumnContents->findChildren()) { child->deleteLater(); } - foreach(QWidget* child, ui->sensorContents->findChildren()) - { + foreach(QWidget* child, ui->sensorContents->findChildren()) { child->deleteLater(); } // And then delete any custom tabs - foreach(QWidget* child, additionalTabs) - { + foreach(QWidget* child, additionalTabs) { child->deleteLater(); } additionalTabs.clear(); @@ -866,6 +866,7 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) // Connect new system mav = active; + paramCommsMgr = mav->getParamCommsMgr(); // Reset current state resetCalibrationRC(); @@ -875,25 +876,23 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) chanCount = 0; // Connect new system - connect(active, SIGNAL(remoteControlChannelRawChanged(int,float)), this, + connect(mav, SIGNAL(remoteControlChannelRawChanged(int,float)), this, SLOT(remoteControlChannelRawChanged(int,float))); - connect(active, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, + connect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); - connect(ui->refreshButton, SIGNAL(clicked()), active, SLOT(requestParameters())); + connect(ui->refreshButton, SIGNAL(clicked()), + paramCommsMgr,SLOT(requestParameterList())); - if (systemTypeToParamMap.contains(mav->getSystemTypeName())) - { + if (systemTypeToParamMap.contains(mav->getSystemTypeName())) { paramToWidgetMap = systemTypeToParamMap[mav->getSystemTypeName()]; } - else - { + else { //Indication that we have no meta data for this system type. qDebug() << "No parameters defined for system type:" << mav->getSystemTypeName(); paramToWidgetMap = systemTypeToParamMap[mav->getSystemTypeName()]; } - if (!paramTooltips.isEmpty()) - { + if (!paramTooltips.isEmpty()) { mav->getParamManager()->setParamDescriptions(paramTooltips); } @@ -912,8 +911,7 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) ui->writeButton->setEnabled(true); ui->loadFileButton->setEnabled(true); ui->saveFileButton->setEnabled(true); - if (mav->getAutopilotTypeName() == "ARDUPILOTMEGA") - { + if (mav->getAutopilotTypeName() == "ARDUPILOTMEGA") { ui->readButton->hide(); ui->writeButton->hide(); } @@ -978,8 +976,8 @@ void QGCPX4VehicleConfig::writeCalibrationRC() void QGCPX4VehicleConfig::requestCalibrationRC() { - if (mav) { - mav->getParamCommsMgr()->requestRcCalibrationParamsUpdate(); + if (paramCommsMgr) { + paramCommsMgr->requestRcCalibrationParamsUpdate(); } } diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index b11d2e60e2..93761d52f2 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -10,6 +10,8 @@ #include "QGCToolWidget.h" #include "UASInterface.h" +class UASParameterCommsMgr; + namespace Ui { class QGCPX4VehicleConfig; } @@ -159,6 +161,7 @@ protected slots: protected: bool doneLoadingConfig; UASInterface* mav; ///< The current MAV + UASParameterCommsMgr* paramCommsMgr; ///< param comms mgr for the mav static const unsigned int chanMax = 8; ///< Maximum number of channels unsigned int chanCount; ///< Actual channels int rcType; ///< Type of the remote control diff --git a/src/ui/QGCVehicleConfig.cc b/src/ui/QGCVehicleConfig.cc index a296f28ff3..2aa2ead2e6 100644 --- a/src/ui/QGCVehicleConfig.cc +++ b/src/ui/QGCVehicleConfig.cc @@ -790,7 +790,8 @@ void QGCVehicleConfig::loadConfig() mav->getParamManager()->setParamDescriptions(paramTooltips); doneLoadingConfig = true; - mav->requestParameters(); //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. + //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. + mav->getParamCommsMgr()->requestParameterList(); } void QGCVehicleConfig::setActiveUAS(UASInterface* active) -- GitLab From 86f5864bba0338d1bfe3fff61f298fcf759889d0 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 09:23:44 -0700 Subject: [PATCH 238/460] Fix statusMsgUpdate wiring; remove cruft --- src/uas/QGCUASParamManager.cc | 122 -------------------------------- src/uas/UASParameterCommsMgr.cc | 19 ++--- src/uas/UASParameterCommsMgr.h | 4 +- src/uas/UASWaypointManager.cc | 4 +- src/ui/QGCParamWidget.cc | 3 + 5 files changed, 16 insertions(+), 136 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index f1cc5fd20c..1dd6050c57 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -70,128 +70,6 @@ void QGCUASParamManager::requestParameterList() paramCommsMgr->requestParameterList(); } -//void QGCUASParamManager::retransmissionGuardTick() -//{ -// if (transmissionActive) { -// //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; - -// // Check for timeout -// // stop retransmission attempts on timeout -// if (QGC::groundTimeMilliseconds() > transmissionTimeout) { -// setRetransmissionGuardEnabled(false); -// transmissionActive = false; - -// // Empty read retransmission list -// // Empty write retransmission list -// int missingReadCount = 0; -// QList readKeys = transmissionMissingPackets.keys(); -// foreach (int component, readKeys) { -// missingReadCount += transmissionMissingPackets.value(component)->count(); -// transmissionMissingPackets.value(component)->clear(); -// } - -// // Empty write retransmission list -// int missingWriteCount = 0; -// QList writeKeys = transmissionMissingWriteAckPackets.keys(); -// foreach (int component, writeKeys) { -// missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); -// transmissionMissingWriteAckPackets.value(component)->clear(); -// } -// setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); -// } - -// // Re-request at maximum retransmissionBurstRequestSize parameters at once -// // to prevent link flooding -// QMap*>::iterator i; -// QMap*> onboardParams = paramDataModel->getOnboardParameters(); -// for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { -// // Iterate through the parameters of the component -// int component = i.key(); -// // Request n parameters from this component (at maximum) -// QList * paramList = transmissionMissingPackets.value(component, NULL); -// if (paramList) { -// int count = 0; -// foreach (int id, *paramList) { -// if (count < retransmissionBurstRequestSize) { -// //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; -// //TODO mavlink msg type for "request parameter set" ? -// emit parameterUpdateRequestedById(component, id); -// setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); -// count++; -// } else { -// break; -// } -// } -// } -// } - -// // Re-request at maximum retransmissionBurstRequestSize parameters at once -// // to prevent write-request link flooding -// // Empty write retransmission list -// QList writeKeys = transmissionMissingWriteAckPackets.keys(); -// foreach (int component, writeKeys) { -// int count = 0; -// QMap * missingParams = transmissionMissingWriteAckPackets.value(component); -// foreach (QString key, missingParams->keys()) { -// if (count < retransmissionBurstRequestSize) { -// // Re-request write operation -// QVariant value = missingParams->value(key); -// switch ((int)onboardParams.value(component)->value(key).type()) -// { -// case QVariant::Int: -// { -// QVariant fixedValue(value.toInt()); -// emit parameterChanged(component, key, fixedValue); -// } -// break; -// case QVariant::UInt: -// { -// QVariant fixedValue(value.toUInt()); -// emit parameterChanged(component, key, fixedValue); -// } -// break; -// case QMetaType::Float: -// { -// QVariant fixedValue(value.toFloat()); -// emit parameterChanged(component, key, fixedValue); -// } -// break; -// default: -// //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; -// return; -// } -// setParameterStatusMsg(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); -// count++; -// } else { -// break; -// } -// } -// } -// } else { -// //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; -// setRetransmissionGuardEnabled(false); -// } -//} - - - -//* -// * Enabling the retransmission guard enables the parameter widget to track -// * dropped parameters and to re-request them. This works for both individual -// * parameter reads as well for whole list requests. -// * -// * @param enabled True if retransmission checking should be enabled, false else - -//void QGCUASParamManager::setRetransmissionGuardEnabled(bool enabled) -//{ -// qDebug() << "setRetransmissionGuardEnabled: " << enabled; -// -// if (enabled) { -// retransmissionTimer.start(retransmissionTimeout); -// } else { -// retransmissionTimer.stop(); -// } -//} void QGCUASParamManager::setParameterStatusMsg(const QString& msg) { diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index e2231064db..93cab1d195 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -94,7 +94,7 @@ void UASParameterCommsMgr::requestParameterList() void UASParameterCommsMgr::retransmissionGuardTick() { if (transmissionActive) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; + qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; // Check for timeout // stop retransmission attempts on timeout @@ -189,7 +189,7 @@ void UASParameterCommsMgr::retransmissionGuardTick() } } } else { - //qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; + qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; setRetransmissionGuardEnabled(false); } } @@ -353,16 +353,6 @@ void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg, ParamCommsS parameterStatusMsg = msg; emit parameterStatusMsgUpdated(msg,level); - - //TODO indicate OK status somehow (eg color) -// QPalette pal = statusLabel->palette(); -// pal.setColor(backgroundRole(), QGC::colorGreen); -// statusLabel->setPalette(pal); - -// pal.setColor(backgroundRole(), QGC::colorRed); - // pal.setColor(backgroundRole(), QGC::colorOrange); - - } @@ -534,3 +524,8 @@ void UASParameterCommsMgr::sendPendingParameters() } } +UASParameterCommsMgr::~UASParameterCommsMgr() +{ + setRetransmissionGuardEnabled(false); +} + diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 8f5a2eeb67..3ac5f53d6e 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -19,6 +19,8 @@ class UASParameterCommsMgr : public QObject public: explicit UASParameterCommsMgr(QObject *parent = 0, UASInterface* uas = NULL); + ~UASParameterCommsMgr(); + typedef enum ParamCommsStatusLevel { ParamCommsStatusLevel_OK = 0, ParamCommsStatusLevel_Warning = 2, @@ -48,7 +50,7 @@ signals: void parameterUpdateRequestedById(int componentId, int paramId); /** @brief We updated the parameter status message */ - void parameterStatusMsgUpdated(QString msg, ParamCommsStatusLevel_t level); + void parameterStatusMsgUpdated(QString msg, int level); public slots: /** @brief Iterate through all components, through all pending parameters and send them to UAS */ diff --git a/src/uas/UASWaypointManager.cc b/src/uas/UASWaypointManager.cc index d6bdb29b86..888a548e70 100644 --- a/src/uas/UASWaypointManager.cc +++ b/src/uas/UASWaypointManager.cc @@ -975,7 +975,9 @@ void UASWaypointManager::sendWaypointRequestList() wprl.target_system = uasid; wprl.target_component = MAV_COMP_ID_MISSIONPLANNER; - emit updateStatusString(QString("Requesting waypoint list...")); + QString statusMsg(tr("Requesting waypoint list...")); + qDebug() << __FILE__ << __LINE__ << statusMsg; + emit updateStatusString(statusMsg); mavlink_msg_mission_request_list_encode(uas->mavlink->getSystemId(), uas->mavlink->getComponentId(), &message, &wprl); uas->sendMessage(message); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 5ec85bceba..ef79ac437f 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -154,6 +154,9 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), this, SLOT(handleParameterListUpToDate())); + connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), + this, SLOT(handleParamStatusMsgUpdate(QString , int ))); + // Get parameters if (uas) { requestAllParamsUpdate(); -- GitLab From 3090fcf2596a04125fe57f19dce2db6e9f6e0fc5 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 10:20:52 -0700 Subject: [PATCH 239/460] Retransmit param list request; fix null data model --- libs/eigen/Eigen/src/Core/BandMatrix.h | 1 + src/uas/UAS.cc | 12 ++++++++---- src/uas/UASParameterCommsMgr.cc | 27 ++++++++++++++++++++++---- src/uas/UASParameterCommsMgr.h | 1 + 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/libs/eigen/Eigen/src/Core/BandMatrix.h b/libs/eigen/Eigen/src/Core/BandMatrix.h index dda8efba36..e6922b50f5 100644 --- a/libs/eigen/Eigen/src/Core/BandMatrix.h +++ b/libs/eigen/Eigen/src/Core/BandMatrix.h @@ -285,6 +285,7 @@ class BandMatrixWrapper : public BandMatrixBaseat(i)) { - qDebug()<<"Antenna tracking: Forwarding Over link: "<getName()<<" "<isConnected()) { + qDebug()<<"Antenna tracking: Forwarding Over link: "<getName()<<" "<getParamDataModel(); loadParamCommsSettings(); @@ -57,6 +58,8 @@ void UASParameterCommsMgr::loadParamCommsSettings() settings.endGroup(); } + + /** * Send a request to deliver the list of onboard parameters * from the MAV. @@ -82,7 +85,9 @@ void UASParameterCommsMgr::requestParameterList() transmissionActive = true; setParameterStatusMsg(tr("Requested param list.. waiting")); + listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; mav->requestParameters(); + setRetransmissionGuardEnabled(true); } else { qDebug() << __FILE__ << __LINE__ << "Ignoring requestParameterList because we're receiving params list"; @@ -94,6 +99,17 @@ void UASParameterCommsMgr::requestParameterList() void UASParameterCommsMgr::retransmissionGuardTick() { if (transmissionActive) { + if (transmissionListMode && transmissionListSizeKnown.isEmpty() ) { + //we are still waitin for the first parameter list response + if (QGC::groundTimeMilliseconds() > this->listRecvTimeout) { + //re-request parameters + setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); + listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; + mav->requestParameters(); + } + return; + } + qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; // Check for timeout @@ -466,11 +482,9 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para transmissionMissingPackets.value(key)->clear(); } + setRetransmissionGuardEnabled(false); //all parameters have been received, broadcast to UI emit parameterListUpToDate(); - //TODO in UI - // Expand visual tree - //tree->expandItem(tree->topLevelItem(0)); } } @@ -527,5 +541,10 @@ void UASParameterCommsMgr::sendPendingParameters() UASParameterCommsMgr::~UASParameterCommsMgr() { setRetransmissionGuardEnabled(false); + + QString ptrStr; + ptrStr.sprintf("%8p", this); + qDebug() << "UASParameterCommsMgr destructor: " << ptrStr ; + } diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 3ac5f53d6e..03286c1e1e 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -98,6 +98,7 @@ protected: int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds int rewriteTimeout; ///< Write request timeout, in milliseconds int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst + quint64 listRecvTimeout; ///< How long to wait for first parameter list response before re-requesting // Status QString parameterStatusMsg; -- GitLab From cade16c1808ed8fcfad61c59532e11ae34b1bde4 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 10:31:59 -0700 Subject: [PATCH 240/460] Debug parameter list receive; remove cruft --- src/uas/UASParameterCommsMgr.cc | 22 +++-- src/ui/QGCParamWidget.cc | 150 -------------------------------- 2 files changed, 15 insertions(+), 157 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index bdd2494b27..58f02733ef 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -99,13 +99,15 @@ void UASParameterCommsMgr::requestParameterList() void UASParameterCommsMgr::retransmissionGuardTick() { if (transmissionActive) { - if (transmissionListMode && transmissionListSizeKnown.isEmpty() ) { - //we are still waitin for the first parameter list response - if (QGC::groundTimeMilliseconds() > this->listRecvTimeout) { - //re-request parameters - setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); - listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; - mav->requestParameters(); + if (transmissionListMode) { + if (transmissionListSizeKnown.isEmpty() ) { + //we are still waitin for the first parameter list response + if (QGC::groundTimeMilliseconds() > this->listRecvTimeout) { + //re-request parameters + setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); + listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; + mav->requestParameters(); + } } return; } @@ -486,6 +488,12 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para //all parameters have been received, broadcast to UI emit parameterListUpToDate(); } + else { + qDebug() << "missCount:" << missCount << "missWriteCount:" << missWriteCount; + foreach (int key, transmissionMissingPackets.keys()) { + qDebug() << "Missing:" << key ; + } + } } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index ef79ac437f..b125b083a4 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -194,156 +194,6 @@ void QGCParamWidget::addComponentItem( int compId, QString compName) } - -/** - * @param uas System which has the component - * @param component id of the component - * @param parameterName human friendly name of the parameter - */ -//void QGCParamWidget::receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value) -//{ - -// updateParameterDisplay(component, parameterName, value); - -// // Missing packets list has to be instantiated for all components -// if (!transmissionMissingPackets.contains(component)) { -// transmissionMissingPackets.insert(component, new QList()); -// } - -// // List mode is different from single parameter transfers -// if (transmissionListMode) { -// // Only accept the list size once on the first packet from -// // each component -// if (!transmissionListSizeKnown.contains(component)) -// { -// // Mark list size as known -// transmissionListSizeKnown.insert(component, true); - -// // Mark all parameters as missing -// for (int i = 0; i < paramCount; ++i) -// { -// if (!transmissionMissingPackets.value(component)->contains(i)) -// { -// transmissionMissingPackets.value(component)->append(i); -// } -// } - -// // There is only one transmission timeout for all components -// // since components do not manage their transmission, -// // the longest timeout is safe for all components. -// quint64 thisTransmissionTimeout = QGC::groundTimeMilliseconds() + ((paramCount)*retransmissionTimeout); -// if (thisTransmissionTimeout > transmissionTimeout) -// { -// transmissionTimeout = thisTransmissionTimeout; -// } -// } - -// // Start retransmission guard -// // or reset timer -// paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO -// } - -// // Mark this parameter as received in read list -// int index = transmissionMissingPackets.value(component)->indexOf(paramId); -// // If the MAV sent the parameter without request, it wont be in missing list -// if (index != -1) transmissionMissingPackets.value(component)->removeAt(index); - -// bool justWritten = false; -// bool writeMismatch = false; -// //bool lastWritten = false; -// // Mark this parameter as received in write ACK list -// QMap* map = transmissionMissingWriteAckPackets.value(component); -// if (map && map->contains(parameterName)) -// { -// justWritten = true; -// QVariant newval = map->value(parameterName); -// if (map->value(parameterName) != value) -// { -// writeMismatch = true; -// } -// map->remove(parameterName); -// } - -// int missCount = 0; -// foreach (int key, transmissionMissingPackets.keys()) -// { -// missCount += transmissionMissingPackets.value(key)->count(); -// } - -// int missWriteCount = 0; -// foreach (int key, transmissionMissingWriteAckPackets.keys()) -// { -// missWriteCount += transmissionMissingWriteAckPackets.value(key)->count(); -// } - -// if (justWritten && !writeMismatch && missWriteCount == 0) -// { -// // Just wrote one and count went to 0 - this was the last missing write parameter -// statusLabel->setText(tr("SUCCESS: WROTE ALL PARAMETERS")); -// QPalette pal = statusLabel->palette(); -// pal.setColor(backgroundRole(), QGC::colorGreen); -// statusLabel->setPalette(pal); -// } else if (justWritten && !writeMismatch) -// { -// statusLabel->setText(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(parameterName).arg(value.toDouble()).arg(paramCount)); -// QPalette pal = statusLabel->palette(); -// pal.setColor(backgroundRole(), QGC::colorGreen); -// statusLabel->setPalette(pal); -// } else if (justWritten && writeMismatch) -// { -// // Mismatch, tell user -// QPalette pal = statusLabel->palette(); -// pal.setColor(backgroundRole(), QGC::colorRed); -// statusLabel->setPalette(pal); -// statusLabel->setText(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(parameterName).arg(map->value(parameterName).toDouble()).arg(value.toDouble())); -// } -// else -// { -// if (missCount > 0) -// { -// QPalette pal = statusLabel->palette(); -// pal.setColor(backgroundRole(), QGC::colorOrange); -// statusLabel->setPalette(pal); -// } -// else -// { -// QPalette pal = statusLabel->palette(); -// pal.setColor(backgroundRole(), QGC::colorGreen); -// statusLabel->setPalette(pal); -// } -// QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); -// //statusLabel->setText(tr("OK: %1 %2 #%3/%4, %5 miss").arg(parameterName).arg(val).arg(paramId+1).arg(paramCount).arg(missCount)); -// if (missCount == 0) -// { -// // Transmission done -// QTime time = QTime::currentTime(); -// QString timeString = time.toString(); -// statusLabel->setText(tr("All received. (updated at %1)").arg(timeString)); -// } -// else -// { -// // Transmission in progress -// statusLabel->setText(tr("OK: %1 %2 (%3/%4)").arg(parameterName).arg(val).arg(paramCount-missCount).arg(paramCount)); -// } -// } - -// // Check if last parameter was received -// if (missCount == 0 && missWriteCount == 0) -// { -// this->transmissionActive = false; -// this->transmissionListMode = false; -// transmissionListSizeKnown.clear(); -// foreach (int key, transmissionMissingPackets.keys()) -// { -// transmissionMissingPackets.value(key)->clear(); -// } - -// // Expand visual tree -// tree->expandItem(tree->topLevelItem(0)); -// } -//} - - void QGCParamWidget::handleParameterUpdate(int componentId, const QString& paramName, QVariant value) { updateParameterDisplay(componentId, paramName, value); -- GitLab From 440cc226dca232c35b2dfdd28360669ed760e667 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 11:14:48 -0700 Subject: [PATCH 241/460] keep the received params list clean --- src/uas/UASParameterCommsMgr.cc | 43 +++++++++++++++++++-------------- src/uas/UASParameterDataModel.h | 8 +++--- src/ui/QGCParamWidget.cc | 4 +-- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 58f02733ef..8b65d65ee7 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -99,15 +99,14 @@ void UASParameterCommsMgr::requestParameterList() void UASParameterCommsMgr::retransmissionGuardTick() { if (transmissionActive) { - if (transmissionListMode) { - if (transmissionListSizeKnown.isEmpty() ) { - //we are still waitin for the first parameter list response - if (QGC::groundTimeMilliseconds() > this->listRecvTimeout) { - //re-request parameters - setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); - listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; - mav->requestParameters(); - } + + if (transmissionListMode && transmissionListSizeKnown.isEmpty() ) { + //we are still waitin for the first parameter list response + if (QGC::groundTimeMilliseconds() > this->listRecvTimeout) { + //re-request parameters + setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); + listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; + mav->requestParameters(); } return; } @@ -142,8 +141,8 @@ void UASParameterCommsMgr::retransmissionGuardTick() // Re-request at maximum retransmissionBurstRequestSize parameters at once // to prevent link flooding QMap*>::iterator i; - QMap*> onboardParams = paramDataModel->getOnboardParameters(); - for (i = onboardParams.begin(); i != onboardParams.end(); ++i) { + QMap*>* onboardParams = paramDataModel->getOnboardParameters(); + for (i = onboardParams->begin(); i != onboardParams->end(); ++i) { // Iterate through the parameters of the component int component = i.key(); // Request n parameters from this component (at maximum) @@ -175,7 +174,7 @@ void UASParameterCommsMgr::retransmissionGuardTick() if (count < retransmissionBurstRequestSize) { // Re-request write operation QVariant value = missingParams->value(key); - switch ((int)onboardParams.value(component)->value(key).type()) + switch ((int)onboardParams->value(component)->value(key).type()) { case QVariant::Int: { @@ -395,13 +394,20 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para // Mark list size as known transmissionListSizeKnown.insert(compId, true); - // Mark all parameters as missing + qDebug() << "Mark all parameters as missing"; + QList* compParamList = transmissionMissingPackets.value(compId); for (int i = 0; i < paramCount; ++i) { - if (!transmissionMissingPackets.value(compId)->contains(i)) { - transmissionMissingPackets.value(compId)->append(i); + if (!compParamList->contains(i)) { + if (i != paramId) { + compParamList->append(i); + } + else { + qDebug() << "Already received " << paramId; + } } } + // There is only one transmission timeout for all components // since components do not manage their transmission, // the longest timeout is safe for all components. @@ -491,7 +497,8 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para else { qDebug() << "missCount:" << missCount << "missWriteCount:" << missWriteCount; foreach (int key, transmissionMissingPackets.keys()) { - qDebug() << "Missing:" << key ; + QList* list = transmissionMissingPackets.value(key); + qDebug() << "Component" << key << "missing numParams:" << list->count() ; } } } @@ -509,9 +516,9 @@ void UASParameterCommsMgr::sendPendingParameters() { // Iterate through all components, through all pending parameters and send them to UAS int parametersSent = 0; - QMap*> changedValues = paramDataModel->getPendingParameters(); + QMap*>* changedValues = paramDataModel->getPendingParameters(); QMap*>::iterator i; - for (i = changedValues.begin(); i != changedValues.end(); ++i) { + for (i = changedValues->begin(); i != changedValues->end(); ++i) { // Iterate through the parameters of the component int compid = i.key(); QMap* comp = i.value(); diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 352fb0eea6..219eff900b 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -69,12 +69,12 @@ public: return onboardParameters.value(componentId); } - QMap* > getPendingParameters() { - return pendingParameters; + QMap* >* getPendingParameters() { + return &pendingParameters; } - QMap* > getOnboardParameters() { - return onboardParameters; + QMap* >* getOnboardParameters() { + return &onboardParameters; } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index b125b083a4..7600d15768 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -432,9 +432,9 @@ void QGCParamWidget::writeParameters() int changedParamCount = 0; QMap*>::iterator i; - QMap*> changedValues = paramDataModel->getPendingParameters(); + QMap*>* changedValues = paramDataModel->getPendingParameters(); - for (i = changedValues.begin(); i != changedValues.end() , (0 == changedParamCount); ++i) { + for (i = changedValues->begin(); (i != changedValues->end()) && (0 == changedParamCount); ++i) { // Iterate through the parameters of the component QMap* compPending = i.value(); changedParamCount += compPending->count(); -- GitLab From 32f1ea870e7ca06656927b05e86fa78cec4ebe62 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 22:51:29 -0700 Subject: [PATCH 242/460] debugging premature timeouts of param list recv --- src/uas/UAS.cc | 4 +- src/uas/UASParameterCommsMgr.cc | 294 ++++++++++++++++---------------- src/uas/UASParameterCommsMgr.h | 7 + src/ui/QGCParamWidget.cc | 94 ---------- 4 files changed, 159 insertions(+), 240 deletions(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 2a95b08862..d21f55343d 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -2259,7 +2259,9 @@ void UAS::requestParameters() mavlink_message_t msg; mavlink_msg_param_request_list_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_COMP_ID_ALL); sendMessage(msg); - qDebug() << __FILE__ << ":" << __LINE__ << "LOADING PARAM LIST"; + + QDateTime time = QDateTime::currentDateTime(); + qDebug() << __FILE__ << ":" << __LINE__ << time.toString() << "LOADING PARAM LIST"; } void UAS::writeParametersToStorage() diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 8b65d65ee7..712cd9b1cb 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -14,8 +14,8 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : transmissionListMode(false), transmissionActive(false), transmissionTimeout(0), - retransmissionTimeout(350), - rewriteTimeout(500), + retransmissionTimeout(1000), + rewriteTimeout(1000), retransmissionBurstRequestSize(5) { paramDataModel = mav->getParamDataModel(); @@ -96,6 +96,125 @@ void UASParameterCommsMgr::requestParameterList() } +/* + Empty read retransmission list + Empty write retransmission list +*/ +void UASParameterCommsMgr::clearRetransmissionLists() +{ + qDebug() << __FILE__ << __LINE__ << "clearRetransmissionLists"; + + int missingReadCount = 0; + QList readKeys = transmissionMissingPackets.keys(); + foreach (int component, readKeys) { + missingReadCount += transmissionMissingPackets.value(component)->count(); + transmissionMissingPackets.value(component)->clear(); + } + + int missingWriteCount = 0; + QList writeKeys = transmissionMissingWriteAckPackets.keys(); + foreach (int component, writeKeys) { + missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); + transmissionMissingWriteAckPackets.value(component)->clear(); + } + setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount), + ParamCommsStatusLevel_Warning); + +} + + +void UASParameterCommsMgr::emitParameterChanged(int compId, const QString& key, QVariant& value) +{ + int paramType = (int)value.type(); + switch (paramType) + { + case QVariant::Char: + { + QVariant fixedValue(QChar((unsigned char)value.toInt())); + emit parameterChanged(compId, key, fixedValue); + } + break; + case QVariant::Int: + { + QVariant fixedValue(value.toInt()); + emit parameterChanged(compId, key, fixedValue); + } + break; + case QVariant::UInt: + { + QVariant fixedValue(value.toUInt()); + emit parameterChanged(compId, key, fixedValue); + } + break; + case QMetaType::Float: + { + QVariant fixedValue(value.toFloat()); + emit parameterChanged(compId, key, fixedValue); + } + break; + default: + qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE"; + return; + } + + setParameterStatusMsg(tr("Requested write of: %1: %2").arg(key).arg(value.toDouble())); + +} + + +void UASParameterCommsMgr::resendReadWriteRequests() +{ + int compId; + QList compIds; + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent link flooding' + int requestedReadCount = 0; + + compIds = transmissionMissingPackets.keys(); + foreach (compId, compIds) { + // Request n parameters from this component (at maximum) + QList* missingReadParams = transmissionMissingPackets.value(compId, NULL); + foreach (int paramId, *missingReadParams) { + if (requestedReadCount < retransmissionBurstRequestSize) { + qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << paramId << "FROM COMPONENT #" << compId; + emit parameterUpdateRequestedById(compId, paramId); + setParameterStatusMsg(tr("Requested retransmission of #%1").arg(paramId+1)); + requestedReadCount++; + } + else { + qDebug() << "Throttling read retransmit requests at" << requestedReadCount; + break; + } + } + } + + // Re-request at maximum retransmissionBurstRequestSize parameters at once + // to prevent write-request link flooding + int requestedWriteCount = 0; + compIds = transmissionMissingWriteAckPackets.keys(); + foreach (compId, compIds) { + QMap * missingParams = transmissionMissingWriteAckPackets.value(compId); + foreach (QString key, missingParams->keys()) { + if (requestedWriteCount < retransmissionBurstRequestSize) { + // Re-request write operation + QVariant value = missingParams->value(key); + emitParameterChanged(compId, key, value); + requestedWriteCount++; + } + else { + qDebug() << "Throttling write retransmit requests at" << requestedWriteCount; + break; + } + } + } + + if ((0 == requestedWriteCount) && (0 == requestedReadCount) ) { + qDebug() << __FILE__ << __LINE__ << "NO re-read or rewrite requests??"; + //setRetransmissionGuardEnabled(false); + } +} + void UASParameterCommsMgr::retransmissionGuardTick() { if (transmissionActive) { @@ -118,94 +237,14 @@ void UASParameterCommsMgr::retransmissionGuardTick() if (QGC::groundTimeMilliseconds() > transmissionTimeout) { setRetransmissionGuardEnabled(false); transmissionActive = false; - - // Empty read retransmission list - // Empty write retransmission list - int missingReadCount = 0; - QList readKeys = transmissionMissingPackets.keys(); - foreach (int component, readKeys) { - missingReadCount += transmissionMissingPackets.value(component)->count(); - transmissionMissingPackets.value(component)->clear(); - } - - // Empty write retransmission list - int missingWriteCount = 0; - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); - transmissionMissingWriteAckPackets.value(component)->clear(); - } - setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount)); - } - - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent link flooding - QMap*>::iterator i; - QMap*>* onboardParams = paramDataModel->getOnboardParameters(); - for (i = onboardParams->begin(); i != onboardParams->end(); ++i) { - // Iterate through the parameters of the component - int component = i.key(); - // Request n parameters from this component (at maximum) - QList * paramList = transmissionMissingPackets.value(component, NULL); - if (paramList) { - int count = 0; - foreach (int id, *paramList) { - if (count < retransmissionBurstRequestSize) { - //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << id << "FROM COMPONENT #" << component; - //TODO mavlink msg type for "request parameter set" ? - emit parameterUpdateRequestedById(component, id); - setParameterStatusMsg(tr("Requested retransmission of #%1").arg(id+1)); - count++; - } else { - break; - } - } - } + transmissionListMode = false; + clearRetransmissionLists(); + return; } - // Re-request at maximum retransmissionBurstRequestSize parameters at once - // to prevent write-request link flooding - // Empty write retransmission list - QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - int count = 0; - QMap * missingParams = transmissionMissingWriteAckPackets.value(component); - foreach (QString key, missingParams->keys()) { - if (count < retransmissionBurstRequestSize) { - // Re-request write operation - QVariant value = missingParams->value(key); - switch ((int)onboardParams->value(component)->value(key).type()) - { - case QVariant::Int: - { - QVariant fixedValue(value.toInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QVariant::UInt: - { - QVariant fixedValue(value.toUInt()); - emit parameterChanged(component, key, fixedValue); - } - break; - case QMetaType::Float: - { - QVariant fixedValue(value.toFloat()); - emit parameterChanged(component, key, fixedValue); - } - break; - default: - //qCritical() << "ABORTED PARAM RETRANSMISSION, NO VALID QVARIANT TYPE"; - return; - } - setParameterStatusMsg(tr("Requested rewrite of: %1: %2").arg(key).arg(missingParams->value(key).toDouble())); - count++; - } else { - break; - } - } - } - } else { + resendReadWriteRequests(); + } + else { qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; setRetransmissionGuardEnabled(false); } @@ -293,6 +332,7 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV ); return; } + QVariant onboardVal; paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); if (onboardVal == value) { @@ -302,43 +342,11 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV return; } - //int paramType = (int)onboardParameters.value(component)->value(parameterName).type(); - int paramType = (int)value.type(); - switch (paramType) - { - case QVariant::Char: - { - QVariant fixedValue(QChar((unsigned char)value.toInt())); - emit parameterChanged(component, parameterName, fixedValue); - } - break; - case QVariant::Int: - { - QVariant fixedValue(value.toInt()); - emit parameterChanged(component, parameterName, fixedValue); - } - break; - case QVariant::UInt: - { - QVariant fixedValue(value.toUInt()); - emit parameterChanged(component, parameterName, fixedValue); - } - break; - case QMetaType::Float: - { - QVariant fixedValue(value.toFloat()); - emit parameterChanged(component, parameterName, fixedValue); - } - break; - default: - qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE"; - return; - } + emitParameterChanged(component, parameterName, value); // Wait for parameter to be written back // mark it therefore as missing - if (!transmissionMissingWriteAckPackets.contains(component)) - { + if (!transmissionMissingWriteAckPackets.contains(component)) { transmissionMissingWriteAckPackets.insert(component, new QMap()); } @@ -346,15 +354,12 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV transmissionMissingWriteAckPackets.value(component)->insert(parameterName, value); // Set timeouts - if (transmissionActive) - { + if (transmissionActive) { transmissionTimeout += rewriteTimeout; } - else - { + else { quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + rewriteTimeout; - if (newTransmissionTimeout > transmissionTimeout) - { + if (newTransmissionTimeout > transmissionTimeout) { transmissionTimeout = newTransmissionTimeout; } transmissionActive = true; @@ -386,6 +391,8 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para transmissionMissingPackets.insert(compId, new QList()); } + QList* compXmitMissing = transmissionMissingPackets.value(compId); + // List mode is different from single parameter transfers if (transmissionListMode) { // Only accept the list size once on the first packet from @@ -394,20 +401,13 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para // Mark list size as known transmissionListSizeKnown.insert(compId, true); - qDebug() << "Mark all parameters as missing"; - QList* compParamList = transmissionMissingPackets.value(compId); + qDebug() << "Mark all parameters as missing: " << paramCount; for (int i = 0; i < paramCount; ++i) { - if (!compParamList->contains(i)) { - if (i != paramId) { - compParamList->append(i); - } - else { - qDebug() << "Already received " << paramId; - } + if (!compXmitMissing->contains(i)) { + compXmitMissing->append(i); } } - // There is only one transmission timeout for all components // since components do not manage their transmission, // the longest timeout is safe for all components. @@ -419,19 +419,19 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para // Start retransmission guard // or reset timer - setRetransmissionGuardEnabled(true); //TODO + setRetransmissionGuardEnabled(true); } // Mark this parameter as received in read list - int index = transmissionMissingPackets.value(compId)->indexOf(paramId); + int index = compXmitMissing->indexOf(paramId); // If the MAV sent the parameter without request, it wont be in missing list if (index != -1) { - transmissionMissingPackets.value(compId)->removeAt(index); + compXmitMissing->removeAt(index); } bool justWritten = false; bool writeMismatch = false; - //bool lastWritten = false; + // Mark this parameter as received in write ACK list QMap* map = transmissionMissingWriteAckPackets.value(compId); if (map && map->contains(paramName)) { @@ -496,10 +496,14 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para } else { qDebug() << "missCount:" << missCount << "missWriteCount:" << missWriteCount; - foreach (int key, transmissionMissingPackets.keys()) { - QList* list = transmissionMissingPackets.value(key); - qDebug() << "Component" << key << "missing numParams:" << list->count() ; + + if (missCount < 4) { + foreach (int key, transmissionMissingPackets.keys()) { + QList* list = transmissionMissingPackets.value(key); + qDebug() << "Component" << key << "missing params:" << list ; + } } + setRetransmissionGuardEnabled(true); //reset the timeout timer since we received one } } diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 03286c1e1e..327d99a94b 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -38,6 +38,13 @@ protected: /** @brief Load settings that control eg retransmission timeouts */ void loadParamCommsSettings(); + /** @brief clear transmissionMissingPackets and transmissionMissingWriteAckPackets */ + void clearRetransmissionLists(); + + void resendReadWriteRequests(); + + void emitParameterChanged(int compId, const QString& key, QVariant& value); + signals: void parameterChanged(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 7600d15768..c7b75939ad 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -450,100 +450,6 @@ void QGCParamWidget::writeParameters() } } -/** - * @param component the subsystem which has the parameter - * @param parameterName name of the parameter, as delivered by the system - * @param value value of the parameter - */ -//void QGCParamWidget::setParameter(int component, QString parameterName, QVariant value) -//{ - -// if (parameterName.isEmpty()) { -// return; -// } - -// double dblValue = value.toDouble(); - -// if (paramDataModel->isValueLessThanParamMin(parameterName,dblValue)) { -// statusLabel->setText(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue)); -// return; -// } -// if (paramDataModel->isValueGreaterThanParamMax(parameterName,dblValue)) { -// statusLabel->setText(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue)); -// return; -// } -// QVariant onboardVal; -// paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); -// if (onboardVal == value) { -// statusLabel->setText(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue)); -// return; -// } - -// //int paramType = (int)onboardParameters.value(component)->value(parameterName).type(); -// int paramType = (int)value.type(); -// switch (paramType) -// { -// case QVariant::Char: -// { -// QVariant fixedValue(QChar((unsigned char)value.toInt())); -// emit parameterChanged(component, parameterName, fixedValue); -// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; -// } -// break; -// case QVariant::Int: -// { -// QVariant fixedValue(value.toInt()); -// emit parameterChanged(component, parameterName, fixedValue); -// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; -// } -// break; -// case QVariant::UInt: -// { -// QVariant fixedValue(value.toUInt()); -// emit parameterChanged(component, parameterName, fixedValue); -// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; -// } -// break; -// case QMetaType::Float: -// { -// QVariant fixedValue(value.toFloat()); -// emit parameterChanged(component, parameterName, fixedValue); -// //qDebug() << "PARAM WIDGET SENT:" << fixedValue; -// } -// break; -// default: -// qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE"; -// return; -// } - -// // Wait for parameter to be written back -// // mark it therefore as missing -// if (!transmissionMissingWriteAckPackets.contains(component)) -// { -// transmissionMissingWriteAckPackets.insert(component, new QMap()); -// } - -// // Insert it in missing write ACK list -// transmissionMissingWriteAckPackets.value(component)->insert(parameterName, value); - -// // Set timeouts -// if (transmissionActive) -// { -// transmissionTimeout += rewriteTimeout; -// } -// else -// { -// quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + rewriteTimeout; -// if (newTransmissionTimeout > transmissionTimeout) -// { -// transmissionTimeout = newTransmissionTimeout; -// } -// transmissionActive = true; -// } - -// // Enable guard / reset timeouts -// paramCommsMgr->setRetransmissionGuardEnabled(true); //TODO -//} void QGCParamWidget::readParameters() { -- GitLab From 23552c494093e39b9ce5089e573d38af01d9c9e2 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 23:22:41 -0700 Subject: [PATCH 243/460] reset timeout timer every time we receive a param --- src/uas/UASParameterCommsMgr.cc | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 712cd9b1cb..3c9818d4a4 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -495,15 +495,31 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para emit parameterListUpToDate(); } else { - qDebug() << "missCount:" << missCount << "missWriteCount:" << missWriteCount; + //reset the timeout timer since we received one + setRetransmissionGuardEnabled(true); - if (missCount < 4) { - foreach (int key, transmissionMissingPackets.keys()) { - QList* list = transmissionMissingPackets.value(key); - qDebug() << "Component" << key << "missing params:" << list ; - } - } - setRetransmissionGuardEnabled(true); //reset the timeout timer since we received one + //qDebug() << "missCount:" << missCount << "missWriteCount:" << missWriteCount; + //if (missCount < 4) { + // foreach (int key, transmissionMissingPackets.keys()) { + // QList* list = transmissionMissingPackets.value(key); + + // if (list && list->count()) { + // QString yazza = QString().sprintf("Component %d missing %d: ",key,list->count()); + + // for (int i = 0; i < list->count(); i++) { + // int val = list->at(i); + // yazza.append( QString().sprintf("%d,",val) ); + // } + + // qDebug() << yazza; + // } + // else { + // //very suspicious...no actual missing items?? + // transmissionMissingPackets.remove(key); + // break; + // } + // } + //} } } -- GitLab From 32ba51823ca1bd677446cd8813fd026a2080a743 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 8 Aug 2013 23:46:58 -0700 Subject: [PATCH 244/460] refresh tree display after list recv --- src/ui/QGCParamWidget.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index c7b75939ad..d5f769b088 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -202,6 +202,21 @@ void QGCParamWidget::handleParameterUpdate(int componentId, const QString& param void QGCParamWidget::handleParameterListUpToDate() { + tree->collapseAll(); + + //rewrite the component item tree after receiving the full list + QMap*>::iterator i; + QMap*>* onboardParams = paramDataModel->getOnboardParameters(); + + for (i = onboardParams->begin(); i != onboardParams->end(); ++i) { + int compId = i.key(); + QMap* paramPairs = onboardParams->value(compId); + QMap::iterator j; + for (j = paramPairs->begin(); j != paramPairs->end(); j++) { + updateParameterDisplay(compId, j.key(),j.value()); + } + } + // Expand visual tree tree->expandItem(tree->topLevelItem(0)); } -- GitLab From b11c5a69849afd7d3b270f0e53eaaf6d8698a2b9 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 00:03:13 -0700 Subject: [PATCH 245/460] rm totalOnboardParameters --- src/uas/QGCUASParamManager.cc | 23 +++-------------------- src/uas/UASParameterDataModel.cc | 3 ++- src/uas/UASParameterDataModel.h | 2 -- src/ui/designer/QGCParamSlider.cc | 3 +++ 4 files changed, 8 insertions(+), 23 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 1dd6050c57..c1b29e88f1 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -8,7 +8,9 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : QWidget(parent), - mav(uas) + mav(uas), + paramDataModel(NULL), + paramCommsMgr(NULL) { paramDataModel = uas->getParamDataModel(); paramCommsMgr = uas->getParamCommsMgr(); @@ -18,25 +20,6 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : loadParamMetaInfoCSV(); -// // Connect retransmission guard -// connect(this, SIGNAL(parameterUpdateRequested(int,QString)), -// this, SLOT(requestParameterUpdate(int,QString))); - -// //TODO connect in paramCommsMgr instead -// connect(this, SIGNAL(parameterUpdateRequestedById(int,int)), -// mav, SLOT(requestParameter(int,int))); - - // New parameters from UAS - - void parameterUpdated(int compId, QString paramName, QVariant value); - - -// connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), -// this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); - - - - } diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 9815ce7779..96d7479f0b 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -11,7 +11,8 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : QObject(parent) { - + onboardParameters.clear(); + pendingParameters.clear(); } diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 219eff900b..535cc03082 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -14,7 +14,6 @@ public: explicit UASParameterDataModel(QObject *parent = 0); - int getTotalOnboardParams() { return totalOnboardParameters; } //Parameter meta info bool isParamMinKnown(const QString& param) { return paramMin.contains(param); } virtual bool isValueLessThanParamMin(const QString& param, double dblVal); @@ -97,7 +96,6 @@ protected: int uasId; ///< The UAS / MAV to which this data model pertains QMap* > pendingParameters; ///< Changed values that have not yet been transmitted to the UAS, by component ID QMap* > onboardParameters; ///< All parameters confirmed to be stored onboard the UAS, by component ID - int totalOnboardParameters;///< The known count of onboard parameters, may not match onboardParameters until all params are received // Tooltip data structures QMap paramDescriptions; ///< Tooltip values diff --git a/src/ui/designer/QGCParamSlider.cc b/src/ui/designer/QGCParamSlider.cc index e927dea032..32b236a4b8 100644 --- a/src/ui/designer/QGCParamSlider.cc +++ b/src/ui/designer/QGCParamSlider.cc @@ -175,6 +175,9 @@ void QGCParamSlider::selectParameter(int paramIndex) { // Set name parameterName = ui->editSelectParamComboBox->itemText(paramIndex); + if (parameterName.isEmpty()) { + return; + } // Update min and max values if available if (uas) { -- GitLab From d00f2b4332b53566e1dfca1196d6b24eaedfabfa Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 07:15:03 -0700 Subject: [PATCH 246/460] fix comm mgr -> data model wiring --- src/uas/UASParameterCommsMgr.cc | 10 ++- src/ui/QGCParamWidget.cc | 152 ++++++++++++++++---------------- src/ui/QGCParamWidget.h | 1 + 3 files changed, 86 insertions(+), 77 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 3c9818d4a4..690851cbeb 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -30,7 +30,7 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), mav, SLOT(setParameter(int,QString,QVariant))); - // New parameters from UAS + // Received parameter updates from UAS connect(mav, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); @@ -177,7 +177,7 @@ void UASParameterCommsMgr::resendReadWriteRequests() QList* missingReadParams = transmissionMissingPackets.value(compId, NULL); foreach (int paramId, *missingReadParams) { if (requestedReadCount < retransmissionBurstRequestSize) { - qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << paramId << "FROM COMPONENT #" << compId; + //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << paramId << "FROM COMPONENT #" << compId; emit parameterUpdateRequestedById(compId, paramId); setParameterStatusMsg(tr("Requested retransmission of #%1").arg(paramId+1)); requestedReadCount++; @@ -385,6 +385,10 @@ void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg, ParamCommsS */ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value) { + Q_UNUSED(uas); //this object is assigned to one UAS only + + //notify the data model that we have an updated param + paramDataModel->handleParameterUpdate(compId,paramName,value); // Missing packets list has to be instantiated for all components if (!transmissionMissingPackets.contains(compId)) { @@ -402,7 +406,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para transmissionListSizeKnown.insert(compId, true); qDebug() << "Mark all parameters as missing: " << paramCount; - for (int i = 0; i < paramCount; ++i) { + for (int i = 1; i < paramCount; ++i) { //TODO check: param Id 0 is "all parameters" ? if (!compXmitMissing->contains(i)) { compXmitMissing->append(i); } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index d5f769b088..a141ec4ea8 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -54,6 +54,36 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : componentItems(new QMap()) { + layoutWidget(); + + // Connect signals/slots + + // Listen for edits to the tree UI + connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), + this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); + + // Listen to updated param signals from the data model + connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), + this, SLOT(handleParameterUpdate(int,QString,QVariant))); + + // Listen for param list reload finished + connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), + this, SLOT(handleParameterListUpToDate())); + + // Listen to communications status messages so we can display them + connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), + this, SLOT(handleParamStatusMsgUpdate(QString , int ))); + + // Ensure we're receiving the list of params + requestAllParamsUpdate(); + +} + + + + +void QGCParamWidget::layoutWidget() +{ // Create tree widget tree = new QTreeWidget(this); statusLabel = new QLabel(); @@ -77,7 +107,6 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : statusLabel->setText(tr("Click refresh to download parameters")); horizontalLayout->addWidget(statusLabel, 1, 0, 1, 3); - // BUTTONS QPushButton* refreshButton = new QPushButton(tr("Get")); refreshButton->setToolTip(tr("Load parameters currently in non-permanent memory of aircraft.")); @@ -130,61 +159,35 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : headerItems.append("Value"); tree->setHeaderLabels(headerItems); tree->setColumnCount(2); + tree->setColumnWidth(0,120); + tree->setColumnWidth(1,120); tree->setExpandsOnDoubleClick(true); - // Connect signals/slots -// connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), -// mav, SLOT(setParameter(int,QString,QVariant))); - connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), - this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); - -// // New parameters from UAS -// connect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); - - -// connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); -// connect(this, SIGNAL(requestParameter(int,QString)), uas, SLOT(requestParameter(int,QString))); -// connect(this, SIGNAL(requestParameter(int,int)), uas, SLOT(requestParameter(int,int))); - - - connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), - this, SLOT(handleParameterUpdate(int,QString,QVariant))); - - // Listen for param list reload finished - connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), - this, SLOT(handleParameterListUpToDate())); - - connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), - this, SLOT(handleParamStatusMsgUpdate(QString , int ))); - - // Get parameters - if (uas) { - requestAllParamsUpdate(); - } + tree->setVisible(true); } - - - - - void QGCParamWidget::addComponentItem( int compId, QString compName) { + QString compLine = QString("%1 (#%2)").arg(compName).arg(compId); + + QString ptrStr.sprintf("%8p", this); + qDebug() << "QGCParamWidget" << ptrStr << "addComponentItem:" << compLine; + if (componentItems->contains(compId)) { - // Update existing - componentItems->value(compId)->setData(0, Qt::DisplayRole, QString("%1 (#%2)").arg(compName).arg(compId)); + // Update existing component item + componentItems->value(compId)->setData(0, Qt::DisplayRole, compLine); //components->value(component)->setData(1, Qt::DisplayRole, QString::number(component)); componentItems->value(compId)->setFirstColumnSpanned(true); } else { - // Add new - QStringList list(QString("%1 (#%2)").arg(compName).arg(compId)); - QTreeWidgetItem* comp = new QTreeWidgetItem(list); - comp->setFirstColumnSpanned(true); - componentItems->insert(compId, comp); - // Create grouping and update maps + // Add new component item + QStringList list(compLine); + QTreeWidgetItem* compItem = new QTreeWidgetItem(list); + compItem->setFirstColumnSpanned(true); + componentItems->insert(compId, compItem); + // Create parameter grouping for this component and update maps paramGroups.insert(compId, new QMap()); - tree->addTopLevelItem(comp); + tree->addTopLevelItem(compItem); tree->update(); } @@ -202,7 +205,10 @@ void QGCParamWidget::handleParameterUpdate(int componentId, const QString& param void QGCParamWidget::handleParameterListUpToDate() { - tree->collapseAll(); +// tree->collapseAll(); + + //turn off updates while we refresh the entire list + tree->setUpdatesEnabled(false); //rewrite the component item tree after receiving the full list QMap*>::iterator i; @@ -219,44 +225,38 @@ void QGCParamWidget::handleParameterListUpToDate() // Expand visual tree tree->expandItem(tree->topLevelItem(0)); + tree->setUpdatesEnabled(true); + tree->update(); + } void QGCParamWidget::updateParameterDisplay(int componentId, QString parameterName, QVariant value) { +// qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName; -// QString ptrStr; -// ptrStr.sprintf("%8p", this); -// qDebug() << "QGCParamWidget " << ptrStr << " got param" << parameterName; // Reference to item in tree QTreeWidgetItem* parameterItem = NULL; - // Get component + // Add component item if necessary if (!componentItems->contains(componentId)) { QString componentName = tr("Component #%1").arg(componentId); addComponentItem(componentId, componentName); } - //TODO this should be bubbling up from the model, not vice-versa, right? -// // Replace value in data model -// paramDataModel->handleParameterUpdate(componentId,parameterName,value); - - QString splitToken = "_"; // Check if auto-grouping can work - if (parameterName.contains(splitToken)) - { + if (parameterName.contains(splitToken)) { QString parent = parameterName.section(splitToken, 0, 0, QString::SectionSkipEmpty); QMap* compParamGroups = paramGroups.value(componentId); - if (!compParamGroups->contains(parent)) - { + if (!compParamGroups->contains(parent)) { // Insert group item QStringList glist; glist.append(parent); - QTreeWidgetItem* item = new QTreeWidgetItem(glist); - compParamGroups->insert(parent, item); - componentItems->value(componentId)->addChild(item); + QTreeWidgetItem* groupItem = new QTreeWidgetItem(glist); + compParamGroups->insert(parent, groupItem); + componentItems->value(componentId)->addChild(groupItem); } // Append child to group @@ -322,26 +322,30 @@ void QGCParamWidget::updateParameterDisplay(int componentId, QString parameterNa componentItems->value(componentId)->addChild(parameterItem); parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); } - //tree->expandAll(); } + // Reset background color parameterItem->setBackground(0, Qt::NoBrush); parameterItem->setBackground(1, Qt::NoBrush); + + parameterItem->setTextColor(0, QGC::colorDarkWhite); + parameterItem->setTextColor(1, QGC::colorDarkWhite); + // Add tooltip QString paramDesc = paramDataModel->getParamDescription(parameterName); - QString tooltipFormat; - if (paramDataModel->isParamDefaultKnown(parameterName)) { - tooltipFormat = tr("Default: %1, %2"); - double paramDefValue = paramDataModel->getParamDefault(parameterName); - tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc); - } - else { - tooltipFormat = paramDesc; + if (!paramDesc.isEmpty()) { + QString tooltipFormat; + if (paramDataModel->isParamDefaultKnown(parameterName)) { + tooltipFormat = tr("Default: %1, %2"); + double paramDefValue = paramDataModel->getParamDefault(parameterName); + tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc); + } + else { + tooltipFormat = paramDesc; + } + parameterItem->setToolTip(0, tooltipFormat); + parameterItem->setToolTip(1, tooltipFormat); } - parameterItem->setToolTip(0, tooltipFormat); - parameterItem->setToolTip(1, tooltipFormat); - - //paramDataModel->handleParameterUpdate(componentId,parameterName,value); } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 5a356b722b..85794966d5 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -51,6 +51,7 @@ public: protected: virtual void setParameterStatusMsg(const QString& msg); + virtual void layoutWidget(); signals: /** @brief A parameter was changed in the widget, NOT onboard */ -- GitLab From a1266be030ec05fa8c48c87667986792a9e46bc0 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 07:16:18 -0700 Subject: [PATCH 247/460] propagate error signal on too many link errs reduce serial link logging; clear transmit buffer on disconnect --- src/comm/SerialLink.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 07807e550a..1e19bc2a80 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -176,7 +176,9 @@ void SerialLink::run() } if (isConnected() && (linkErrorCount > 100)) { + qDebug() << "linkErrorCount too high: disconnecting!"; linkErrorCount = 0; + communicationError("SerialLink", tr("Disconnecting on too many link errors")); disconnect(); } @@ -210,7 +212,7 @@ void SerialLink::run() } } else { linkErrorCount++; - qDebug() << "Wait read response timeout" << QTime::currentTime().toString(); + //qDebug() << "Wait read response timeout" << QTime::currentTime().toString(); } if (bytes != m_bytesRead) // i.e things are good and data is being read. @@ -370,6 +372,8 @@ bool SerialLink::disconnect() return true; } + m_transmitBuffer.clear(); //clear the output buffer to avoid sending garbage at next connect + qDebug() << "already disconnected"; return true; } -- GitLab From 4c79a3f28a1a9b55f90f86c6a06164f19172b830 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 07:17:17 -0700 Subject: [PATCH 248/460] fix typo --- src/ui/QGCParamWidget.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index a141ec4ea8..025e68f5e4 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -171,7 +171,7 @@ void QGCParamWidget::addComponentItem( int compId, QString compName) { QString compLine = QString("%1 (#%2)").arg(compName).arg(compId); - QString ptrStr.sprintf("%8p", this); + QString ptrStr = QString().sprintf("%8p", this); qDebug() << "QGCParamWidget" << ptrStr << "addComponentItem:" << compLine; if (componentItems->contains(compId)) { -- GitLab From 3319dc6577f116f26dea73928f6960069991ec2e Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 09:11:42 -0700 Subject: [PATCH 249/460] move sendPendingParams --- src/uas/QGCUASParamManager.cc | 6 ++++ src/uas/QGCUASParamManager.h | 3 ++ src/uas/UASParameterCommsMgr.cc | 36 ++++++++++++---------- src/uas/UASParameterCommsMgr.h | 2 +- src/ui/QGCParamWidget.cc | 53 ++++++++++++++++----------------- src/ui/QGCParamWidget.h | 6 +--- 6 files changed, 56 insertions(+), 50 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index c1b29e88f1..6796ef0b49 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -70,6 +70,12 @@ void QGCUASParamManager::setParameter(int component, QString parameterName, QVar paramCommsMgr->setParameter(component,parameterName,value); } +void QGCUASParamManager::sendPendingParameters() +{ + paramCommsMgr->sendPendingParameters(); +} + + void QGCUASParamManager::loadParamMetaInfoCSV() { diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index a5c4b40f2f..9836de2d10 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -46,6 +46,9 @@ public slots: /** @brief Send one parameter to the MAV: changes value in transient memory of MAV */ virtual void setParameter(int component, QString parameterName, QVariant value); + /** @brief Send all pending parameters to the MAV, for storage in transient (RAM) memory */ + virtual void sendPendingParameters(); + /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 690851cbeb..e92ef2ed9c 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -100,25 +100,23 @@ void UASParameterCommsMgr::requestParameterList() Empty read retransmission list Empty write retransmission list */ -void UASParameterCommsMgr::clearRetransmissionLists() +void UASParameterCommsMgr::clearRetransmissionLists(int& missingReadCount, int& missingWriteCount ) { qDebug() << __FILE__ << __LINE__ << "clearRetransmissionLists"; - int missingReadCount = 0; + missingReadCount = 0; QList readKeys = transmissionMissingPackets.keys(); foreach (int component, readKeys) { missingReadCount += transmissionMissingPackets.value(component)->count(); transmissionMissingPackets.value(component)->clear(); } - int missingWriteCount = 0; + missingWriteCount = 0; QList writeKeys = transmissionMissingWriteAckPackets.keys(); foreach (int component, writeKeys) { missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); transmissionMissingWriteAckPackets.value(component)->clear(); } - setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount), - ParamCommsStatusLevel_Warning); } @@ -230,7 +228,6 @@ void UASParameterCommsMgr::retransmissionGuardTick() return; } - qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; // Check for timeout // stop retransmission attempts on timeout @@ -238,10 +235,17 @@ void UASParameterCommsMgr::retransmissionGuardTick() setRetransmissionGuardEnabled(false); transmissionActive = false; transmissionListMode = false; - clearRetransmissionLists(); + int missingReadCount, missingWriteCount; + clearRetransmissionLists(missingReadCount,missingWriteCount); + if ((missingReadCount > 0) || (missingWriteCount > 0)) { + setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount), + ParamCommsStatusLevel_Warning); + } + return; } + qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; resendReadWriteRequests(); } else { @@ -544,15 +548,15 @@ void UASParameterCommsMgr::sendPendingParameters() QMap*>::iterator i; for (i = changedValues->begin(); i != changedValues->end(); ++i) { // Iterate through the parameters of the component - int compid = i.key(); - QMap* comp = i.value(); - { - QMap::iterator j; - for (j = comp->begin(); j != comp->end(); ++j) { - //TODO mavlink command for "set parameter list" ? - setParameter(compid, j.key(), j.value()); - parametersSent++; - } + int compId = i.key(); + QMap* paramList = i.value(); + QMap::iterator j; + setParameterStatusMsg(tr("%1 pending params for component %2").arg(paramList->count()).arg(compId)); + + for (j = paramList->begin(); j != paramList->end(); ++j) { + //TODO mavlink command for "set parameter list" ? + setParameter(compId, j.key(), j.value()); + parametersSent++; } } diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 327d99a94b..b36dc7fb83 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -39,7 +39,7 @@ protected: void loadParamCommsSettings(); /** @brief clear transmissionMissingPackets and transmissionMissingWriteAckPackets */ - void clearRetransmissionLists(); + void clearRetransmissionLists(int& missingReadCount, int& missingWriteCount ); void resendReadWriteRequests(); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 025e68f5e4..6818856401 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -88,7 +88,6 @@ void QGCParamWidget::layoutWidget() tree = new QTreeWidget(this); statusLabel = new QLabel(); statusLabel->setAutoFillBackground(true); - tree->setColumnWidth(70, 30); // Set tree widget as widget onto this component QGridLayout* horizontalLayout; @@ -117,7 +116,8 @@ void QGCParamWidget::layoutWidget() QPushButton* setButton = new QPushButton(tr("Set")); setButton->setToolTip(tr("Set current parameters in non-permanent onboard memory")); setButton->setWhatsThis(tr("Set current parameters in non-permanent onboard memory")); - connect(setButton, SIGNAL(clicked()), this, SLOT(setParameters())); + connect(setButton, SIGNAL(clicked()), + this, SLOT(sendPendingParameters())); horizontalLayout->addWidget(setButton, 2, 1); QPushButton* writeButton = new QPushButton(tr("Write (ROM)")); @@ -159,7 +159,7 @@ void QGCParamWidget::layoutWidget() headerItems.append("Value"); tree->setHeaderLabels(headerItems); tree->setColumnCount(2); - tree->setColumnWidth(0,120); + tree->setColumnWidth(0,200); tree->setColumnWidth(1,120); tree->setExpandsOnDoubleClick(true); @@ -167,8 +167,9 @@ void QGCParamWidget::layoutWidget() } -void QGCParamWidget::addComponentItem( int compId, QString compName) +void QGCParamWidget::addComponentItem(int compId, QString compName) { + QString compLine = QString("%1 (#%2)").arg(compName).arg(compId); QString ptrStr = QString().sprintf("%8p", this); @@ -231,37 +232,41 @@ void QGCParamWidget::handleParameterListUpToDate() } -void QGCParamWidget::updateParameterDisplay(int componentId, QString parameterName, QVariant value) +void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, QVariant value) { // qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName; - // Reference to item in tree QTreeWidgetItem* parameterItem = NULL; // Add component item if necessary - if (!componentItems->contains(componentId)) { - QString componentName = tr("Component #%1").arg(componentId); - addComponentItem(componentId, componentName); + if (!componentItems->contains(compId)) { + QString componentName = tr("Component #%1").arg(compId); + addComponentItem(compId, componentName); } QString splitToken = "_"; // Check if auto-grouping can work if (parameterName.contains(splitToken)) { - QString parent = parameterName.section(splitToken, 0, 0, QString::SectionSkipEmpty); - QMap* compParamGroups = paramGroups.value(componentId); - if (!compParamGroups->contains(parent)) { + QString parentStr = parameterName.section(splitToken, 0, 0, QString::SectionSkipEmpty); + QMap* compParamGroups = paramGroups.value(compId); + if (!compParamGroups->contains(parentStr)) { // Insert group item QStringList glist; - glist.append(parent); + glist.append(parentStr); QTreeWidgetItem* groupItem = new QTreeWidgetItem(glist); - compParamGroups->insert(parent, groupItem); - componentItems->value(componentId)->addChild(groupItem); + + compParamGroups->insert(parentStr, groupItem); + + // insert new group alphabetized + QList groupKeys = compParamGroups->uniqueKeys(); + int insertIdx = groupKeys.indexOf(parentStr); + componentItems->value(compId)->insertChild(insertIdx,groupItem); } // Append child to group bool found = false; - QTreeWidgetItem* parentItem = compParamGroups->value(parent); + QTreeWidgetItem* parentItem = compParamGroups->value(parentStr); for (int i = 0; i < parentItem->childCount(); i++) { QTreeWidgetItem* child = parentItem->child(i); QString key = child->data(0, Qt::DisplayRole).toString(); @@ -292,13 +297,13 @@ void QGCParamWidget::updateParameterDisplay(int componentId, QString parameterNa parameterItem->setData(1, Qt::DisplayRole, value); } - compParamGroups->value(parent)->addChild(parameterItem); + compParamGroups->value(parentStr)->addChild(parameterItem); parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); } } else { bool found = false; - QTreeWidgetItem* parent = componentItems->value(componentId); + QTreeWidgetItem* parent = componentItems->value(compId); for (int i = 0; i < parent->childCount(); i++) { QTreeWidgetItem* child = parent->child(i); QString key = child->data(0, Qt::DisplayRole).toString(); @@ -319,7 +324,7 @@ void QGCParamWidget::updateParameterDisplay(int componentId, QString parameterNa // CONFIGURE PARAMETER ITEM parameterItem->setData(1, Qt::DisplayRole, value); - componentItems->value(componentId)->addChild(parameterItem); + componentItems->value(compId)->addChild(parameterItem); parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); } } @@ -434,14 +439,6 @@ void QGCParamWidget::requestAllParamsUpdate() -/** - * Set all parameter in the parameter tree on the MAV - */ -void QGCParamWidget::setParameters() -{ - paramCommsMgr->sendPendingParameters(); -} - /** * Write the current onboard parameters from RAM into * permanent storage, e.g. EEPROM or harddisk @@ -454,7 +451,7 @@ void QGCParamWidget::writeParameters() QMap*>* changedValues = paramDataModel->getPendingParameters(); for (i = changedValues->begin(); (i != changedValues->end()) && (0 == changedParamCount); ++i) { - // Iterate through the parameters of the component + // Iterate through the pending parameters of the component, break on the first changed parameter QMap* compPending = i.value(); changedParamCount += compPending->count(); } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 85794966d5..2176b5b4a5 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -77,10 +77,7 @@ public slots: void updateParameterDisplay(int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ void requestAllParamsUpdate(); - /** @brief Set one parameter, changes value in RAM of MAV */ -// virtual void setParameter(int component, QString parameterName, QVariant value); - /** @brief Set all parameters, changes the value in RAM of MAV */ - void setParameters(); + /** @brief Write the current parameters to permanent storage (EEPROM/HDD) */ void writeParameters(); /** @brief Read the parameters from permanent storage to RAM */ @@ -103,7 +100,6 @@ protected: QMap* componentItems; ///< The tree of component items, stored by component ID QMap* > paramGroups; ///< Parameter groups to organize component items - }; #endif // QGCPARAMWIDGET_H -- GitLab From 251501447bf418e6ea7d263e9f034d8dcb20bde6 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 09:40:04 -0700 Subject: [PATCH 250/460] clear guard timer when list mode done --- src/uas/UASParameterCommsMgr.cc | 42 ++++++++----- src/uas/UASParameterCommsMgr.h | 1 + src/ui/QGCParamWidget.cc | 101 +++++++++++++++++++++++--------- 3 files changed, 99 insertions(+), 45 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index e92ef2ed9c..c2655dc046 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -106,16 +106,16 @@ void UASParameterCommsMgr::clearRetransmissionLists(int& missingReadCount, int& missingReadCount = 0; QList readKeys = transmissionMissingPackets.keys(); - foreach (int component, readKeys) { - missingReadCount += transmissionMissingPackets.value(component)->count(); - transmissionMissingPackets.value(component)->clear(); + foreach (int compId, readKeys) { + missingReadCount += transmissionMissingPackets.value(compId)->count(); + transmissionMissingPackets.value(compId)->clear(); } missingWriteCount = 0; QList writeKeys = transmissionMissingWriteAckPackets.keys(); - foreach (int component, writeKeys) { - missingWriteCount += transmissionMissingWriteAckPackets.value(component)->count(); - transmissionMissingWriteAckPackets.value(component)->clear(); + foreach (int compId, writeKeys) { + missingWriteCount += transmissionMissingWriteAckPackets.value(compId)->count(); + transmissionMissingWriteAckPackets.value(compId)->clear(); } } @@ -209,10 +209,26 @@ void UASParameterCommsMgr::resendReadWriteRequests() if ((0 == requestedWriteCount) && (0 == requestedReadCount) ) { qDebug() << __FILE__ << __LINE__ << "NO re-read or rewrite requests??"; - //setRetransmissionGuardEnabled(false); + if (!transmissionListMode) { + setRetransmissionGuardEnabled(false); + transmissionActive = false; + } } } +void UASParameterCommsMgr::resetAfterListReceive() +{ + transmissionListMode = false; + transmissionListSizeKnown.clear(); + + //TODO we shouldn't clear missingPackets because other transactions might be using them? + //for list reception we only clear receive packets? +// foreach (int key, transmissionMissingPackets.keys()) { +// transmissionMissingPackets.value(key)->clear(); +// } + +} + void UASParameterCommsMgr::retransmissionGuardTick() { if (transmissionActive) { @@ -233,8 +249,8 @@ void UASParameterCommsMgr::retransmissionGuardTick() // stop retransmission attempts on timeout if (QGC::groundTimeMilliseconds() > transmissionTimeout) { setRetransmissionGuardEnabled(false); - transmissionActive = false; - transmissionListMode = false; + resetAfterListReceive(); + int missingReadCount, missingWriteCount; clearRetransmissionLists(missingReadCount,missingWriteCount); if ((missingReadCount > 0) || (missingWriteCount > 0)) { @@ -491,13 +507,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para // Check if last parameter was received if (missCount == 0 && missWriteCount == 0) { - this->transmissionActive = false; - this->transmissionListMode = false; - transmissionListSizeKnown.clear(); - foreach (int key, transmissionMissingPackets.keys()) { - transmissionMissingPackets.value(key)->clear(); - } - + resetAfterListReceive(); setRetransmissionGuardEnabled(false); //all parameters have been received, broadcast to UI emit parameterListUpToDate(); diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index b36dc7fb83..b1ece5fa18 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -42,6 +42,7 @@ protected: void clearRetransmissionLists(int& missingReadCount, int& missingWriteCount ); void resendReadWriteRequests(); + void resetAfterListReceive(); void emitParameterChanged(int compId, const QString& key, QVariant& value); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 6818856401..069e4cd60e 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -245,6 +245,9 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q addComponentItem(compId, componentName); } + //default parent item for this parameter widget item will be the top level component item + QTreeWidgetItem* parentItem = componentItems->value(compId); + QString splitToken = "_"; // Check if auto-grouping can work if (parameterName.contains(splitToken)) { @@ -265,8 +268,75 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q } // Append child to group + //bool found = false; + //parent item for this tree widget item will be a group widget item + parentItem = compParamGroups->value(parentStr); + +// for (int i = 0; i < parentItem->childCount(); i++) { +// QTreeWidgetItem* child = parentItem->child(i); +// QString key = child->data(0, Qt::DisplayRole).toString(); +// if (key == parameterName) { +// //qDebug() << "UPDATED CHILD"; +// parameterItem = child; +// if (value.type() == QVariant::Char) { +// parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); +// } +// else { +// parameterItem->setData(1, Qt::DisplayRole, value); +// } +// found = true; +// } +// } + +// if (!found) { +// // Insert parameter into map +// QStringList plist; +// plist.append(parameterName); +// // CREATE PARAMETER ITEM +// parameterItem = new QTreeWidgetItem(plist); +// // CONFIGURE PARAMETER ITEM +// if (value.type() == QVariant::Char) { +// parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); +// } +// else { +// parameterItem->setData(1, Qt::DisplayRole, value); +// } +// parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); + +// parentItem->addChild(parameterItem); +// } + } + else { + //bool found = false; + parentItem = componentItems->value(compId); + +// for (int i = 0; i < parent->childCount(); i++) { +// QTreeWidgetItem* child = parent->child(i); +// QString key = child->data(0, Qt::DisplayRole).toString(); +// if (key == parameterName) { +// //qDebug() << "UPDATED CHILD"; +// parameterItem = child; +// parameterItem->setData(1, Qt::DisplayRole, value); +// found = true; +// } +// } + +// if (!found) { +// // Insert parameter into map +// QStringList plist; +// plist.append(parameterName); +// // CREATE PARAMETER ITEM +// parameterItem = new QTreeWidgetItem(plist); +// // CONFIGURE PARAMETER ITEM +// parameterItem->setData(1, Qt::DisplayRole, value); + +// componentItems->value(compId)->addChild(parameterItem); +// parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); +// } + } + + if (parentItem) { bool found = false; - QTreeWidgetItem* parentItem = compParamGroups->value(parentStr); for (int i = 0; i < parentItem->childCount(); i++) { QTreeWidgetItem* child = parentItem->child(i); QString key = child->data(0, Qt::DisplayRole).toString(); @@ -296,36 +366,9 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q else { parameterItem->setData(1, Qt::DisplayRole, value); } - - compParamGroups->value(parentStr)->addChild(parameterItem); parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); - } - } - else { - bool found = false; - QTreeWidgetItem* parent = componentItems->value(compId); - for (int i = 0; i < parent->childCount(); i++) { - QTreeWidgetItem* child = parent->child(i); - QString key = child->data(0, Qt::DisplayRole).toString(); - if (key == parameterName) { - //qDebug() << "UPDATED CHILD"; - parameterItem = child; - parameterItem->setData(1, Qt::DisplayRole, value); - found = true; - } - } - if (!found) { - // Insert parameter into map - QStringList plist; - plist.append(parameterName); - // CREATE PARAMETER ITEM - parameterItem = new QTreeWidgetItem(plist); - // CONFIGURE PARAMETER ITEM - parameterItem->setData(1, Qt::DisplayRole, value); - - componentItems->value(compId)->addChild(parameterItem); - parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); + parentItem->addChild(parameterItem); } } -- GitLab From 3c6bc561c290f27761302098dd03c201d8cd1796 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 11:09:20 -0700 Subject: [PATCH 251/460] fix change checking for params; better pending status indication --- src/uas/UASParameterDataModel.cc | 16 +++--- src/uas/UASParameterDataModel.h | 2 +- src/ui/QGCParamWidget.cc | 86 +++++--------------------------- 3 files changed, 20 insertions(+), 84 deletions(-) diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 96d7479f0b..a4f6976ee6 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -18,25 +18,21 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : -bool UASParameterDataModel::checkParameterChanged(int componentId, const QString& key, const QVariant &value) +bool UASParameterDataModel::checkParameterChanged(int compId, const QString& key, const QVariant& value) { bool changed = true; - addComponent(componentId); - QMap* existParams = getOnbardParametersForComponent(componentId); + //ensure we have this component in our onboard and pending lists already + addComponent(compId); + QMap* existParams = getOnbardParametersForComponent(compId); if (existParams->contains(key)) { QVariant existValue = existParams->value(key); - QMap* pendParams = getPendingParametersForComponent(componentId); - if (pendParams->contains(key)) { - QVariant pendValue = pendParams->value(key); - if (existValue == pendValue) { - changed = false; - } + if (existValue == value) { + changed = false; } } return changed; - } bool UASParameterDataModel::addPendingIfParameterChanged(int componentId, QString& key, QVariant &value) diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 535cc03082..57dbc8f0af 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -45,7 +45,7 @@ public: virtual void forgetAllOnboardParameters(); /** - * @return true if the parameter has changed + * @return true if the given value for the parameter is different from the existing value */ virtual bool checkParameterChanged(int componentId, const QString& key, const QVariant &value); diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 069e4cd60e..484d61d5de 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -267,72 +267,12 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q componentItems->value(compId)->insertChild(insertIdx,groupItem); } - // Append child to group - //bool found = false; - //parent item for this tree widget item will be a group widget item + //parent item for this parameter item will be a group widget item parentItem = compParamGroups->value(parentStr); - -// for (int i = 0; i < parentItem->childCount(); i++) { -// QTreeWidgetItem* child = parentItem->child(i); -// QString key = child->data(0, Qt::DisplayRole).toString(); -// if (key == parameterName) { -// //qDebug() << "UPDATED CHILD"; -// parameterItem = child; -// if (value.type() == QVariant::Char) { -// parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); -// } -// else { -// parameterItem->setData(1, Qt::DisplayRole, value); -// } -// found = true; -// } -// } - -// if (!found) { -// // Insert parameter into map -// QStringList plist; -// plist.append(parameterName); -// // CREATE PARAMETER ITEM -// parameterItem = new QTreeWidgetItem(plist); -// // CONFIGURE PARAMETER ITEM -// if (value.type() == QVariant::Char) { -// parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); -// } -// else { -// parameterItem->setData(1, Qt::DisplayRole, value); -// } -// parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); - -// parentItem->addChild(parameterItem); -// } } else { - //bool found = false; + //parent item for this parameter will be the top level component widget item parentItem = componentItems->value(compId); - -// for (int i = 0; i < parent->childCount(); i++) { -// QTreeWidgetItem* child = parent->child(i); -// QString key = child->data(0, Qt::DisplayRole).toString(); -// if (key == parameterName) { -// //qDebug() << "UPDATED CHILD"; -// parameterItem = child; -// parameterItem->setData(1, Qt::DisplayRole, value); -// found = true; -// } -// } - -// if (!found) { -// // Insert parameter into map -// QStringList plist; -// plist.append(parameterName); -// // CREATE PARAMETER ITEM -// parameterItem = new QTreeWidgetItem(plist); -// // CONFIGURE PARAMETER ITEM -// parameterItem->setData(1, Qt::DisplayRole, value); - -// componentItems->value(compId)->addChild(parameterItem); -// parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); -// } } if (parentItem) { @@ -367,7 +307,7 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q parameterItem->setData(1, Qt::DisplayRole, value); } parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); - + //TODO insert alphabetically parentItem->addChild(parameterItem); } } @@ -411,25 +351,25 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) QString key = current->data(0, Qt::DisplayRole).toString(); QVariant value = current->data(1, Qt::DisplayRole); - // Set parameter on changed list to be transmitted to MAV - QPalette pal = statusLabel->palette(); - pal.setColor(backgroundRole(), QGC::colorOrange); - statusLabel->setPalette(pal); - statusLabel->setText(tr("Transmit pend. %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); - //qDebug() << "PARAM CHANGED: COMP:" << key << "KEY:" << str << "VALUE:" << value; - // Changed values list bool changed = paramDataModel->addPendingIfParameterChanged(componentId,key,value); // If the value was numerically changed, display it differently if (changed) { + + // Set parameter on changed list to be transmitted to MAV + statusLabel->setText(tr("Transmit pend. %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); + + if (current == tree->currentItem()) { + //need to unset current item to clear highlighting (green by default) + tree->setCurrentItem(NULL); //clear the selected line + } current->setBackground(0, QBrush(QColor(QGC::colorOrange))); current->setBackground(1, QBrush(QColor(QGC::colorOrange))); - - //TODO this seems incorrect-- we're pre-updating the onboard value before we've received confirmation - //paramDataModel->setOnboardParameterWithType(componentId,key,value); + tree->update(); } + } } -- GitLab From 5d23be2e61852937954c27d001723f340e19c8fa Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 12:25:17 -0700 Subject: [PATCH 252/460] fix pending parameter change check --- src/uas/QGCUASParamManager.cc | 2 +- src/uas/UASParameterCommsMgr.cc | 11 +++-- src/uas/UASParameterDataModel.cc | 83 +++++++++++++++----------------- src/uas/UASParameterDataModel.h | 40 +++++++-------- src/ui/QGCParamWidget.cc | 26 +++++----- 5 files changed, 80 insertions(+), 82 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 6796ef0b49..fcc78a6cb6 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -26,7 +26,7 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : bool QGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const { - return paramDataModel->getOnboardParameterValue(component,parameter,value); + return paramDataModel->getOnboardParamValue(component,parameter,value); } diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index c2655dc046..47ec654b3f 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -168,7 +168,6 @@ void UASParameterCommsMgr::resendReadWriteRequests() // Re-request at maximum retransmissionBurstRequestSize parameters at once // to prevent link flooding' int requestedReadCount = 0; - compIds = transmissionMissingPackets.keys(); foreach (compId, compIds) { // Request n parameters from this component (at maximum) @@ -214,6 +213,10 @@ void UASParameterCommsMgr::resendReadWriteRequests() transmissionActive = false; } } + else { + //restart the timer now that we've sent + setRetransmissionGuardEnabled(true); + } } void UASParameterCommsMgr::resetAfterListReceive() @@ -354,7 +357,7 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV } QVariant onboardVal; - paramDataModel->getOnboardParameterValue(component,parameterName,onboardVal); + paramDataModel->getOnboardParamValue(component,parameterName,onboardVal); if (onboardVal == value) { setParameterStatusMsg(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue), ParamCommsStatusLevel_Warning @@ -408,7 +411,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para Q_UNUSED(uas); //this object is assigned to one UAS only //notify the data model that we have an updated param - paramDataModel->handleParameterUpdate(compId,paramName,value); + paramDataModel->handleParamUpdate(compId,paramName,value); // Missing packets list has to be instantiated for all components if (!transmissionMissingPackets.contains(compId)) { @@ -554,7 +557,7 @@ void UASParameterCommsMgr::sendPendingParameters() { // Iterate through all components, through all pending parameters and send them to UAS int parametersSent = 0; - QMap*>* changedValues = paramDataModel->getPendingParameters(); + QMap*>* changedValues = paramDataModel->getAllPendingParams(); QMap*>::iterator i; for (i = changedValues->begin(); i != changedValues->end(); ++i) { // Iterate through the parameters of the component diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index a4f6976ee6..c942b4437b 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -18,53 +18,58 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : -bool UASParameterDataModel::checkParameterChanged(int compId, const QString& key, const QVariant& value) + + +bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key, QVariant& value) { - bool changed = true; + bool pending = true; //ensure we have this component in our onboard and pending lists already addComponent(compId); - QMap* existParams = getOnbardParametersForComponent(compId); + QMap* existParams = getOnboardParamsForComponent(compId); if (existParams->contains(key)) { QVariant existValue = existParams->value(key); if (existValue == value) { - changed = false; + pending = false; } } - return changed; -} + if (pending) { + setPendingParam(compId,key,value); + } + else { + removePendingParam(compId,key); + } -bool UASParameterDataModel::addPendingIfParameterChanged(int componentId, QString& key, QVariant &value) + return pending; +} +void UASParameterDataModel::removePendingParam(int compId, QString& key) { - bool changed = checkParameterChanged(componentId,key,value); - - if (changed ) { - setPendingParameter(componentId,key,value); + QMap *params = getPendingParamsForComponent(compId); + if (params) { + params->remove(key); } - - return changed; } -void UASParameterDataModel::setPendingParameter(int componentId, QString& key, const QVariant &value) +void UASParameterDataModel::setPendingParam(int compId, QString& key, const QVariant &value) { //ensure we have a placeholder map for this component - addComponent(componentId); - QMap *params = getPendingParametersForComponent(componentId); + addComponent(compId); + QMap *params = getPendingParamsForComponent(compId); params->insert(key,value); } -void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, const QVariant& value) +void UASParameterDataModel::setOnboardParam(int compId, QString& key, const QVariant& value) { //ensure we have a placeholder map for this component - addComponent(componentId); - QMap *params = getOnbardParametersForComponent(componentId); + addComponent(compId); + QMap *params = getOnboardParamsForComponent(compId); params->insert(key,value); } -void UASParameterDataModel::setOnboardParameterWithType(int componentId, QString& key, QVariant& value) +void UASParameterDataModel::setOnboardParamWithType(int compId, QString& key, QVariant& value) { // switch ((int)onboardParameters.value(componentId)->value(key).type()) @@ -73,25 +78,25 @@ void UASParameterDataModel::setOnboardParameterWithType(int componentId, QString case QVariant::Int: { QVariant fixedValue(value.toInt()); - onboardParameters.value(componentId)->insert(key, fixedValue); + onboardParameters.value(compId)->insert(key, fixedValue); } break; case QVariant::UInt: { QVariant fixedValue(value.toUInt()); - onboardParameters.value(componentId)->insert(key, fixedValue); + onboardParameters.value(compId)->insert(key, fixedValue); } break; case QMetaType::Float: { QVariant fixedValue(value.toFloat()); - onboardParameters.value(componentId)->insert(key, fixedValue); + onboardParameters.value(compId)->insert(key, fixedValue); } break; case QMetaType::QChar: { QVariant fixedValue(QChar((unsigned char)value.toUInt())); - onboardParameters.value(componentId)->insert(key, fixedValue); + onboardParameters.value(compId)->insert(key, fixedValue); } break; default: @@ -111,7 +116,7 @@ void UASParameterDataModel::addComponent(int compId) } -void UASParameterDataModel::handleParameterUpdate(int compId, QString& key, QVariant& value) +void UASParameterDataModel::handleParamUpdate(int compId, QString& key, QVariant& value) { //verify that the value requested by the user matches the set value //if it doesn't match, leave the pending parameter in the pending list! @@ -128,13 +133,13 @@ void UASParameterDataModel::handleParameterUpdate(int compId, QString& key, QVar } } - setOnboardParameter(compId,key,value); + setOnboardParam(compId,key,value); emit parameterUpdated(compId,key,value); } -bool UASParameterDataModel::getOnboardParameterValue(int componentId, const QString& key, QVariant& value) const +bool UASParameterDataModel::getOnboardParamValue(int componentId, const QString& key, QVariant& value) const { if (onboardParameters.contains(componentId)) { @@ -147,14 +152,13 @@ bool UASParameterDataModel::getOnboardParameterValue(int componentId, const QStr return false; } -void UASParameterDataModel::forgetAllOnboardParameters() +void UASParameterDataModel::forgetAllOnboardParams() { onboardParameters.clear(); } -void UASParameterDataModel::readUpdateParametersFromStream( QTextStream& stream) +void UASParameterDataModel::readUpdateParamsFromStream( QTextStream& stream) { - bool userWarned = false; while (!stream.atEnd()) { @@ -165,7 +169,7 @@ void UASParameterDataModel::readUpdateParametersFromStream( QTextStream& stream) if (wpParams.size() == 5) { // Only load parameters for right mav if (!userWarned && (uasId != lineMavId)) { - //TODO warn the user somehow + //TODO warn the user somehow ?? QString msg = tr("The parameters in the stream have been saved from system %1, but the currently selected system has the ID %2.").arg(lineMavId).arg(uasId); // MainWindow::instance()->showCriticalMessage( // tr("Parameter loading warning"), @@ -199,26 +203,17 @@ void UASParameterDataModel::readUpdateParametersFromStream( QTextStream& stream) switch (paramType) { case MAV_PARAM_TYPE_REAL32: - //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toFloat()); - setPendingParameter(componentId,key,QVariant(valStr.toFloat())); - //setParameter(componentId, key, valStr.toFloat()); + setPendingParam(componentId,key,QVariant(valStr.toFloat())); break; case MAV_PARAM_TYPE_UINT32: - //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toUInt()); - setPendingParameter(componentId,key, QVariant(valStr.toUInt())); - //setParameter(componentId, key, QVariant(valStr.toUInt())); + setPendingParam(componentId,key, QVariant(valStr.toUInt())); break; case MAV_PARAM_TYPE_INT32: - //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toInt()); - setPendingParameter(componentId,key,QVariant(valStr.toInt())); - //setParameter(componentId, key, QVariant(valStr.toInt())); + setPendingParam(componentId,key,QVariant(valStr.toInt())); break; default: qDebug() << "FAILED LOADING PARAM" << key << "UNKNOWN DATA TYPE"; } - - //TODO update display - } @@ -228,7 +223,7 @@ void UASParameterDataModel::readUpdateParametersFromStream( QTextStream& stream) } -void UASParameterDataModel::writeOnboardParametersToStream( QTextStream &stream, const QString& name) +void UASParameterDataModel::writeOnboardParamsToStream( QTextStream &stream, const QString& name) { stream << "# Onboard parameters for system " << name << "\n"; stream << "#\n"; diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 57dbc8f0af..6ae4f685cd 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -35,55 +35,51 @@ public: virtual void addComponent(int compId); /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ - virtual void setPendingParameter(int componentId, QString& key, const QVariant& value); - virtual void setOnboardParameter(int componentId, QString& key, const QVariant& value); + virtual void setPendingParam(int componentId, QString& key, const QVariant& value); + + virtual void removePendingParam(int compId, QString& key); /** @brief Save the onboard parameter with a the type specified in the QVariant as fixed */ - virtual void setOnboardParameterWithType(int componentId, QString& key, QVariant& value); + virtual void setOnboardParamWithType(int componentId, QString& key, QVariant& value); /** @brief clears every parameter for every loaded component */ - virtual void forgetAllOnboardParameters(); - - /** - * @return true if the given value for the parameter is different from the existing value - */ - virtual bool checkParameterChanged(int componentId, const QString& key, const QVariant &value); + virtual void forgetAllOnboardParams(); /** @brief add this parameter to pending list iff it has changed from onboard value - * @return true if the parameter has changed + * @return true if the parameter is now pending */ - virtual bool addPendingIfParameterChanged(int componentId, QString& key, QVariant& value); - + virtual bool updatePendingParamWithValue(int componentId, QString& key, QVariant& value); + virtual void handleParamUpdate(int componentId, QString& key, QVariant& value); + virtual bool getOnboardParamValue(int componentId, const QString& key, QVariant& value) const; - virtual void handleParameterUpdate(int componentId, QString& key, QVariant& value); - - virtual bool getOnboardParameterValue(int componentId, const QString& key, QVariant& value) const; - - QMap* getPendingParametersForComponent(int componentId) { + QMap* getPendingParamsForComponent(int componentId) { return pendingParameters.value(componentId); } - QMap* getOnbardParametersForComponent(int componentId) { + QMap* getOnboardParamsForComponent(int componentId) { return onboardParameters.value(componentId); } - QMap* >* getPendingParameters() { + QMap* >* getAllPendingParams() { return &pendingParameters; } - QMap* >* getOnboardParameters() { + QMap* >* getAllOnboardParams() { return &onboardParameters; } - virtual void writeOnboardParametersToStream(QTextStream &stream, const QString& uasName); - virtual void readUpdateParametersFromStream(QTextStream &stream); + virtual void writeOnboardParamsToStream(QTextStream &stream, const QString& uasName); + virtual void readUpdateParamsFromStream(QTextStream &stream); virtual void loadParamMetaInfoFromStream(QTextStream& stream); void setUASID(int anId) { this->uasId = anId; } +protected: + virtual void setOnboardParam(int componentId, QString& key, const QVariant& value); + signals: /** @brief We've received an update of a parameter's value */ diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 484d61d5de..7f18df8c93 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -213,7 +213,7 @@ void QGCParamWidget::handleParameterListUpToDate() //rewrite the component item tree after receiving the full list QMap*>::iterator i; - QMap*>* onboardParams = paramDataModel->getOnboardParameters(); + QMap*>* onboardParams = paramDataModel->getAllOnboardParams(); for (i = onboardParams->begin(); i != onboardParams->end(); ++i) { int compId = i.key(); @@ -352,13 +352,12 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) QString key = current->data(0, Qt::DisplayRole).toString(); QVariant value = current->data(1, Qt::DisplayRole); - bool changed = paramDataModel->addPendingIfParameterChanged(componentId,key,value); - - // If the value was numerically changed, display it differently - if (changed) { + bool pending = paramDataModel->updatePendingParamWithValue(componentId,key,value); + // If the value will result in an update + if (pending) { // Set parameter on changed list to be transmitted to MAV - statusLabel->setText(tr("Transmit pend. %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); + statusLabel->setText(tr("Pending: %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); if (current == tree->currentItem()) { //need to unset current item to clear highlighting (green by default) @@ -366,9 +365,14 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) } current->setBackground(0, QBrush(QColor(QGC::colorOrange))); current->setBackground(1, QBrush(QColor(QGC::colorOrange))); - tree->update(); } - + else { + QMap* pendingParams = paramDataModel->getOnboardParamsForComponent(componentId); + int pendingCount = pendingParams->count(); + statusLabel->setText(tr("Pending items: %1").arg(pendingCount)); + current->setBackground(0, Qt::NoBrush); + current->setBackground(1, Qt::NoBrush); + } } } @@ -385,7 +389,7 @@ void QGCParamWidget::saveParametersToFile() } QTextStream outstream(&file); - paramDataModel->writeOnboardParametersToStream(outstream,mav->getUASName()); + paramDataModel->writeOnboardParamsToStream(outstream,mav->getUASName()); file.close(); } @@ -399,7 +403,7 @@ void QGCParamWidget::loadParametersFromFile() return; QTextStream in(&file); - paramDataModel->readUpdateParametersFromStream(in); + paramDataModel->readUpdateParamsFromStream(in); file.close(); } @@ -431,7 +435,7 @@ void QGCParamWidget::writeParameters() int changedParamCount = 0; QMap*>::iterator i; - QMap*>* changedValues = paramDataModel->getPendingParameters(); + QMap*>* changedValues = paramDataModel->getAllPendingParams(); for (i = changedValues->begin(); (i != changedValues->end()) && (0 == changedParamCount); ++i) { // Iterate through the pending parameters of the component, break on the first changed parameter -- GitLab From 1bc43cabe4e7079a2115d2c0b07e0b3cc7be486b Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 13:01:39 -0700 Subject: [PATCH 253/460] workaround for premature timer firing bug --- src/uas/UASParameterCommsMgr.cc | 26 ++++++++++++++++---------- src/uas/UASParameterCommsMgr.h | 5 +---- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 47ec654b3f..18b31ec3c8 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -234,23 +234,33 @@ void UASParameterCommsMgr::resetAfterListReceive() void UASParameterCommsMgr::retransmissionGuardTick() { + quint64 curTime = QGC::groundTimeMilliseconds(); + + //Workaround for an apparent Qt bug that causes retransmission guard timer to fire prematurely (350ms) + quint64 elapsed = (curTime = lastTimerReset); + if (elapsed < transmissionTimeout) { + qDebug() << "retransmissionGuardTick elapsed:" << (curTime - lastTimerReset); + //reset the guard timer: it fired prematurely + setRetransmissionGuardEnabled(true); + return; + } + if (transmissionActive) { if (transmissionListMode && transmissionListSizeKnown.isEmpty() ) { //we are still waitin for the first parameter list response - if (QGC::groundTimeMilliseconds() > this->listRecvTimeout) { + if (curTime > this->listRecvTimeout) { //re-request parameters setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); - listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; + listRecvTimeout = curTime + 10000; mav->requestParameters(); } return; } - // Check for timeout // stop retransmission attempts on timeout - if (QGC::groundTimeMilliseconds() > transmissionTimeout) { + if (curTime > transmissionTimeout) { setRetransmissionGuardEnabled(false); resetAfterListReceive(); @@ -285,10 +295,9 @@ void UASParameterCommsMgr::retransmissionGuardTick() void UASParameterCommsMgr::setRetransmissionGuardEnabled(bool enabled) { -// qDebug() << "setRetransmissionGuardEnabled: " << enabled; - if (enabled) { retransmissionTimer.start(retransmissionTimeout); + lastTimerReset = QGC::groundTimeMilliseconds() ; } else { retransmissionTimer.stop(); } @@ -429,7 +438,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para transmissionListSizeKnown.insert(compId, true); qDebug() << "Mark all parameters as missing: " << paramCount; - for (int i = 1; i < paramCount; ++i) { //TODO check: param Id 0 is "all parameters" ? + for (int i = 1; i < paramCount; ++i) { //TODO check: param Id 0 is "all parameters" and not valid ? if (!compXmitMissing->contains(i)) { compXmitMissing->append(i); } @@ -444,9 +453,6 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para } } - // Start retransmission guard - // or reset timer - setRetransmissionGuardEnabled(true); } // Mark this parameter as received in read list diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index b1ece5fa18..006d45d83f 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -84,10 +84,6 @@ public slots: virtual void receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value); -//protected slots: -// void receivedParameterChange(int uas, int component, QString parameterName, QVariant value); -// void receivedParameterListChange(int uas, int component, int parameterCount, int parameterId, QString parameterName, QVariant value); - protected: UASInterface* mav; ///< The MAV we're talking to @@ -103,6 +99,7 @@ protected: bool transmissionActive; ///< Missing packets, working on list? quint64 transmissionTimeout; ///< Timeout QTimer retransmissionTimer; ///< Timer handling parameter retransmission + quint64 lastTimerReset; ///< Last time the guard timer was reset, to prevent premature firing int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds int rewriteTimeout; ///< Write request timeout, in milliseconds int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst -- GitLab From 0af584991bdaca375e82be6d658bbc8496733ba3 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 13:57:21 -0700 Subject: [PATCH 254/460] propagate pending list updates fix pending items indicator --- src/uas/UASParameterDataModel.cc | 6 ++ src/uas/UASParameterDataModel.h | 3 + src/ui/QGCParamWidget.cc | 130 +++++++++++++++++++------------ src/ui/QGCParamWidget.h | 11 +-- 4 files changed, 95 insertions(+), 55 deletions(-) diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index c942b4437b..1806ec23fc 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -49,6 +49,10 @@ void UASParameterDataModel::removePendingParam(int compId, QString& key) QMap *params = getPendingParamsForComponent(compId); if (params) { params->remove(key); + //broadcast the existing value + QVariant existVal; + bool ok = getOnboardParamValue(compId,key,existVal); + emit pendingParamUpdate(compId, key,existVal, false); } } @@ -59,6 +63,8 @@ void UASParameterDataModel::setPendingParam(int compId, QString& key, const QVa addComponent(compId); QMap *params = getPendingParamsForComponent(compId); params->insert(key,value); + emit pendingParamUpdate(compId, key, value, true); + } void UASParameterDataModel::setOnboardParam(int compId, QString& key, const QVariant& value) diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 6ae4f685cd..fde760b703 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -85,6 +85,9 @@ signals: /** @brief We've received an update of a parameter's value */ void parameterUpdated(int compId, QString paramName, QVariant value); + /** @brief Notifies listeners that a param was added to or removed from the pending list */ + void pendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); + public slots: diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 7f18df8c93..ce20a29d67 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -66,6 +66,9 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), this, SLOT(handleParameterUpdate(int,QString,QVariant))); + connect(paramDataModel, SIGNAL(pendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending)), + this, SLOT(handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending))); + // Listen for param list reload finished connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), this, SLOT(handleParameterListUpToDate())); @@ -197,6 +200,19 @@ void QGCParamWidget::addComponentItem(int compId, QString compName) } +void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) +{ + QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); + if (isPending) { + paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); + paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); + } + else { + paramItem->setBackground(0, Qt::NoBrush); + paramItem->setBackground(1, Qt::NoBrush); + } + +} void QGCParamWidget::handleParameterUpdate(int componentId, const QString& paramName, QVariant value) { @@ -206,7 +222,6 @@ void QGCParamWidget::handleParameterUpdate(int componentId, const QString& param void QGCParamWidget::handleParameterListUpToDate() { -// tree->collapseAll(); //turn off updates while we refresh the entire list tree->setUpdatesEnabled(false); @@ -231,27 +246,30 @@ void QGCParamWidget::handleParameterListUpToDate() } - -void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, QVariant value) +QTreeWidgetItem* QGCParamWidget::findChildWidgetItemForParam(QTreeWidgetItem* parentItem, const QString& paramName) { -// qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName; - - // Reference to item in tree - QTreeWidgetItem* parameterItem = NULL; - - // Add component item if necessary - if (!componentItems->contains(compId)) { - QString componentName = tr("Component #%1").arg(compId); - addComponentItem(compId, componentName); + QTreeWidgetItem* childItem = NULL; + + for (int i = 0; i < parentItem->childCount(); i++) { + QTreeWidgetItem* child = parentItem->child(i); + QString key = child->data(0, Qt::DisplayRole).toString(); + if (key == paramName) { + childItem = child; + break; + } } - //default parent item for this parameter widget item will be the top level component item + return childItem; +} + +QTreeWidgetItem* QGCParamWidget::getParentWidgetItemForParam(int compId, const QString& paramName) +{ QTreeWidgetItem* parentItem = componentItems->value(compId); QString splitToken = "_"; // Check if auto-grouping can work - if (parameterName.contains(splitToken)) { - QString parentStr = parameterName.section(splitToken, 0, 0, QString::SectionSkipEmpty); + if (paramName.contains(splitToken)) { + QString parentStr = paramName.section(splitToken, 0, 0, QString::SectionSkipEmpty); QMap* compParamGroups = paramGroups.value(compId); if (!compParamGroups->contains(parentStr)) { // Insert group item @@ -271,29 +289,31 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q parentItem = compParamGroups->value(parentStr); } else { - //parent item for this parameter will be the top level component widget item + //parent item for this parameter will be the top level (component) widget item parentItem = componentItems->value(compId); } - if (parentItem) { - bool found = false; - for (int i = 0; i < parentItem->childCount(); i++) { - QTreeWidgetItem* child = parentItem->child(i); - QString key = child->data(0, Qt::DisplayRole).toString(); - if (key == parameterName) { - //qDebug() << "UPDATED CHILD"; - parameterItem = child; - if (value.type() == QVariant::Char) { - parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); - } - else { - parameterItem->setData(1, Qt::DisplayRole, value); - } - found = true; - } - } + return parentItem; +} + +QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, QVariant value) +{ +// qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName; + + // Reference to item in tree + QTreeWidgetItem* parameterItem = NULL; - if (!found) { + // Add component item if necessary + if (!componentItems->contains(compId)) { + QString componentName = tr("Component #%1").arg(compId); + addComponentItem(compId, componentName); + } + + //default parent item for this parameter widget item will be the top level component item + QTreeWidgetItem* parentItem = getParentWidgetItemForParam(compId,parameterName); + if (parentItem) { + parameterItem = findChildWidgetItemForParam(parentItem,parameterName); + if (!parameterItem) { // Insert parameter into map QStringList plist; plist.append(parameterName); @@ -309,6 +329,30 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); //TODO insert alphabetically parentItem->addChild(parameterItem); + + //only add the tooltip when the parameter item is first added + QString paramDesc = paramDataModel->getParamDescription(parameterName); + if (!paramDesc.isEmpty()) { + QString tooltipFormat; + if (paramDataModel->isParamDefaultKnown(parameterName)) { + tooltipFormat = tr("Default: %1, %2"); + double paramDefValue = paramDataModel->getParamDefault(parameterName); + tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc); + } + else { + tooltipFormat = paramDesc; + } + parameterItem->setToolTip(0, tooltipFormat); + parameterItem->setToolTip(1, tooltipFormat); + } + } + + //update the parameterItem's data + if (value.type() == QVariant::Char) { + parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); + } + else { + parameterItem->setData(1, Qt::DisplayRole, value); } } @@ -319,21 +363,7 @@ void QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, Q parameterItem->setTextColor(0, QGC::colorDarkWhite); parameterItem->setTextColor(1, QGC::colorDarkWhite); - // Add tooltip - QString paramDesc = paramDataModel->getParamDescription(parameterName); - if (!paramDesc.isEmpty()) { - QString tooltipFormat; - if (paramDataModel->isParamDefaultKnown(parameterName)) { - tooltipFormat = tr("Default: %1, %2"); - double paramDefValue = paramDataModel->getParamDefault(parameterName); - tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc); - } - else { - tooltipFormat = paramDesc; - } - parameterItem->setToolTip(0, tooltipFormat); - parameterItem->setToolTip(1, tooltipFormat); - } + return parameterItem; } @@ -367,7 +397,7 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) current->setBackground(1, QBrush(QColor(QGC::colorOrange))); } else { - QMap* pendingParams = paramDataModel->getOnboardParamsForComponent(componentId); + QMap* pendingParams = paramDataModel->getPendingParamsForComponent(componentId); int pendingCount = pendingParams->count(); statusLabel->setText(tr("Pending items: %1").arg(pendingCount)); current->setBackground(0, Qt::NoBrush); diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 2176b5b4a5..33df32200b 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -52,10 +52,11 @@ public: protected: virtual void setParameterStatusMsg(const QString& msg); virtual void layoutWidget(); + virtual QTreeWidgetItem* getParentWidgetItemForParam(int compId, const QString& paramName); + virtual QTreeWidgetItem* findChildWidgetItemForParam(QTreeWidgetItem* parentItem, const QString& paramName); + signals: - /** @brief A parameter was changed in the widget, NOT onboard */ - //void parameterChanged(int component, QString parametername, float value); // defined in QGCUASParamManager already public slots: @@ -65,16 +66,16 @@ public slots: */ void addComponentItem(int compId, QString compName); - /** @brief Add a parameter to the list with retransmission / safety checks */ -// void receivedParameterUpdate(int uas, int component, int paramCount, int paramId, QString parameterName, QVariant value); virtual void handleParameterUpdate(int component,const QString& parameterName, QVariant value); + virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); + virtual void handleParameterListUpToDate(); virtual void handleParamStatusMsgUpdate(QString msg, int level); /** @brief Ensure that view of parameter matches data in the model */ - void updateParameterDisplay(int component, QString parameterName, QVariant value); + QTreeWidgetItem* updateParameterDisplay(int component, QString parameterName, QVariant value); /** @brief Request list of parameters from MAV */ void requestAllParamsUpdate(); -- GitLab From 8d860fdc0089596f245de1b3e56def56eb4cb168 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 16:57:02 -0700 Subject: [PATCH 255/460] fix lastTimerReset bug --- src/uas/UASParameterCommsMgr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 18b31ec3c8..5e04a92ffa 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -237,7 +237,7 @@ void UASParameterCommsMgr::retransmissionGuardTick() quint64 curTime = QGC::groundTimeMilliseconds(); //Workaround for an apparent Qt bug that causes retransmission guard timer to fire prematurely (350ms) - quint64 elapsed = (curTime = lastTimerReset); + quint64 elapsed = (curTime - lastTimerReset); if (elapsed < transmissionTimeout) { qDebug() << "retransmissionGuardTick elapsed:" << (curTime - lastTimerReset); //reset the guard timer: it fired prematurely -- GitLab From d907b9341b65cf77cc2ead4bde4439440eeb35d5 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 17:19:51 -0700 Subject: [PATCH 256/460] fix timeout checker --- src/uas/UASParameterCommsMgr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 5e04a92ffa..c80b6e522b 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -238,7 +238,7 @@ void UASParameterCommsMgr::retransmissionGuardTick() //Workaround for an apparent Qt bug that causes retransmission guard timer to fire prematurely (350ms) quint64 elapsed = (curTime - lastTimerReset); - if (elapsed < transmissionTimeout) { + if (elapsed < retransmissionTimeout) { qDebug() << "retransmissionGuardTick elapsed:" << (curTime - lastTimerReset); //reset the guard timer: it fired prematurely setRetransmissionGuardEnabled(true); -- GitLab From fb50a3cdb5d7d60355a2f80277e8773bf986c67c Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 17:24:45 -0700 Subject: [PATCH 257/460] fix slot wiring; debounce echo from data model --- src/uas/UASParameterCommsMgr.cc | 6 +----- src/ui/QGCParamWidget.cc | 31 +++++++++++++++++++------------ src/ui/QGCParamWidget.h | 1 + 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index c80b6e522b..ec1395041c 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -224,11 +224,7 @@ void UASParameterCommsMgr::resetAfterListReceive() transmissionListMode = false; transmissionListSizeKnown.clear(); - //TODO we shouldn't clear missingPackets because other transactions might be using them? - //for list reception we only clear receive packets? -// foreach (int key, transmissionMissingPackets.keys()) { -// transmissionMissingPackets.value(key)->clear(); -// } + //We shouldn't clear missingPackets because other transactions might be using them? } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index ce20a29d67..52bfc208c1 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -66,8 +66,8 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), this, SLOT(handleParameterUpdate(int,QString,QVariant))); - connect(paramDataModel, SIGNAL(pendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending)), - this, SLOT(handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending))); + connect(paramDataModel, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), + this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); // Listen for param list reload finished connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), @@ -348,6 +348,7 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para } //update the parameterItem's data + updatedLineItem_weak = parameterItem; //keep a temporary ref to the item that's being updated if (value.type() == QVariant::Char) { parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); } @@ -363,24 +364,30 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para parameterItem->setTextColor(0, QGC::colorDarkWhite); parameterItem->setTextColor(1, QGC::colorDarkWhite); + updatedLineItem_weak = NULL; return parameterItem; } -void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) +void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column) { - if (current && column > 0) { - QTreeWidgetItem* parent = current->parent(); + if (paramItem && column > 0) { + if (paramItem == updatedLineItem_weak) { + //ignore updates reflected back from the data model, to avoid infinite loop + return; + } + + QTreeWidgetItem* parent = paramItem->parent(); while (parent->parent() != NULL) { parent = parent->parent(); } // Parent is now top-level component int componentId = componentItems->key(parent); - QString key = current->data(0, Qt::DisplayRole).toString(); - QVariant value = current->data(1, Qt::DisplayRole); + QString key = paramItem->data(0, Qt::DisplayRole).toString(); + QVariant value = paramItem->data(1, Qt::DisplayRole); bool pending = paramDataModel->updatePendingParamWithValue(componentId,key,value); @@ -389,19 +396,19 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column) // Set parameter on changed list to be transmitted to MAV statusLabel->setText(tr("Pending: %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); - if (current == tree->currentItem()) { + if (paramItem == tree->currentItem()) { //need to unset current item to clear highlighting (green by default) tree->setCurrentItem(NULL); //clear the selected line } - current->setBackground(0, QBrush(QColor(QGC::colorOrange))); - current->setBackground(1, QBrush(QColor(QGC::colorOrange))); + paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); + paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); } else { QMap* pendingParams = paramDataModel->getPendingParamsForComponent(componentId); int pendingCount = pendingParams->count(); statusLabel->setText(tr("Pending items: %1").arg(pendingCount)); - current->setBackground(0, Qt::NoBrush); - current->setBackground(1, Qt::NoBrush); + paramItem->setBackground(0, Qt::NoBrush); + paramItem->setBackground(1, Qt::NoBrush); } } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 33df32200b..d0e6f96c39 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -100,6 +100,7 @@ protected: QLabel* statusLabel; ///< User-facing parameter status label QMap* componentItems; ///< The tree of component items, stored by component ID QMap* > paramGroups; ///< Parameter groups to organize component items + QTreeWidgetItem* updatedLineItem_weak;///< weak ref to user-edited line }; -- GitLab From 9af23ff72c6bd83956636d2c9c047c9a9033f2cd Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 9 Aug 2013 18:28:10 -0700 Subject: [PATCH 258/460] Begin to connect separate param widgets via data model still some remaining issues with pending line items bouncing back from data model --- src/uas/UASParameterCommsMgr.cc | 8 ++++++-- src/ui/QGCParamWidget.cc | 35 +++++++++++++++++++++++++-------- src/ui/QGCParamWidget.h | 1 + 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index ec1395041c..27ee774faf 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -50,6 +50,7 @@ void UASParameterCommsMgr::loadParamCommsSettings() int val = settings.value("PARAMETER_RETRANSMISSION_TIMEOUT", retransmissionTimeout).toInt(&ok); if (ok) { retransmissionTimeout = val; + qDebug() << "retransmissionTimeout" << retransmissionTimeout; } val = settings.value("PARAMETER_REWRITE_TIMEOUT", rewriteTimeout).toInt(&ok); if (ok) { @@ -240,6 +241,8 @@ void UASParameterCommsMgr::retransmissionGuardTick() setRetransmissionGuardEnabled(true); return; } + qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE after" << elapsed; + if (transmissionActive) { @@ -250,6 +253,8 @@ void UASParameterCommsMgr::retransmissionGuardTick() setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); listRecvTimeout = curTime + 10000; mav->requestParameters(); + //reset the timer + setRetransmissionGuardEnabled(true); } return; } @@ -270,7 +275,6 @@ void UASParameterCommsMgr::retransmissionGuardTick() return; } - qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE, CHECKING FOR DROPS.."; resendReadWriteRequests(); } else { @@ -443,7 +447,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para // There is only one transmission timeout for all components // since components do not manage their transmission, // the longest timeout is safe for all components. - quint64 thisTransmissionTimeout = QGC::groundTimeMilliseconds() + ((paramCount)*retransmissionTimeout); + quint64 thisTransmissionTimeout = QGC::groundTimeMilliseconds() + (paramCount*retransmissionTimeout); if (thisTransmissionTimeout > transmissionTimeout) { transmissionTimeout = thisTransmissionTimeout; } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 52bfc208c1..2f7f8ca541 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -202,7 +202,20 @@ void QGCParamWidget::addComponentItem(int compId, QString compName) void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) { + qDebug() << "handlePendingParamUpdate:" << paramName << "with updatedLineItem_weak:" << updatedLineItem_weak; + + if (updatedLineItem_weak) { + QString key = updatedLineItem_weak->data(0, Qt::DisplayRole).toString(); + if (paramName == key) { + //debounce echo from data model + return; + } + } + QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); + if (updatedLineItem_weak == NULL) { + updatedLineItem_weak = paramItem; + } if (isPending) { paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); @@ -327,6 +340,8 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para parameterItem->setData(1, Qt::DisplayRole, value); } parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); + updatedLineItem_weak = parameterItem; //keep a temporary ref to the item that's being updated + //TODO insert alphabetically parentItem->addChild(parameterItem); @@ -347,8 +362,9 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para } } - //update the parameterItem's data updatedLineItem_weak = parameterItem; //keep a temporary ref to the item that's being updated + + //update the parameterItem's data if (value.type() == QVariant::Char) { parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); } @@ -357,14 +373,16 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para } } - // Reset background color - parameterItem->setBackground(0, Qt::NoBrush); - parameterItem->setBackground(1, Qt::NoBrush); + if (parameterItem) { + // Reset background color + parameterItem->setBackground(0, Qt::NoBrush); + parameterItem->setBackground(1, Qt::NoBrush); - parameterItem->setTextColor(0, QGC::colorDarkWhite); - parameterItem->setTextColor(1, QGC::colorDarkWhite); + parameterItem->setTextColor(0, QGC::colorDarkWhite); + parameterItem->setTextColor(1, QGC::colorDarkWhite); - updatedLineItem_weak = NULL; + updatedLineItem_weak = NULL; + } return parameterItem; } @@ -374,7 +392,8 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column) { if (paramItem && column > 0) { - if (paramItem == updatedLineItem_weak) { + + if (!paramItem->isSelected() || (paramItem == updatedLineItem_weak)) { //ignore updates reflected back from the data model, to avoid infinite loop return; } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index d0e6f96c39..5779b2e4b2 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -101,6 +101,7 @@ protected: QMap* componentItems; ///< The tree of component items, stored by component ID QMap* > paramGroups; ///< Parameter groups to organize component items QTreeWidgetItem* updatedLineItem_weak;///< weak ref to user-edited line +// QTreeWidgetItem* updatedPendingItem_weak;///< weak ref to pending-modified line }; -- GitLab From 656841a65231b53fd3548a1d72860144c1eeb5f5 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 12 Aug 2013 14:08:00 -0700 Subject: [PATCH 259/460] Better data model update debouncing --- src/ui/QGCParamWidget.cc | 44 ++++++++++++++++++++++------------------ src/ui/QGCParamWidget.h | 3 +-- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 2f7f8ca541..5fa7727093 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -51,7 +51,8 @@ This file is part of the QGROUNDCONTROL project */ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QGCUASParamManager(uas, parent), - componentItems(new QMap()) + componentItems(new QMap()), + updatingParamNameLock("") { layoutWidget(); @@ -202,20 +203,17 @@ void QGCParamWidget::addComponentItem(int compId, QString compName) void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) { - qDebug() << "handlePendingParamUpdate:" << paramName << "with updatedLineItem_weak:" << updatedLineItem_weak; + qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; - if (updatedLineItem_weak) { - QString key = updatedLineItem_weak->data(0, Qt::DisplayRole).toString(); - if (paramName == key) { - //debounce echo from data model - return; - } + if (updatingParamNameLock == paramName) { + qDebug() << "ignoring bounce from " << paramName; + return; + } + else { + updatingParamNameLock = paramName; } QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); - if (updatedLineItem_weak == NULL) { - updatedLineItem_weak = paramItem; - } if (isPending) { paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); @@ -225,17 +223,20 @@ void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramNa paramItem->setBackground(1, Qt::NoBrush); } + updatingParamNameLock.clear(); + } void QGCParamWidget::handleParameterUpdate(int componentId, const QString& paramName, QVariant value) { + updatingParamNameLock = paramName; updateParameterDisplay(componentId, paramName, value); + updatingParamNameLock.clear(); } void QGCParamWidget::handleParameterListUpToDate() { - //turn off updates while we refresh the entire list tree->setUpdatesEnabled(false); @@ -340,7 +341,6 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para parameterItem->setData(1, Qt::DisplayRole, value); } parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); - updatedLineItem_weak = parameterItem; //keep a temporary ref to the item that's being updated //TODO insert alphabetically parentItem->addChild(parameterItem); @@ -362,8 +362,6 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para } } - updatedLineItem_weak = parameterItem; //keep a temporary ref to the item that's being updated - //update the parameterItem's data if (value.type() == QVariant::Char) { parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); @@ -381,7 +379,6 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para parameterItem->setTextColor(0, QGC::colorDarkWhite); parameterItem->setTextColor(1, QGC::colorDarkWhite); - updatedLineItem_weak = NULL; } return parameterItem; @@ -391,12 +388,19 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column) { + if (paramItem && column > 0) { - if (!paramItem->isSelected() || (paramItem == updatedLineItem_weak)) { - //ignore updates reflected back from the data model, to avoid infinite loop + QString key = paramItem->data(0, Qt::DisplayRole).toString(); + qDebug() << "parameterItemChanged:" << key << "with updatingParamNameLock:" << updatingParamNameLock; + + if (key == updatingParamNameLock) { + qDebug() << "ignoring parameterItemChanged" << key; return; } + else { + updatingParamNameLock = key; + } QTreeWidgetItem* parent = paramItem->parent(); while (parent->parent() != NULL) { @@ -404,10 +408,9 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column } // Parent is now top-level component int componentId = componentItems->key(parent); - - QString key = paramItem->data(0, Qt::DisplayRole).toString(); QVariant value = paramItem->data(1, Qt::DisplayRole); + bool pending = paramDataModel->updatePendingParamWithValue(componentId,key,value); // If the value will result in an update @@ -430,6 +433,7 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column paramItem->setBackground(1, Qt::NoBrush); } + updatingParamNameLock.clear(); } } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 5779b2e4b2..3578ed04ba 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -100,8 +100,7 @@ protected: QLabel* statusLabel; ///< User-facing parameter status label QMap* componentItems; ///< The tree of component items, stored by component ID QMap* > paramGroups; ///< Parameter groups to organize component items - QTreeWidgetItem* updatedLineItem_weak;///< weak ref to user-edited line -// QTreeWidgetItem* updatedPendingItem_weak;///< weak ref to pending-modified line + QString updatingParamNameLock; ///< Name of param currently being updated-- used for reducing echo on param change }; -- GitLab From 98f2ae2307a2f53828abfe934a6c26322e3db725 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 12 Aug 2013 14:59:58 -0700 Subject: [PATCH 260/460] more strict locking of currently updating parameter --- src/ui/QGCParamWidget.cc | 53 +++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 5fa7727093..ab8624c64f 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -249,7 +249,9 @@ void QGCParamWidget::handleParameterListUpToDate() QMap* paramPairs = onboardParams->value(compId); QMap::iterator j; for (j = paramPairs->begin(); j != paramPairs->end(); j++) { + updatingParamNameLock = j.key(); updateParameterDisplay(compId, j.key(),j.value()); + updatingParamNameLock.clear(); } } @@ -315,7 +317,7 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para // qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName; // Reference to item in tree - QTreeWidgetItem* parameterItem = NULL; + QTreeWidgetItem* paramItem = NULL; // Add component item if necessary if (!componentItems->contains(compId)) { @@ -326,24 +328,24 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para //default parent item for this parameter widget item will be the top level component item QTreeWidgetItem* parentItem = getParentWidgetItemForParam(compId,parameterName); if (parentItem) { - parameterItem = findChildWidgetItemForParam(parentItem,parameterName); - if (!parameterItem) { + paramItem = findChildWidgetItemForParam(parentItem,parameterName); + if (!paramItem) { // Insert parameter into map QStringList plist; plist.append(parameterName); // CREATE PARAMETER ITEM - parameterItem = new QTreeWidgetItem(plist); + paramItem = new QTreeWidgetItem(plist); // CONFIGURE PARAMETER ITEM if (value.type() == QVariant::Char) { - parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); + paramItem->setData(1, Qt::DisplayRole, value.toUInt()); } else { - parameterItem->setData(1, Qt::DisplayRole, value); + paramItem->setData(1, Qt::DisplayRole, value); } - parameterItem->setFlags(parameterItem->flags() | Qt::ItemIsEditable); + paramItem->setFlags(paramItem->flags() | Qt::ItemIsEditable); //TODO insert alphabetically - parentItem->addChild(parameterItem); + parentItem->addChild(paramItem); //only add the tooltip when the parameter item is first added QString paramDesc = paramDataModel->getParamDescription(parameterName); @@ -357,30 +359,35 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para else { tooltipFormat = paramDesc; } - parameterItem->setToolTip(0, tooltipFormat); - parameterItem->setToolTip(1, tooltipFormat); + paramItem->setToolTip(0, tooltipFormat); + paramItem->setToolTip(1, tooltipFormat); } } //update the parameterItem's data if (value.type() == QVariant::Char) { - parameterItem->setData(1, Qt::DisplayRole, value.toUInt()); + paramItem->setData(1, Qt::DisplayRole, value.toUInt()); } else { - parameterItem->setData(1, Qt::DisplayRole, value); + paramItem->setData(1, Qt::DisplayRole, value); } } - if (parameterItem) { + if (paramItem) { // Reset background color - parameterItem->setBackground(0, Qt::NoBrush); - parameterItem->setBackground(1, Qt::NoBrush); + paramItem->setBackground(0, Qt::NoBrush); + paramItem->setBackground(1, Qt::NoBrush); - parameterItem->setTextColor(0, QGC::colorDarkWhite); - parameterItem->setTextColor(1, QGC::colorDarkWhite); + paramItem->setTextColor(0, QGC::colorDarkWhite); + paramItem->setTextColor(1, QGC::colorDarkWhite); + + if (paramItem == tree->currentItem()) { + //need to unset current item to clear highlighting (green by default) + tree->setCurrentItem(NULL); //clear the selected line + } } - return parameterItem; + return paramItem; } @@ -418,10 +425,6 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column // Set parameter on changed list to be transmitted to MAV statusLabel->setText(tr("Pending: %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); - if (paramItem == tree->currentItem()) { - //need to unset current item to clear highlighting (green by default) - tree->setCurrentItem(NULL); //clear the selected line - } paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); } @@ -433,6 +436,12 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column paramItem->setBackground(1, Qt::NoBrush); } + + if (paramItem == tree->currentItem()) { + //need to unset current item to clear highlighting (green by default) + tree->setCurrentItem(NULL); //clear the selected line + } + updatingParamNameLock.clear(); } } -- GitLab From d7c6cad7f1c0bd006037eb7078132798e8196916 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 12 Aug 2013 17:10:22 -0700 Subject: [PATCH 261/460] cleanup cruft --- src/uas/QGCUASParamManager.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 9836de2d10..5612334e6e 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -29,7 +29,7 @@ public: UASInterface* getUAS(); protected: - //TODO decouple this UI message display further + //TODO decouple this UI message display further? virtual void setParameterStatusMsg(const QString& msg); /** @brief Load parameter meta information from appropriate CSV file */ virtual void loadParamMetaInfoCSV(); @@ -38,9 +38,6 @@ protected: signals: void parameterChanged(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); -// void parameterUpdateRequested(int component, const QString& parameter); -// void parameterUpdateRequestedById(int componentId, int paramId); - public slots: /** @brief Send one parameter to the MAV: changes value in transient memory of MAV */ @@ -62,8 +59,8 @@ public slots: protected: // Parameter data model - UASInterface* mav; ///< The MAV this widget is controlling - UASParameterDataModel* paramDataModel;///< Shared data model of parameters + UASInterface* mav; ///< The MAV this manager is controlling + UASParameterDataModel* paramDataModel;///< Shared data model of parameters UASParameterCommsMgr* paramCommsMgr; ///< Shared comms mgr for parameters // Status -- GitLab From 624bb0a4efdaa1bfefe03c3ac5cbb80852eddad0 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 12 Aug 2013 18:13:45 -0700 Subject: [PATCH 262/460] prelim extraction of read-only pending params widget --- qgroundcontrol.pro | 6 +- src/uas/QGCUASParamManager.cc | 8 +- src/uas/QGCUASParamManager.h | 2 + src/ui/ParameterInterface.cc | 1 + src/ui/QGCPX4VehicleConfig.cc | 8 +- src/ui/QGCPX4VehicleConfig.h | 1 + src/ui/QGCPX4VehicleConfig.ui | 24 +++++- src/ui/QGCParamWidget.cc | 19 +++-- src/ui/QGCParamWidget.h | 4 +- src/ui/QGCPendingParamWidget.cc | 33 +++++++++ src/ui/QGCPendingParamWidget.h | 26 +++++++ src/ui/designer/QGCComboBox.cc | 23 ++---- src/ui/designer/QGCComboBox.h | 4 +- src/ui/designer/QGCParamSlider.cc | 117 ++++++++++++++---------------- src/ui/designer/QGCParamSlider.h | 4 +- 15 files changed, 173 insertions(+), 107 deletions(-) create mode 100644 src/ui/QGCPendingParamWidget.cc create mode 100644 src/ui/QGCPendingParamWidget.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 6f0f51ca48..cf714d579c 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -470,7 +470,8 @@ HEADERS += src/MG.h \ src/ui/configuration/ApmHighlighter.h \ src/ui/configuration/ApmFirmwareConfig.h \ src/uas/UASParameterDataModel.h \ - src/uas/UASParameterCommsMgr.h + src/uas/UASParameterCommsMgr.h \ + src/ui/QGCPendingParamWidget.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -687,7 +688,8 @@ SOURCES += src/main.cc \ src/ui/configuration/ApmHighlighter.cc \ src/ui/configuration/ApmFirmwareConfig.cc \ src/uas/UASParameterDataModel.cc \ - src/uas/UASParameterCommsMgr.cc + src/uas/UASParameterCommsMgr.cc \ + src/ui/QGCPendingParamWidget.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index fcc78a6cb6..f1fd085bff 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -18,9 +18,6 @@ QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : // Load default values and tooltips loadParamMetaInfoCSV(); - - - } @@ -75,6 +72,11 @@ void QGCUASParamManager::sendPendingParameters() paramCommsMgr->sendPendingParameters(); } +void QGCUASParamManager::setPendingParam(int compId, QString& paramName, const QVariant& value) +{ + paramDataModel->setPendingParam(compId,paramName,value); +} + void QGCUASParamManager::loadParamMetaInfoCSV() diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 5612334e6e..6c910509cd 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -49,6 +49,8 @@ public slots: /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); + virtual void setPendingParam(int componentId, QString& key, const QVariant& value); + /** @brief Request a single parameter by name from the MAV */ virtual void requestParameterUpdate(int component, const QString& parameter); diff --git a/src/ui/ParameterInterface.cc b/src/ui/ParameterInterface.cc index c7d5f811b3..93624d50ea 100644 --- a/src/ui/ParameterInterface.cc +++ b/src/ui/ParameterInterface.cc @@ -98,6 +98,7 @@ void ParameterInterface::addUAS(UASInterface* uas) } QGCParamWidget* param = new QGCParamWidget(uas, this); + param->init(); QString ptrStr; ptrStr.sprintf("QGCParamWidget %8p (parent %8p)", param,this); qDebug() << "Created " << ptrStr << " for UAS id: " << uasId << " count: " << paramWidgets->count(); diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 177a5e0660..e28569335b 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -15,6 +15,7 @@ #include "QGCPX4VehicleConfig.h" #include "QGC.h" +#include "QGCPendingParamWidget.h" #include "QGCToolWidget.h" #include "UASManager.h" #include "UASParameterCommsMgr.h" @@ -82,7 +83,9 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(ui->rcModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setRCModeIndex(int))); //connect(ui->setTrimButton, SIGNAL(clicked()), this, SLOT(setTrimPositions())); - + //TODO connect buttons here to save/clear actions? + ui->pendingCommitsWidget->init(); + ui->pendingCommitsWidget->update(); //TODO the following methods are not yet implemented @@ -301,7 +304,6 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) } // Generate widgets for the Advanced tab. - left = true; foreach (QString file,vehicledir.entryList(QDir::Files | QDir::NoDotAndDotDot)) { if (file.toLower().endsWith(".qgw")) { @@ -1232,8 +1234,6 @@ void QGCPX4VehicleConfig::handleRcParameterChange(QString parameterName, QVarian void QGCPX4VehicleConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) { - Q_UNUSED(uas); - Q_UNUSED(component); if (!doneLoadingConfig) { //We do not want to attempt to generate any UI elements until loading of the config file is complete. //We should re-request params later if needed, that is not implemented yet. diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index 93761d52f2..a242fcf9d3 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -187,6 +187,7 @@ protected: QTimer updateTimer; ///< Controls update intervals enum RC_MODE rc_mode; ///< Mode of the remote control, according to usual convention QList toolWidgets; ///< Configurable widgets + QMap toolWidgetsByName; ///< bool calibrationEnabled; ///< calibration mode on / off QMap paramToWidgetMap; ///< Holds the current active MAV's parameter widgets. diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 8607a55643..da0ddfd9b1 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -138,7 +138,7 @@ Config - 0 + 3 @@ -1035,8 +1035,8 @@ p, li { white-space: pre-wrap; } 0 0 - 16 - 16 + 597 + 569 @@ -1168,7 +1168,17 @@ p, li { white-space: pre-wrap; } 0 - + + + + 0 + 30 + + + + true + + @@ -1259,6 +1269,12 @@ p, li { white-space: pre-wrap; }
ui/designer/QGCRadioChannelDisplay.h
1 + + QGCPendingParamWidget + QWidget +
/ui/QGCPendingParamWidget.h
+ 1 +
diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index ab8624c64f..1f4889603d 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -55,9 +55,19 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : updatingParamNameLock("") { +} + +void QGCParamWidget::init() +{ layoutWidget(); + connectSignalsAndSlots(); + + // Ensure we're receiving the list of params + requestAllParamsUpdate(); +} - // Connect signals/slots +void QGCParamWidget::connectSignalsAndSlots() +{ // Listen for edits to the tree UI connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), @@ -77,15 +87,8 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : // Listen to communications status messages so we can display them connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), this, SLOT(handleParamStatusMsgUpdate(QString , int ))); - - // Ensure we're receiving the list of params - requestAllParamsUpdate(); - } - - - void QGCParamWidget::layoutWidget() { // Create tree widget diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 3578ed04ba..f23a627d33 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -48,10 +48,12 @@ class QGCParamWidget : public QGCUASParamManager Q_OBJECT public: QGCParamWidget(UASInterface* uas, QWidget *parent = 0); + virtual void init(); ///< Two-stage construction: initialize the object protected: virtual void setParameterStatusMsg(const QString& msg); - virtual void layoutWidget(); + virtual void layoutWidget();///< Layout the appearance of this widget + virtual void connectSignalsAndSlots();///< Connect signals/slots as needed virtual QTreeWidgetItem* getParentWidgetItemForParam(int compId, const QString& paramName); virtual QTreeWidgetItem* findChildWidgetItemForParam(QTreeWidgetItem* parentItem, const QString& paramName); diff --git a/src/ui/QGCPendingParamWidget.cc b/src/ui/QGCPendingParamWidget.cc new file mode 100644 index 0000000000..800ca354e0 --- /dev/null +++ b/src/ui/QGCPendingParamWidget.cc @@ -0,0 +1,33 @@ +#include "QGCPendingParamWidget.h" + +#include "UASManager.h" +#include "UASParameterCommsMgr.h" + + +QGCPendingParamWidget::QGCPendingParamWidget(QObject *parent) : + QGCParamWidget(UASManager::instance()->getActiveUAS(),(QWidget*)parent) +{ +} + + +void QGCPendingParamWidget::init() +{ + //we override a lot of the super's init methods + layoutWidget(); + connectSignalsAndSlots(); + + //don't request update params here...assume that everything we need is in the data model +} + +void QGCPendingParamWidget::connectSignalsAndSlots() +{ + // Listing for pending list update + connect(paramDataModel, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), + this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); + + // Listen to communications status messages so we can display them + connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), + this, SLOT(handleParamStatusMsgUpdate(QString , int ))); +} + + diff --git a/src/ui/QGCPendingParamWidget.h b/src/ui/QGCPendingParamWidget.h new file mode 100644 index 0000000000..91f08a522f --- /dev/null +++ b/src/ui/QGCPendingParamWidget.h @@ -0,0 +1,26 @@ +#ifndef QGCPENDINGPARAMWIDGET_H +#define QGCPENDINGPARAMWIDGET_H + + +#include "QGCParamWidget.h" + +class QGCPendingParamWidget : public QGCParamWidget +{ + Q_OBJECT + +public: + explicit QGCPendingParamWidget(QObject* parent); + virtual void init(); ///< Two-stage construction: initialize the object + +protected: + virtual void connectSignalsAndSlots(); + + + +signals: + +public slots: + +}; + +#endif // QGCPENDINGPARAMWIDGET_H diff --git a/src/ui/designer/QGCComboBox.cc b/src/ui/designer/QGCComboBox.cc index 91f9dfc21b..01ca3881b8 100644 --- a/src/ui/designer/QGCComboBox.cc +++ b/src/ui/designer/QGCComboBox.cc @@ -48,7 +48,7 @@ QGCComboBox::QGCComboBox(QWidget *parent) : connect(ui->editRemoveItemButton,SIGNAL(clicked()),this,SLOT(delButtonClicked())); // Sending actions - connect(ui->writeButton, SIGNAL(clicked()), this, SLOT(sendParameter())); + connect(ui->writeButton, SIGNAL(clicked()), this, SLOT(setParamPending())); connect(ui->editSelectComponentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectComponent(int))); connect(ui->editSelectParamComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectParameter(int))); //connect(ui->valueSlider, SIGNAL(valueChanged(int)), this, SLOT(setSliderValue(int))); @@ -233,24 +233,13 @@ void QGCComboBox::endEditMode() emit editingFinished(); } -void QGCComboBox::sendParameter() +void QGCComboBox::setParamPending() { - if (uas) - { - // Set value, param manager handles retransmission - if (uas->getParamManager()) - { - qDebug() << "Sending param:" << parameterName << "to component" << component << "with a value of" << parameterValue; - uas->getParamManager()->setParameter(component, parameterName, parameterValue); - } - else - { - qDebug() << "UAS HAS NO PARAM MANAGER, DOING NOTHING"; - } + if (uas) { + uas->getParamManager()->setPendingParam(component, parameterName, parameterValue); } - else - { - qDebug() << __FILE__ << __LINE__ << "NO UAS SET, DOING NOTHING"; + else { + qWarning() << __FILE__ << __LINE__ << "NO UAS SET, DOING NOTHING"; } } diff --git a/src/ui/designer/QGCComboBox.h b/src/ui/designer/QGCComboBox.h index 4c5491580e..ecc71126b5 100644 --- a/src/ui/designer/QGCComboBox.h +++ b/src/ui/designer/QGCComboBox.h @@ -23,8 +23,8 @@ public: public slots: void startEditMode(); void endEditMode(); - /** @brief Send the parameter to the MAV */ - void sendParameter(); + /** @brief Queue parameter for sending to the MAV (add to pending list)*/ + void setParamPending(); /** @brief Update the UI with the new parameter value */ void setParameterValue(int uas, int component, int paramCount, int paramIndex, QString parameterName, const QVariant value); void writeSettings(QSettings& settings); diff --git a/src/ui/designer/QGCParamSlider.cc b/src/ui/designer/QGCParamSlider.cc index 32b236a4b8..54b3bd723e 100644 --- a/src/ui/designer/QGCParamSlider.cc +++ b/src/ui/designer/QGCParamSlider.cc @@ -47,20 +47,31 @@ QGCParamSlider::QGCParamSlider(QWidget *parent) : connect(ui->editDoneButton, SIGNAL(clicked()), this, SLOT(endEditMode())); // Sending actions - connect(ui->writeButton, SIGNAL(clicked()), this, SLOT(sendParameter())); - connect(ui->editSelectComponentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectComponent(int))); - connect(ui->editSelectParamComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectParameter(int))); - connect(ui->valueSlider, SIGNAL(valueChanged(int)), this, SLOT(setSliderValue(int))); - connect(ui->doubleValueSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setParamValue(double))); - connect(ui->intValueSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setParamValue(int))); - connect(ui->editNameLabel, SIGNAL(textChanged(QString)), ui->nameLabel, SLOT(setText(QString))); + connect(ui->writeButton, SIGNAL(clicked()), + this, SLOT(setParamPending())); + connect(ui->editSelectComponentComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(selectComponent(int))); + connect(ui->editSelectParamComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(selectParameter(int))); + connect(ui->valueSlider, SIGNAL(valueChanged(int)), + this, SLOT(setSliderValue(int))); + connect(ui->doubleValueSpinBox, SIGNAL(valueChanged(double)), + this, SLOT(setParamValue(double))); + connect(ui->intValueSpinBox, SIGNAL(valueChanged(int)), + this, SLOT(setParamValue(int))); + connect(ui->editNameLabel, SIGNAL(textChanged(QString)), + ui->nameLabel, SLOT(setText(QString))); connect(ui->readButton, SIGNAL(clicked()), this, SLOT(requestParameter())); - connect(ui->editRefreshParamsButton, SIGNAL(clicked()), this, SLOT(refreshParamList())); - connect(ui->editInfoCheckBox, SIGNAL(clicked(bool)), this, SLOT(showInfo(bool))); + connect(ui->editRefreshParamsButton, SIGNAL(clicked()), + this, SLOT(refreshParamList())); + connect(ui->editInfoCheckBox, SIGNAL(clicked(bool)), + this, SLOT(showInfo(bool))); // connect to self - connect(ui->infoLabel, SIGNAL(released()), this, SLOT(showTooltip())); + connect(ui->infoLabel, SIGNAL(released()), + this, SLOT(showTooltip())); // Set the current UAS if present - connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); + connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), + this, SLOT(setActiveUAS(UASInterface*))); } QGCParamSlider::~QGCParamSlider() @@ -83,8 +94,7 @@ void QGCParamSlider::refreshParamList() { ui->editSelectParamComboBox->setEnabled(true); ui->editSelectComponentComboBox->setEnabled(true); - if (uas) - { + if (uas) { uas->getParamManager()->requestParameterList(); ui->editStatusLabel->setText(tr("Parameter list updating..")); } @@ -122,9 +132,8 @@ void QGCParamSlider::setActiveUAS(UASInterface* activeUas) void QGCParamSlider::requestParameter() { - if (!parameterName.isEmpty() && uas) - { - uas->getParamManager()->requestParameterUpdate(this->component, this->parameterName); + if (uas && !parameterName.isEmpty()) { + uas->getParamManager()->requestParameterUpdate(component, parameterName); } } @@ -268,23 +277,13 @@ void QGCParamSlider::endEditMode() emit editingFinished(); } -void QGCParamSlider::sendParameter() +void QGCParamSlider::setParamPending() { - if (uas) - { - // Set value, param manager handles retransmission - if (uas->getParamManager()) - { - uas->getParamManager()->setParameter(component, parameterName, parameterValue); - } - else - { - qDebug() << "UAS HAS NO PARAM MANAGER, DOING NOTHING"; - } + if (uas) { + uas->getParamManager()->setPendingParam(component, parameterName, parameterValue); } - else - { - qDebug() << __FILE__ << __LINE__ << "NO UAS SET, DOING NOTHING"; + else { + qWarning() << __FILE__ << __LINE__ << "NO UAS SET, DOING NOTHING"; } } @@ -329,55 +328,48 @@ void QGCParamSlider::setSliderValue(int sliderValue) * @brief parameterName Key/name of the parameter * @brief value Value of the parameter */ -void QGCParamSlider::setParameterValue(int uas, int component, int paramCount, int paramIndex, QString parameterName, QVariant value) +void QGCParamSlider::setParameterValue(int uasId, int compId, int paramCount, int paramIndex, QString paramName, QVariant value) { Q_UNUSED(paramCount); - if (ui->nameLabel->text() == "Name") - { - ui->nameLabel->setText(parameterName); + if (uasId != this->uas->getUASID()) { + return; + } + + if (ui->nameLabel->text() == "Name") { + ui->nameLabel->setText(paramName); } // Check if this component and parameter are part of the list bool found = false; - for (int i = 0; i< ui->editSelectComponentComboBox->count(); ++i) - { - if (component == ui->editSelectComponentComboBox->itemData(i).toInt()) - { + for (int i = 0; i< ui->editSelectComponentComboBox->count(); ++i) { + if (compId == ui->editSelectComponentComboBox->itemData(i).toInt()) { found = true; } } - if (!found) - { - ui->editSelectComponentComboBox->addItem(tr("Component #%1").arg(component), component); + if (!found) { + ui->editSelectComponentComboBox->addItem(tr("Component #%1").arg(compId), compId); } // Parameter checking found = false; - for (int i = 0; i < ui->editSelectParamComboBox->count(); ++i) - { - if (parameterName == ui->editSelectParamComboBox->itemText(i)) - { + for (int i = 0; i < ui->editSelectParamComboBox->count(); ++i) { + if (paramName == ui->editSelectParamComboBox->itemText(i)) { found = true; } } - if (!found) - { - ui->editSelectParamComboBox->addItem(parameterName, paramIndex); + if (!found) { + ui->editSelectParamComboBox->addItem(paramName, paramIndex); } - if (visibleParam != "") - { - if (parameterName == visibleParam) - { - if (visibleVal == value.toInt()) - { - this->uas->requestParameter(this->component,this->parameterName); + if (visibleParam != "") { + if (paramName == visibleParam) { + if (visibleVal == value.toInt()) { + uas->getParamManager()->requestParameterUpdate(compId,paramName); visibleEnabled = true; this->show(); } - else - { + else { //Disable the component here. ui->valueSlider->setEnabled(false); ui->intValueSpinBox->setEnabled(false); @@ -388,10 +380,8 @@ void QGCParamSlider::setParameterValue(int uas, int component, int paramCount, i } } Q_UNUSED(uas); - if (component == this->component && parameterName == this->parameterName) - { - if (!visibleEnabled) - { + if (compId == this->component && paramName == this->parameterName) { + if (!visibleEnabled) { return; } parameterValue = value; @@ -460,8 +450,7 @@ void QGCParamSlider::setParameterValue(int uas, int component, int paramCount, i parameterMin = ui->editMinSpinBox->value(); } - if (paramIndex == paramCount - 1) - { + if (paramIndex == paramCount - 1) { ui->editStatusLabel->setText(tr("Complete parameter list received.")); } } diff --git a/src/ui/designer/QGCParamSlider.h b/src/ui/designer/QGCParamSlider.h index 7160cd937e..3ef78fdf71 100644 --- a/src/ui/designer/QGCParamSlider.h +++ b/src/ui/designer/QGCParamSlider.h @@ -23,8 +23,8 @@ public: public slots: void startEditMode(); void endEditMode(); - /** @brief Send the parameter to the MAV */ - void sendParameter(); + /** @brief Queue parameter for sending to the MAV (add to pending list)*/ + void setParamPending(); /** @brief Set the slider value as parameter value */ void setSliderValue(int sliderValue); /** @brief Update the UI with the new parameter value */ -- GitLab From 4ace23f96c36a5ee84cb3c8baeaad8b8ed3bbd46 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 13 Aug 2013 11:50:50 -0700 Subject: [PATCH 263/460] fix counting of written params; fix wiring of pend param widget to model --- src/uas/QGCUASParamManager.cc | 7 +-- src/uas/UASParameterCommsMgr.cc | 77 ++++++++++++++++---------------- src/uas/UASParameterCommsMgr.h | 6 +-- src/uas/UASParameterDataModel.cc | 77 ++++++++++++++++++++++++-------- src/uas/UASParameterDataModel.h | 13 ++++-- src/ui/QGCParamWidget.cc | 17 ++++--- src/ui/QGCPendingParamWidget.cc | 29 ++++++++++++ src/ui/QGCPendingParamWidget.h | 3 +- 8 files changed, 157 insertions(+), 72 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index f1fd085bff..569daebb67 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -62,9 +62,10 @@ void QGCUASParamManager::setParamDescriptions(const QMap& param } -void QGCUASParamManager::setParameter(int component, QString parameterName, QVariant value) +void QGCUASParamManager::setParameter(int compId, QString paramName, QVariant value) { - paramCommsMgr->setParameter(component,parameterName,value); + //paramCommsMgr->setParameter(compId,paramName,value); + paramDataModel->updatePendingParamWithValue(compId,paramName,value); } void QGCUASParamManager::sendPendingParameters() @@ -74,7 +75,7 @@ void QGCUASParamManager::sendPendingParameters() void QGCUASParamManager::setPendingParam(int compId, QString& paramName, const QVariant& value) { - paramDataModel->setPendingParam(compId,paramName,value); + paramDataModel->updatePendingParamWithValue(compId,paramName,value); } diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 27ee774faf..63ccac4839 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -27,7 +27,7 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : mav, SLOT(requestParameter(int,int))); // Sending params to the UAS - connect(this, SIGNAL(parameterChanged(int,QString,QVariant)), + connect(this, SIGNAL(commitPendingParameter(int,QString,QVariant)), mav, SLOT(setParameter(int,QString,QVariant))); // Received parameter updates from UAS @@ -113,16 +113,16 @@ void UASParameterCommsMgr::clearRetransmissionLists(int& missingReadCount, int& } missingWriteCount = 0; - QList writeKeys = transmissionMissingWriteAckPackets.keys(); + QList writeKeys = missingWriteAckPackets.keys(); foreach (int compId, writeKeys) { - missingWriteCount += transmissionMissingWriteAckPackets.value(compId)->count(); - transmissionMissingWriteAckPackets.value(compId)->clear(); + missingWriteCount += missingWriteAckPackets.value(compId)->count(); + missingWriteAckPackets.value(compId)->clear(); } } -void UASParameterCommsMgr::emitParameterChanged(int compId, const QString& key, QVariant& value) +void UASParameterCommsMgr::emitPendingParameterCommit(int compId, const QString& key, QVariant& value) { int paramType = (int)value.type(); switch (paramType) @@ -130,25 +130,25 @@ void UASParameterCommsMgr::emitParameterChanged(int compId, const QString& key, case QVariant::Char: { QVariant fixedValue(QChar((unsigned char)value.toInt())); - emit parameterChanged(compId, key, fixedValue); + emit commitPendingParameter(compId, key, fixedValue); } break; case QVariant::Int: { QVariant fixedValue(value.toInt()); - emit parameterChanged(compId, key, fixedValue); + emit commitPendingParameter(compId, key, fixedValue); } break; case QVariant::UInt: { QVariant fixedValue(value.toUInt()); - emit parameterChanged(compId, key, fixedValue); + emit commitPendingParameter(compId, key, fixedValue); } break; case QMetaType::Float: { QVariant fixedValue(value.toFloat()); - emit parameterChanged(compId, key, fixedValue); + emit commitPendingParameter(compId, key, fixedValue); } break; default: @@ -190,14 +190,14 @@ void UASParameterCommsMgr::resendReadWriteRequests() // Re-request at maximum retransmissionBurstRequestSize parameters at once // to prevent write-request link flooding int requestedWriteCount = 0; - compIds = transmissionMissingWriteAckPackets.keys(); + compIds = missingWriteAckPackets.keys(); foreach (compId, compIds) { - QMap * missingParams = transmissionMissingWriteAckPackets.value(compId); + QMap * missingParams = missingWriteAckPackets.value(compId); foreach (QString key, missingParams->keys()) { if (requestedWriteCount < retransmissionBurstRequestSize) { // Re-request write operation QVariant value = missingParams->value(key); - emitParameterChanged(compId, key, value); + emitPendingParameterCommit(compId, key, value); requestedWriteCount++; } else { @@ -234,7 +234,7 @@ void UASParameterCommsMgr::retransmissionGuardTick() quint64 curTime = QGC::groundTimeMilliseconds(); //Workaround for an apparent Qt bug that causes retransmission guard timer to fire prematurely (350ms) - quint64 elapsed = (curTime - lastTimerReset); + int elapsed = (int)(curTime - lastTimerReset); if (elapsed < retransmissionTimeout) { qDebug() << "retransmissionGuardTick elapsed:" << (curTime - lastTimerReset); //reset the guard timer: it fired prematurely @@ -374,16 +374,16 @@ void UASParameterCommsMgr::setParameter(int component, QString parameterName, QV return; } - emitParameterChanged(component, parameterName, value); + emitPendingParameterCommit(component, parameterName, value); // Wait for parameter to be written back // mark it therefore as missing - if (!transmissionMissingWriteAckPackets.contains(component)) { - transmissionMissingWriteAckPackets.insert(component, new QMap()); + if (!missingWriteAckPackets.contains(component)) { + missingWriteAckPackets.insert(component, new QMap()); } // Insert it in missing write ACK list - transmissionMissingWriteAckPackets.value(component)->insert(parameterName, value); + missingWriteAckPackets.value(component)->insert(parameterName, value); // Set timeouts if (transmissionActive) { @@ -466,42 +466,42 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para bool writeMismatch = false; // Mark this parameter as received in write ACK list - QMap* map = transmissionMissingWriteAckPackets.value(compId); + QMap* map = missingWriteAckPackets.value(compId); if (map && map->contains(paramName)) { justWritten = true; - QVariant newval = map->value(paramName); if (map->value(paramName) != value) { writeMismatch = true; } map->remove(paramName); } - int missCount = 0; + int missReadCount = 0; foreach (int key, transmissionMissingPackets.keys()) { - missCount += transmissionMissingPackets.value(key)->count(); + missReadCount += transmissionMissingPackets.value(key)->count(); } int missWriteCount = 0; - foreach (int key, transmissionMissingWriteAckPackets.keys()) { - missWriteCount += transmissionMissingWriteAckPackets.value(key)->count(); + foreach (int key, missingWriteAckPackets.keys()) { + missWriteCount += missingWriteAckPackets.value(key)->count(); } //TODO simplify this if-else tree - if (justWritten && !writeMismatch && missWriteCount == 0) { - // Just wrote one and count went to 0 - this was the last missing write parameter - setParameterStatusMsg(tr("SUCCESS: WROTE ALL PARAMETERS")); - } - else if (justWritten && !writeMismatch) { - setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount)); - } - else if (justWritten && writeMismatch) { - // Mismatch, tell user - setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(map->value(paramName).toDouble()).arg(value.toDouble()), - ParamCommsStatusLevel_Warning); + if (justWritten) { + if (!writeMismatch) { + setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount)); + if (0 == missWriteCount) { + setParameterStatusMsg(tr("SUCCESS: WROTE ALL PARAMETERS")); + paramDataModel->commitAllPendingParams(); + } + } + else { + // Mismatch, tell user + setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(map->value(paramName).toDouble()).arg(value.toDouble()), + ParamCommsStatusLevel_Warning); + } } else { - QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); - if (missCount == 0) { + if (missReadCount == 0) { // Transmission done QTime time = QTime::currentTime(); QString timeString = time.toString(); @@ -509,13 +509,14 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para } else { // Transmission in progress - setParameterStatusMsg(tr("OK: %1 %2 (%3/%4)").arg(paramName).arg(val).arg(paramCount-missCount).arg(paramCount), + QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); + setParameterStatusMsg(tr("OK: %1 %2 (%3/%4)").arg(paramName).arg(val).arg(paramCount-missReadCount).arg(paramCount), ParamCommsStatusLevel_Warning); } } // Check if last parameter was received - if (missCount == 0 && missWriteCount == 0) { + if (missReadCount == 0 && missWriteCount == 0) { resetAfterListReceive(); setRetransmissionGuardEnabled(false); //all parameters have been received, broadcast to UI diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 006d45d83f..d554e0021a 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -44,10 +44,10 @@ protected: void resendReadWriteRequests(); void resetAfterListReceive(); - void emitParameterChanged(int compId, const QString& key, QVariant& value); + void emitPendingParameterCommit(int compId, const QString& key, QVariant& value); signals: - void parameterChanged(int component, QString parameter, QVariant value); + void commitPendingParameter(int component, QString parameter, QVariant value); void parameterChanged(int component, int parameterIndex, QVariant value); void parameterValueConfirmed(int uas, int component,int paramCount, int paramId, QString parameter, QVariant value); @@ -93,7 +93,7 @@ protected: // Communications management QVector receivedParamsList; ///< Successfully received parameters QMap* > transmissionMissingPackets; ///< Missing packets - QMap* > transmissionMissingWriteAckPackets; ///< Missing write ACK packets + QMap* > missingWriteAckPackets; ///< Missing write ACK packets bool transmissionListMode; ///< Currently requesting list QMap transmissionListSizeKnown; ///< List size initialized? bool transmissionActive; ///< Missing packets, working on list? diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 1806ec23fc..ab444d4962 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -18,9 +18,42 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : +int UASParameterDataModel::countPendingParams() +{ + int totalPending = 0; + QMap*>::iterator i; + for (i = pendingParameters.begin(); i != pendingParameters.end(); ++i) { + // Iterate through the parameters of the component + QMap* paramList = i.value(); + totalPending += paramList->count(); + } + + return totalPending; +} + +void UASParameterDataModel::commitAllPendingParams() +{ + qDebug() << "commitAllPendingParams:" << countPendingParams(); + + QList allCompIds = pendingParameters.keys(); + foreach (int compId, allCompIds) { + // Iterate through the parameters of the component + QMap* compParams = pendingParameters.value(compId); + QList paramNames = compParams->keys(); + qDebug() << paramNames.count() << "committed params for component" << compId; + + foreach (QString paramName, paramNames) { + QVariant value = compParams->value(paramName); + setOnboardParamWithType( compId, paramName, value);//update the onboard value to match pending value + emit pendingParamUpdate(compId,paramName,value,false); //no longer pending + emit parameterUpdated(compId,paramName,value);//ensure the new onboard value is broadcast + } + + } +} -bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key, QVariant& value) +bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key, const QVariant& value) { bool pending = true; //ensure we have this component in our onboard and pending lists already @@ -44,27 +77,36 @@ bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key return pending; } -void UASParameterDataModel::removePendingParam(int compId, QString& key) + +bool UASParameterDataModel::isParamChangePending(int compId, const QString& key) { - QMap *params = getPendingParamsForComponent(compId); - if (params) { - params->remove(key); - //broadcast the existing value - QVariant existVal; - bool ok = getOnboardParamValue(compId,key,existVal); - emit pendingParamUpdate(compId, key,existVal, false); - } + QMap* pendingParms = getPendingParamsForComponent(compId); + return ((NULL != pendingParms) && pendingParms->contains(key)); } - void UASParameterDataModel::setPendingParam(int compId, QString& key, const QVariant &value) { //ensure we have a placeholder map for this component addComponent(compId); - QMap *params = getPendingParamsForComponent(compId); - params->insert(key,value); - emit pendingParamUpdate(compId, key, value, true); + QMap *pendParams = getPendingParamsForComponent(compId); + if (pendParams) { + pendParams->insert(key,value); + emit pendingParamUpdate(compId, key, value, true); + } +} +void UASParameterDataModel::removePendingParam(int compId, QString& key) +{ + qDebug() << "removePendingParam:" << key; + + QMap *pendParams = getPendingParamsForComponent(compId); + if (pendParams) { + pendParams->remove(key); + //broadcast the existing value + QVariant existVal; + getOnboardParamValue(compId,key,existVal); + emit pendingParamUpdate(compId, key,existVal, false); + } } void UASParameterDataModel::setOnboardParam(int compId, QString& key, const QVariant& value) @@ -78,7 +120,6 @@ void UASParameterDataModel::setOnboardParam(int compId, QString& key, const QVa void UASParameterDataModel::setOnboardParamWithType(int compId, QString& key, QVariant& value) { -// switch ((int)onboardParameters.value(componentId)->value(key).type()) switch ((int)value.type()) { case QVariant::Int: @@ -209,13 +250,13 @@ void UASParameterDataModel::readUpdateParamsFromStream( QTextStream& stream) switch (paramType) { case MAV_PARAM_TYPE_REAL32: - setPendingParam(componentId,key,QVariant(valStr.toFloat())); + updatePendingParamWithValue(componentId,key,QVariant(valStr.toFloat())); break; case MAV_PARAM_TYPE_UINT32: - setPendingParam(componentId,key, QVariant(valStr.toUInt())); + updatePendingParamWithValue(componentId,key, QVariant(valStr.toUInt())); break; case MAV_PARAM_TYPE_INT32: - setPendingParam(componentId,key,QVariant(valStr.toInt())); + updatePendingParamWithValue(componentId,key,QVariant(valStr.toInt())); break; default: qDebug() << "FAILED LOADING PARAM" << key << "UNKNOWN DATA TYPE"; diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index fde760b703..f3da12f199 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -34,10 +34,9 @@ public: */ virtual void addComponent(int compId); - /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ - virtual void setPendingParam(int componentId, QString& key, const QVariant& value); virtual void removePendingParam(int compId, QString& key); + virtual void commitAllPendingParams();///< Called by eg params comms mgr when all pending params have been sent & acked /** @brief Save the onboard parameter with a the type specified in the QVariant as fixed */ virtual void setOnboardParamWithType(int componentId, QString& key, QVariant& value); @@ -49,10 +48,12 @@ public: /** @brief add this parameter to pending list iff it has changed from onboard value * @return true if the parameter is now pending */ - virtual bool updatePendingParamWithValue(int componentId, QString& key, QVariant& value); + virtual bool updatePendingParamWithValue(int componentId, QString& key, const QVariant &value); virtual void handleParamUpdate(int componentId, QString& key, QVariant& value); virtual bool getOnboardParamValue(int componentId, const QString& key, QVariant& value) const; + virtual bool isParamChangePending(int componentId,const QString& key); + QMap* getPendingParamsForComponent(int componentId) { return pendingParameters.value(componentId); } @@ -79,6 +80,10 @@ public: protected: virtual void setOnboardParam(int componentId, QString& key, const QVariant& value); + /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ + virtual void setPendingParam(int componentId, QString& key, const QVariant& value); + + int countPendingParams(); signals: @@ -88,6 +93,8 @@ signals: /** @brief Notifies listeners that a param was added to or removed from the pending list */ void pendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); + void allPendingParamsCommitted(); ///< All pending params have been committed to the MAV + public slots: diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 1f4889603d..571283d2d3 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -206,10 +206,10 @@ void QGCParamWidget::addComponentItem(int compId, QString compName) void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) { - qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; + // qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; if (updatingParamNameLock == paramName) { - qDebug() << "ignoring bounce from " << paramName; + //qDebug() << "ignoring bounce from " << paramName; return; } else { @@ -230,10 +230,15 @@ void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramNa } -void QGCParamWidget::handleParameterUpdate(int componentId, const QString& paramName, QVariant value) +void QGCParamWidget::handleParameterUpdate(int compId, const QString& paramName, QVariant value) { +// qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; + if (paramName == updatingParamNameLock) { + qDebug() << "handlePendingParamUpdate ignoring bounce from " << paramName; + return; + } updatingParamNameLock = paramName; - updateParameterDisplay(componentId, paramName, value); + updateParameterDisplay(compId, paramName, value); updatingParamNameLock.clear(); } @@ -402,10 +407,10 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column if (paramItem && column > 0) { QString key = paramItem->data(0, Qt::DisplayRole).toString(); - qDebug() << "parameterItemChanged:" << key << "with updatingParamNameLock:" << updatingParamNameLock; + //qDebug() << "parameterItemChanged:" << key << "with updatingParamNameLock:" << updatingParamNameLock; if (key == updatingParamNameLock) { - qDebug() << "ignoring parameterItemChanged" << key; + //qDebug() << "parameterItemChanged ignoring parameterItemChanged" << key; return; } else { diff --git a/src/ui/QGCPendingParamWidget.cc b/src/ui/QGCPendingParamWidget.cc index 800ca354e0..57ee57d5db 100644 --- a/src/ui/QGCPendingParamWidget.cc +++ b/src/ui/QGCPendingParamWidget.cc @@ -30,4 +30,33 @@ void QGCPendingParamWidget::connectSignalsAndSlots() this, SLOT(handleParamStatusMsgUpdate(QString , int ))); } +void QGCPendingParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) +{ + // qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; + + if (updatingParamNameLock == paramName) { + //qDebug() << "ignoring bounce from " << paramName; + return; + } + else { + updatingParamNameLock = paramName; + } + + QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); + + if (isPending) { + QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); + paramItem->setFlags(paramItem->flags() & ~Qt::ItemIsEditable); //disallow editing + paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); + paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); + tree->expandAll(); + } + else { + //we don't display non-pending items + paramItem->parent()->removeChild(paramItem); + } + + updatingParamNameLock.clear(); + +} diff --git a/src/ui/QGCPendingParamWidget.h b/src/ui/QGCPendingParamWidget.h index 91f08a522f..4c6e7370c4 100644 --- a/src/ui/QGCPendingParamWidget.h +++ b/src/ui/QGCPendingParamWidget.h @@ -20,7 +20,8 @@ protected: signals: public slots: - + virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); + }; #endif // QGCPENDINGPARAMWIDGET_H -- GitLab From f6ca6cb64f0f7187bfedd7d6a6d0b40999e61f5b Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 13 Aug 2013 13:00:57 -0700 Subject: [PATCH 264/460] fix updating of pending param list after transmit --- src/uas/UASParameterCommsMgr.cc | 50 +++++++++++++++++--------------- src/uas/UASParameterCommsMgr.h | 2 +- src/uas/UASParameterDataModel.cc | 38 ++++++------------------ src/uas/UASParameterDataModel.h | 10 +++++-- src/ui/QGCParamWidget.cc | 13 ++------- 5 files changed, 45 insertions(+), 68 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 63ccac4839..db74186114 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -80,8 +80,8 @@ void UASParameterCommsMgr::requestParameterList() transmissionListSizeKnown.clear(); transmissionListMode = true; - foreach (int key, transmissionMissingPackets.keys()) { - transmissionMissingPackets.value(key)->clear(); + foreach (int key, missingReadPackets.keys()) { + missingReadPackets.value(key)->clear(); } transmissionActive = true; @@ -106,10 +106,10 @@ void UASParameterCommsMgr::clearRetransmissionLists(int& missingReadCount, int& qDebug() << __FILE__ << __LINE__ << "clearRetransmissionLists"; missingReadCount = 0; - QList readKeys = transmissionMissingPackets.keys(); + QList readKeys = missingReadPackets.keys(); foreach (int compId, readKeys) { - missingReadCount += transmissionMissingPackets.value(compId)->count(); - transmissionMissingPackets.value(compId)->clear(); + missingReadCount += missingReadPackets.value(compId)->count(); + missingReadPackets.value(compId)->clear(); } missingWriteCount = 0; @@ -169,10 +169,11 @@ void UASParameterCommsMgr::resendReadWriteRequests() // Re-request at maximum retransmissionBurstRequestSize parameters at once // to prevent link flooding' int requestedReadCount = 0; - compIds = transmissionMissingPackets.keys(); + compIds = missingReadPackets.keys(); foreach (compId, compIds) { // Request n parameters from this component (at maximum) - QList* missingReadParams = transmissionMissingPackets.value(compId, NULL); + QList* missingReadParams = missingReadPackets.value(compId, NULL); + qDebug() << "missingReadParams:" << missingReadParams->count(); foreach (int paramId, *missingReadParams) { if (requestedReadCount < retransmissionBurstRequestSize) { //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << paramId << "FROM COMPONENT #" << compId; @@ -423,11 +424,11 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para paramDataModel->handleParamUpdate(compId,paramName,value); // Missing packets list has to be instantiated for all components - if (!transmissionMissingPackets.contains(compId)) { - transmissionMissingPackets.insert(compId, new QList()); + if (!missingReadPackets.contains(compId)) { + missingReadPackets.insert(compId, new QList()); } - QList* compXmitMissing = transmissionMissingPackets.value(compId); + QList* compMissReadPackets = missingReadPackets.value(compId); // List mode is different from single parameter transfers if (transmissionListMode) { @@ -439,8 +440,8 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para qDebug() << "Mark all parameters as missing: " << paramCount; for (int i = 1; i < paramCount; ++i) { //TODO check: param Id 0 is "all parameters" and not valid ? - if (!compXmitMissing->contains(i)) { - compXmitMissing->append(i); + if (!compMissReadPackets->contains(i)) { + compMissReadPackets->append(i); } } @@ -456,28 +457,27 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para } // Mark this parameter as received in read list - int index = compXmitMissing->indexOf(paramId); - // If the MAV sent the parameter without request, it wont be in missing list + int index = compMissReadPackets->indexOf(paramId); if (index != -1) { - compXmitMissing->removeAt(index); + compMissReadPackets->removeAt(index); } bool justWritten = false; bool writeMismatch = false; // Mark this parameter as received in write ACK list - QMap* map = missingWriteAckPackets.value(compId); - if (map && map->contains(paramName)) { + QMap* compMissWritePackets = missingWriteAckPackets.value(compId); + if (compMissWritePackets && compMissWritePackets->contains(paramName)) { justWritten = true; - if (map->value(paramName) != value) { + if (compMissWritePackets->value(paramName) != value) { writeMismatch = true; } - map->remove(paramName); + compMissWritePackets->remove(paramName); } int missReadCount = 0; - foreach (int key, transmissionMissingPackets.keys()) { - missReadCount += transmissionMissingPackets.value(key)->count(); + foreach (int key, missingReadPackets.keys()) { + missReadCount += missingReadPackets.value(key)->count(); } int missWriteCount = 0; @@ -488,15 +488,14 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para //TODO simplify this if-else tree if (justWritten) { if (!writeMismatch) { - setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount)); + setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3 [%5]").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount).arg(missWriteCount)); if (0 == missWriteCount) { setParameterStatusMsg(tr("SUCCESS: WROTE ALL PARAMETERS")); - paramDataModel->commitAllPendingParams(); } } else { // Mismatch, tell user - setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(map->value(paramName).toDouble()).arg(value.toDouble()), + setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(compMissWritePackets->value(paramName).toDouble()).arg(value.toDouble()), ParamCommsStatusLevel_Warning); } } @@ -512,6 +511,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); setParameterStatusMsg(tr("OK: %1 %2 (%3/%4)").arg(paramName).arg(val).arg(paramCount-missReadCount).arg(paramCount), ParamCommsStatusLevel_Warning); + //transmissionMissingPackets } } @@ -598,6 +598,8 @@ void UASParameterCommsMgr::sendPendingParameters() } // Enable guard setRetransmissionGuardEnabled(true); + + qDebug() << "Pending parameters now:" << paramDataModel->countPendingParams(); } } diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index d554e0021a..acdab75a86 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -92,7 +92,7 @@ protected: // Communications management QVector receivedParamsList; ///< Successfully received parameters - QMap* > transmissionMissingPackets; ///< Missing packets + QMap* > missingReadPackets; ///< Missing packets QMap* > missingWriteAckPackets; ///< Missing write ACK packets bool transmissionListMode; ///< Currently requesting list QMap transmissionListSizeKnown; ///< List size initialized? diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index ab444d4962..66b847e88e 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -31,27 +31,6 @@ int UASParameterDataModel::countPendingParams() return totalPending; } -void UASParameterDataModel::commitAllPendingParams() -{ - qDebug() << "commitAllPendingParams:" << countPendingParams(); - - QList allCompIds = pendingParameters.keys(); - foreach (int compId, allCompIds) { - // Iterate through the parameters of the component - QMap* compParams = pendingParameters.value(compId); - QList paramNames = compParams->keys(); - qDebug() << paramNames.count() << "committed params for component" << compId; - - foreach (QString paramName, paramNames) { - QVariant value = compParams->value(paramName); - setOnboardParamWithType( compId, paramName, value);//update the onboard value to match pending value - emit pendingParamUpdate(compId,paramName,value,false); //no longer pending - emit parameterUpdated(compId,paramName,value);//ensure the new onboard value is broadcast - } - - } -} - bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key, const QVariant& value) { @@ -163,26 +142,27 @@ void UASParameterDataModel::addComponent(int compId) } -void UASParameterDataModel::handleParamUpdate(int compId, QString& key, QVariant& value) +void UASParameterDataModel::handleParamUpdate(int compId, QString& paramName, QVariant& value) { //verify that the value requested by the user matches the set value //if it doesn't match, leave the pending parameter in the pending list! if (pendingParameters.contains(compId)) { QMap *pendingParams = pendingParameters.value(compId); - if ((NULL != pendingParams) && pendingParams->contains(key)) { - QVariant reqVal = pendingParams->value(key); + if ((NULL != pendingParams) && pendingParams->contains(paramName)) { + QVariant reqVal = pendingParams->value(paramName); if (reqVal == value) { - pendingParams->remove(key); + //notify everyone that this item is being removed from the pending parameters list since it's now confirmed + emit pendingParamUpdate(compId, paramName, value, false); + pendingParams->remove(paramName); } else { - qDebug() << "Pending commit for " << key << " want: " << reqVal << " got: " << value; + qDebug() << "Pending commit for " << paramName << " want: " << reqVal << " got: " << value; } } } - setOnboardParam(compId,key,value); - - emit parameterUpdated(compId,key,value); + emit parameterUpdated(compId,paramName,value); + setOnboardParam(compId,paramName,value); } diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index f3da12f199..2ca97965d8 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -35,8 +35,6 @@ public: virtual void addComponent(int compId); - virtual void removePendingParam(int compId, QString& key); - virtual void commitAllPendingParams();///< Called by eg params comms mgr when all pending params have been sent & acked /** @brief Save the onboard parameter with a the type specified in the QVariant as fixed */ virtual void setOnboardParamWithType(int componentId, QString& key, QVariant& value); @@ -70,6 +68,9 @@ public: return &onboardParameters; } + /** @brief return a count of all pending parameters */ + int countPendingParams(); + virtual void writeOnboardParamsToStream(QTextStream &stream, const QString& uasName); virtual void readUpdateParamsFromStream(QTextStream &stream); @@ -79,11 +80,14 @@ public: void setUASID(int anId) { this->uasId = anId; } protected: + /** @brief set the confirmed value of a parameter in the onboard params list */ virtual void setOnboardParam(int componentId, QString& key, const QVariant& value); + /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ virtual void setPendingParam(int componentId, QString& key, const QVariant& value); + /** @brief remove a parameter from the pending list */ + virtual void removePendingParam(int compId, QString& key); - int countPendingParams(); signals: diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 571283d2d3..f2fc58073e 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -509,16 +509,7 @@ void QGCParamWidget::requestAllParamsUpdate() */ void QGCParamWidget::writeParameters() { - int changedParamCount = 0; - - QMap*>::iterator i; - QMap*>* changedValues = paramDataModel->getAllPendingParams(); - - for (i = changedValues->begin(); (i != changedValues->end()) && (0 == changedParamCount); ++i) { - // Iterate through the pending parameters of the component, break on the first changed parameter - QMap* compPending = i.value(); - changedParamCount += compPending->count(); - } + int changedParamCount = paramDataModel->countPendingParams(); if (changedParamCount > 0) { QMessageBox msgBox; @@ -534,7 +525,7 @@ void QGCParamWidget::writeParameters() void QGCParamWidget::readParameters() { if (!mav) return; - mav->readParametersFromStorage(); + mav->readParametersFromStorage(); //TODO use data model / mgr instead? } /** -- GitLab From f83821e5a14c292930865d80e2689dddcd300215 Mon Sep 17 00:00:00 2001 From: David Goodman Date: Mon, 12 Aug 2013 18:12:29 -0700 Subject: [PATCH 265/460] Added Set Home option to map menu. Fix home icon always placed in bottom right. --- src/ui/map/QGCMapWidget.cc | 36 ++++++++++++++++++++++++++++++++++++ src/ui/map/QGCMapWidget.h | 2 ++ 2 files changed, 38 insertions(+) diff --git a/src/ui/map/QGCMapWidget.cc b/src/ui/map/QGCMapWidget.cc index 9146e347ab..4b90ab3277 100644 --- a/src/ui/map/QGCMapWidget.cc +++ b/src/ui/map/QGCMapWidget.cc @@ -38,6 +38,7 @@ QGCMapWidget::QGCMapWidget(QWidget *parent) : this->setContextMenuPolicy(Qt::ActionsContextMenu); + // Got to options QAction *guidedaction = new QAction(this); guidedaction->setText("Go To Here (Guided Mode)"); connect(guidedaction,SIGNAL(triggered()),this,SLOT(guidedActionTriggered())); @@ -46,10 +47,16 @@ QGCMapWidget::QGCMapWidget(QWidget *parent) : guidedaction->setText("Go To Here Alt (Guided Mode)"); connect(guidedaction,SIGNAL(triggered()),this,SLOT(guidedAltActionTriggered())); this->addAction(guidedaction); + // Point camera option QAction *cameraaction = new QAction(this); cameraaction->setText("Point Camera Here"); connect(cameraaction,SIGNAL(triggered()),this,SLOT(cameraActionTriggered())); this->addAction(cameraaction); + // Set home location option + QAction *sethomeaction = new QAction(this); + sethomeaction->setText("Set Home Location Here"); + connect(sethomeaction,SIGNAL(triggered()),this,SLOT(setHomeActionTriggered())); + this->addAction(sethomeaction); } void QGCMapWidget::guidedActionTriggered() { @@ -111,6 +118,35 @@ void QGCMapWidget::cameraActionTriggered() } } +/** + * @brief QGCMapWidget::setHomeActionTriggered + */ +bool QGCMapWidget::setHomeActionTriggered() +{ + if (!uas) + { + QMessageBox::information(0,"Error","Please connect first"); + return false; + } + UASManager *uasManager = UASManager::instance(); + if (!uasManager) { return false; } + + // Enter an altitude + bool ok = false; + int alt = QInputDialog::getInt(this,"Altitude","Enter default altitude (in meters) of destination point for guided mode",100,0,30000,1,&ok); + if (!ok) return false; //Use has chosen cancel. Do not send the waypoint + + // Create new waypoint and send it to the WPManager to send out. + internals::PointLatLng pos = map->FromLocalToLatLng(mousePressPos.x(), mousePressPos.y()); + qDebug() << "Set home location sent. Lat:" << pos.Lat() << ", Lon:" << pos.Lng() << ", Alt: " << alt; + + bool success = uasManager->setHomePositionAndNotify(pos.Lat(),pos.Lng(), alt); + + qDebug() << ((success)? "Set new home location." : "Failed to set new home location."); + + return success; +} + void QGCMapWidget::mousePressEvent(QMouseEvent *event) { mapcontrol::OPMapWidget::mousePressEvent(event); diff --git a/src/ui/map/QGCMapWidget.h b/src/ui/map/QGCMapWidget.h index d6f3b53d79..48ba49618a 100644 --- a/src/ui/map/QGCMapWidget.h +++ b/src/ui/map/QGCMapWidget.h @@ -46,6 +46,8 @@ public slots: void guidedActionTriggered(); /** @brief Action triggered when guided action is selected from the context menu, allows for altitude selection */ bool guidedAltActionTriggered(); + /** @brief Action triggered when set home action is selected from the context menu. */ + bool setHomeActionTriggered(); /** @brief Add system to map view */ void addUAS(UASInterface* uas); /** @brief Update the global position of a system */ -- GitLab From 861b363c66523003dd8230e55443693f6079c064 Mon Sep 17 00:00:00 2001 From: David Goodman Date: Tue, 13 Aug 2013 19:52:18 -0700 Subject: [PATCH 266/460] Fixed obtaining position. Fixed message box text. --- src/uas/UAS.cc | 6 +++++- src/ui/map/QGCMapWidget.cc | 25 +++++++++++++++++++++---- src/ui/map/QGCMapWidget.h | 3 +++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 142e53b20f..8c47c2acd2 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -1651,9 +1651,13 @@ void UAS::setHomePosition(double lat, double lon, double alt) if (blockHomePositionChanges) return; + QString uasName = (getUASName() == "")? + tr("UAS") + QString::number(getUASID()) + : getUASName(); + QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); - msgBox.setText(tr("Set a new home position for vehicle %s").arg(getUASName())); + msgBox.setText(tr("Set a new home position for vehicle %1").arg(uasName)); msgBox.setInformativeText("Do you want to set a new origin? Waypoints defined in the local frame will be shifted in their physical location"); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); msgBox.setDefaultButton(QMessageBox::Cancel); diff --git a/src/ui/map/QGCMapWidget.cc b/src/ui/map/QGCMapWidget.cc index 4b90ab3277..748d1c2dfb 100644 --- a/src/ui/map/QGCMapWidget.cc +++ b/src/ui/map/QGCMapWidget.cc @@ -38,7 +38,7 @@ QGCMapWidget::QGCMapWidget(QWidget *parent) : this->setContextMenuPolicy(Qt::ActionsContextMenu); - // Got to options + // Go to options QAction *guidedaction = new QAction(this); guidedaction->setText("Go To Here (Guided Mode)"); connect(guidedaction,SIGNAL(triggered()),this,SLOT(guidedActionTriggered())); @@ -133,12 +133,12 @@ bool QGCMapWidget::setHomeActionTriggered() // Enter an altitude bool ok = false; - int alt = QInputDialog::getInt(this,"Altitude","Enter default altitude (in meters) of destination point for guided mode",100,0,30000,1,&ok); + double alt = QInputDialog::getDouble(this,"Home Altitude","Enter altitude (in meters) of new home location",0.0,0.0,30000.0,2,&ok); if (!ok) return false; //Use has chosen cancel. Do not send the waypoint // Create new waypoint and send it to the WPManager to send out. - internals::PointLatLng pos = map->FromLocalToLatLng(mousePressPos.x(), mousePressPos.y()); - qDebug() << "Set home location sent. Lat:" << pos.Lat() << ", Lon:" << pos.Lng() << ", Alt: " << alt; + internals::PointLatLng pos = map->FromLocalToLatLng(contextMousePressPos.x(), contextMousePressPos.y()); + qDebug("Set home location sent. Lat: %f, Lon: %f, Alt: %f.", pos.Lat(), pos.Lng(), alt); bool success = uasManager->setHomePositionAndNotify(pos.Lat(),pos.Lng(), alt); @@ -149,6 +149,13 @@ bool QGCMapWidget::setHomeActionTriggered() void QGCMapWidget::mousePressEvent(QMouseEvent *event) { + + // Store right-click event presses separate for context menu + // TODO add check if click was on map, or popup box. + if (event->button() == Qt::RightButton) { + contextMousePressPos = event->pos(); + } + mapcontrol::OPMapWidget::mousePressEvent(event); } @@ -158,6 +165,15 @@ void QGCMapWidget::mouseReleaseEvent(QMouseEvent *event) mapcontrol::OPMapWidget::mouseReleaseEvent(event); } +/* +void QGCMapWidget::contextMenuEvent(QContextMenuEvent *event) +{ + // TODO Remove this method + qDebug() << "Context menu event triggered."; + mapcontrol::OPMapWidget::contextMenuEvent(event); +} +*/ + QGCMapWidget::~QGCMapWidget() { SetShowHome(false); // doing this appears to stop the map lib crashing on exit @@ -556,6 +572,7 @@ void QGCMapWidget::updateHomePosition(double latitude, double longitude, double Home->SetAltitude(altitude); homeAltitude = altitude; SetShowHome(true); // display the HOME position on the map + Home->RefreshPos(); } void QGCMapWidget::goHome() diff --git a/src/ui/map/QGCMapWidget.h b/src/ui/map/QGCMapWidget.h index 48ba49618a..8657ede17a 100644 --- a/src/ui/map/QGCMapWidget.h +++ b/src/ui/map/QGCMapWidget.h @@ -138,6 +138,8 @@ protected: void mouseReleaseEvent(QMouseEvent *event); void mouseDoubleClickEvent(QMouseEvent* event); + //void contextMenuEvent(QContextMenuEvent *); + UASWaypointManager* currWPManager; ///< The current waypoint manager bool offlineMode; QMap waypointsToIcons; @@ -162,6 +164,7 @@ protected: bool mapInitialized; ///< Map initialized? float homeAltitude; ///< Home altitude QPoint mousePressPos; ///< Mouse position when the button is released. + QPoint contextMousePressPos; ///< Mouse position when context menu activated. int defaultGuidedAlt; ///< Default altitude for guided mode UASInterface *uas; ///< Currently selected UAS. -- GitLab From 8541598f9c60cba2ee678c32285b615cb870a903 Mon Sep 17 00:00:00 2001 From: Anton Babushkin Date: Wed, 14 Aug 2013 22:08:59 +0200 Subject: [PATCH 267/460] base_mode/custom mode support --- src/uas/UAS.cc | 168 +++++++++++---------------- src/uas/UAS.h | 9 +- src/uas/UASInterface.h | 2 +- src/ui/uas/UASControlWidget.cc | 202 +++++++++++++++++++-------------- src/ui/uas/UASControlWidget.h | 28 ++++- 5 files changed, 209 insertions(+), 200 deletions(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 8c47c2acd2..47fb36bbcf 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -56,9 +56,9 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), airframe(QGC_AIRFRAME_GENERIC), autopilot(-1), systemIsArmed(false), - mode(-1), + base_mode(0), + custom_mode(0), // custom_mode not initialized - navMode(-1), status(-1), // shortModeText not initialized // shortStateText not initialized @@ -335,7 +335,7 @@ void UAS::updateState() } else { - if (((mode&MAV_MODE_FLAG_DECODE_POSITION_AUTO) || (mode&MAV_MODE_FLAG_DECODE_POSITION_GUIDED)) && positionLock) + if (((base_mode & MAV_MODE_FLAG_DECODE_POSITION_AUTO) || (base_mode & MAV_MODE_FLAG_DECODE_POSITION_GUIDED)) && positionLock) { GAudioOutput::instance()->notifyNegative(); } @@ -566,24 +566,18 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message) stateAudio = uasState; } - if (this->mode != static_cast(state.base_mode)) + if (this->base_mode != state.base_mode || this->custom_mode != state.custom_mode) { modechanged = true; - this->mode = static_cast(state.base_mode); - shortModeText = getShortModeTextFor(this->mode); + this->base_mode = state.base_mode; + this->custom_mode = state.custom_mode; + shortModeText = getShortModeTextFor(this->base_mode, this->custom_mode, this->autopilot); emit modeChanged(this->getUASID(), shortModeText, ""); modeAudio = " is now in " + audiomodeText; } - if (navMode != state.custom_mode) - { - emit navModeChanged(uasId, state.custom_mode, getNavModeText(state.custom_mode)); - navMode = state.custom_mode; - //navModeAudio = tr(" changed nav mode to ") + tr("FIXME"); - } - // AUDIO if (modechanged && statechanged) { @@ -593,7 +587,7 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message) else if (modechanged || statechanged) { // Output the one message - audiostring += modeAudio + stateAudio + navModeAudio; + audiostring += modeAudio + stateAudio; } if (statechanged && ((int)state.system_status == (int)MAV_STATE_CRITICAL || state.system_status == (int)MAV_STATE_EMERGENCY)) @@ -1952,25 +1946,24 @@ QList UAS::getComponentIds() /** * @param mode that UAS is to be set to. */ -void UAS::setMode(int mode) +void UAS::setMode(uint8_t newBaseMode, uint32_t newCustomMode) { //this->mode = mode; //no call assignament, update receive message from UAS // Strip armed / disarmed call, this is not relevant for setting the mode - uint8_t newMode = mode; - newMode &= (~(uint8_t)MAV_MODE_FLAG_SAFETY_ARMED); + newBaseMode &= ~MAV_MODE_FLAG_SAFETY_ARMED; // Now set current state (request no change) - newMode |= (uint8_t)(this->mode) & (uint8_t)(MAV_MODE_FLAG_SAFETY_ARMED); + newBaseMode |= this->base_mode & MAV_MODE_FLAG_SAFETY_ARMED; // Strip HIL part, replace it with current system state - newMode &= (~(uint8_t)MAV_MODE_FLAG_HIL_ENABLED); + newBaseMode &= (~MAV_MODE_FLAG_HIL_ENABLED); // Now set current state (request no change) - newMode |= (uint8_t)(this->mode) & (uint8_t)(MAV_MODE_FLAG_HIL_ENABLED); + newBaseMode |= this->base_mode & MAV_MODE_FLAG_HIL_ENABLED; mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, (uint8_t)uasId, newMode, (uint16_t)navMode); + mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, (uint8_t)uasId, newBaseMode, newCustomMode); sendMessage(msg); - qDebug() << "SENDING REQUEST TO SET MODE TO SYSTEM" << uasId << ", REQUEST TO SET MODE " << newMode; + qDebug() << "SENDING REQUEST TO SET MODE TO SYSTEM" << uasId << ", REQUEST TO SET MODE " << newBaseMode; } /** @@ -2054,35 +2047,6 @@ float UAS::filterVoltage(float value) const return lpVoltage * 0.7f + value * 0.3f; } -/** -* The mode can be preflight or unknown. -* @Return the mode of the autopilot -*/ -QString UAS::getNavModeText(int mode) -{ - if (autopilot == MAV_AUTOPILOT_PIXHAWK) - { - switch (mode) - { - case 0: - return QString("PREFLIGHT"); - break; - default: - return QString("UNKNOWN"); - } - } - else if (autopilot == MAV_AUTOPILOT_ARDUPILOTMEGA) - { - return QString("UNKNOWN"); - } - else if (autopilot == MAV_AUTOPILOT_OPENPILOT) - { - return QString("UNKNOWN"); - } - // If nothing matches, return unknown - return QString("UNKNOWN"); -} - /** * Get the status of the code and a description of the status. * Status can be unitialized, booting up, calibrating sensors, active @@ -2738,7 +2702,7 @@ void UAS::launch() void UAS::armSystem() { mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode | MAV_MODE_FLAG_SAFETY_ARMED, navMode); + mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); sendMessage(msg); } @@ -2749,35 +2713,35 @@ void UAS::armSystem() void UAS::disarmSystem() { mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode & ~MAV_MODE_FLAG_SAFETY_ARMED, navMode); + mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode & ~MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); sendMessage(msg); } void UAS::toggleArmedState() { mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode ^ MAV_MODE_FLAG_SAFETY_ARMED, navMode); + mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode ^ MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); sendMessage(msg); } void UAS::goAutonomous() { mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode & MAV_MODE_FLAG_AUTO_ENABLED & ~MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, navMode); + mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_MODE_FLAG_AUTO_ENABLED, 0); sendMessage(msg); } void UAS::goManual() { mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode & ~MAV_MODE_FLAG_AUTO_ENABLED & MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, navMode); + mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, 0); sendMessage(msg); } void UAS::toggleAutonomy() { mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode ^ MAV_MODE_FLAG_AUTO_ENABLED ^ MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, navMode); + mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode ^ MAV_MODE_FLAG_AUTO_ENABLED ^ MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, 0); sendMessage(msg); } @@ -2801,7 +2765,7 @@ void UAS::setManualControlCommands(double roll, double pitch, double yaw, double manualThrust = thrust * thrustScaling; // If system has manual inputs enabled and is armed - if(((mode & MAV_MODE_FLAG_DECODE_POSITION_MANUAL) && (mode & MAV_MODE_FLAG_DECODE_POSITION_SAFETY)) || (mode & MAV_MODE_FLAG_HIL_ENABLED)) + if(((base_mode & MAV_MODE_FLAG_DECODE_POSITION_MANUAL) && (base_mode & MAV_MODE_FLAG_DECODE_POSITION_SAFETY)) || (base_mode & MAV_MODE_FLAG_HIL_ENABLED)) { mavlink_message_t message; mavlink_msg_manual_control_pack(mavlink->getSystemId(), mavlink->getComponentId(), &message, this->uasId, (float)manualPitchAngle, (float)manualRollAngle, (float)manualThrust, (float)manualYawAngle, buttons); @@ -2819,7 +2783,7 @@ void UAS::setManualControlCommands(double roll, double pitch, double yaw, double void UAS::setManual6DOFControlCommands(double x, double y, double z, double roll, double pitch, double yaw) { // If system has manual inputs enabled and is armed - if(((mode & MAV_MODE_FLAG_DECODE_POSITION_MANUAL) && (mode & MAV_MODE_FLAG_DECODE_POSITION_SAFETY)) || (mode & MAV_MODE_FLAG_HIL_ENABLED)) + if(((base_mode & MAV_MODE_FLAG_DECODE_POSITION_MANUAL) && (base_mode & MAV_MODE_FLAG_DECODE_POSITION_SAFETY)) || (base_mode & MAV_MODE_FLAG_HIL_ENABLED)) { mavlink_message_t message; mavlink_msg_setpoint_6dof_pack(mavlink->getSystemId(), mavlink->getComponentId(), &message, this->uasId, (float)x, (float)y, (float)z, (float)roll, (float)pitch, (float)yaw); @@ -3098,7 +3062,7 @@ void UAS::sendHilState(quint64 time_us, float roll, float pitch, float yaw, floa float pitchspeed, float yawspeed, double lat, double lon, double alt, float vx, float vy, float vz, float ind_airspeed, float true_airspeed, float xacc, float yacc, float zacc) { - if (this->mode & MAV_MODE_FLAG_HIL_ENABLED) + if (this->base_mode & MAV_MODE_FLAG_HIL_ENABLED) { float q[4]; @@ -3127,7 +3091,7 @@ void UAS::sendHilState(quint64 time_us, float roll, float pitch, float yaw, floa { // Attempt to set HIL mode mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode | MAV_MODE_FLAG_HIL_ENABLED, navMode); + mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); sendMessage(msg); qDebug() << __FILE__ << __LINE__ << "HIL is onboard not enabled, trying to enable."; } @@ -3136,7 +3100,7 @@ void UAS::sendHilState(quint64 time_us, float roll, float pitch, float yaw, floa void UAS::sendHilSensors(quint64 time_us, float xacc, float yacc, float zacc, float rollspeed, float pitchspeed, float yawspeed, float xmag, float ymag, float zmag, float abs_pressure, float diff_pressure, float pressure_alt, float temperature, quint32 fields_changed) { - if (this->mode & MAV_MODE_FLAG_HIL_ENABLED) + if (this->base_mode & MAV_MODE_FLAG_HIL_ENABLED) { mavlink_message_t msg; mavlink_msg_hil_sensor_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, @@ -3150,7 +3114,7 @@ void UAS::sendHilSensors(quint64 time_us, float xacc, float yacc, float zacc, fl { // Attempt to set HIL mode mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode | MAV_MODE_FLAG_HIL_ENABLED, navMode); + mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); sendMessage(msg); qDebug() << __FILE__ << __LINE__ << "HIL is onboard not enabled, trying to enable."; } @@ -3162,7 +3126,7 @@ void UAS::sendHilGps(quint64 time_us, double lat, double lon, double alt, int fi if (QGC::groundTimeMilliseconds() - lastSendTimeGPS < 100) return; - if (this->mode & MAV_MODE_FLAG_HIL_ENABLED) + if (this->base_mode & MAV_MODE_FLAG_HIL_ENABLED) { float course = cog; // map to 0..2pi @@ -3181,7 +3145,7 @@ void UAS::sendHilGps(quint64 time_us, double lat, double lon, double alt, int fi { // Attempt to set HIL mode mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode | MAV_MODE_FLAG_HIL_ENABLED, navMode); + mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); sendMessage(msg); qDebug() << __FILE__ << __LINE__ << "HIL is onboard not enabled, trying to enable."; } @@ -3197,7 +3161,7 @@ void UAS::startHil() hilEnabled = true; sensorHil = false; mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode | MAV_MODE_FLAG_HIL_ENABLED, navMode); + mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); sendMessage(msg); // Connect HIL simulation link simulation->connectSimulation(); @@ -3210,7 +3174,7 @@ void UAS::stopHil() { if (simulation) simulation->disconnectSimulation(); mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode & !MAV_MODE_FLAG_HIL_ENABLED, navMode); + mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode & !MAV_MODE_FLAG_HIL_ENABLED, custom_mode); sendMessage(msg); hilEnabled = false; sensorHil = false; @@ -3338,51 +3302,57 @@ QString UAS::getAudioModeTextFor(int id) * The mode returned can be auto, stabilized, test, manual, preflight or unknown. * @return the short text of the mode for the id given. */ -QString UAS::getShortModeTextFor(int id) +QString UAS::getShortModeTextFor(uint8_t base_mode, uint32_t custom_mode, int autopilot) { QString mode = ""; - uint8_t modeid = id; - - // BASE MODE DECODING - - if (modeid == 0) - { - mode = "|PREFLIGHT"; - } - else { - if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_AUTO){ - mode += "|AUTO"; + enum PX4_CUSTOM_MODE { + PX4_CUSTOM_MODE_MANUAL = 1, + PX4_CUSTOM_MODE_SEATBELT, + PX4_CUSTOM_MODE_EASY, + PX4_CUSTOM_MODE_AUTO + }; + + if (base_mode & MAV_MODE_FLAG_CUSTOM_MODE_ENABLED) { + // use custom_mode - autopilot-specific + if (autopilot == MAV_AUTOPILOT_PX4) { + if (custom_mode == PX4_CUSTOM_MODE_MANUAL) { + mode += "|MANUAL"; + } else if (custom_mode == PX4_CUSTOM_MODE_SEATBELT) { + mode += "|SEATBELT"; + } else if (custom_mode == PX4_CUSTOM_MODE_EASY) { + mode += "|EASY"; + } else if (custom_mode == PX4_CUSTOM_MODE_AUTO) { + mode += "|AUTO"; + } } + } - if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_MANUAL){ + // fallback to using base_mode + if (mode.length() == 0) { + // use base_mode - not autopilot-specific + if (base_mode == 0) { + mode += "|PREFLIGHT"; + } else if (base_mode & MAV_MODE_FLAG_DECODE_POSITION_AUTO) { + mode += "|AUTO"; + } else if (base_mode & MAV_MODE_FLAG_DECODE_POSITION_MANUAL) { mode += "|MANUAL"; + if (base_mode & MAV_MODE_FLAG_DECODE_POSITION_GUIDED) { + mode += "|GUIDED"; + } else if (base_mode & MAV_MODE_FLAG_DECODE_POSITION_STABILIZE) { + mode += "|STABILIZED"; + } } - - if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_GUIDED){ - mode += "|VECTOR"; - } - - if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_STABILIZE){ - mode += "|STABILIZED"; - } - - - if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_TEST){ - mode += "|TEST"; - } - - } if (mode.length() == 0) { mode = "|UNKNOWN"; - qDebug() << __FILE__ << __LINE__ << " Unknown modeid: " << modeid; + qDebug() << __FILE__ << __LINE__ << " Unknown mode: base_mode=" << base_mode << " custom_mode=" << custom_mode << " autopilot=" << autopilot; } // ARMED STATE DECODING - if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_SAFETY) + if (base_mode & MAV_MODE_FLAG_DECODE_POSITION_SAFETY) { mode.prepend("A"); } @@ -3392,12 +3362,12 @@ QString UAS::getShortModeTextFor(int id) } // HARDWARE IN THE LOOP DECODING - if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_HIL) + if (base_mode & MAV_MODE_FLAG_DECODE_POSITION_HIL) { mode.prepend("HIL:"); } - qDebug() << "MODE: " << modeid << " " << mode; + //qDebug() << "base_mode=" << base_mode << " custom_mode=" << custom_mode << " autopilot=" << autopilot << ": " << mode; return mode; } diff --git a/src/uas/UAS.h b/src/uas/UAS.h index b1c027bd1f..57db6761e2 100644 --- a/src/uas/UAS.h +++ b/src/uas/UAS.h @@ -68,7 +68,7 @@ public: /** @brief Get short mode */ const QString& getShortMode() const; /** @brief Translate from mode id to text */ - static QString getShortModeTextFor(int id); + static QString getShortModeTextFor(uint8_t base_mode, uint32_t custom_mode, int autopilot); /** @brief Translate from mode id to audio text */ static QString getAudioModeTextFor(int id); /** @brief Get the unique system id */ @@ -361,9 +361,8 @@ protected: //COMMENTS FOR TEST UNIT int airframe; ///< The airframe type int autopilot; ///< Type of the Autopilot: -1: None, 0: Generic, 1: PIXHAWK, 2: SLUGS, 3: Ardupilot (up to 15 types), defined in MAV_AUTOPILOT_TYPE ENUM bool systemIsArmed; ///< If the system is armed - uint8_t mode; ///< The current mode of the MAV + uint8_t base_mode; ///< The current mode of the MAV uint32_t custom_mode; ///< The current mode of the MAV - uint32_t navMode; ///< The current navigation mode of the MAV int status; ///< The current status of the MAV QString shortModeText; ///< Short textual mode description QString shortStateText; ///< Short textual state description @@ -505,8 +504,6 @@ public: float getChargeLevel(); /** @brief Get the human-readable status message for this code */ void getStatusForCode(int statusCode, QString& uasState, QString& stateDescription); - /** @brief Get the human-readable navigation mode translation for this mode */ - QString getNavModeText(int mode); /** @brief Check if vehicle is in autonomous mode */ bool isAuto(); /** @brief Check if vehicle is armed */ @@ -833,7 +830,7 @@ public slots: void setSelected(); /** @brief Set current mode of operation, e.g. auto or manual */ - void setMode(int mode); + void setMode(uint8_t newBaseMode, uint32_t newCustomMode); /** @brief Request all parameters */ void requestParameters(); diff --git a/src/uas/UASInterface.h b/src/uas/UASInterface.h index 37382e3eb4..c17d4e0024 100644 --- a/src/uas/UASInterface.h +++ b/src/uas/UASInterface.h @@ -296,7 +296,7 @@ public slots: /** @brief Start/continue the current robot action */ virtual void go() = 0; /** @brief Set the current mode of operation */ - virtual void setMode(int mode) = 0; + virtual void setMode(uint8_t newBaseMode, uint32_t newCustomMode) = 0; /** Stops the robot system. If it is an MAV, the robot starts the emergency landing procedure **/ virtual void emergencySTOP() = 0; /** Kills the robot. All systems are immediately shut down (e.g. the main power line is cut). This might lead to a crash **/ diff --git a/src/ui/uas/UASControlWidget.cc b/src/ui/uas/UASControlWidget.cc index b7d8cf7981..aae8644991 100644 --- a/src/ui/uas/UASControlWidget.cc +++ b/src/ui/uas/UASControlWidget.cc @@ -33,7 +33,6 @@ This file is part of the PIXHAWK project #include #include #include -#include #include #include @@ -42,71 +41,111 @@ This file is part of the PIXHAWK project #include #include "QGC.h" +static struct full_mode_s modes_list_common[] = { + { MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, + 0 }, + { (MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED), + 0 }, + { (MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED | MAV_MODE_FLAG_GUIDED_ENABLED), + 0 }, + { (MAV_MODE_FLAG_AUTO_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED | MAV_MODE_FLAG_GUIDED_ENABLED), + 0 }, +}; + +static struct full_mode_s modes_list_px4[] = { + { (MAV_MODE_FLAG_CUSTOM_MODE_ENABLED | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED), + PX4_CUSTOM_MODE_MANUAL }, + { (MAV_MODE_FLAG_CUSTOM_MODE_ENABLED | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED), + PX4_CUSTOM_MODE_SEATBELT }, + { (MAV_MODE_FLAG_CUSTOM_MODE_ENABLED | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED | MAV_MODE_FLAG_GUIDED_ENABLED), + PX4_CUSTOM_MODE_EASY }, + { (MAV_MODE_FLAG_CUSTOM_MODE_ENABLED | MAV_MODE_FLAG_AUTO_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED | MAV_MODE_FLAG_GUIDED_ENABLED), + PX4_CUSTOM_MODE_AUTO }, +}; + UASControlWidget::UASControlWidget(QWidget *parent) : QWidget(parent), - uas(0), - uasMode(0), - engineOn(false) + uasID(-1), + modesList(NULL), + modesNum(0), + modeIdx(0), + armed(false) { ui.setupUi(this); + this->setUAS(UASManager::instance()->getActiveUAS()); + connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setUAS(UASInterface*))); - ui.modeComboBox->clear(); - int modes[] = { - MAV_MODE_PREFLIGHT, - MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, - MAV_MODE_FLAG_STABILIZE_ENABLED | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, - MAV_MODE_FLAG_STABILIZE_ENABLED | MAV_MODE_FLAG_AUTO_ENABLED, - MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_TEST_ENABLED, - }; - for (int i = 0; i < sizeof(modes) / sizeof(int); i++) { - int mode = modes[i]; - ui.modeComboBox->insertItem(i, UAS::getShortModeTextFor(mode).remove(0, 2), mode); - } connect(ui.modeComboBox, SIGNAL(activated(int)), this, SLOT(setMode(int))); connect(ui.setModeButton, SIGNAL(clicked()), this, SLOT(transmitMode())); - uasMode = ui.modeComboBox->itemData(ui.modeComboBox->currentIndex()).toInt(); + ui.gridLayout->setAlignment(Qt::AlignTop); +} - ui.modeComboBox->setCurrentIndex(0); +void UASControlWidget::updateModesList() +{ + // Detect autopilot type + int autopilot = 0; + if (this->uasID >= 0) { + UASInterface *uas = UASManager::instance()->getUASForId(this->uasID); + if (uas) { + autopilot = UASManager::instance()->getUASForId(this->uasID)->getAutopilotType(); + } + } - ui.gridLayout->setAlignment(Qt::AlignTop); + // Use corresponding modes list + if (autopilot == MAV_AUTOPILOT_PX4) { + modesList = modes_list_px4; + modesNum = sizeof(modes_list_px4) / sizeof(struct full_mode_s); + } else { + modesList = modes_list_common; + modesNum = sizeof(modes_list_common) / sizeof(struct full_mode_s); + } + + // Set combobox items + ui.modeComboBox->clear(); + for (int i = 0; i < modesNum; i++) { + struct full_mode_s mode = modesList[i]; + ui.modeComboBox->insertItem(i, UAS::getShortModeTextFor(mode.baseMode, mode.customMode, autopilot).remove(0, 2), i); + } + // Select first mode in list + modeIdx = 0; + ui.modeComboBox->setCurrentIndex(modeIdx); + ui.modeComboBox->update(); } void UASControlWidget::setUAS(UASInterface* uas) { - if (this->uas) - { - UASInterface* oldUAS = UASManager::instance()->getUASForId(this->uas); + if (this->uasID) { + UASInterface* oldUAS = UASManager::instance()->getUASForId(this->uasID); disconnect(ui.controlButton, SIGNAL(clicked()), oldUAS, SLOT(armSystem())); disconnect(ui.liftoffButton, SIGNAL(clicked()), oldUAS, SLOT(launch())); disconnect(ui.landButton, SIGNAL(clicked()), oldUAS, SLOT(home())); disconnect(ui.shutdownButton, SIGNAL(clicked()), oldUAS, SLOT(shutdown())); //connect(ui.setHomeButton, SIGNAL(clicked()), uas, SLOT(setLocalOriginAtCurrentGPSPosition())); - disconnect(uas, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int,QString,QString))); + disconnect(uas, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int, QString, QString))); disconnect(uas, SIGNAL(statusChanged(int)), this, SLOT(updateState(int))); } // Connect user interface controls - if (uas) - { - connect(ui.controlButton, SIGNAL(clicked()), this, SLOT(cycleContextButton())); - connect(ui.liftoffButton, SIGNAL(clicked()), uas, SLOT(launch())); - connect(ui.landButton, SIGNAL(clicked()), uas, SLOT(home())); - connect(ui.shutdownButton, SIGNAL(clicked()), uas, SLOT(shutdown())); - //connect(ui.setHomeButton, SIGNAL(clicked()), uas, SLOT(setLocalOriginAtCurrentGPSPosition())); - connect(uas, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int,QString,QString))); - connect(uas, SIGNAL(statusChanged(int)), this, SLOT(updateState(int))); - - ui.controlStatusLabel->setText(tr("Connected to ") + uas->getUASName()); - - this->uas = uas->getUASID(); - setBackgroundColor(uas->getColor()); - } - else - { - this->uas = -1; - } + if (uas) { + connect(ui.controlButton, SIGNAL(clicked()), this, SLOT(cycleContextButton())); + connect(ui.liftoffButton, SIGNAL(clicked()), uas, SLOT(launch())); + connect(ui.landButton, SIGNAL(clicked()), uas, SLOT(home())); + connect(ui.shutdownButton, SIGNAL(clicked()), uas, SLOT(shutdown())); + //connect(ui.setHomeButton, SIGNAL(clicked()), uas, SLOT(setLocalOriginAtCurrentGPSPosition())); + connect(uas, SIGNAL(modeChanged(int, QString, QString)), this, SLOT(updateMode(int, QString, QString))); + connect(uas, SIGNAL(statusChanged(int)), this, SLOT(updateState(int))); + + ui.controlStatusLabel->setText(tr("Connected to ") + uas->getUASName()); + + this->uasID = uas->getUASID(); + setBackgroundColor(uas->getColor()); + } else { + this->uasID = -1; + } + this->updateModesList(); + this->updateArmText(); } UASControlWidget::~UASControlWidget() @@ -114,15 +153,11 @@ UASControlWidget::~UASControlWidget() } -void UASControlWidget::updateStatemachine() +void UASControlWidget::updateArmText() { - - if (engineOn) - { + if (armed) { ui.controlButton->setText(tr("DISARM SYSTEM")); - } - else - { + } else { ui.controlButton->setText(tr("ARM SYSTEM")); } } @@ -138,7 +173,7 @@ void UASControlWidget::setBackgroundColor(QColor color) QString colorstyle; QString borderColor = "#4A4A4F"; borderColor = "#FA4A4F"; - uasColor = uasColor.darker(900); + uasColor = uasColor.darker(400); colorstyle = colorstyle.sprintf("QLabel { border-radius: 3px; padding: 0px; margin: 0px; background-color: #%02X%02X%02X; border: 0px solid %s; }", uasColor.red(), uasColor.green(), uasColor.blue(), borderColor.toStdString().c_str()); setStyleSheet(colorstyle); @@ -149,7 +184,7 @@ void UASControlWidget::setBackgroundColor(QColor color) } -void UASControlWidget::updateMode(int uas,QString mode,QString description) +void UASControlWidget::updateMode(int uas, QString mode, QString description) { Q_UNUSED(uas); Q_UNUSED(mode); @@ -158,17 +193,15 @@ void UASControlWidget::updateMode(int uas,QString mode,QString description) void UASControlWidget::updateState(int state) { - switch (state) - { + switch (state) { case (int)MAV_STATE_ACTIVE: - engineOn = true; - ui.controlButton->setText(tr("DISARM SYSTEM")); + armed = true; break; case (int)MAV_STATE_STANDBY: - engineOn = false; - ui.controlButton->setText(tr("ARM SYSTEM")); + armed = false; break; } + this->updateArmText(); } /** @@ -177,7 +210,7 @@ void UASControlWidget::updateState(int state) void UASControlWidget::setMode(int mode) { // Adapt context button mode - uasMode = ui.modeComboBox->itemData(mode).toInt(); + modeIdx = mode; ui.modeComboBox->blockSignals(true); ui.modeComboBox->setCurrentIndex(mode); ui.modeComboBox->blockSignals(false); @@ -187,43 +220,36 @@ void UASControlWidget::setMode(int mode) void UASControlWidget::transmitMode() { - UASInterface* mav = UASManager::instance()->getUASForId(this->uas); - if (mav) - { - // include armed state - if (engineOn) - uasMode |= MAV_MODE_FLAG_SAFETY_ARMED; - else - uasMode &= ~MAV_MODE_FLAG_SAFETY_ARMED; - - mav->setMode(uasMode); - QString mode = ui.modeComboBox->currentText(); - - ui.lastActionLabel->setText(QString("Sent new mode %1 to %2").arg(mode).arg(mav->getUASName())); + UASInterface* uas = UASManager::instance()->getUASForId(this->uasID); + if (uas) { + if (modeIdx >= 0 && modeIdx < modesNum) { + struct full_mode_s mode = modesList[modeIdx]; + // include armed state + if (armed) { + mode.baseMode |= MAV_MODE_FLAG_SAFETY_ARMED; + } else { + mode.baseMode &= ~MAV_MODE_FLAG_SAFETY_ARMED; + } + + uas->setMode(mode.baseMode, mode.customMode); + QString modeText = ui.modeComboBox->currentText(); + + ui.lastActionLabel->setText(QString("Sent new mode %1 to %2").arg(modeText).arg(uas->getUASName())); + } } } void UASControlWidget::cycleContextButton() { - UAS* mav = dynamic_cast(UASManager::instance()->getUASForId(this->uas)); - if (mav) - { - - if (!engineOn) - { - mav->armSystem(); - ui.lastActionLabel->setText(QString("Enabled motors on %1").arg(mav->getUASName())); + UAS* uas = dynamic_cast(UASManager::instance()->getUASForId(this->uasID)); + if (uas) { + if (!armed) { + uas->armSystem(); + ui.lastActionLabel->setText(QString("Arm %1").arg(uas->getUASName())); } else { - mav->disarmSystem(); - ui.lastActionLabel->setText(QString("Disabled motors on %1").arg(mav->getUASName())); + uas->disarmSystem(); + ui.lastActionLabel->setText(QString("Disarm %1").arg(uas->getUASName())); } - // Update state now and in several intervals when MAV might have changed state - updateStatemachine(); - - QTimer::singleShot(50, this, SLOT(updateStatemachine())); - QTimer::singleShot(200, this, SLOT(updateStatemachine())); - } - } diff --git a/src/ui/uas/UASControlWidget.h b/src/ui/uas/UASControlWidget.h index 4ec60f6930..7f9a5652b7 100644 --- a/src/ui/uas/UASControlWidget.h +++ b/src/ui/uas/UASControlWidget.h @@ -39,6 +39,18 @@ This file is part of the QGROUNDCONTROL project #include #include +enum PX4_CUSTOM_MODE { + PX4_CUSTOM_MODE_MANUAL = 1, + PX4_CUSTOM_MODE_SEATBELT, + PX4_CUSTOM_MODE_EASY, + PX4_CUSTOM_MODE_AUTO +}; + +struct full_mode_s { + uint8_t baseMode; + uint32_t customMode; +}; + /** * @brief Widget controlling one MAV */ @@ -51,8 +63,10 @@ public: ~UASControlWidget(); public slots: + /** @brief Update modes list for selected system */ + void updateModesList(); /** @brief Set the system this widget controls */ - void setUAS(UASInterface* uas); + void setUAS(UASInterface* uasID); /** @brief Trigger next context action */ void cycleContextButton(); /** @brief Set the operation mode of the MAV */ @@ -60,11 +74,11 @@ public slots: /** @brief Transmit the operation mode */ void transmitMode(); /** @brief Update the mode */ - void updateMode(int uas,QString mode,QString description); + void updateMode(int uasID, QString mode, QString description); /** @brief Update state */ void updateState(int state); /** @brief Update internal state machine */ - void updateStatemachine(); + void updateArmText(); signals: void changedMode(int); @@ -75,9 +89,11 @@ protected slots: void setBackgroundColor(QColor color); protected: - int uas; ///< Reference to the current uas - unsigned int uasMode; ///< Current uas mode - bool engineOn; ///< Engine state + int uasID; ///< Reference to the current uas + struct full_mode_s *modesList; ///< Modes list for the current UAS + int modesNum; ///< Number of modes in list for the current UAS + int modeIdx; ///< Current uas mode index + bool armed; ///< Engine state private: Ui::uasControl ui; -- GitLab From 9bdb1a3a4d9c10e8d6c94f03c4b3ba41d4365c18 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 14 Aug 2013 16:04:03 -0700 Subject: [PATCH 268/460] Fix path for promoted widget --- src/ui/QGCPX4VehicleConfig.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index da0ddfd9b1..b153d7391a 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -1272,7 +1272,7 @@ p, li { white-space: pre-wrap; } QGCPendingParamWidget QWidget -
/ui/QGCPendingParamWidget.h
+
ui/QGCPendingParamWidget.h
1
-- GitLab From d3db72a69d38bda292b0ee65686432fcefd61081 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 14 Aug 2013 16:18:32 -0700 Subject: [PATCH 269/460] when param widget is loaded we only want to re-request the whole param list if we don't already have one --- src/uas/UASParameterCommsMgr.cc | 9 +++++++++ src/uas/UASParameterCommsMgr.h | 2 ++ src/uas/UASParameterDataModel.cc | 19 ++++++++++++++++--- src/uas/UASParameterDataModel.h | 4 +++- src/ui/QGCPX4VehicleConfig.cc | 2 +- src/ui/QGCVehicleConfig.cc | 2 +- 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index db74186114..1a3df2d81c 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -60,6 +60,15 @@ void UASParameterCommsMgr::loadParamCommsSettings() } +void UASParameterCommsMgr::requestParameterListIfEmpty() +{ + int totalOnboard = paramDataModel->countOnboardParams(); + if (totalOnboard < 2) { //TODO arbitrary constant, maybe 0 is OK? + requestParameterList(); + } +} + + /** * Send a request to deliver the list of onboard parameters diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index acdab75a86..39a67d1f5e 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -72,6 +72,8 @@ public slots: /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); + /** @brief Request a list of params onboard the MAV if the onboard param list we have is empty */ + virtual void requestParameterListIfEmpty(); /** @brief Check for missing parameters */ virtual void retransmissionGuardTick(); diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 66b847e88e..012749f659 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -20,15 +20,28 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : int UASParameterDataModel::countPendingParams() { - int totalPending = 0; + int total = 0; QMap*>::iterator i; for (i = pendingParameters.begin(); i != pendingParameters.end(); ++i) { // Iterate through the parameters of the component QMap* paramList = i.value(); - totalPending += paramList->count(); + total += paramList->count(); } - return totalPending; + return total; +} + +int UASParameterDataModel::countOnboardParams() +{ + int total = 0; + QMap*>::iterator i; + for (i = onboardParameters.begin(); i != onboardParameters.end(); ++i) { + // Iterate through the parameters of the component + QMap* paramList = i.value(); + total += paramList->count(); + } + + return total; } diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 2ca97965d8..40c6cead10 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -69,8 +69,10 @@ public: } /** @brief return a count of all pending parameters */ - int countPendingParams(); + virtual int countPendingParams(); + /** @brief return a count of all onboard parameters we've received */ + virtual int countOnboardParams(); virtual void writeOnboardParamsToStream(QTextStream &stream, const QString& uasName); virtual void readUpdateParamsFromStream(QTextStream &stream); diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index e28569335b..4f69090d0c 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -802,7 +802,7 @@ void QGCPX4VehicleConfig::loadConfig() } doneLoadingConfig = true; //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. - mav->getParamCommsMgr()->requestParameterList(); + paramCommsMgr->requestParameterListIfEmpty(); } void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) diff --git a/src/ui/QGCVehicleConfig.cc b/src/ui/QGCVehicleConfig.cc index 2aa2ead2e6..62823682ba 100644 --- a/src/ui/QGCVehicleConfig.cc +++ b/src/ui/QGCVehicleConfig.cc @@ -791,7 +791,7 @@ void QGCVehicleConfig::loadConfig() mav->getParamManager()->setParamDescriptions(paramTooltips); doneLoadingConfig = true; //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. - mav->getParamCommsMgr()->requestParameterList(); + mav->getParamCommsMgr()->requestParameterListIfEmpty(); } void QGCVehicleConfig::setActiveUAS(UASInterface* active) -- GitLab From f22f7f7f305b5c11518adc34bc56deb0a0a66298 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 14 Aug 2013 16:28:01 -0700 Subject: [PATCH 270/460] don't re-request param list each time we open a param widget --- src/uas/QGCUASParamManager.cc | 1 - src/ui/QGCParamWidget.cc | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 569daebb67..332f786065 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -45,7 +45,6 @@ void QGCUASParamManager::requestParameterList() if (!mav) { return; } - //paramDataModel->forgetAllOnboardParameters(); //TODO really?? setParameterStatusMsg(tr("Requested param list.. waiting")); paramCommsMgr->requestParameterList(); } diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index f2fc58073e..5d7d37da42 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -62,8 +62,9 @@ void QGCParamWidget::init() layoutWidget(); connectSignalsAndSlots(); - // Ensure we're receiving the list of params - requestAllParamsUpdate(); + // Ensure we have a list of params + paramCommsMgr->requestParameterListIfEmpty(); + } void QGCParamWidget::connectSignalsAndSlots() @@ -497,6 +498,7 @@ void QGCParamWidget::requestAllParamsUpdate() // Clear view and request param list clear(); + //paramDataModel->forgetAllOnboardParameters(); //TODO really?? requestParameterList(); } -- GitLab From 98936a41999d078b6ef3fb3d6b8f73317a7adf2a Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 15 Aug 2013 08:31:26 +0200 Subject: [PATCH 271/460] Minor UI fixes --- src/ui/DebugConsole.cc | 9 ++++++++- src/ui/QGCToolBar.cc | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ui/DebugConsole.cc b/src/ui/DebugConsole.cc index bdc5f149de..311a87f140 100644 --- a/src/ui/DebugConsole.cc +++ b/src/ui/DebugConsole.cc @@ -30,6 +30,7 @@ This file is part of the QGROUNDCONTROL project */ #include #include +#include #include "DebugConsole.h" #include "ui_DebugConsole.h" @@ -313,9 +314,15 @@ void DebugConsole::receiveTextMessage(int id, int component, int severity, QStri break; } + //turn off updates while we're appending content to avoid breaking the autoscroll behavior + m_ui->receiveText->setUpdatesEnabled(false); + QScrollBar *scroller = m_ui->receiveText->verticalScrollBar(); + m_ui->receiveText->appendHtml(QString("(%2:%3) %4\n").arg(UASManager::instance()->getUASForId(id)->getColor().name(), name, comp, text)); + // Ensure text area scrolls correctly - m_ui->receiveText->ensureCursorVisible(); + scroller->setValue(scroller->maximum()); + m_ui->receiveText->setUpdatesEnabled(true); } } diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 52f112d835..f5253c2835 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -75,6 +75,8 @@ void QGCToolBar::heartbeatTimeout(bool timeout, unsigned int ms) } toolBarTimeoutLabel->setText(tr("CONNECTION LOST: %1 s").arg((ms / 1000.0f), 2, 'f', 1, ' ')); toolBarTimeoutAction->setVisible(true); + + toolBarMessageLabel->hide(); } else { @@ -82,6 +84,8 @@ void QGCToolBar::heartbeatTimeout(bool timeout, unsigned int ms) if (toolBarTimeoutAction->isVisible()) { toolBarTimeoutAction->setVisible(false); + + toolBarMessageLabel->show(); } } } -- GitLab From d7137bbe397cddb39a0ab187189b716ba3a0f90f Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 15 Aug 2013 16:02:24 -0700 Subject: [PATCH 272/460] refactor QGCUASParamManager to be Controller-only (no View code) --- qgroundcontrol.pro | 6 +- src/uas/QGCUASParamManager.cc | 111 +++++++++--- src/uas/QGCUASParamManager.h | 42 +++-- src/uas/UAS.cc | 273 ++++++++++++++---------------- src/uas/UAS.h | 28 +-- src/uas/UASInterface.h | 12 +- src/uas/UASParameterCommsMgr.cc | 11 +- src/uas/UASParameterCommsMgr.h | 2 - src/ui/ParameterInterface.cc | 13 +- src/ui/QGCBaseParamWidget.cc | 121 +++++++++++++ src/ui/QGCBaseParamWidget.h | 59 +++++++ src/ui/QGCPX4VehicleConfig.cc | 22 +-- src/ui/QGCPX4VehicleConfig.h | 2 +- src/ui/QGCParamWidget.cc | 163 +++++------------- src/ui/QGCParamWidget.h | 53 +++--- src/ui/QGCPendingParamWidget.cc | 37 ++-- src/ui/QGCPendingParamWidget.h | 6 +- src/ui/QGCVehicleConfig.cc | 12 +- src/ui/QGCVehicleConfig.h | 1 + src/ui/designer/QGCComboBox.cc | 32 ++-- src/ui/designer/QGCComboBox.h | 10 +- src/ui/designer/QGCParamSlider.cc | 4 +- 22 files changed, 582 insertions(+), 438 deletions(-) create mode 100644 src/ui/QGCBaseParamWidget.cc create mode 100644 src/ui/QGCBaseParamWidget.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index cf714d579c..37f28f8112 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -471,7 +471,8 @@ HEADERS += src/MG.h \ src/ui/configuration/ApmFirmwareConfig.h \ src/uas/UASParameterDataModel.h \ src/uas/UASParameterCommsMgr.h \ - src/ui/QGCPendingParamWidget.h + src/ui/QGCPendingParamWidget.h \ + src/ui/QGCBaseParamWidget.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -689,7 +690,8 @@ SOURCES += src/main.cc \ src/ui/configuration/ApmFirmwareConfig.cc \ src/uas/UASParameterDataModel.cc \ src/uas/UASParameterCommsMgr.cc \ - src/ui/QGCPendingParamWidget.cc + src/ui/QGCPendingParamWidget.cc \ + src/ui/QGCBaseParamWidget.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 332f786065..bfb946732a 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -2,28 +2,46 @@ #include > #include +#include #include "UASInterface.h" #include "UASParameterCommsMgr.h" -QGCUASParamManager::QGCUASParamManager(UASInterface* uas, QWidget *parent) : - QWidget(parent), +QGCUASParamManager::QGCUASParamManager(QObject *parent, UASInterface* uas) : + QObject(parent), mav(uas), - paramDataModel(NULL), + paramDataModel(this), paramCommsMgr(NULL) { - paramDataModel = uas->getParamDataModel(); - paramCommsMgr = uas->getParamCommsMgr(); - mav->setParamManager(this); + paramCommsMgr = new UASParameterCommsMgr(this,mav); // Load default values and tooltips loadParamMetaInfoCSV(); + + connectToCommsMgr(); + } +void QGCUASParamManager::connectToCommsMgr() +{ + + // Pass along comms mgr status msgs + connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), + this, SIGNAL(parameterStatusMsgUpdated(QString,int))); + + connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), + this, SIGNAL(parameterListUpToDate())); + + +} + + + + bool QGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const { - return paramDataModel->getOnboardParamValue(component,parameter,value); + return paramDataModel.getOnboardParamValue(component,parameter,value); } @@ -42,29 +60,31 @@ void QGCUASParamManager::requestParameterUpdate(int component, const QString& pa */ void QGCUASParamManager::requestParameterList() { - if (!mav) { - return; + if (mav) { + emit parameterStatusMsgUpdated(tr("Requested param list.. waiting"), UASParameterCommsMgr::ParamCommsStatusLevel_OK); + paramCommsMgr->requestParameterList(); } - setParameterStatusMsg(tr("Requested param list.. waiting")); - paramCommsMgr->requestParameterList(); } - -void QGCUASParamManager::setParameterStatusMsg(const QString& msg) +void QGCUASParamManager::requestParameterListIfEmpty() { - qDebug() << "parameterStatusMsg: " << msg; - parameterStatusMsg = msg; + if (mav) { + int totalOnboard = paramDataModel.countOnboardParams(); + if (totalOnboard < 2) { //TODO arbitrary constant, maybe 0 is OK? + requestParameterList(); + } + } } + void QGCUASParamManager::setParamDescriptions(const QMap& paramInfo) { - paramDataModel->setParamDescriptions(paramInfo); + paramDataModel.setParamDescriptions(paramInfo); } void QGCUASParamManager::setParameter(int compId, QString paramName, QVariant value) { - //paramCommsMgr->setParameter(compId,paramName,value); - paramDataModel->updatePendingParamWithValue(compId,paramName,value); + paramDataModel.updatePendingParamWithValue(compId,paramName,value); } void QGCUASParamManager::sendPendingParameters() @@ -74,7 +94,7 @@ void QGCUASParamManager::sendPendingParameters() void QGCUASParamManager::setPendingParam(int compId, QString& paramName, const QVariant& value) { - paramDataModel->updatePendingParamWithValue(compId,paramName,value); + paramDataModel.updatePendingParamWithValue(compId,paramName,value); } @@ -97,16 +117,59 @@ void QGCUASParamManager::loadParamMetaInfoCSV() } QTextStream in(¶mMetaFile); - paramDataModel->loadParamMetaInfoFromStream(in); + paramDataModel.loadParamMetaInfoFromStream(in); paramMetaFile.close(); } -/** - * @return The MAV of this mgr. Unless the MAV object has been destroyed, this - * pointer is never zero. - */ + UASInterface* QGCUASParamManager::getUAS() { return mav; } + +UASParameterDataModel* QGCUASParamManager::dataModel() +{ + return ¶mDataModel; +} + + + +void QGCUASParamManager::writeOnboardParamsToStream(QTextStream &stream, const QString& uasName) +{ + paramDataModel.writeOnboardParamsToStream(stream,uasName); +} + +void QGCUASParamManager::readPendingParamsFromStream(QTextStream &stream) +{ + paramDataModel.readUpdateParamsFromStream(stream); +} + + + +void QGCUASParamManager::copyVolatileParamsToPersistent() +{ + int changedParamCount = paramDataModel.countPendingParams(); + + if (changedParamCount > 0) { + QMessageBox msgBox; + msgBox.setText(tr("There are locally changed parameters. Please transmit them first () or update them with the onboard values () before storing onboard from RAM to ROM.")); + msgBox.exec(); + } + else { + paramCommsMgr->writeParamsToPersistentStorage(); + } +} + + +void QGCUASParamManager::copyPersistentParamsToVolatile() +{ + if (mav) { + mav->readParametersFromStorage(); //TODO use comms mgr instead? + } +} + + +void QGCUASParamManager::requestRcCalibrationParamsUpdate() { + paramCommsMgr->requestRcCalibrationParamsUpdate(); +} diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 6c910509cd..a346bbaa4b 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -6,16 +6,18 @@ #include #include +#include "UASParameterDataModel.h" + //forward declarations +class QTextStream; class UASInterface; class UASParameterCommsMgr; -class UASParameterDataModel; -class QGCUASParamManager : public QWidget +class QGCUASParamManager : public QObject { Q_OBJECT public: - QGCUASParamManager(UASInterface* uas, QWidget *parent = 0); + QGCUASParamManager(QObject* parent = 0,UASInterface* uas = 0); /** @brief Get the known, confirmed value of a parameter */ virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; @@ -28,16 +30,23 @@ public: */ UASInterface* getUAS(); + /** @return The data model managed by this class */ + virtual UASParameterDataModel* dataModel(); + protected: - //TODO decouple this UI message display further? - virtual void setParameterStatusMsg(const QString& msg); + /** @brief Load parameter meta information from appropriate CSV file */ virtual void loadParamMetaInfoCSV(); + void connectToCommsMgr(); + signals: - void parameterChanged(int component, QString parameter, QVariant value); - void parameterChanged(int component, int parameterIndex, QVariant value); + + /** @brief We updated the parameter status message */ + void parameterStatusMsgUpdated(QString msg, int level); + /** @brief We have received a complete list of all parameters onboard the MAV */ + void parameterListUpToDate(); public slots: /** @brief Send one parameter to the MAV: changes value in transient memory of MAV */ @@ -49,25 +58,32 @@ public slots: /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); + /** @brief Request a list of params onboard the MAV if the onboard param list we have is empty */ + virtual void requestParameterListIfEmpty(); + virtual void setPendingParam(int componentId, QString& key, const QVariant& value); /** @brief Request a single parameter by name from the MAV */ virtual void requestParameterUpdate(int component, const QString& parameter); - virtual void handleParameterUpdate(int component, const QString& parameterName, QVariant value) = 0; - virtual void handleParameterListUpToDate() = 0; + virtual void writeOnboardParamsToStream(QTextStream &stream, const QString& uasName); + virtual void readPendingParamsFromStream(QTextStream &stream); + + virtual void requestRcCalibrationParamsUpdate(); + + /** @brief Copy the current parameters in volatile RAM to persistent storage (EEPROM/HDD) */ + virtual void copyVolatileParamsToPersistent(); + /** @brief Copy the parameters from persistent storage to volatile RAM */ + virtual void copyPersistentParamsToVolatile(); protected: // Parameter data model UASInterface* mav; ///< The MAV this manager is controlling - UASParameterDataModel* paramDataModel;///< Shared data model of parameters + UASParameterDataModel paramDataModel;///< Shared data model of parameters UASParameterCommsMgr* paramCommsMgr; ///< Shared comms mgr for parameters - // Status - QString parameterStatusMsg; - }; #endif // QGCUASPARAMMANAGER_H diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index aeec7716bc..80c0558362 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -131,9 +131,7 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), lastAttitude(0), paramsOnceRequested(false), - paramManager(NULL), - paramDataModel(NULL), - paramCommsMgr(NULL), + paramManager(this,this), simulation(0), @@ -154,10 +152,6 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), componentMulti[i] = false; } - paramDataModel = new UASParameterDataModel(this); - paramDataModel->setUASID(this->getUASID()); - - paramCommsMgr = new UASParameterCommsMgr(this,this); // Store a list of available actions for this UAS. // Basically everything exposted as a SLOT with no return value or arguments. @@ -234,8 +228,6 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), */ UAS::~UAS() { - delete paramCommsMgr; - delete paramDataModel; writeSettings(); delete links; delete statusTimeout; @@ -1036,147 +1028,19 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message) break; case MAVLINK_MSG_ID_PARAM_VALUE: { - mavlink_param_value_t value; - mavlink_msg_param_value_decode(&message, &value); - QByteArray bytes(value.param_id, MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN); + mavlink_param_value_t rawValue; + mavlink_msg_param_value_decode(&message, &rawValue); + QByteArray bytes(rawValue.param_id, MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN); // Construct a string stopping at the first NUL (0) character, else copy the whole // byte array (max MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN, so safe) QString parameterName(bytes); - int component = message.compid; - mavlink_param_union_t val; - val.param_float = value.param_value; - val.type = value.param_type; - - // Insert component if necessary - if (!parameters.contains(component)) - { - parameters.insert(component, new QMap()); - } + mavlink_param_union_t paramVal; + paramVal.param_float = rawValue.param_value; + paramVal.type = rawValue.param_type; - // Insert parameter into registry - if (parameters.value(component)->contains(parameterName)) parameters.value(component)->remove(parameterName); + processParamValueMsg(message, parameterName,rawValue,paramVal); - // Insert with correct type - // TODO: This is a hack for MAV_AUTOPILOT_ARDUPILOTMEGA until the new version of MAVLink and a fix for their param handling. - switch (value.param_type) - { - case MAV_PARAM_TYPE_REAL32: - { - // Variant - QVariant param; - if (getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA) - { - param = QVariant(val.param_float); - } - else - { - param = QVariant(val.param_float); - } - parameters.value(component)->insert(parameterName, param); - // Emit change - emit parameterChanged(uasId, message.compid, parameterName, param); - emit parameterChanged(uasId, message.compid, value.param_count, value.param_index, parameterName, param); -// qDebug() << "RECEIVED PARAM:" << param; - } - break; - case MAV_PARAM_TYPE_UINT8: - { - // Variant - QVariant param; - if (getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA) - { - param = QVariant(QChar((unsigned char)val.param_float)); - } - else - { - param = QVariant(QChar((unsigned char)val.param_uint8)); - } - parameters.value(component)->insert(parameterName, param); - // Emit change - emit parameterChanged(uasId, message.compid, parameterName, param); - emit parameterChanged(uasId, message.compid, value.param_count, value.param_index, parameterName, param); - //qDebug() << "RECEIVED PARAM:" << param; - } - break; - case MAV_PARAM_TYPE_INT8: - { - // Variant - QVariant param; - if (getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA) - { - param = QVariant(QChar((char)val.param_float)); - } - else - { - param = QVariant(QChar((char)val.param_int8)); - } - parameters.value(component)->insert(parameterName, param); - // Emit change - emit parameterChanged(uasId, message.compid, parameterName, param); - emit parameterChanged(uasId, message.compid, value.param_count, value.param_index, parameterName, param); - //qDebug() << "RECEIVED PARAM:" << param; - } - break; - case MAV_PARAM_TYPE_INT16: - { - // Variant - QVariant param; - if (getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA) - { - param = QVariant((short)val.param_float); - } - else - { - param = QVariant(val.param_int16); - } - parameters.value(component)->insert(parameterName, param); - // Emit change - emit parameterChanged(uasId, message.compid, parameterName, param); - emit parameterChanged(uasId, message.compid, value.param_count, value.param_index, parameterName, param); - //qDebug() << "RECEIVED PARAM:" << param; - } - break; - case MAV_PARAM_TYPE_UINT32: - { - // Variant - QVariant param; - if (getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA) - { - param = QVariant((unsigned int)val.param_float); - } - else - { - param = QVariant(val.param_uint32); - } - parameters.value(component)->insert(parameterName, param); - // Emit change - emit parameterChanged(uasId, message.compid, parameterName, param); - emit parameterChanged(uasId, message.compid, value.param_count, value.param_index, parameterName, param); - } - break; - case MAV_PARAM_TYPE_INT32: - { - // Variant - QVariant param; - if (getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA) - { - param = QVariant((int)val.param_float); - } - else - { - param = QVariant(val.param_int32); - } - parameters.value(component)->insert(parameterName, param); - // Emit change - emit parameterChanged(uasId, message.compid, parameterName, param); - emit parameterChanged(uasId, message.compid, value.param_count, value.param_index, parameterName, param); -// qDebug() << "RECEIVED PARAM:" << param; - } - break; - default: - qCritical() << "INVALID DATA TYPE USED AS PARAMETER VALUE: " << value.param_type; - } //switch (value.param_type) - } + } break; case MAVLINK_MSG_ID_COMMAND_ACK: { @@ -2625,6 +2489,125 @@ void UAS::setParameter(const int component, const QString& id, const QVariant& v } } + + + +//TODO update this to use the parameter manager / param data model instead +void UAS::processParamValueMsg(mavlink_message_t& msg, const QString& paramName, const mavlink_param_value_t& rawValue, mavlink_param_union_t& paramValue) +{ + int compId = msg.compid; + + // Insert component if necessary + if (!parameters.contains(compId)) { + parameters.insert(compId, new QMap()); + } + + // Insert parameter into registry + if (parameters.value(compId)->contains(paramName)) { + parameters.value(compId)->remove(paramName); + } + + QVariant param; + + // Insert with correct type + // TODO: This is a hack for MAV_AUTOPILOT_ARDUPILOTMEGA until the new version of MAVLink and a fix for their param handling. + switch (rawValue.param_type) + { + case MAV_PARAM_TYPE_REAL32: + { + if (getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA) { + param = QVariant(paramValue.param_float); + } + else { + param = QVariant(paramValue.param_float); + } + parameters.value(compId)->insert(paramName, param); + // Emit change + emit parameterChanged(uasId, compId, paramName, param); + emit parameterChanged(uasId, compId, rawValue.param_count, rawValue.param_index, paramName, param); +// qDebug() << "RECEIVED PARAM:" << param; + } + break; + case MAV_PARAM_TYPE_UINT8: + { + if (getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA) { + param = QVariant(QChar((unsigned char)paramValue.param_float)); + } + else { + param = QVariant(QChar((unsigned char)paramValue.param_uint8)); + } + parameters.value(compId)->insert(paramName, param); + // Emit change + emit parameterChanged(uasId, compId, paramName, param); + emit parameterChanged(uasId, compId, rawValue.param_count, rawValue.param_index, paramName, param); + //qDebug() << "RECEIVED PARAM:" << param; + } + break; + case MAV_PARAM_TYPE_INT8: + { + if (getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA) { + param = QVariant(QChar((char)paramValue.param_float)); + } + else { + param = QVariant(QChar((char)paramValue.param_int8)); + } + parameters.value(compId)->insert(paramName, param); + // Emit change + emit parameterChanged(uasId, compId, paramName, param); + emit parameterChanged(uasId, compId, rawValue.param_count, rawValue.param_index, paramName, param); + //qDebug() << "RECEIVED PARAM:" << param; + } + break; + case MAV_PARAM_TYPE_INT16: + { + if (getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA) { + param = QVariant((short)paramValue.param_float); + } + else { + param = QVariant(paramValue.param_int16); + } + parameters.value(compId)->insert(paramName, param); + // Emit change + emit parameterChanged(uasId, compId, paramName, param); + emit parameterChanged(uasId, compId, rawValue.param_count, rawValue.param_index, paramName, param); + //qDebug() << "RECEIVED PARAM:" << param; + } + break; + case MAV_PARAM_TYPE_UINT32: + { + if (getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA) { + param = QVariant((unsigned int)paramValue.param_float); + } + else { + param = QVariant(paramValue.param_uint32); + } + parameters.value(compId)->insert(paramName, param); + // Emit change + emit parameterChanged(uasId, compId, paramName, param); + emit parameterChanged(uasId, compId, rawValue.param_count, rawValue.param_index, paramName, param); + } + break; + case MAV_PARAM_TYPE_INT32: + { + if (getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA) { + param = QVariant((int)paramValue.param_float); + } + else { + param = QVariant(paramValue.param_int32); + } + parameters.value(compId)->insert(paramName, param); + // Emit change + emit parameterChanged(uasId, compId, paramName, param); + emit parameterChanged(uasId, compId, rawValue.param_count, rawValue.param_index, paramName, param); +// qDebug() << "RECEIVED PARAM:" << param; + } + break; + default: + qCritical() << "INVALID DATA TYPE USED AS PARAMETER VALUE: " << rawValue.param_type; + } //switch (value.param_type) + +} + /** * Request parameter, use parameter name to request it. */ diff --git a/src/uas/UAS.h b/src/uas/UAS.h index 5acd2c9ef4..b62a81a6de 100644 --- a/src/uas/UAS.h +++ b/src/uas/UAS.h @@ -492,9 +492,7 @@ protected: //COMMENTS FOR TEST UNIT /// PARAMETERS QMap* > parameters; ///< All parameters bool paramsOnceRequested; ///< If the parameter list has been read at least once - QGCUASParamManager* paramManager; ///< Parameter manager class - UASParameterDataModel* paramDataModel; ///< The parameter data model for this UAS - UASParameterCommsMgr* paramCommsMgr; + QGCUASParamManager paramManager; ///< Parameter manager for this UAS /// SIMULATION QGCHilLink* simulation; ///< Hardware in the loop simulation link @@ -515,36 +513,22 @@ public: /** @brief Check if vehicle is armed */ bool isArmed() const { return systemIsArmed; } + /** @brief Get reference to the waypoint manager **/ UASWaypointManager* getWaypointManager() { return &waypointManager; } - /** @brief Get reference to the param manager **/ - QGCUASParamManager* getParamManager() const { - return paramManager; - } - /** @brief Get reference to the parameter data model (same one shared with the parameter manager) **/ - UASParameterDataModel* getParamDataModel() { - return paramDataModel; - } - - UASParameterCommsMgr* getParamCommsMgr() { - return paramCommsMgr; + /** @brief Get reference to the param manager **/ + virtual QGCUASParamManager* getParamManager() { + return ¶mManager; } - /** @brief Get the HIL simulation */ QGCHilLink* getHILSimulation() const { return simulation; } - - // TODO Will be removed - /** @brief Set reference to the param manager **/ - void setParamManager(QGCUASParamManager* manager) { - paramManager = manager; - } int getSystemType(); /** @@ -953,6 +937,8 @@ protected: /** @brief Get the UNIX timestamp in milliseconds, ignore attitudeStamped mode */ quint64 getUnixReferenceTime(quint64 time); + virtual void processParamValueMsg(mavlink_message_t& msg, const QString& paramName,const mavlink_param_value_t& rawValue, mavlink_param_union_t& paramValue); + int componentID[256]; bool componentMulti[256]; bool connectionLost; ///< Flag indicates a timed out connection diff --git a/src/uas/UASInterface.h b/src/uas/UASInterface.h index 6e6fe2fb33..8714ad3c43 100644 --- a/src/uas/UASInterface.h +++ b/src/uas/UASInterface.h @@ -154,18 +154,8 @@ public: /** @brief Get reference to the waypoint manager **/ virtual UASWaypointManager* getWaypointManager(void) = 0; - /** @brief Access the parameter data model for this UAS (sans widget). This is the same parameter data model used by the parameter manager. **/ - virtual UASParameterDataModel* getParamDataModel() = 0; - - - virtual UASParameterCommsMgr* getParamCommsMgr() = 0; - /** @brief Get reference to the param manager **/ - virtual QGCUASParamManager* getParamManager() const = 0; - - // TODO Will be removed - /** @brief Set reference to the param manager **/ - virtual void setParamManager(QGCUASParamManager* manager) = 0; + virtual QGCUASParamManager* getParamManager() = 0; /* COMMUNICATION FLAGS */ diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 1a3df2d81c..96d7d19ec4 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -18,7 +18,7 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : rewriteTimeout(1000), retransmissionBurstRequestSize(5) { - paramDataModel = mav->getParamDataModel(); + paramDataModel = mav->getParamManager()->dataModel(); loadParamCommsSettings(); @@ -60,15 +60,6 @@ void UASParameterCommsMgr::loadParamCommsSettings() } -void UASParameterCommsMgr::requestParameterListIfEmpty() -{ - int totalOnboard = paramDataModel->countOnboardParams(); - if (totalOnboard < 2) { //TODO arbitrary constant, maybe 0 is OK? - requestParameterList(); - } -} - - /** * Send a request to deliver the list of onboard parameters diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 39a67d1f5e..acdab75a86 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -72,8 +72,6 @@ public slots: /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); - /** @brief Request a list of params onboard the MAV if the onboard param list we have is empty */ - virtual void requestParameterListIfEmpty(); /** @brief Check for missing parameters */ virtual void retransmissionGuardTick(); diff --git a/src/ui/ParameterInterface.cc b/src/ui/ParameterInterface.cc index 93624d50ea..5218978962 100644 --- a/src/ui/ParameterInterface.cc +++ b/src/ui/ParameterInterface.cc @@ -97,14 +97,15 @@ void ParameterInterface::addUAS(UASInterface* uas) return; } - QGCParamWidget* param = new QGCParamWidget(uas, this); - param->init(); + QGCParamWidget* paramWidget = new QGCParamWidget(this); + paramWidget = (QGCParamWidget*)paramWidget->initWithUAS(uas); + QString ptrStr; - ptrStr.sprintf("QGCParamWidget %8p (parent %8p)", param,this); + ptrStr.sprintf("QGCParamWidget %8p (parent %8p)", paramWidget,this); qDebug() << "Created " << ptrStr << " for UAS id: " << uasId << " count: " << paramWidgets->count(); - paramWidgets->insert(uasId, param); - m_ui->stackedWidget->addWidget(param); + paramWidgets->insert(uasId, paramWidget); + m_ui->stackedWidget->addWidget(paramWidget); QGCSensorSettingsWidget* sensor = NULL; @@ -119,7 +120,7 @@ void ParameterInterface::addUAS(UASInterface* uas) // Clear if (m_ui->sensorSettings && sensor) m_ui->sensorSettings->setCurrentWidget(sensor); - m_ui->stackedWidget->setCurrentWidget(param); + m_ui->stackedWidget->setCurrentWidget(paramWidget); curr = 0; } } diff --git a/src/ui/QGCBaseParamWidget.cc b/src/ui/QGCBaseParamWidget.cc new file mode 100644 index 0000000000..b7c3891580 --- /dev/null +++ b/src/ui/QGCBaseParamWidget.cc @@ -0,0 +1,121 @@ +#include "QGCBaseParamWidget.h" + +#include +#include +#include +#include > + +#include "QGCUASParamManager.h" +#include "UASInterface.h" + + +QGCBaseParamWidget::QGCBaseParamWidget(QWidget *parent) : + QWidget(parent), + mav(NULL), + paramMgr(NULL), + updatingParamNameLock("") +{ +} + +QGCBaseParamWidget* QGCBaseParamWidget::initWithUAS(UASInterface *uas) +{ + setUAS(uas); + layoutWidget(); + + return this; +} + +void QGCBaseParamWidget::setUAS(UASInterface* uas) +{ + if (mav) { + //TODO disconnect any connections as needed + disconnectViewSignalsAndSlots(); + disconnectFromParamManager(); + clearOnboardParamDisplay(); + clearPendingParamDisplay(); + } + mav = uas; + connectToParamManager(); + connectViewSignalsAndSlots(); + + paramMgr->requestParameterListIfEmpty(); + +} + + +void QGCBaseParamWidget::connectToParamManager() +{ + //TODO route via paramManager instead? + // Listen to updated param signals from the data model + connect(paramMgr->dataModel(), SIGNAL(parameterUpdated(int, QString , QVariant )), + this, SLOT(handleOnboardParamUpdate(int,QString,QVariant))); + + connect(paramMgr->dataModel(), SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), + this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); + + // Listen for param list reload finished + connect(paramMgr, SIGNAL(parameterListUpToDate()), + this, SLOT(handleOnboardParameterListUpToDate())); + + // Listen to communications status messages so we can display them + connect(paramMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), + this, SLOT(handleParamStatusMsgUpdate(QString , int ))); +} + + +void QGCBaseParamWidget::disconnectFromParamManager() +{ + disconnect(paramMgr->dataModel(), SIGNAL(parameterUpdated(int, QString , QVariant )), + this, SLOT(handleOnboardParamUpdate(int,QString,QVariant))); + + disconnect(paramMgr->dataModel(), SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), + this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); + + disconnect(paramMgr, SIGNAL(parameterListUpToDate()), + this, SLOT(handleOnboardParameterListUpToDate())); + + // Listen to communications status messages so we can display them + disconnect(paramMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), + this, SLOT(handleParamStatusMsgUpdate(QString , int ))); +} + + + +void QGCBaseParamWidget::requestOnboardParamsUpdate() +{ + paramMgr->requestParameterList(); +} + + +void QGCBaseParamWidget::saveParametersToFile() +{ + if (!mav) + return; + QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "./parameters.txt", tr("Parameter File (*.txt)")); + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + return; + } + + QTextStream outstream(&file); + paramMgr->writeOnboardParamsToStream(outstream,mav->getUASName()); + file.close(); +} + + +void QGCBaseParamWidget::loadParametersFromFile() +{ + if (!mav) + return; + + QString fileName = QFileDialog::getOpenFileName(this, tr("Load File"), ".", tr("Parameter file (*.txt)")); + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + return; + + QTextStream in(&file); + paramMgr->readPendingParamsFromStream(in); + file.close(); +} + + diff --git a/src/ui/QGCBaseParamWidget.h b/src/ui/QGCBaseParamWidget.h new file mode 100644 index 0000000000..e9e1309d3c --- /dev/null +++ b/src/ui/QGCBaseParamWidget.h @@ -0,0 +1,59 @@ +#ifndef QGCBASEPARAMWIDGET_H +#define QGCBASEPARAMWIDGET_H + +#include +#include + + + + +//forward declarations +class QGCUASParamManager; +class UASInterface; + + +class QGCBaseParamWidget : public QWidget +{ + Q_OBJECT +public: + explicit QGCBaseParamWidget(QWidget *parent = 0); + virtual QGCBaseParamWidget* initWithUAS(UASInterface* uas);///< Two-stage construction: initialize this object + virtual void setUAS(UASInterface* uas);///< Allows swapping the underlying UAS + +protected: + virtual void setParameterStatusMsg(const QString& msg) = 0; + virtual void layoutWidget() = 0;///< Layout the appearance of this widget + virtual void connectViewSignalsAndSlots() = 0;///< Connect view signals/slots as needed + virtual void disconnectViewSignalsAndSlots() = 0;///< Disconnect view signals/slots as needed + virtual void connectToParamManager(); ///>Connect to any required param manager signals + virtual void disconnectFromParamManager(); ///< Disconnect from any connected param manager signals + +signals: + +public slots: + virtual void handleOnboardParamUpdate(int component,const QString& parameterName, QVariant value) = 0; + virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) = 0; + virtual void handleOnboardParameterListUpToDate() = 0; + virtual void handleParamStatusMsgUpdate(QString msg, int level) = 0; + /** @brief Clear the rendering of onboard parameters */ + virtual void clearOnboardParamDisplay() = 0; + /** @brief Clear the rendering of pending parameters */ + virtual void clearPendingParamDisplay() = 0; + + /** @brief Request list of parameters from MAV */ + virtual void requestOnboardParamsUpdate(); + + + /** @brief Store parameters to a file */ + virtual void saveParametersToFile(); + /** @brief Load parameters from a file */ + virtual void loadParametersFromFile(); + +protected: + QGCUASParamManager* paramMgr; + UASInterface* mav; + QString updatingParamNameLock; ///< Name of param currently being updated-- used for reducing echo on param change + +}; + +#endif // QGCBASEPARAMWIDGET_H diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 4f69090d0c..bddc235b32 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -84,7 +84,7 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : //connect(ui->setTrimButton, SIGNAL(clicked()), this, SLOT(setTrimPositions())); //TODO connect buttons here to save/clear actions? - ui->pendingCommitsWidget->init(); + ui->pendingCommitsWidget->initWithUAS(this->mav); ui->pendingCommitsWidget->update(); //TODO the following methods are not yet implemented @@ -798,11 +798,11 @@ void QGCPX4VehicleConfig::loadConfig() } if (!paramTooltips.isEmpty()) { - mav->getParamManager()->setParamDescriptions(paramTooltips); + paramMgr->setParamDescriptions(paramTooltips); } doneLoadingConfig = true; //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. - paramCommsMgr->requestParameterListIfEmpty(); + paramMgr->requestParameterListIfEmpty(); } void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) @@ -828,6 +828,7 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) if (mav) { + // Disconnect old system disconnect(mav, SIGNAL(remoteControlChannelRawChanged(int,float)), this, SLOT(remoteControlChannelRawChanged(int,float))); @@ -835,7 +836,7 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) disconnect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); disconnect(ui->refreshButton,SIGNAL(clicked()), - paramCommsMgr,SLOT(requestParameterList())); + paramMgr,SLOT(requestParameterList())); // Delete all children from all fixed tabs. foreach(QWidget* child, ui->generalLeftContents->findChildren()) { @@ -868,22 +869,23 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) // Connect new system mav = active; - paramCommsMgr = mav->getParamCommsMgr(); + paramMgr = mav->getParamManager(); + // Reset current state resetCalibrationRC(); - - requestCalibrationRC(); + //TODO eliminate the separate RC_TYPE call mav->requestParameter(0, "RC_TYPE"); chanCount = 0; + //TODO get parameter changes via Param Mgr instead // Connect new system connect(mav, SIGNAL(remoteControlChannelRawChanged(int,float)), this, SLOT(remoteControlChannelRawChanged(int,float))); connect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); connect(ui->refreshButton, SIGNAL(clicked()), - paramCommsMgr,SLOT(requestParameterList())); + paramMgr,SLOT(requestParameterList())); if (systemTypeToParamMap.contains(mav->getSystemTypeName())) { paramToWidgetMap = systemTypeToParamMap[mav->getSystemTypeName()]; @@ -978,9 +980,7 @@ void QGCPX4VehicleConfig::writeCalibrationRC() void QGCPX4VehicleConfig::requestCalibrationRC() { - if (paramCommsMgr) { - paramCommsMgr->requestRcCalibrationParamsUpdate(); - } + paramMgr->requestRcCalibrationParamsUpdate(); } void QGCPX4VehicleConfig::writeParameters() diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index a242fcf9d3..217d72c664 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -161,7 +161,7 @@ protected slots: protected: bool doneLoadingConfig; UASInterface* mav; ///< The current MAV - UASParameterCommsMgr* paramCommsMgr; ///< param comms mgr for the mav + QGCUASParamManager* paramMgr; ///< params mgr for the mav static const unsigned int chanMax = 8; ///< Maximum number of channels unsigned int chanCount; ///< Actual channels int rcType; ///< Type of the remote control diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 5d7d37da42..5c095b3bdb 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -49,47 +49,30 @@ This file is part of the QGROUNDCONTROL project * @param uas MAV to set the parameters on * @param parent Parent widget */ -QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : - QGCUASParamManager(uas, parent), - componentItems(new QMap()), - updatingParamNameLock("") +QGCParamWidget::QGCParamWidget(QWidget *parent) : + QGCBaseParamWidget(parent), + componentItems(new QMap()) { } -void QGCParamWidget::init() -{ - layoutWidget(); - connectSignalsAndSlots(); - // Ensure we have a list of params - paramCommsMgr->requestParameterListIfEmpty(); +void QGCParamWidget::disconnectViewSignalsAndSlots() +{ + disconnect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), + this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); } -void QGCParamWidget::connectSignalsAndSlots() -{ +void QGCParamWidget::connectViewSignalsAndSlots() +{ // Listen for edits to the tree UI connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); - - // Listen to updated param signals from the data model - connect(paramDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), - this, SLOT(handleParameterUpdate(int,QString,QVariant))); - - connect(paramDataModel, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), - this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); - - // Listen for param list reload finished - connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), - this, SLOT(handleParameterListUpToDate())); - - // Listen to communications status messages so we can display them - connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), - this, SLOT(handleParamStatusMsgUpdate(QString , int ))); } + void QGCParamWidget::layoutWidget() { // Create tree widget @@ -118,7 +101,8 @@ void QGCParamWidget::layoutWidget() QPushButton* refreshButton = new QPushButton(tr("Get")); refreshButton->setToolTip(tr("Load parameters currently in non-permanent memory of aircraft.")); refreshButton->setWhatsThis(tr("Load parameters currently in non-permanent memory of aircraft.")); - connect(refreshButton, SIGNAL(clicked()), this, SLOT(requestAllParamsUpdate())); + connect(refreshButton, SIGNAL(clicked()), + this, SLOT(requestOnboardParamsUpdate())); horizontalLayout->addWidget(refreshButton, 2, 0); QPushButton* setButton = new QPushButton(tr("Set")); @@ -131,25 +115,29 @@ void QGCParamWidget::layoutWidget() QPushButton* writeButton = new QPushButton(tr("Write (ROM)")); writeButton->setToolTip(tr("Copy current parameters in non-permanent memory of the aircraft to permanent memory. Transmit your parameters first to write these.")); writeButton->setWhatsThis(tr("Copy current parameters in non-permanent memory of the aircraft to permanent memory. Transmit your parameters first to write these.")); - connect(writeButton, SIGNAL(clicked()), this, SLOT(writeParameters())); + connect(writeButton, SIGNAL(clicked()), + paramMgr, SLOT(copyVolatileParamsToPersistent())); horizontalLayout->addWidget(writeButton, 2, 2); QPushButton* loadFileButton = new QPushButton(tr("Load File")); loadFileButton->setToolTip(tr("Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them.")); loadFileButton->setWhatsThis(tr("Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them.")); - connect(loadFileButton, SIGNAL(clicked()), this, SLOT(loadParametersFromFile())); + connect(loadFileButton, SIGNAL(clicked()), + this, SLOT(loadParametersFromFile())); horizontalLayout->addWidget(loadFileButton, 3, 0); QPushButton* saveFileButton = new QPushButton(tr("Save File")); saveFileButton->setToolTip(tr("Save parameters in this view to a file on this computer.")); saveFileButton->setWhatsThis(tr("Save parameters in this view to a file on this computer.")); - connect(saveFileButton, SIGNAL(clicked()), this, SLOT(saveParametersToFile())); + connect(saveFileButton, SIGNAL(clicked()), + this, SLOT(saveParametersToFile())); horizontalLayout->addWidget(saveFileButton, 3, 1); QPushButton* readButton = new QPushButton(tr("Read (ROM)")); readButton->setToolTip(tr("Copy parameters from permanent memory to non-permanent current memory of aircraft. DOES NOT update the parameters in this view, click refresh after copying them to get them.")); readButton->setWhatsThis(tr("Copy parameters from permanent memory to non-permanent current memory of aircraft. DOES NOT update the parameters in this view, click refresh after copying them to get them.")); - connect(readButton, SIGNAL(clicked()), this, SLOT(readParameters())); + connect(readButton, SIGNAL(clicked()), + paramMgr, SLOT(copyPersistentParamsToVolatile())); horizontalLayout->addWidget(readButton, 3, 2); // Set correct vertical scaling @@ -180,8 +168,8 @@ void QGCParamWidget::addComponentItem(int compId, QString compName) QString compLine = QString("%1 (#%2)").arg(compName).arg(compId); - QString ptrStr = QString().sprintf("%8p", this); - qDebug() << "QGCParamWidget" << ptrStr << "addComponentItem:" << compLine; + //QString ptrStr = QString().sprintf("%8p", this); + //qDebug() << "QGCParamWidget" << ptrStr << "addComponentItem:" << compLine; if (componentItems->contains(compId)) { // Update existing component item @@ -200,14 +188,11 @@ void QGCParamWidget::addComponentItem(int compId, QString compName) tree->update(); } - //TODO it seems unlikely that the UI would know about a component before the data model... - paramDataModel->addComponent(compId); - } void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) { - // qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; + //qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; if (updatingParamNameLock == paramName) { //qDebug() << "ignoring bounce from " << paramName; @@ -231,11 +216,11 @@ void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramNa } -void QGCParamWidget::handleParameterUpdate(int compId, const QString& paramName, QVariant value) +void QGCParamWidget::handleOnboardParamUpdate(int compId, const QString& paramName, QVariant value) { -// qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; + //qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; if (paramName == updatingParamNameLock) { - qDebug() << "handlePendingParamUpdate ignoring bounce from " << paramName; + //qDebug() << "handlePendingParamUpdate ignoring bounce from " << paramName; return; } updatingParamNameLock = paramName; @@ -244,14 +229,14 @@ void QGCParamWidget::handleParameterUpdate(int compId, const QString& paramName, } -void QGCParamWidget::handleParameterListUpToDate() +void QGCParamWidget::handleOnboardParameterListUpToDate() { //turn off updates while we refresh the entire list tree->setUpdatesEnabled(false); //rewrite the component item tree after receiving the full list QMap*>::iterator i; - QMap*>* onboardParams = paramDataModel->getAllOnboardParams(); + QMap*>* onboardParams = paramMgr->dataModel()->getAllOnboardParams(); for (i = onboardParams->begin(); i != onboardParams->end(); ++i) { int compId = i.key(); @@ -323,7 +308,7 @@ QTreeWidgetItem* QGCParamWidget::getParentWidgetItemForParam(int compId, const Q QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, QVariant value) { -// qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName; + //qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName; // Reference to item in tree QTreeWidgetItem* paramItem = NULL; @@ -357,12 +342,12 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para parentItem->addChild(paramItem); //only add the tooltip when the parameter item is first added - QString paramDesc = paramDataModel->getParamDescription(parameterName); + QString paramDesc = paramMgr->dataModel()->getParamDescription(parameterName); if (!paramDesc.isEmpty()) { QString tooltipFormat; - if (paramDataModel->isParamDefaultKnown(parameterName)) { + if (paramMgr->dataModel()->isParamDefaultKnown(parameterName)) { tooltipFormat = tr("Default: %1, %2"); - double paramDefValue = paramDataModel->getParamDefault(parameterName); + double paramDefValue = paramMgr->dataModel()->getParamDefault(parameterName); tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc); } else { @@ -396,22 +381,21 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para } } - return paramItem; + return paramItem; } void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column) { - if (paramItem && column > 0) { QString key = paramItem->data(0, Qt::DisplayRole).toString(); //qDebug() << "parameterItemChanged:" << key << "with updatingParamNameLock:" << updatingParamNameLock; if (key == updatingParamNameLock) { - //qDebug() << "parameterItemChanged ignoring parameterItemChanged" << key; + //qDebug() << "parameterItemChanged ignoring bounce from " << key; return; } else { @@ -427,7 +411,7 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column QVariant value = paramItem->data(1, Qt::DisplayRole); - bool pending = paramDataModel->updatePendingParamWithValue(componentId,key,value); + bool pending = paramMgr->dataModel()->updatePendingParamWithValue(componentId,key,value); // If the value will result in an update if (pending) { @@ -438,7 +422,7 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); } else { - QMap* pendingParams = paramDataModel->getPendingParamsForComponent(componentId); + QMap* pendingParams = paramMgr->dataModel()->getPendingParamsForComponent(componentId); int pendingCount = pendingParams->count(); statusLabel->setText(tr("Pending items: %1").arg(pendingCount)); paramItem->setBackground(0, Qt::NoBrush); @@ -456,89 +440,25 @@ void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column } - -void QGCParamWidget::saveParametersToFile() -{ - if (!mav) return; - QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "./parameters.txt", tr("Parameter File (*.txt)")); - QFile file(fileName); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - return; - } - - QTextStream outstream(&file); - paramDataModel->writeOnboardParamsToStream(outstream,mav->getUASName()); - file.close(); -} - - -void QGCParamWidget::loadParametersFromFile() -{ - if (!mav) return; - QString fileName = QFileDialog::getOpenFileName(this, tr("Load File"), ".", tr("Parameter file (*.txt)")); - QFile file(fileName); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - return; - - QTextStream in(&file); - paramDataModel->readUpdateParamsFromStream(in); - file.close(); -} - void QGCParamWidget::setParameterStatusMsg(const QString& msg) { statusLabel->setText(msg); } -void QGCParamWidget::requestAllParamsUpdate() -{ - if (!mav) { - return; - } - - // Clear view and request param list - clear(); - //paramDataModel->forgetAllOnboardParameters(); //TODO really?? - - requestParameterList(); -} - - -/** - * Write the current onboard parameters from RAM into - * permanent storage, e.g. EEPROM or harddisk - */ -void QGCParamWidget::writeParameters() +void QGCParamWidget::clearOnboardParamDisplay() { - int changedParamCount = paramDataModel->countPendingParams(); - - if (changedParamCount > 0) { - QMessageBox msgBox; - msgBox.setText(tr("There are locally changed parameters. Please transmit them first () or update them with the onboard values () before storing onboard from RAM to ROM.")); - msgBox.exec(); - } - else { - paramCommsMgr->writeParamsToPersistentStorage(); - } -} - - -void QGCParamWidget::readParameters() -{ - if (!mav) return; - mav->readParametersFromStorage(); //TODO use data model / mgr instead? + tree->clear(); + componentItems->clear(); } -/** - * Clear all data in the parameter widget - */ -void QGCParamWidget::clear() +void QGCParamWidget::clearPendingParamDisplay() { tree->clear(); componentItems->clear(); } + void QGCParamWidget::handleParamStatusMsgUpdate(QString msg, int level) { QColor bgColor = QGC::colorGreen; @@ -553,5 +473,4 @@ void QGCParamWidget::handleParamStatusMsgUpdate(QString msg, int level) pal.setColor(backgroundRole(), bgColor); statusLabel->setPalette(pal); statusLabel->setText(msg); - } diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index f23a627d33..e009d50828 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -37,64 +37,54 @@ This file is part of the QGROUNDCONTROL project #include #include -#include "QGCUASParamManager.h" -#include "UASInterface.h" +#include "QGCBaseParamWidget.h" + + +//forward declarations +class UASInterface; /** * @brief Widget to read/set onboard parameters */ -class QGCParamWidget : public QGCUASParamManager +class QGCParamWidget : public QGCBaseParamWidget { Q_OBJECT public: - QGCParamWidget(UASInterface* uas, QWidget *parent = 0); - virtual void init(); ///< Two-stage construction: initialize the object + QGCParamWidget(QWidget *parent = 0); protected: virtual void setParameterStatusMsg(const QString& msg); virtual void layoutWidget();///< Layout the appearance of this widget - virtual void connectSignalsAndSlots();///< Connect signals/slots as needed + virtual void connectViewSignalsAndSlots();///< Connect view signals/slots as needed + virtual void disconnectViewSignalsAndSlots();///< Connect view signals/slots as needed + virtual QTreeWidgetItem* getParentWidgetItemForParam(int compId, const QString& paramName); virtual QTreeWidgetItem* findChildWidgetItemForParam(QTreeWidgetItem* parentItem, const QString& paramName); - -signals: - - -public slots: - /** @brief Add a component to the list + /** @brief Add a component item as a child of this widget * @param compId Component id of the component * @param compName Human friendly name of the component */ void addComponentItem(int compId, QString compName); +signals: - virtual void handleParameterUpdate(int component,const QString& parameterName, QVariant value); - virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); - - virtual void handleParameterListUpToDate(); +public slots: + virtual void handleOnboardParamUpdate(int component,const QString& parameterName, QVariant value); + virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); + virtual void handleOnboardParameterListUpToDate(); virtual void handleParamStatusMsgUpdate(QString msg, int level); + virtual void clearOnboardParamDisplay(); + virtual void clearPendingParamDisplay(); + /** @brief Ensure that view of parameter matches data in the model */ QTreeWidgetItem* updateParameterDisplay(int component, QString parameterName, QVariant value); - /** @brief Request list of parameters from MAV */ - void requestAllParamsUpdate(); - - /** @brief Write the current parameters to permanent storage (EEPROM/HDD) */ - void writeParameters(); - /** @brief Read the parameters from permanent storage to RAM */ - void readParameters(); - /** @brief Clear the parameter list */ - void clear(); - /** @brief Update when user changes parameters */ - void parameterItemChanged(QTreeWidgetItem* prev, int column); - /** @brief Store parameters to a file */ - void saveParametersToFile(); - /** @brief Load parameters from a file */ - void loadParametersFromFile(); + /** @brief Update when user changes parameters */ + void parameterItemChanged(QTreeWidgetItem* prev, int column); protected: @@ -102,7 +92,6 @@ protected: QLabel* statusLabel; ///< User-facing parameter status label QMap* componentItems; ///< The tree of component items, stored by component ID QMap* > paramGroups; ///< Parameter groups to organize component items - QString updatingParamNameLock; ///< Name of param currently being updated-- used for reducing echo on param change }; diff --git a/src/ui/QGCPendingParamWidget.cc b/src/ui/QGCPendingParamWidget.cc index 57ee57d5db..3230583e02 100644 --- a/src/ui/QGCPendingParamWidget.cc +++ b/src/ui/QGCPendingParamWidget.cc @@ -5,31 +5,48 @@ QGCPendingParamWidget::QGCPendingParamWidget(QObject *parent) : - QGCParamWidget(UASManager::instance()->getActiveUAS(),(QWidget*)parent) + QGCParamWidget((QWidget*)parent) { } -void QGCPendingParamWidget::init() +void QGCPendingParamWidget::connectToParamManager() { - //we override a lot of the super's init methods - layoutWidget(); - connectSignalsAndSlots(); + //TODO route via paramManager instead? + // Listen to updated param signals from the data model + connect(paramMgr->dataModel(), SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), + this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); - //don't request update params here...assume that everything we need is in the data model + // Listen to communications status messages so we can display them + connect(paramMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), + this, SLOT(handleParamStatusMsgUpdate(QString , int ))); } -void QGCPendingParamWidget::connectSignalsAndSlots() + +void QGCPendingParamWidget::disconnectFromParamManager() { - // Listing for pending list update - connect(paramDataModel, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), + //TODO route via paramManager instead? + // Listen to updated param signals from the data model + disconnect(paramMgr->dataModel(), SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); // Listen to communications status messages so we can display them - connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), + disconnect(paramMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), this, SLOT(handleParamStatusMsgUpdate(QString , int ))); } + +void QGCPendingParamWidget::disconnectViewSignalsAndSlots() +{ + //we ignore edits from the tree view +} + + +void QGCPendingParamWidget::connectViewSignalsAndSlots() +{ + //we ignore edits from the tree view +} + void QGCPendingParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) { // qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock; diff --git a/src/ui/QGCPendingParamWidget.h b/src/ui/QGCPendingParamWidget.h index 4c6e7370c4..27e53f1d84 100644 --- a/src/ui/QGCPendingParamWidget.h +++ b/src/ui/QGCPendingParamWidget.h @@ -10,11 +10,13 @@ class QGCPendingParamWidget : public QGCParamWidget public: explicit QGCPendingParamWidget(QObject* parent); - virtual void init(); ///< Two-stage construction: initialize the object protected: - virtual void connectSignalsAndSlots(); + virtual void connectToParamManager(); + virtual void disconnectFromParamManager(); + virtual void connectViewSignalsAndSlots(); + virtual void disconnectViewSignalsAndSlots(); signals: diff --git a/src/ui/QGCVehicleConfig.cc b/src/ui/QGCVehicleConfig.cc index d3cf955836..171c83ce80 100644 --- a/src/ui/QGCVehicleConfig.cc +++ b/src/ui/QGCVehicleConfig.cc @@ -788,10 +788,12 @@ void QGCVehicleConfig::loadConfig() xml.readNext(); } - mav->getParamManager()->setParamDescriptions(paramTooltips); + if (!paramTooltips.isEmpty()) { + paramMgr->setParamDescriptions(paramTooltips); + } doneLoadingConfig = true; //Config is finished, lets do a parameter request to ensure none are missed if someone else started requesting before we were finished. - mav->getParamCommsMgr()->requestParameterListIfEmpty(); + paramMgr->requestParameterListIfEmpty(); } void QGCVehicleConfig::setActiveUAS(UASInterface* active) @@ -862,6 +864,7 @@ void QGCVehicleConfig::setActiveUAS(UASInterface* active) // Connect new system mav = active; + paramMgr = mav->getParamManager(); // Reset current state resetCalibrationRC(); @@ -977,15 +980,14 @@ void QGCVehicleConfig::writeCalibrationRC() void QGCVehicleConfig::requestCalibrationRC() { - if (mav) { - mav->getParamCommsMgr()->requestRcCalibrationParamsUpdate(); - } + paramMgr->requestRcCalibrationParamsUpdate(); } void QGCVehicleConfig::writeParameters() { updateStatus(tr("Writing all onboard parameters.")); writeCalibrationRC(); + mav->writeParametersToStorage(); } diff --git a/src/ui/QGCVehicleConfig.h b/src/ui/QGCVehicleConfig.h index 4db21ed1c8..d63e32f4fe 100644 --- a/src/ui/QGCVehicleConfig.h +++ b/src/ui/QGCVehicleConfig.h @@ -158,6 +158,7 @@ protected slots: protected: bool doneLoadingConfig; UASInterface* mav; ///< The current MAV + QGCUASParamManager* paramMgr; ///< params mgr for the mav static const unsigned int chanMax = 8; ///< Maximum number of channels unsigned int chanCount; ///< Actual channels int rcType; ///< Type of the remote control diff --git a/src/ui/designer/QGCComboBox.cc b/src/ui/designer/QGCComboBox.cc index 01ca3881b8..c5ae6a4b59 100644 --- a/src/ui/designer/QGCComboBox.cc +++ b/src/ui/designer/QGCComboBox.cc @@ -17,7 +17,7 @@ QGCComboBox::QGCComboBox(QWidget *parent) : parameterScalingFactor(0.0), parameterMin(0.0f), parameterMax(0.0f), - component(0), + componentId(0), ui(new Ui::QGCComboBox) { ui->setupUi(this); @@ -56,7 +56,7 @@ QGCComboBox::QGCComboBox(QWidget *parent) : //connect(ui->intValueSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setParamValue(int))); connect(ui->editNameLabel, SIGNAL(textChanged(QString)), ui->nameLabel, SLOT(setText(QString))); connect(ui->readButton, SIGNAL(clicked()), this, SLOT(requestParameter())); - connect(ui->editRefreshParamsButton, SIGNAL(clicked()), this, SLOT(refreshParamList())); + connect(ui->editRefreshParamsButton, SIGNAL(clicked()), this, SLOT(refreshParameter())); connect(ui->editInfoCheckBox, SIGNAL(clicked(bool)), this, SLOT(showInfo(bool))); // connect to self connect(ui->infoLabel, SIGNAL(released()), this, SLOT(showTooltip())); @@ -82,14 +82,13 @@ void QGCComboBox::showTooltip() } } -void QGCComboBox::refreshParamList() +void QGCComboBox::refreshParameter() { ui->editSelectParamComboBox->setEnabled(true); ui->editSelectComponentComboBox->setEnabled(true); - if (uas) - { - uas->getParamManager()->requestParameterList(); - ui->editStatusLabel->setText(tr("Parameter list updating..")); + if (uas && !parameterName.isEmpty()) { + uas->getParamManager()->requestParameterUpdate(componentId,parameterName); + ui->editStatusLabel->setText(tr("Requesting refresh...")); } } @@ -105,11 +104,12 @@ void QGCComboBox::setActiveUAS(UASInterface* activeUas) // Connect buttons and signals connect(activeUas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant)), Qt::UniqueConnection); uas = activeUas; + paramMgr = uas->getParamManager(); // Update current param value //requestParameter(); // Set param info - QString text = uas->getParamDataModel()->getParamDescription(parameterName); + QString text = paramMgr->dataModel()->getParamDescription(parameterName); if (!text.isEmpty()) { ui->infoLabel->setToolTip(text); ui->infoLabel->show(); @@ -125,7 +125,7 @@ void QGCComboBox::requestParameter() { if (!parameterName.isEmpty() && uas) { - uas->getParamManager()->requestParameterUpdate(this->component, this->parameterName); + paramMgr->requestParameterUpdate(this->componentId, this->parameterName); } } @@ -137,7 +137,7 @@ void QGCComboBox::showInfo(bool enable) void QGCComboBox::selectComponent(int componentIndex) { - this->component = ui->editSelectComponentComboBox->itemData(componentIndex).toInt(); + this->componentId = ui->editSelectComponentComboBox->itemData(componentIndex).toInt(); } void QGCComboBox::selectParameter(int paramIndex) @@ -147,7 +147,7 @@ void QGCComboBox::selectParameter(int paramIndex) // Update min and max values if available if (uas) { - UASParameterDataModel* dataModel = uas->getParamDataModel(); + UASParameterDataModel* dataModel = paramMgr->dataModel(); if (dataModel) { // Minimum if (dataModel->isParamMinKnown(parameterName)) { @@ -236,7 +236,7 @@ void QGCComboBox::endEditMode() void QGCComboBox::setParamPending() { if (uas) { - uas->getParamManager()->setPendingParam(component, parameterName, parameterValue); + uas->getParamManager()->setPendingParam(componentId, parameterName, parameterValue); } else { qWarning() << __FILE__ << __LINE__ << "NO UAS SET, DOING NOTHING"; @@ -292,7 +292,7 @@ void QGCComboBox::setParameterValue(int uas, int component, int paramCount, int { if (visibleVal == value.toInt()) { - this->uas->requestParameter(this->component,this->parameterName); + this->uas->requestParameter(this->componentId,this->parameterName); visibleEnabled = true; this->show(); } @@ -307,7 +307,7 @@ void QGCComboBox::setParameterValue(int uas, int component, int paramCount, int } } } - if (component == this->component && parameterName == this->parameterName) + if (component == this->componentId && parameterName == this->parameterName) { if (!visibleEnabled) { @@ -350,7 +350,7 @@ void QGCComboBox::writeSettings(QSettings& settings) settings.setValue("QGC_PARAM_COMBOBOX_DESCRIPTION", ui->nameLabel->text()); //settings.setValue("QGC_PARAM_COMBOBOX_BUTTONTEXT", ui->actionButton->text()); settings.setValue("QGC_PARAM_COMBOBOX_PARAMID", parameterName); - settings.setValue("QGC_PARAM_COMBOBOX_COMPONENTID", component); + settings.setValue("QGC_PARAM_COMBOBOX_COMPONENTID", componentId); settings.setValue("QGC_PARAM_COMBOBOX_DISPLAY_INFO", ui->editInfoCheckBox->isChecked()); settings.setValue("QGC_PARAM_COMBOBOX_COUNT", ui->editOptionComboBox->count()); @@ -364,7 +364,7 @@ void QGCComboBox::writeSettings(QSettings& settings) void QGCComboBox::readSettings(const QString& pre,const QVariantMap& settings) { parameterName = settings.value(pre + "QGC_PARAM_COMBOBOX_PARAMID").toString(); - component = settings.value(pre + "QGC_PARAM_COMBOBOX_COMPONENTID").toInt(); + componentId = settings.value(pre + "QGC_PARAM_COMBOBOX_COMPONENTID").toInt(); ui->nameLabel->setText(settings.value(pre + "QGC_PARAM_COMBOBOX_DESCRIPTION").toString()); ui->editNameLabel->setText(settings.value(pre + "QGC_PARAM_COMBOBOX_DESCRIPTION").toString()); //settings.setValue("QGC_PARAM_SLIDER_BUTTONTEXT", ui->actionButton->text()); diff --git a/src/ui/designer/QGCComboBox.h b/src/ui/designer/QGCComboBox.h index ecc71126b5..9b4b9c68a5 100644 --- a/src/ui/designer/QGCComboBox.h +++ b/src/ui/designer/QGCComboBox.h @@ -7,6 +7,8 @@ #include "QGCToolWidgetItem.h" +class QGCUASParamManager; + namespace Ui { class QGCComboBox; @@ -26,11 +28,12 @@ public slots: /** @brief Queue parameter for sending to the MAV (add to pending list)*/ void setParamPending(); /** @brief Update the UI with the new parameter value */ - void setParameterValue(int uas, int component, int paramCount, int paramIndex, QString parameterName, const QVariant value); + void setParameterValue(int uas, int componentId, int paramCount, int paramIndex, QString parameterName, const QVariant value); void writeSettings(QSettings& settings); void readSettings(const QString& pre,const QVariantMap& settings); void readSettings(const QSettings& settings); - void refreshParamList(); + /** @brief request that the parameter for this widget be refreshed */ + void refreshParameter(); void setActiveUAS(UASInterface *uas); void selectComponent(int componentIndex); void selectParameter(int paramIndex); @@ -49,6 +52,7 @@ protected slots: /** @brief Updates current parameter based on new combobox value */ void comboBoxIndexChanged(QString val); protected: + QGCUASParamManager *paramMgr; ///< Access to parameter manager bool visibleEnabled; QString visibleParam; int visibleVal; @@ -61,7 +65,7 @@ protected: float parameterMin; bool isDisabled; float parameterMax; - int component; ///< ID of the MAV component to address + int componentId; ///< ID of the MAV component to address //double scaledInt; void changeEvent(QEvent *e); diff --git a/src/ui/designer/QGCParamSlider.cc b/src/ui/designer/QGCParamSlider.cc index 54b3bd723e..b6b0dd3589 100644 --- a/src/ui/designer/QGCParamSlider.cc +++ b/src/ui/designer/QGCParamSlider.cc @@ -116,7 +116,7 @@ void QGCParamSlider::setActiveUAS(UASInterface* activeUas) } if (uas && !parameterName.isEmpty()) { - QString text = uas->getParamDataModel()->getParamDescription(parameterName); + QString text = uas->getParamManager()->dataModel()->getParamDescription(parameterName); if (!text.isEmpty()) { ui->infoLabel->setToolTip(text); ui->infoLabel->show(); @@ -190,7 +190,7 @@ void QGCParamSlider::selectParameter(int paramIndex) // Update min and max values if available if (uas) { - UASParameterDataModel* dataModel = uas->getParamDataModel(); + UASParameterDataModel* dataModel = uas->getParamManager()->dataModel(); if (dataModel) { // Minimum if (dataModel->isParamMinKnown(parameterName)) { -- GitLab From f1b832687fb81bd16fc5f250a79ac9418f9229f0 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 15 Aug 2013 18:24:50 -0700 Subject: [PATCH 273/460] Fix instance initialization --- src/ui/QGCBaseParamWidget.cc | 3 +++ src/ui/QGCPX4VehicleConfig.cc | 3 ++- src/ui/QGCParamWidget.cc | 9 +++++---- src/ui/QGCParamWidget.h | 4 ++-- src/ui/QGCPendingParamWidget.cc | 3 +++ 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/ui/QGCBaseParamWidget.cc b/src/ui/QGCBaseParamWidget.cc index b7c3891580..f7ba8c9142 100644 --- a/src/ui/QGCBaseParamWidget.cc +++ b/src/ui/QGCBaseParamWidget.cc @@ -45,6 +45,7 @@ void QGCBaseParamWidget::setUAS(UASInterface* uas) void QGCBaseParamWidget::connectToParamManager() { + paramMgr = mav->getParamManager(); //TODO route via paramManager instead? // Listen to updated param signals from the data model connect(paramMgr->dataModel(), SIGNAL(parameterUpdated(int, QString , QVariant )), @@ -77,6 +78,8 @@ void QGCBaseParamWidget::disconnectFromParamManager() // Listen to communications status messages so we can display them disconnect(paramMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), this, SLOT(handleParamStatusMsgUpdate(QString , int ))); + + paramMgr = NULL; } diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index bddc235b32..c0de45aa0a 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -84,7 +84,8 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : //connect(ui->setTrimButton, SIGNAL(clicked()), this, SLOT(setTrimPositions())); //TODO connect buttons here to save/clear actions? - ui->pendingCommitsWidget->initWithUAS(this->mav); + mav = UASManager::instance()->getActiveUAS(); + ui->pendingCommitsWidget->initWithUAS(mav); ui->pendingCommitsWidget->update(); //TODO the following methods are not yet implemented diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 5c095b3bdb..97b0b94adc 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -51,9 +51,12 @@ This file is part of the QGROUNDCONTROL project */ QGCParamWidget::QGCParamWidget(QWidget *parent) : QGCBaseParamWidget(parent), - componentItems(new QMap()) + componentItems(new QMap()), + statusLabel(new QLabel(this)), + tree(new QTreeWidget(this)) { + } @@ -75,9 +78,7 @@ void QGCParamWidget::connectViewSignalsAndSlots() void QGCParamWidget::layoutWidget() { - // Create tree widget - tree = new QTreeWidget(this); - statusLabel = new QLabel(); + statusLabel->setAutoFillBackground(true); // Set tree widget as widget onto this component diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index e009d50828..3fc34214c0 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -88,10 +88,10 @@ public slots: protected: - QTreeWidget* tree; ///< The parameter tree - QLabel* statusLabel; ///< User-facing parameter status label QMap* componentItems; ///< The tree of component items, stored by component ID QMap* > paramGroups; ///< Parameter groups to organize component items + QLabel* statusLabel; ///< User-facing parameter status label + QTreeWidget* tree; ///< The parameter tree }; diff --git a/src/ui/QGCPendingParamWidget.cc b/src/ui/QGCPendingParamWidget.cc index 3230583e02..a37e20c7b4 100644 --- a/src/ui/QGCPendingParamWidget.cc +++ b/src/ui/QGCPendingParamWidget.cc @@ -12,6 +12,7 @@ QGCPendingParamWidget::QGCPendingParamWidget(QObject *parent) : void QGCPendingParamWidget::connectToParamManager() { + paramMgr = mav->getParamManager(); //TODO route via paramManager instead? // Listen to updated param signals from the data model connect(paramMgr->dataModel(), SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), @@ -33,6 +34,8 @@ void QGCPendingParamWidget::disconnectFromParamManager() // Listen to communications status messages so we can display them disconnect(paramMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), this, SLOT(handleParamStatusMsgUpdate(QString , int ))); + + paramMgr = NULL; } -- GitLab From 5a69605a742efb524a47434b6939e9c0629a9ad5 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 15 Aug 2013 18:55:30 -0700 Subject: [PATCH 274/460] Fix param widget init --- src/ui/QGCBaseParamWidget.cc | 13 ++++++++----- src/ui/QGCPX4VehicleConfig.cc | 11 +++++++++-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/ui/QGCBaseParamWidget.cc b/src/ui/QGCBaseParamWidget.cc index f7ba8c9142..baaa0800ea 100644 --- a/src/ui/QGCBaseParamWidget.cc +++ b/src/ui/QGCBaseParamWidget.cc @@ -20,8 +20,6 @@ QGCBaseParamWidget::QGCBaseParamWidget(QWidget *parent) : QGCBaseParamWidget* QGCBaseParamWidget::initWithUAS(UASInterface *uas) { setUAS(uas); - layoutWidget(); - return this; } @@ -34,11 +32,16 @@ void QGCBaseParamWidget::setUAS(UASInterface* uas) clearOnboardParamDisplay(); clearPendingParamDisplay(); } + mav = uas; - connectToParamManager(); - connectViewSignalsAndSlots(); - paramMgr->requestParameterListIfEmpty(); + if (mav) { + connectToParamManager(); + connectViewSignalsAndSlots(); + layoutWidget(); + + paramMgr->requestParameterListIfEmpty(); + } } diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index c0de45aa0a..1c9b768e4c 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -85,8 +85,13 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : //TODO connect buttons here to save/clear actions? mav = UASManager::instance()->getActiveUAS(); - ui->pendingCommitsWidget->initWithUAS(mav); - ui->pendingCommitsWidget->update(); + if (!mav) { + qWarning() << "No active mav! "; + } + else { + ui->pendingCommitsWidget->initWithUAS(mav); + ui->pendingCommitsWidget->update(); + } //TODO the following methods are not yet implemented @@ -872,6 +877,8 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) paramMgr = mav->getParamManager(); + ui->pendingCommitsWidget->setUAS(mav); + // Reset current state resetCalibrationRC(); //TODO eliminate the separate RC_TYPE call -- GitLab From 1b1e0f502778506ce4851df78ee833c3d03e43fd Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 15 Aug 2013 20:15:46 -0700 Subject: [PATCH 275/460] fix one-stage constructor problem --- src/uas/QGCUASParamManager.cc | 18 ++++++++++++++---- src/uas/QGCUASParamManager.h | 3 ++- src/uas/UAS.cc | 6 +++--- src/uas/UAS.h | 4 ++-- src/uas/UASParameterCommsMgr.cc | 15 +++++++++++---- src/uas/UASParameterCommsMgr.h | 4 +++- src/ui/QGCParamWidget.cc | 22 +++++++++++----------- src/ui/designer/QGCParamSlider.cc | 21 ++++++++------------- src/ui/designer/QGCParamSlider.h | 4 ++-- src/ui/designer/QGCTextLabel.h | 2 +- src/ui/designer/QGCToolWidgetItem.h | 2 +- 11 files changed, 58 insertions(+), 43 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index bfb946732a..beedd5c741 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -7,19 +7,29 @@ #include "UASInterface.h" #include "UASParameterCommsMgr.h" -QGCUASParamManager::QGCUASParamManager(QObject *parent, UASInterface* uas) : +QGCUASParamManager::QGCUASParamManager(QObject *parent) : QObject(parent), - mav(uas), + mav(NULL), paramDataModel(this), paramCommsMgr(NULL) { - paramCommsMgr = new UASParameterCommsMgr(this,mav); - // Load default values and tooltips + +} + +QGCUASParamManager* QGCUASParamManager::initWithUAS(UASInterface* uas) +{ + mav = uas; + + // Load default values and tooltips for data model loadParamMetaInfoCSV(); + paramCommsMgr = new UASParameterCommsMgr(this); + paramCommsMgr->initWithUAS(uas); + connectToCommsMgr(); + return this; } void QGCUASParamManager::connectToCommsMgr() diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index a346bbaa4b..29c1150da4 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -17,7 +17,8 @@ class QGCUASParamManager : public QObject { Q_OBJECT public: - QGCUASParamManager(QObject* parent = 0,UASInterface* uas = 0); + QGCUASParamManager(QObject* parent = 0); + QGCUASParamManager* initWithUAS(UASInterface* uas); /** @brief Get the known, confirmed value of a parameter */ virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 80c0558362..457b294e0b 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -115,8 +115,8 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), nedPosGlobalOffset(0,0,0), nedAttGlobalOffset(0,0,0), - waypointManager(this), + paramMgr(this), #if defined(QGC_PROTOBUF_ENABLED) && defined(QGC_USE_PIXHAWK_MESSAGES) receivedOverlayTimestamp(0.0), @@ -131,8 +131,6 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), lastAttitude(0), paramsOnceRequested(false), - paramManager(this,this), - simulation(0), // The protected members. @@ -217,6 +215,8 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), connect(this, SIGNAL(systemSpecsChanged(int)), this, SLOT(writeSettings())); statusTimeout->start(500); readSettings(); + //need to init paramMgr after readSettings have been loaded, to properly set autopilot and so forth + paramMgr.initWithUAS(this); // Initial signals emit disarmed(); emit armingChanged(false); diff --git a/src/uas/UAS.h b/src/uas/UAS.h index b62a81a6de..0d89a75e33 100644 --- a/src/uas/UAS.h +++ b/src/uas/UAS.h @@ -492,7 +492,7 @@ protected: //COMMENTS FOR TEST UNIT /// PARAMETERS QMap* > parameters; ///< All parameters bool paramsOnceRequested; ///< If the parameter list has been read at least once - QGCUASParamManager paramManager; ///< Parameter manager for this UAS + QGCUASParamManager paramMgr; ///< Parameter manager for this UAS /// SIMULATION QGCHilLink* simulation; ///< Hardware in the loop simulation link @@ -520,7 +520,7 @@ public: /** @brief Get reference to the param manager **/ virtual QGCUASParamManager* getParamManager() { - return ¶mManager; + return ¶mMgr; } /** @brief Get the HIL simulation */ diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 96d7d19ec4..a5ed632ca4 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -7,9 +7,9 @@ #define RC_CAL_CHAN_MAX 8 -UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : +UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent) : QObject(parent), - mav(uas), + mav(NULL), paramDataModel(NULL), transmissionListMode(false), transmissionActive(false), @@ -18,10 +18,16 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : rewriteTimeout(1000), retransmissionBurstRequestSize(5) { + + +} + +UASParameterCommsMgr* UASParameterCommsMgr::initWithUAS(UASInterface* uas) +{ + mav = uas; paramDataModel = mav->getParamManager()->dataModel(); loadParamCommsSettings(); - //Requesting parameters one-by-one from mav connect(this, SIGNAL(parameterUpdateRequestedById(int,int)), mav, SLOT(requestParameter(int,int))); @@ -34,10 +40,11 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent, UASInterface *uas) : connect(mav, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); - //connecto retransmissionTimer + //connect to retransmissionTimer connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick())); + return this; } diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index acdab75a86..1320d7187e 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -18,7 +18,9 @@ class UASParameterCommsMgr : public QObject public: - explicit UASParameterCommsMgr(QObject *parent = 0, UASInterface* uas = NULL); + explicit UASParameterCommsMgr(QObject *parent = 0); + UASParameterCommsMgr* initWithUAS(UASInterface* model);///< Two-stage constructor + ~UASParameterCommsMgr(); typedef enum ParamCommsStatusLevel { diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 97b0b94adc..f01e526de3 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -100,29 +100,29 @@ void QGCParamWidget::layoutWidget() // BUTTONS QPushButton* refreshButton = new QPushButton(tr("Get")); - refreshButton->setToolTip(tr("Load parameters currently in non-permanent memory of aircraft.")); - refreshButton->setWhatsThis(tr("Load parameters currently in non-permanent memory of aircraft.")); + refreshButton->setToolTip(tr("Fetch parameters currently in volatile memory of aircraft.")); + refreshButton->setWhatsThis(tr("Fetch parameters currently in volatile memory of aircraft.")); connect(refreshButton, SIGNAL(clicked()), this, SLOT(requestOnboardParamsUpdate())); horizontalLayout->addWidget(refreshButton, 2, 0); QPushButton* setButton = new QPushButton(tr("Set")); - setButton->setToolTip(tr("Set current parameters in non-permanent onboard memory")); - setButton->setWhatsThis(tr("Set current parameters in non-permanent onboard memory")); + setButton->setToolTip(tr("Send pending parameters to volatile onboard memory")); + setButton->setWhatsThis(tr("Send pending parameters to volatile onboard memory")); connect(setButton, SIGNAL(clicked()), - this, SLOT(sendPendingParameters())); + paramMgr, SLOT(sendPendingParameters())); horizontalLayout->addWidget(setButton, 2, 1); QPushButton* writeButton = new QPushButton(tr("Write (ROM)")); - writeButton->setToolTip(tr("Copy current parameters in non-permanent memory of the aircraft to permanent memory. Transmit your parameters first to write these.")); - writeButton->setWhatsThis(tr("Copy current parameters in non-permanent memory of the aircraft to permanent memory. Transmit your parameters first to write these.")); + writeButton->setToolTip(tr("Copy parameters in volatile memory of the aircraft to persistent memory. Transmit your parameters first to write these.")); + writeButton->setWhatsThis(tr("Copy parameters in volatile memory of the aircraft to persistent memory. Transmit your parameters first to write these.")); connect(writeButton, SIGNAL(clicked()), paramMgr, SLOT(copyVolatileParamsToPersistent())); horizontalLayout->addWidget(writeButton, 2, 2); QPushButton* loadFileButton = new QPushButton(tr("Load File")); - loadFileButton->setToolTip(tr("Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them.")); - loadFileButton->setWhatsThis(tr("Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them.")); + loadFileButton->setToolTip(tr("Load parameters from a file into qgroundcontrol. To write these to the aircraft, use transmit after loading them.")); + loadFileButton->setWhatsThis(tr("Load parameters from a file into qgroundcontrol. To write these to the aircraft, use transmit after loading them.")); connect(loadFileButton, SIGNAL(clicked()), this, SLOT(loadParametersFromFile())); horizontalLayout->addWidget(loadFileButton, 3, 0); @@ -135,8 +135,8 @@ void QGCParamWidget::layoutWidget() horizontalLayout->addWidget(saveFileButton, 3, 1); QPushButton* readButton = new QPushButton(tr("Read (ROM)")); - readButton->setToolTip(tr("Copy parameters from permanent memory to non-permanent current memory of aircraft. DOES NOT update the parameters in this view, click refresh after copying them to get them.")); - readButton->setWhatsThis(tr("Copy parameters from permanent memory to non-permanent current memory of aircraft. DOES NOT update the parameters in this view, click refresh after copying them to get them.")); + readButton->setToolTip(tr("Copy parameters from persistent onboard memory to volatile onboard memory of aircraft. DOES NOT update the parameters in this view: click refresh after copying them to get them.")); + readButton->setWhatsThis(tr("Copy parameters from persistent onboard memory to volatile onboard memory of aircraft. DOES NOT update the parameters in this view: click refresh after copying them to get them.")); connect(readButton, SIGNAL(clicked()), paramMgr, SLOT(copyPersistentParamsToVolatile())); horizontalLayout->addWidget(readButton, 3, 2); diff --git a/src/ui/designer/QGCParamSlider.cc b/src/ui/designer/QGCParamSlider.cc index b6b0dd3589..6331ac7212 100644 --- a/src/ui/designer/QGCParamSlider.cc +++ b/src/ui/designer/QGCParamSlider.cc @@ -17,7 +17,7 @@ QGCParamSlider::QGCParamSlider(QWidget *parent) : parameterScalingFactor(0.0), parameterMin(0.0f), parameterMax(0.0f), - component(0), + componentId(0), ui(new Ui::QGCParamSlider) { valueModLock = false; @@ -133,7 +133,7 @@ void QGCParamSlider::setActiveUAS(UASInterface* activeUas) void QGCParamSlider::requestParameter() { if (uas && !parameterName.isEmpty()) { - uas->getParamManager()->requestParameterUpdate(component, parameterName); + uas->getParamManager()->requestParameterUpdate(componentId, parameterName); } } @@ -177,7 +177,7 @@ void QGCParamSlider::setParamValue(int value) void QGCParamSlider::selectComponent(int componentIndex) { - this->component = ui->editSelectComponentComboBox->itemData(componentIndex).toInt(); + this->componentId = ui->editSelectComponentComboBox->itemData(componentIndex).toInt(); } void QGCParamSlider::selectParameter(int paramIndex) @@ -280,7 +280,7 @@ void QGCParamSlider::endEditMode() void QGCParamSlider::setParamPending() { if (uas) { - uas->getParamManager()->setPendingParam(component, parameterName, parameterValue); + uas->getParamManager()->setPendingParam(componentId, parameterName, parameterValue); } else { qWarning() << __FILE__ << __LINE__ << "NO UAS SET, DOING NOTHING"; @@ -380,7 +380,7 @@ void QGCParamSlider::setParameterValue(int uasId, int compId, int paramCount, in } } Q_UNUSED(uas); - if (compId == this->component && paramName == this->parameterName) { + if (compId == this->componentId && paramName == this->parameterName) { if (!visibleEnabled) { return; } @@ -487,7 +487,7 @@ void QGCParamSlider::writeSettings(QSettings& settings) settings.setValue("QGC_PARAM_SLIDER_DESCRIPTION", ui->nameLabel->text()); //settings.setValue("QGC_PARAM_SLIDER_BUTTONTEXT", ui->actionButton->text()); settings.setValue("QGC_PARAM_SLIDER_PARAMID", parameterName); - settings.setValue("QGC_PARAM_SLIDER_COMPONENTID", component); + settings.setValue("QGC_PARAM_SLIDER_COMPONENTID", componentId); settings.setValue("QGC_PARAM_SLIDER_MIN", ui->editMinSpinBox->value()); settings.setValue("QGC_PARAM_SLIDER_MAX", ui->editMaxSpinBox->value()); settings.setValue("QGC_PARAM_SLIDER_DISPLAY_INFO", ui->editInfoCheckBox->isChecked()); @@ -496,7 +496,7 @@ void QGCParamSlider::writeSettings(QSettings& settings) void QGCParamSlider::readSettings(const QString& pre,const QVariantMap& settings) { parameterName = settings.value(pre + "QGC_PARAM_SLIDER_PARAMID").toString(); - component = settings.value(pre + "QGC_PARAM_SLIDER_COMPONENTID").toInt(); + componentId = settings.value(pre + "QGC_PARAM_SLIDER_COMPONENTID").toInt(); ui->nameLabel->setText(settings.value(pre + "QGC_PARAM_SLIDER_DESCRIPTION").toString()); ui->editNameLabel->setText(settings.value(pre + "QGC_PARAM_SLIDER_DESCRIPTION").toString()); //settings.setValue("QGC_PARAM_SLIDER_BUTTONTEXT", ui->actionButton->text()); @@ -516,9 +516,6 @@ void QGCParamSlider::readSettings(const QString& pre,const QVariantMap& settings ui->editSelectComponentComboBox->setEnabled(true); setActiveUAS(UASManager::instance()->getActiveUAS()); - - // Get param value after settings have been loaded - //requestParameter(); } void QGCParamSlider::readSettings(const QSettings& settings) @@ -532,7 +529,7 @@ void QGCParamSlider::readSettings(const QSettings& settings) readSettings("",map); return; parameterName = settings.value("QGC_PARAM_SLIDER_PARAMID").toString(); - component = settings.value("QGC_PARAM_SLIDER_COMPONENTID").toInt(); + componentId = settings.value("QGC_PARAM_SLIDER_COMPONENTID").toInt(); ui->nameLabel->setText(settings.value("QGC_PARAM_SLIDER_DESCRIPTION").toString()); ui->editNameLabel->setText(settings.value("QGC_PARAM_SLIDER_DESCRIPTION").toString()); //settings.setValue("QGC_PARAM_SLIDER_BUTTONTEXT", ui->actionButton->text()); @@ -552,6 +549,4 @@ void QGCParamSlider::readSettings(const QSettings& settings) setActiveUAS(UASManager::instance()->getActiveUAS()); - // Get param value after settings have been loaded - //requestParameter(); } diff --git a/src/ui/designer/QGCParamSlider.h b/src/ui/designer/QGCParamSlider.h index 3ef78fdf71..74df0db05e 100644 --- a/src/ui/designer/QGCParamSlider.h +++ b/src/ui/designer/QGCParamSlider.h @@ -28,7 +28,7 @@ public slots: /** @brief Set the slider value as parameter value */ void setSliderValue(int sliderValue); /** @brief Update the UI with the new parameter value */ - void setParameterValue(int uas, int component, int paramCount, int paramIndex, QString parameterName, const QVariant value); + void setParameterValue(int uas, int componentId, int paramCount, int paramIndex, QString parameterName, const QVariant value); void writeSettings(QSettings& settings); void readSettings(const QSettings& settings); void readSettings(const QString& pre,const QVariantMap& settings); @@ -62,7 +62,7 @@ protected: double parameterScalingFactor; ///< Factor to scale the parameter between slider and true value float parameterMin; float parameterMax; - int component; ///< ID of the MAV component to address + int componentId; ///< ID of the MAV component to address double scaledInt; void changeEvent(QEvent *e); diff --git a/src/ui/designer/QGCTextLabel.h b/src/ui/designer/QGCTextLabel.h index 67ed0ae638..3828d734fc 100644 --- a/src/ui/designer/QGCTextLabel.h +++ b/src/ui/designer/QGCTextLabel.h @@ -25,7 +25,7 @@ public slots: void writeSettings(QSettings& settings); void readSettings(const QSettings& settings); void readSettings(const QString& pre,const QVariantMap& settings); - void textMessageReceived(int uasid, int component, int severity, QString message); + void textMessageReceived(int uasid, int componentId, int severity, QString message); private: int enabledNum; Ui::QGCTextLabel *ui; diff --git a/src/ui/designer/QGCToolWidgetItem.h b/src/ui/designer/QGCToolWidgetItem.h index e0a0cb0a33..ac09123487 100644 --- a/src/ui/designer/QGCToolWidgetItem.h +++ b/src/ui/designer/QGCToolWidgetItem.h @@ -14,7 +14,7 @@ public: QGCToolWidgetItem(const QString& name, QWidget *parent = 0); ~QGCToolWidgetItem(); - int component() { + int componentId() { return _component; } -- GitLab From d6801ac6bb9aab27bab0703fda75a8e4a1dfc17f Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 15 Aug 2013 20:50:20 -0700 Subject: [PATCH 276/460] fix rendering of advanced parameters editors --- src/ui/QGCBaseParamWidget.cc | 34 ++++++++++++++++++---------------- src/ui/QGCPX4VehicleConfig.cc | 18 ++++++++++-------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/ui/QGCBaseParamWidget.cc b/src/ui/QGCBaseParamWidget.cc index baaa0800ea..d80e53693e 100644 --- a/src/ui/QGCBaseParamWidget.cc +++ b/src/ui/QGCBaseParamWidget.cc @@ -25,22 +25,24 @@ QGCBaseParamWidget* QGCBaseParamWidget::initWithUAS(UASInterface *uas) void QGCBaseParamWidget::setUAS(UASInterface* uas) { - if (mav) { - //TODO disconnect any connections as needed - disconnectViewSignalsAndSlots(); - disconnectFromParamManager(); - clearOnboardParamDisplay(); - clearPendingParamDisplay(); - } - - mav = uas; - - if (mav) { - connectToParamManager(); - connectViewSignalsAndSlots(); - layoutWidget(); - - paramMgr->requestParameterListIfEmpty(); + if (uas != mav) { + if (mav) { + //TODO disconnect any connections as needed + disconnectViewSignalsAndSlots(); + disconnectFromParamManager(); + clearOnboardParamDisplay(); + clearPendingParamDisplay(); + } + + mav = uas; + + if (mav) { + connectToParamManager(); + connectViewSignalsAndSlots(); + layoutWidget(); + + paramMgr->requestParameterListIfEmpty(); + } } } diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 1c9b768e4c..2a5772aee8 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -84,15 +84,16 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : //connect(ui->setTrimButton, SIGNAL(clicked()), this, SLOT(setTrimPositions())); //TODO connect buttons here to save/clear actions? - mav = UASManager::instance()->getActiveUAS(); - if (!mav) { - qWarning() << "No active mav! "; - } - else { - ui->pendingCommitsWidget->initWithUAS(mav); + UASInterface* tmpMav = UASManager::instance()->getActiveUAS(); + if (tmpMav) { + ui->pendingCommitsWidget->initWithUAS(tmpMav); ui->pendingCommitsWidget->update(); + setActiveUAS(tmpMav); } + connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), + this, SLOT(setActiveUAS(UASInterface*))); + //TODO the following methods are not yet implemented // Connect RC mapping assignments @@ -115,9 +116,9 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : // connect(ui->invertCheckBox_7, SIGNAL(clicked(bool)), this, SLOT(setAux2Inverted(bool))); // connect(ui->invertCheckBox_8, SIGNAL(clicked(bool)), this, SLOT(setAux3Inverted(bool))); - connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); - setActiveUAS(UASManager::instance()->getActiveUAS()); + + for (unsigned int i = 0; i < chanMax; i++) { rcValue[i] = UINT16_MAX; @@ -1248,6 +1249,7 @@ void QGCPX4VehicleConfig::parameterChanged(int uas, int component, QString param return; } + //TODO this may introduce a bug with param editor widgets not receiving param updates if (parameterName.startsWith("RC")) { handleRcParameterChange(parameterName,value); return; -- GitLab From 4646c6818a579eef1778f1daa77b212bc3d9fd86 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 15 Aug 2013 21:51:57 -0700 Subject: [PATCH 277/460] Cleanup buttons in px4config; impl clearing pending list --- src/uas/QGCUASParamManager.cc | 12 +++--- src/uas/QGCUASParamManager.h | 7 +++- src/uas/UASParameterDataModel.cc | 16 +++++++- src/uas/UASParameterDataModel.h | 4 +- src/ui/QGCPX4VehicleConfig.cc | 20 ++++++--- src/ui/QGCPX4VehicleConfig.ui | 69 +++++++------------------------- src/ui/QGCParamWidget.cc | 68 ++++++++++++++++--------------- src/ui/QGCParamWidget.h | 4 ++ src/ui/QGCPendingParamWidget.cc | 22 ++++++++++ src/ui/QGCPendingParamWidget.h | 4 ++ 10 files changed, 125 insertions(+), 101 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index beedd5c741..d62244e552 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -1,6 +1,6 @@ #include "QGCUASParamManager.h" -#include > +#include #include #include @@ -27,28 +27,30 @@ QGCUASParamManager* QGCUASParamManager::initWithUAS(UASInterface* uas) paramCommsMgr = new UASParameterCommsMgr(this); paramCommsMgr->initWithUAS(uas); - connectToCommsMgr(); + connectToModelAndComms(); return this; } -void QGCUASParamManager::connectToCommsMgr() +void QGCUASParamManager::connectToModelAndComms() { - // Pass along comms mgr status msgs connect(paramCommsMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), this, SIGNAL(parameterStatusMsgUpdated(QString,int))); connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), this, SIGNAL(parameterListUpToDate())); +} +void QGCUASParamManager::clearAllPendingParams() +{ + paramDataModel.clearAllPendingParams(); } - bool QGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const { return paramDataModel.getOnboardParamValue(component,parameter,value); diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 29c1150da4..f4598db0af 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -39,7 +39,7 @@ protected: /** @brief Load parameter meta information from appropriate CSV file */ virtual void loadParamMetaInfoCSV(); - void connectToCommsMgr(); + void connectToModelAndComms(); signals: @@ -49,6 +49,8 @@ signals: /** @brief We have received a complete list of all parameters onboard the MAV */ void parameterListUpToDate(); + + public slots: /** @brief Send one parameter to the MAV: changes value in transient memory of MAV */ virtual void setParameter(int component, QString parameterName, QVariant value); @@ -64,6 +66,9 @@ public slots: virtual void setPendingParam(int componentId, QString& key, const QVariant& value); + /** @brief remove all params from the pending list */ + virtual void clearAllPendingParams(); + /** @brief Request a single parameter by name from the MAV */ virtual void requestParameterUpdate(int component, const QString& parameter); diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 012749f659..5ecb37db89 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -87,7 +87,7 @@ void UASParameterDataModel::setPendingParam(int compId, QString& key, const QVa } } -void UASParameterDataModel::removePendingParam(int compId, QString& key) +void UASParameterDataModel::removePendingParam(int compId, const QString& key) { qDebug() << "removePendingParam:" << key; @@ -197,6 +197,20 @@ void UASParameterDataModel::forgetAllOnboardParams() onboardParameters.clear(); } +void UASParameterDataModel::clearAllPendingParams() +{ + QList compIds = pendingParameters.keys(); + foreach (int compId , compIds) { + QMap* compParams = pendingParameters.value(compId); + QList paramNames = compParams->keys(); + foreach (QString paramName, paramNames) { + //remove this item from pending status and broadcast update + removePendingParam(compId,paramName); + } + } + +} + void UASParameterDataModel::readUpdateParamsFromStream( QTextStream& stream) { bool userWarned = false; diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 40c6cead10..738e9c36e5 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -43,6 +43,7 @@ public: virtual void forgetAllOnboardParams(); + /** @brief add this parameter to pending list iff it has changed from onboard value * @return true if the parameter is now pending */ @@ -88,7 +89,7 @@ protected: /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ virtual void setPendingParam(int componentId, QString& key, const QVariant& value); /** @brief remove a parameter from the pending list */ - virtual void removePendingParam(int compId, QString& key); + virtual void removePendingParam(int compId, const QString &key); signals: @@ -103,6 +104,7 @@ signals: public slots: + virtual void clearAllPendingParams(); protected: int uasId; ///< The UAS / MAV to which this data model pertains diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 2a5772aee8..c87306f9c5 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -79,7 +79,9 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : ui->rcCalibrationButton->setCheckable(true); connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool))); - connect(ui->setButton, SIGNAL(clicked()), this, SLOT(writeParameters())); + connect(ui->writeButton, SIGNAL(clicked()), + this, SLOT(writeParameters())); + connect(ui->rcModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setRCModeIndex(int))); //connect(ui->setTrimButton, SIGNAL(clicked()), this, SLOT(setTrimPositions())); @@ -816,14 +818,16 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) { // Hide items if NULL and abort if (!active) { - ui->setButton->setEnabled(false); ui->refreshButton->setEnabled(false); - ui->readButton->show(); + ui->refreshButton->show(); ui->readButton->setEnabled(false); - ui->writeButton->show(); + ui->readButton->show(); ui->writeButton->setEnabled(false); + ui->writeButton->show(); ui->loadFileButton->setEnabled(false); + ui->loadFileButton->show(); ui->saveFileButton->setEnabled(false); + ui->saveFileButton->show(); return; } @@ -918,12 +922,18 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) updateStatus(QString("Reading from system %1").arg(mav->getUASName())); // Since a system is now connected, enable the VehicleConfig UI. - ui->setButton->setEnabled(true); ui->refreshButton->setEnabled(true); + ui->refreshButton->show(); ui->readButton->setEnabled(true); + ui->readButton->show(); ui->writeButton->setEnabled(true); + ui->writeButton->show(); ui->loadFileButton->setEnabled(true); + ui->loadFileButton->show(); ui->saveFileButton->setEnabled(true); + ui->saveFileButton->show(); + + //TODO never true? if (mav->getAutopilotTypeName() == "ARDUPILOTMEGA") { ui->readButton->hide(); ui->writeButton->hide(); diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index b153d7391a..fd13f905e2 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -817,8 +817,8 @@ p, li { white-space: pre-wrap; } 0 0 - 26 - 26 + 98 + 28 @@ -906,8 +906,8 @@ p, li { white-space: pre-wrap; } 0 0 - 16 - 16 + 98 + 28 @@ -943,8 +943,8 @@ p, li { white-space: pre-wrap; } 0 0 - 16 - 16 + 98 + 28 @@ -1103,6 +1103,13 @@ p, li { white-space: pre-wrap; }
+ + + + Load File + + + @@ -1163,7 +1170,7 @@ p, li { white-space: pre-wrap; } 601 - + 0 @@ -1180,54 +1187,6 @@ p, li { white-space: pre-wrap; } - - - - false - - - Set current parameters in non-permanent onboard memory. - - - - - - Commit to UAS - - - - - - - false - - - Set current parameters in non-permanent onboard memory. - - - - - - Clear - - - - - - - false - - - Load parameters from a file on this computer in the view. To write them to the aircraft, use transmit after loading them. - - - - - - Load from File - - -
diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index f01e526de3..07cf8fdff9 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -76,79 +76,81 @@ void QGCParamWidget::connectViewSignalsAndSlots() } -void QGCParamWidget::layoutWidget() +void QGCParamWidget::addActionButtonsToLayout(QGridLayout* layout) { - - statusLabel->setAutoFillBackground(true); - - // Set tree widget as widget onto this component - QGridLayout* horizontalLayout; - //form->setAutoFillBackground(false); - horizontalLayout = new QGridLayout(this); - horizontalLayout->setHorizontalSpacing(6); - horizontalLayout->setVerticalSpacing(6); - horizontalLayout->setMargin(0); - horizontalLayout->setSizeConstraint(QLayout::SetMinimumSize); - //horizontalLayout->setSizeConstraint( QLayout::SetFixedSize ); - - // Parameter tree - horizontalLayout->addWidget(tree, 0, 0, 1, 3); - - // Status line - statusLabel->setText(tr("Click refresh to download parameters")); - horizontalLayout->addWidget(statusLabel, 1, 0, 1, 3); - - // BUTTONS QPushButton* refreshButton = new QPushButton(tr("Get")); refreshButton->setToolTip(tr("Fetch parameters currently in volatile memory of aircraft.")); refreshButton->setWhatsThis(tr("Fetch parameters currently in volatile memory of aircraft.")); connect(refreshButton, SIGNAL(clicked()), this, SLOT(requestOnboardParamsUpdate())); - horizontalLayout->addWidget(refreshButton, 2, 0); + layout->addWidget(refreshButton, 2, 0); QPushButton* setButton = new QPushButton(tr("Set")); setButton->setToolTip(tr("Send pending parameters to volatile onboard memory")); setButton->setWhatsThis(tr("Send pending parameters to volatile onboard memory")); connect(setButton, SIGNAL(clicked()), paramMgr, SLOT(sendPendingParameters())); - horizontalLayout->addWidget(setButton, 2, 1); + layout->addWidget(setButton, 2, 1); QPushButton* writeButton = new QPushButton(tr("Write (ROM)")); writeButton->setToolTip(tr("Copy parameters in volatile memory of the aircraft to persistent memory. Transmit your parameters first to write these.")); writeButton->setWhatsThis(tr("Copy parameters in volatile memory of the aircraft to persistent memory. Transmit your parameters first to write these.")); connect(writeButton, SIGNAL(clicked()), paramMgr, SLOT(copyVolatileParamsToPersistent())); - horizontalLayout->addWidget(writeButton, 2, 2); + layout->addWidget(writeButton, 2, 2); QPushButton* loadFileButton = new QPushButton(tr("Load File")); loadFileButton->setToolTip(tr("Load parameters from a file into qgroundcontrol. To write these to the aircraft, use transmit after loading them.")); loadFileButton->setWhatsThis(tr("Load parameters from a file into qgroundcontrol. To write these to the aircraft, use transmit after loading them.")); connect(loadFileButton, SIGNAL(clicked()), this, SLOT(loadParametersFromFile())); - horizontalLayout->addWidget(loadFileButton, 3, 0); + layout->addWidget(loadFileButton, 3, 0); QPushButton* saveFileButton = new QPushButton(tr("Save File")); saveFileButton->setToolTip(tr("Save parameters in this view to a file on this computer.")); saveFileButton->setWhatsThis(tr("Save parameters in this view to a file on this computer.")); connect(saveFileButton, SIGNAL(clicked()), this, SLOT(saveParametersToFile())); - horizontalLayout->addWidget(saveFileButton, 3, 1); + layout->addWidget(saveFileButton, 3, 1); QPushButton* readButton = new QPushButton(tr("Read (ROM)")); readButton->setToolTip(tr("Copy parameters from persistent onboard memory to volatile onboard memory of aircraft. DOES NOT update the parameters in this view: click refresh after copying them to get them.")); readButton->setWhatsThis(tr("Copy parameters from persistent onboard memory to volatile onboard memory of aircraft. DOES NOT update the parameters in this view: click refresh after copying them to get them.")); connect(readButton, SIGNAL(clicked()), paramMgr, SLOT(copyPersistentParamsToVolatile())); - horizontalLayout->addWidget(readButton, 3, 2); + layout->addWidget(readButton, 3, 2); + +} + +void QGCParamWidget::layoutWidget() +{ + + statusLabel->setAutoFillBackground(true); + + QGridLayout* layout = new QGridLayout(this); + layout->setHorizontalSpacing(6); + layout->setVerticalSpacing(6); + layout->setMargin(0); + layout->setSizeConstraint(QLayout::SetMinimumSize); + + // Parameter tree + layout->addWidget(tree, 0, 0, 1, 3); + + // Status line + statusLabel->setText(tr("Click refresh to download parameters")); + layout->addWidget(statusLabel, 1, 0, 1, 3); + + // BUTTONS + addActionButtonsToLayout(layout); // Set correct vertical scaling - horizontalLayout->setRowStretch(0, 100); - horizontalLayout->setRowStretch(1, 10); - horizontalLayout->setRowStretch(2, 10); - horizontalLayout->setRowStretch(3, 10); + layout->setRowStretch(0, 100); + layout->setRowStretch(1, 10); + layout->setRowStretch(2, 10); + layout->setRowStretch(3, 10); // Set layout - this->setLayout(horizontalLayout); + this->setLayout(layout); // Set header QStringList headerItems; diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h index 3fc34214c0..83787de1d4 100644 --- a/src/ui/QGCParamWidget.h +++ b/src/ui/QGCParamWidget.h @@ -41,6 +41,7 @@ This file is part of the QGROUNDCONTROL project //forward declarations +class QGridLayout; class UASInterface; /** @@ -67,6 +68,9 @@ protected: */ void addComponentItem(int compId, QString compName); + virtual void addActionButtonsToLayout(QGridLayout* layout); + + signals: diff --git a/src/ui/QGCPendingParamWidget.cc b/src/ui/QGCPendingParamWidget.cc index a37e20c7b4..c5fb5a010f 100644 --- a/src/ui/QGCPendingParamWidget.cc +++ b/src/ui/QGCPendingParamWidget.cc @@ -1,5 +1,8 @@ #include "QGCPendingParamWidget.h" +#include +#include + #include "UASManager.h" #include "UASParameterCommsMgr.h" @@ -80,3 +83,22 @@ void QGCPendingParamWidget::handlePendingParamUpdate(int compId, const QString& } +void QGCPendingParamWidget::addActionButtonsToLayout(QGridLayout* layout) +{ + + QPushButton* setButton = new QPushButton(tr("Set")); + setButton->setToolTip(tr("Send pending parameters to volatile onboard memory")); + setButton->setWhatsThis(tr("Send pending parameters to volatile onboard memory")); + connect(setButton, SIGNAL(clicked()), + paramMgr, SLOT(sendPendingParameters())); + layout->addWidget(setButton, 2, 0); + + QPushButton* clearButton = new QPushButton(tr("Clear")); + clearButton->setToolTip(tr("Clear pending parameters without sending")); + clearButton->setWhatsThis(tr("Clear pending parameters without sending")); + connect(clearButton, SIGNAL(clicked()), + paramMgr, SLOT(clearAllPendingParams())); + layout->addWidget(clearButton, 2, 1); + + +} diff --git a/src/ui/QGCPendingParamWidget.h b/src/ui/QGCPendingParamWidget.h index 27e53f1d84..31b0d758d8 100644 --- a/src/ui/QGCPendingParamWidget.h +++ b/src/ui/QGCPendingParamWidget.h @@ -4,6 +4,8 @@ #include "QGCParamWidget.h" +class QGridLayout; + class QGCPendingParamWidget : public QGCParamWidget { Q_OBJECT @@ -18,6 +20,8 @@ protected: virtual void connectViewSignalsAndSlots(); virtual void disconnectViewSignalsAndSlots(); + virtual void addActionButtonsToLayout(QGridLayout* layout); + signals: -- GitLab From 82afc8ed6607812fe33b0ed120f423f3cece21c3 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 16 Aug 2013 12:53:36 -0700 Subject: [PATCH 278/460] ensure that pending items are visible across multiple widgets --- src/ui/QGCParamWidget.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc index 07cf8fdff9..a817822385 100644 --- a/src/ui/QGCParamWidget.cc +++ b/src/ui/QGCParamWidget.cc @@ -209,6 +209,8 @@ void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramNa if (isPending) { paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); + //ensure that the adjusted item is visible + tree->expandItem(paramItem->parent()); } else { paramItem->setBackground(0, Qt::NoBrush); @@ -368,6 +370,7 @@ QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString para else { paramItem->setData(1, Qt::DisplayRole, value); } + } if (paramItem) { -- GitLab From f1b68b50936def6d325b9e841204a0803bf7b09c Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 16 Aug 2013 13:02:34 -0700 Subject: [PATCH 279/460] hide Status and Actions widgets for now --- src/ui/QGCTabbedInfoView.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ui/QGCTabbedInfoView.cpp b/src/ui/QGCTabbedInfoView.cpp index 42095760e0..3247548a90 100644 --- a/src/ui/QGCTabbedInfoView.cpp +++ b/src/ui/QGCTabbedInfoView.cpp @@ -4,18 +4,18 @@ QGCTabbedInfoView::QGCTabbedInfoView(QWidget *parent) : QWidget(parent) { ui.setupUi(this); messageView = new QGCMessageView(this); - actionsWidget = new UASActionsWidget(this); + //actionsWidget = new UASActionsWidget(this); quickView = new UASQuickView(this); - rawView = new UASRawStatusView(this); + //rawView = new UASRawStatusView(this); ui.tabWidget->addTab(quickView,"Quick"); - ui.tabWidget->addTab(actionsWidget,"Actions"); - ui.tabWidget->addTab(rawView,"Status"); + //ui.tabWidget->addTab(actionsWidget,"Actions"); + //ui.tabWidget->addTab(rawView,"Status"); ui.tabWidget->addTab(messageView,"Messages"); } void QGCTabbedInfoView::addSource(MAVLinkDecoder *decoder) { m_decoder = decoder; - rawView->addSource(decoder); + //rawView->addSource(decoder); quickView->addSource(decoder); } -- GitLab From 97d2bf457c1122975da5a9115c89735767d2afca Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 15 Aug 2013 10:30:05 +0200 Subject: [PATCH 280/460] Merged PX4 config widget --- qgroundcontrol.pro | 9 +- .../px4_configuration/QGCPX4AirframeConfig.cc | 14 + .../px4_configuration/QGCPX4AirframeConfig.h | 22 ++ .../px4_configuration/QGCPX4AirframeConfig.ui | 318 ++++++++++++++++++ 4 files changed, 360 insertions(+), 3 deletions(-) create mode 100644 src/ui/px4_configuration/QGCPX4AirframeConfig.cc create mode 100644 src/ui/px4_configuration/QGCPX4AirframeConfig.h create mode 100644 src/ui/px4_configuration/QGCPX4AirframeConfig.ui diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index cf714d579c..cddca39f97 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -269,7 +269,8 @@ FORMS += src/ui/MainWindow.ui \ src/ui/main/QGCWelcomeMainWindow.ui \ src/ui/configuration/terminalconsole.ui \ src/ui/configuration/SerialSettingsDialog.ui \ - src/ui/configuration/ApmFirmwareConfig.ui + src/ui/configuration/ApmFirmwareConfig.ui \ + src/ui/px4_configuration/QGCPX4AirframeConfig.ui INCLUDEPATH += src \ src/ui \ @@ -471,7 +472,8 @@ HEADERS += src/MG.h \ src/ui/configuration/ApmFirmwareConfig.h \ src/uas/UASParameterDataModel.h \ src/uas/UASParameterCommsMgr.h \ - src/ui/QGCPendingParamWidget.h + src/ui/QGCPendingParamWidget.h \ + src/ui/px4_configuration/QGCPX4AirframeConfig.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -689,7 +691,8 @@ SOURCES += src/main.cc \ src/ui/configuration/ApmFirmwareConfig.cc \ src/uas/UASParameterDataModel.cc \ src/uas/UASParameterCommsMgr.cc \ - src/ui/QGCPendingParamWidget.cc + src/ui/QGCPendingParamWidget.cc \ + src/ui/px4_configuration/QGCPX4AirframeConfig.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc new file mode 100644 index 0000000000..6c448b3297 --- /dev/null +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -0,0 +1,14 @@ +#include "QGCPX4AirframeConfig.h" +#include "ui_QGCPX4AirframeConfig.h" + +QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : + QWidget(parent), + ui(new Ui::QGCPX4AirframeConfig) +{ + ui->setupUi(this); +} + +QGCPX4AirframeConfig::~QGCPX4AirframeConfig() +{ + delete ui; +} diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.h b/src/ui/px4_configuration/QGCPX4AirframeConfig.h new file mode 100644 index 0000000000..5cad0cb9d0 --- /dev/null +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.h @@ -0,0 +1,22 @@ +#ifndef QGCPX4AIRFRAMECONFIG_H +#define QGCPX4AIRFRAMECONFIG_H + +#include + +namespace Ui { +class QGCPX4AirframeConfig; +} + +class QGCPX4AirframeConfig : public QWidget +{ + Q_OBJECT + +public: + explicit QGCPX4AirframeConfig(QWidget *parent = 0); + ~QGCPX4AirframeConfig(); + +private: + Ui::QGCPX4AirframeConfig *ui; +}; + +#endif // QGCPX4AIRFRAMECONFIG_H diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui new file mode 100644 index 0000000000..f5aa09aa93 --- /dev/null +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui @@ -0,0 +1,318 @@ + + + QGCPX4AirframeConfig + + + + 0 + 0 + 602 + 345 + + + + Form + + + + + + true + + + + + 0 + 0 + 561 + 299 + + + + + + + + + + + + + 120 + 120 + + + + + + + + + Please select + + + + + EasyStar + + + + + EasyStar 2 + + + + + EasyStar 2 w. Ailerons + + + + + Bixler 2 + + + + + + + + Standard Plane + + + + + + + + + + + + + + + + + + + Bormatec CamFlyer Q + + + + + FX-61 Phantom + + + + + + + + Flying Wing + + + + + + + + + + + + + + + + + + + AR.Drone Frame + + + + + Arducopter C Frame + + + + + DJI F330 Frame + + + + + DJI F450 Frame + + + + + + + + Quadrotor X + + + + + + + + + + + PushButton + + + + + + + + + + Quadrotor + + + + + + + + + + + + PushButton + + + + + + + + + + Hexarotor X + + + + + + + + + + + PushButton + + + + + + + + + + Hexarotor + + + + + + + + + + + + PushButton + + + + + + + + + + Octorotor X + + + + + + + + + + + PushButton + + + + + + + + + + Octorotor + + + + + + + + + + + + PushButton + + + + + + + + Steadydrone + + + + + H Frame Custom + + + + + + + + H Frame + + + + + + + + + + + + + No changes values + + + + + + + Apply and Restart + + + + + + + + -- GitLab From 1d79eb003f7b73e547aff2efce8701a608895440 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sat, 17 Aug 2013 16:00:37 +0200 Subject: [PATCH 281/460] Checkpoint: RC calibration much better / operation, can use UI tweaks. Airframe config in, but not operational and still very functional / ugly. --- files/px4/widgets/px4_calibration.qgw | 14 +- src/ui/QGCPX4VehicleConfig.cc | 214 +++++++----- src/ui/QGCPX4VehicleConfig.h | 52 +++ src/ui/QGCPX4VehicleConfig.ui | 458 ++++++++++++-------------- src/ui/uas/UASControlWidget.cc | 24 +- 5 files changed, 424 insertions(+), 338 deletions(-) diff --git a/files/px4/widgets/px4_calibration.qgw b/files/px4/widgets/px4_calibration.qgw index 2a498a3ebf..bb895bc371 100644 --- a/files/px4/widgets/px4_calibration.qgw +++ b/files/px4/widgets/px4_calibration.qgw @@ -58,4 +58,16 @@ QGC_TOOL_WIDGET_ITEMS\5\QGC_COMMAND_BUTTON_PARAM4=1 QGC_TOOL_WIDGET_ITEMS\5\QGC_COMMAND_BUTTON_PARAM5=0 QGC_TOOL_WIDGET_ITEMS\5\QGC_COMMAND_BUTTON_PARAM6=0 QGC_TOOL_WIDGET_ITEMS\5\QGC_COMMAND_BUTTON_PARAM7=0 -QGC_TOOL_WIDGET_ITEMS\size=5 +QGC_TOOL_WIDGET_ITEMS\6\TYPE=COMMANDBUTTON +QGC_TOOL_WIDGET_ITEMS\6\QGC_COMMAND_BUTTON_DESCRIPTION=Reboot to Bootloader +QGC_TOOL_WIDGET_ITEMS\6\QGC_COMMAND_BUTTON_BUTTONTEXT=BOOTLOADER +QGC_TOOL_WIDGET_ITEMS\6\QGC_COMMAND_BUTTON_COMMANDID=246 +QGC_TOOL_WIDGET_ITEMS\6\QGC_COMMAND_BUTTON_PARAMS_VISIBLE=false +QGC_TOOL_WIDGET_ITEMS\6\QGC_COMMAND_BUTTON_PARAM1=3 +QGC_TOOL_WIDGET_ITEMS\6\QGC_COMMAND_BUTTON_PARAM2=0 +QGC_TOOL_WIDGET_ITEMS\6\QGC_COMMAND_BUTTON_PARAM3=0 +QGC_TOOL_WIDGET_ITEMS\6\QGC_COMMAND_BUTTON_PARAM4=0 +QGC_TOOL_WIDGET_ITEMS\6\QGC_COMMAND_BUTTON_PARAM5=0 +QGC_TOOL_WIDGET_ITEMS\6\QGC_COMMAND_BUTTON_PARAM6=0 +QGC_TOOL_WIDGET_ITEMS\6\QGC_COMMAND_BUTTON_PARAM7=0 +QGC_TOOL_WIDGET_ITEMS\size=7 diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index c87306f9c5..f4fbde4df5 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -20,13 +20,13 @@ #include "UASManager.h" #include "UASParameterCommsMgr.h" #include "ui_QGCPX4VehicleConfig.h" - +#include "px4_configuration/QGCPX4AirframeConfig.h" #define WIDGET_INDEX_RC 0 #define WIDGET_INDEX_SENSOR_CAL 1 -#define WIDGET_INDEX_GENERAL_CONFIG 2 -#define WIDGET_INDEX_ADV_CONFIG 3 - +#define WIDGET_INDEX_AIRFRAME_CONFIG 2 +#define WIDGET_INDEX_GENERAL_CONFIG 3 +#define WIDGET_INDEX_ADV_CONFIG 4 #define MIN_PWM_VAL 800 #define MAX_PWM_VAL 2200 @@ -44,15 +44,33 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : rcAux2(0.0f), rcAux3(0.0f), dataModelChanged(true), + channelWanted(-1), rc_mode(RC_MODE_NONE), calibrationEnabled(false), + px4AirframeConfig(NULL), ui(new Ui::QGCPX4VehicleConfig) { doneLoadingConfig = false; + channelNames << "Roll / Aileron"; + channelNames << "Pitch / Elevator"; + channelNames << "Yaw / Rudder"; + channelNames << "Throttle"; + channelNames << "SW1 / Main Mode Switch"; + channelNames << "SW2 / Sub Mode Switch"; + channelNames << "Aux1 / Flaps"; + channelNames << "Aux2"; + channelNames << "Aux3"; + channelNames << "Aux4"; + channelNames << "Aux5"; + channelNames << "Aux6"; + setObjectName("QGC_VEHICLECONFIG"); ui->setupUi(this); + px4AirframeConfig = new QGCPX4AirframeConfig(this); + ui->airframeLayout->addWidget(px4AirframeConfig); + ui->rollWidget->setOrientation(Qt::Horizontal); ui->rollWidget->setName("Roll"); ui->yawWidget->setOrientation(Qt::Horizontal); @@ -72,19 +90,13 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(ui->sensorMenuButton,SIGNAL(clicked()),this,SLOT(sensorMenuButtonClicked())); connect(ui->generalMenuButton,SIGNAL(clicked()),this,SLOT(generalMenuButtonClicked())); connect(ui->advancedMenuButton,SIGNAL(clicked()),this,SLOT(advancedMenuButtonClicked())); - - - int selectedRcModeIdx = (RC_MODE_NONE != rc_mode) ? (int)(rc_mode -1) : -1; - ui->rcModeComboBox->setCurrentIndex(selectedRcModeIdx); + connect(ui->airframeMenuButton, SIGNAL(clicked()), this, SLOT(airframeMenuButtonClicked())); ui->rcCalibrationButton->setCheckable(true); connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool))); connect(ui->writeButton, SIGNAL(clicked()), this, SLOT(writeParameters())); - connect(ui->rcModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setRCModeIndex(int))); - //connect(ui->setTrimButton, SIGNAL(clicked()), this, SLOT(setTrimPositions())); - //TODO connect buttons here to save/clear actions? UASInterface* tmpMav = UASManager::instance()->getActiveUAS(); if (tmpMav) { @@ -96,44 +108,48 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); - //TODO the following methods are not yet implemented - -// Connect RC mapping assignments -// connect(ui->rollSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setRollChan(int))); -// connect(ui->pitchSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setPitchChan(int))); -// connect(ui->yawSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setYawChan(int))); -// connect(ui->throttleSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setThrottleChan(int))); -// connect(ui->modeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setModeChan(int))); -// connect(ui->aux1SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux1Chan(int))); -// connect(ui->aux2SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux2Chan(int))); -// connect(ui->aux3SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux3Chan(int))); - -// // Connect RC reverse assignments -// connect(ui->invertCheckBox, SIGNAL(clicked(bool)), this, SLOT(setRollInverted(bool))); -// connect(ui->invertCheckBox_2, SIGNAL(clicked(bool)), this, SLOT(setPitchInverted(bool))); -// connect(ui->invertCheckBox_3, SIGNAL(clicked(bool)), this, SLOT(setYawInverted(bool))); -// connect(ui->invertCheckBox_4, SIGNAL(clicked(bool)), this, SLOT(setThrottleInverted(bool))); -// connect(ui->invertCheckBox_5, SIGNAL(clicked(bool)), this, SLOT(setModeInverted(bool))); -// connect(ui->invertCheckBox_6, SIGNAL(clicked(bool)), this, SLOT(setAux1Inverted(bool))); -// connect(ui->invertCheckBox_7, SIGNAL(clicked(bool)), this, SLOT(setAux2Inverted(bool))); -// connect(ui->invertCheckBox_8, SIGNAL(clicked(bool)), this, SLOT(setAux3Inverted(bool))); - - - - + // Connect RC mapping assignments + connect(ui->rollSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setRollChan(int))); + connect(ui->pitchSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setPitchChan(int))); + connect(ui->yawSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setYawChan(int))); + connect(ui->throttleSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setThrottleChan(int))); + connect(ui->modeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setModeChan(int))); + connect(ui->aux1SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux1Chan(int))); + connect(ui->aux2SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux2Chan(int))); + connect(ui->aux3SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux3Chan(int))); + + // Connect RC reverse assignments + connect(ui->invertCheckBox, SIGNAL(clicked(bool)), this, SLOT(setRollInverted(bool))); + connect(ui->invertCheckBox_2, SIGNAL(clicked(bool)), this, SLOT(setPitchInverted(bool))); + connect(ui->invertCheckBox_3, SIGNAL(clicked(bool)), this, SLOT(setYawInverted(bool))); + connect(ui->invertCheckBox_4, SIGNAL(clicked(bool)), this, SLOT(setThrottleInverted(bool))); + connect(ui->invertCheckBox_5, SIGNAL(clicked(bool)), this, SLOT(setModeInverted(bool))); + connect(ui->invertCheckBox_6, SIGNAL(clicked(bool)), this, SLOT(setAux1Inverted(bool))); + connect(ui->invertCheckBox_7, SIGNAL(clicked(bool)), this, SLOT(setAux2Inverted(bool))); + connect(ui->invertCheckBox_8, SIGNAL(clicked(bool)), this, SLOT(setAux3Inverted(bool))); + + connect(ui->rollButton, SIGNAL(clicked()), this, SLOT(identifyRollChannel())); + connect(ui->pitchButton, SIGNAL(clicked()), this, SLOT(identifyPitchChannel())); + connect(ui->yawButton, SIGNAL(clicked()), this, SLOT(identifyYawChannel())); + connect(ui->throttleButton, SIGNAL(clicked()), this, SLOT(identifyThrottleChannel())); + connect(ui->modeButton, SIGNAL(clicked()), this, SLOT(identifyModeChannel())); + connect(ui->subButton, SIGNAL(clicked()), this, SLOT(identifySubModeChannel())); + connect(ui->aux1Button, SIGNAL(clicked()), this, SLOT(identifyAux1Channel())); + connect(ui->aux2Button, SIGNAL(clicked()), this, SLOT(identifyAux2Channel())); for (unsigned int i = 0; i < chanMax; i++) { rcValue[i] = UINT16_MAX; rcMapping[i] = i; + channelWantedList[i] = UINT16_MAX; + rcMin[i] = 1000; + rcMax[i] = 2000; } updateTimer.setInterval(150); connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateView())); updateTimer.start(); - - ui->advancedGroupBox->hide(); - connect(ui->advancedCheckBox,SIGNAL(toggled(bool)),ui->advancedGroupBox,SLOT(setShown(bool))); } + void QGCPX4VehicleConfig::rcMenuButtonClicked() { //TODO eg ui->stackedWidget->findChild("rcConfig"); @@ -155,6 +171,28 @@ void QGCPX4VehicleConfig::advancedMenuButtonClicked() ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_ADV_CONFIG); } +void QGCPX4VehicleConfig::airframeMenuButtonClicked() +{ + ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_AIRFRAME_CONFIG); +} + +void QGCPX4VehicleConfig::identifyChannelMapping(int aert_index) +{ + if (chanCount == 0) + return; + channelWanted = aert_index; + + for (unsigned i = 0; i < sizeof(channelWantedList) / sizeof(channelWantedList[0]); i++) + { + if (i >= chanCount) { + channelWantedList[i] = 0; + } else { + channelWantedList[i] = rcValue[i]; + } + } + +} + QGCPX4VehicleConfig::~QGCPX4VehicleConfig() { delete ui; @@ -863,6 +901,11 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) child->deleteLater(); } + foreach(QWidget* child, ui->airframeLayout->findChildren()) + { + child->deleteLater(); + } + // And then delete any custom tabs foreach(QWidget* child, additionalTabs) { child->deleteLater(); @@ -956,6 +999,8 @@ void QGCPX4VehicleConfig::writeCalibrationRC() { if (!mav) return; + setTrimPositions(); + QString minTpl("RC%1_MIN"); QString maxTpl("RC%1_MAX"); QString trimTpl("RC%1_TRIM"); @@ -1019,6 +1064,9 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) chanCount = chan+1; } + // Raw value + rcValue[chan] = val; + // Update calibration data if (calibrationEnabled) { if (val < rcMin[chan]) { @@ -1029,8 +1077,40 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) } } - // Raw value - rcValue[chan] = val; + if (channelWanted >= 0) { + // If the first channel moved considerably, pick it + if (fabsf(channelWantedList[chan] - val) > 300) + { + rcMapping[channelWanted] = chan; + updateInvertedCheckboxes(chan); + + int chanFound = channelWanted; + + channelWanted = -1; + + // Reject + QMessageBox msgBox; + msgBox.setText(tr("%1 Channel found.").arg(channelNames[chanFound])); + msgBox.setInformativeText(tr("Found %1 to be on the raw RC channel %2").arg(channelNames[chanFound]).arg(chan + 1)); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + (void)msgBox.exec(); + } + } + + // Find correct mapped channel + for (int i = 0; i < chanCount; i++) + { + if (chan == rcMapping[i]) + { + + rcMappedValue[i] = (rcRev[chan]) ? rcMax[chan] - (val - rcMin[chan]) : val; + + // Copy min / max + rcMappedMin[i] = rcMin[chan]; + rcMappedMax[i] = rcMax[chan]; + } + } // Normalized value float normalized; @@ -1367,55 +1447,21 @@ void QGCPX4VehicleConfig::checktimeOuts() void QGCPX4VehicleConfig::updateRcWidgetValues() { - //TODO set eg pitchSpinBox values - - switch (rc_mode) { - case RC_MODE_1: - ui->rollWidget->setValueAndRange(rcValue[0],rcMin[0],rcMax[0]); - ui->throttleWidget->setValueAndRange(rcValue[1],rcMin[1],rcMax[1]); - ui->yawWidget->setValueAndRange(rcValue[2],rcMin[2],rcMax[2]); - ui->pitchWidget->setValueAndRange(rcValue[3],rcMin[3],rcMax[3]); - setRollChan(1); - setThrottleChan(2); - - break; - - case RC_MODE_NONE: - case RC_MODE_2: - ui->rollWidget->setValueAndRange(rcValue[0],rcMin[0],rcMax[0]); - ui->pitchWidget->setValueAndRange(rcValue[1],rcMin[1],rcMax[1]); - ui->throttleWidget->setValueAndRange(rcValue[2],rcMin[2],rcMax[2]); - ui->yawWidget->setValueAndRange(rcValue[3],rcMin[3],rcMax[3]); - break; - - case RC_MODE_3: - ui->yawWidget->setValueAndRange(rcValue[0],rcMin[0],rcMax[0]); - ui->throttleWidget->setValueAndRange(rcValue[1],rcMin[1],rcMax[1]); - ui->rollWidget->setValueAndRange(rcValue[2],rcMin[2],rcMax[2]); - ui->pitchWidget->setValueAndRange(rcValue[3],rcMin[3],rcMax[3]); - break; - - case RC_MODE_4: - ui->yawWidget->setValueAndRange(rcValue[0],rcMin[0],rcMax[0]); - ui->pitchWidget->setValueAndRange(rcValue[1],rcMin[1],rcMax[1]); - ui->rollWidget->setValueAndRange(rcValue[2],rcMin[2],rcMax[2]); - ui->throttleWidget->setValueAndRange(rcValue[3],rcMin[3],rcMax[3]); - break; - } - - ui->radio5Widget->setValueAndRange(rcValue[4],rcMin[4],rcMax[4]); - ui->radio6Widget->setValueAndRange(rcValue[5],rcMin[5],rcMax[5]); - ui->radio7Widget->setValueAndRange(rcValue[6],rcMin[6],rcMax[6]); - ui->radio8Widget->setValueAndRange(rcValue[7],rcMin[7],rcMax[7]); + ui->rollWidget->setValueAndRange(rcMappedValue[0],rcMappedMin[0],rcMappedMax[0]); + ui->pitchWidget->setValueAndRange(rcMappedValue[1],rcMappedMin[1],rcMappedMax[1]); + ui->yawWidget->setValueAndRange(rcMappedValue[2],rcMappedMin[2],rcMappedMax[2]); + ui->throttleWidget->setValueAndRange(rcMappedValue[3],rcMappedMin[3],rcMappedMax[3]); + + ui->radio5Widget->setValueAndRange(rcMappedValue[4],rcMin[4],rcMax[4]); + ui->radio6Widget->setValueAndRange(rcMappedValue[5],rcMin[5],rcMax[5]); + ui->radio7Widget->setValueAndRange(rcMappedValue[6],rcMin[6],rcMax[6]); + ui->radio8Widget->setValueAndRange(rcMappedValue[7],rcMin[7],rcMax[7]); } void QGCPX4VehicleConfig::updateView() { if (dataModelChanged) { dataModelChanged = false; - //update the selected RC mode - int selectedRcModeIdx = (RC_MODE_NONE != rc_mode) ? (rc_mode -1) : -1; - ui->rcModeComboBox->setCurrentIndex(selectedRcModeIdx); updateRcWidgetValues(); diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index 217d72c664..8d735a175d 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -6,9 +6,11 @@ #include #include #include +#include #include "QGCToolWidget.h" #include "UASInterface.h" +#include "px4_configuration/QGCPX4AirframeConfig.h" class UASParameterCommsMgr; @@ -37,6 +39,8 @@ public slots: void sensorMenuButtonClicked(); void generalMenuButtonClicked(); void advancedMenuButtonClicked(); + void airframeMenuButtonClicked(); + void identifyChannelMapping(int aert_index); /** Set the MAV currently being calibrated */ void setActiveUAS(UASInterface* active); @@ -136,6 +140,46 @@ public slots: rcRev[rcMapping[7]] = inverted; } + /** Identify roll */ + void identifyRollChannel() { + identifyChannelMapping(0); + } + + /** Identify pitch */ + void identifyPitchChannel() { + identifyChannelMapping(1); + } + + /** Identify yaw */ + void identifyYawChannel() { + identifyChannelMapping(2); + } + + /** Identify throttle */ + void identifyThrottleChannel() { + identifyChannelMapping(3); + } + + /** Identify mode */ + void identifyModeChannel() { + identifyChannelMapping(4); + } + + /** Identify sub mode */ + void identifySubModeChannel() { + identifyChannelMapping(5); + } + + /** Identify aux 1 */ + void identifyAux1Channel() { + identifyChannelMapping(6); + } + + /** Identify aux 2 */ + void identifyAux2Channel() { + identifyChannelMapping(7); + } + protected slots: void menuButtonClicked(); /** Reset the RC calibration */ @@ -174,6 +218,12 @@ protected: float rcScaling[chanMax]; ///< Scaling of channel input to control commands bool rcRev[chanMax]; ///< Channel reverse int rcValue[chanMax]; ///< Last values + float rcMappedMin[chanMax]; ///< Mapped channels in default order + float rcMappedMax[chanMax]; ///< Mapped channels in default order + float rcMappedValue[chanMax]; ///< Mapped channels in default order + int channelWanted; ///< During channel assignment search the requested default index + float channelWantedList[chanMax]; ///< During channel assignment search the start values + QStringList channelNames; ///< List of channel names in standard order float rcRoll; ///< PPM input channel used as roll control input float rcPitch; ///< PPM input channel used as pitch control input float rcYaw; ///< PPM input channel used as yaw control input @@ -197,6 +247,8 @@ protected: QMap toolToBoxMap; ///< Easy method of figuring out which QGroupBox is tied to which ToolWidget. QMap paramTooltips; ///< Tooltips for the ? button next to a parameter. + QGCPX4AirframeConfig* px4AirframeConfig; + private: Ui::QGCPX4VehicleConfig *ui; QMap buttonToWidgetMap; diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index fd13f905e2..058ddfc4a6 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -86,6 +86,14 @@ Calibration
+ + + + Airframe +Config + + + @@ -138,7 +146,7 @@ Config - 3 + 2 @@ -305,96 +313,28 @@ Config
- - - - - - Show advanced RC settings - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - Advanced + Stick to Channel Mapping and Reverse - - - - - RC Transmitter Mode - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - + + + - true - - - - 320 - 16777215 - + false - - - Mode 1 - - - - - Mode 2 - - - - - Mode 3 - - - - - Mode 4 - - - - - - - - - - - - 0000 + + 1 - - Qt::AlignCenter + + 8 - + Aux 3 @@ -404,8 +344,8 @@ Config - - + + false @@ -417,66 +357,79 @@ Config - - + + - Invert + Reverse - - - - Roll / Ailerons + + + + false - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + 1 + + + 8 - - + + - Aux 1 + Reverse + + + + + + + Mode Switch Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - Invert + Reverse - - + + - Mode Switch + 0000 - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignCenter - - + + - Invert + 0000 + + + Qt::AlignCenter - - + + - Invert + Reverse - - + + false @@ -488,8 +441,8 @@ Config - - + + false @@ -501,58 +454,48 @@ Config - - + + - 0000 + Aux 1 - Qt::AlignCenter - - - - - - - false - - - 1 - - - 8 + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - Yaw / Rudder + 0000 - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignCenter - - + + - Invert + 0000 + + + Qt::AlignCenter - - + + - Throttle + Aux 2 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + 0000 @@ -561,31 +504,57 @@ Config - - - - false + + + + Reverse - - 1 + + + + + + Identify Roll Channel - - 8 + + + + + + Identify Pitch Channel - - + + - Pitch / Elevator + Identify Yaw Channel - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + Identify Main Mode Switch - - + + + + Identify Aux 1 Channel + + + + + + + Identify Aux 2 Channel + + + + + 0000 @@ -594,28 +563,36 @@ Config - - + + - Aux 2 + Identify Sub Mode Switch - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + Identify Throttle Channel - - + + - 0000 + Reverse - - Qt::AlignCenter + + + + + + Reverse - + false @@ -627,18 +604,8 @@ Config - - - - 0000 - - - Qt::AlignCenter - - - - - + + false @@ -650,25 +617,28 @@ Config - - + + - 0000 + Yaw / Rudder - Qt::AlignCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - Invert + Throttle + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + false @@ -680,8 +650,18 @@ Config + + + + Pitch / Elevator + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + - + 0000 @@ -690,71 +670,60 @@ Config - - + + - Invert + Reverse - - + + - Invert + 0000 + + + Qt::AlignCenter - - - - Qt::Horizontal - - - - 40 - 20 - - - + + + + Roll / Ailerons + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + - - - - Qt::Horizontal - - - - 40 - 20 - - - + + + + Control Channel Name + + - - - - Qt::Horizontal - - - - 40 - 20 - - - + + + + Normalized Value + + + + + + + Reverse Direction / Invert + + - - - - Qt::Horizontal - - - - 40 - 20 - - - + + + + Index of RC Channel used + + @@ -835,6 +804,9 @@ p, li { white-space: pre-wrap; } + + + @@ -1035,8 +1007,8 @@ p, li { white-space: pre-wrap; } 0 0 - 597 - 569 + 98 + 28 diff --git a/src/ui/uas/UASControlWidget.cc b/src/ui/uas/UASControlWidget.cc index aae8644991..ebc1934c3a 100644 --- a/src/ui/uas/UASControlWidget.cc +++ b/src/ui/uas/UASControlWidget.cc @@ -116,15 +116,17 @@ void UASControlWidget::updateModesList() void UASControlWidget::setUAS(UASInterface* uas) { - if (this->uasID) { + if (this->uasID > 0) { UASInterface* oldUAS = UASManager::instance()->getUASForId(this->uasID); - disconnect(ui.controlButton, SIGNAL(clicked()), oldUAS, SLOT(armSystem())); - disconnect(ui.liftoffButton, SIGNAL(clicked()), oldUAS, SLOT(launch())); - disconnect(ui.landButton, SIGNAL(clicked()), oldUAS, SLOT(home())); - disconnect(ui.shutdownButton, SIGNAL(clicked()), oldUAS, SLOT(shutdown())); - //connect(ui.setHomeButton, SIGNAL(clicked()), uas, SLOT(setLocalOriginAtCurrentGPSPosition())); - disconnect(uas, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int, QString, QString))); - disconnect(uas, SIGNAL(statusChanged(int)), this, SLOT(updateState(int))); + if (oldUAS) { + disconnect(ui.controlButton, SIGNAL(clicked()), oldUAS, SLOT(armSystem())); + disconnect(ui.liftoffButton, SIGNAL(clicked()), oldUAS, SLOT(launch())); + disconnect(ui.landButton, SIGNAL(clicked()), oldUAS, SLOT(home())); + disconnect(ui.shutdownButton, SIGNAL(clicked()), oldUAS, SLOT(shutdown())); + //connect(ui.setHomeButton, SIGNAL(clicked()), uas, SLOT(setLocalOriginAtCurrentGPSPosition())); + disconnect(oldUAS, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int, QString, QString))); + disconnect(oldUAS, SIGNAL(statusChanged(int)), this, SLOT(updateState(int))); + } } // Connect user interface controls @@ -141,11 +143,13 @@ void UASControlWidget::setUAS(UASInterface* uas) this->uasID = uas->getUASID(); setBackgroundColor(uas->getColor()); + + this->updateModesList(); + this->updateArmText(); + } else { this->uasID = -1; } - this->updateModesList(); - this->updateArmText(); } UASControlWidget::~UASControlWidget() -- GitLab From fb4c0a0dc77ad8d6bc4fc949dff741115cece9b6 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sat, 17 Aug 2013 21:43:35 +0200 Subject: [PATCH 282/460] Huge progress in vehicle config view, added text console to sensors view, all WIP, still ugly --- files/images/px4/airframes/hexa_+.png | Bin 0 -> 66128 bytes files/images/px4/airframes/hexa_x.png | Bin 0 -> 67479 bytes files/images/px4/airframes/octo_+.png | Bin 0 -> 74981 bytes files/images/px4/airframes/octo_x.png | Bin 0 -> 101465 bytes files/images/px4/airframes/quad_+.png | Bin 0 -> 39977 bytes files/images/px4/airframes/quad_x.png | Bin 0 -> 39059 bytes files/styles/style-dark.css | 10 + qgroundcontrol.qrc | 6 + src/ui/QGCPX4VehicleConfig.cc | 11 +- src/ui/QGCPX4VehicleConfig.ui | 69 +++---- .../px4_configuration/QGCPX4AirframeConfig.cc | 181 ++++++++++++++++++ .../px4_configuration/QGCPX4AirframeConfig.h | 59 ++++++ .../px4_configuration/QGCPX4AirframeConfig.ui | 102 ++++++++-- src/ui/uas/QGCMessageView.cc | 1 + 14 files changed, 371 insertions(+), 68 deletions(-) create mode 100755 files/images/px4/airframes/hexa_+.png create mode 100755 files/images/px4/airframes/hexa_x.png create mode 100755 files/images/px4/airframes/octo_+.png create mode 100755 files/images/px4/airframes/octo_x.png create mode 100755 files/images/px4/airframes/quad_+.png create mode 100755 files/images/px4/airframes/quad_x.png diff --git a/files/images/px4/airframes/hexa_+.png b/files/images/px4/airframes/hexa_+.png new file mode 100755 index 0000000000000000000000000000000000000000..486d63a04204a925d0515d9195b948d4971453c4 GIT binary patch literal 66128 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 z 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 literal 0 HcmV?d00001 diff --git a/files/images/px4/airframes/hexa_x.png b/files/images/px4/airframes/hexa_x.png new file mode 100755 index 0000000000000000000000000000000000000000..cd1fe507dfd4e448c5f2c1e6113f26463d7c30d1 GIT binary patch literal 67479 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 j&atRzhC|tyfAVupK3gTe~DWM4fG?tk1 literal 0 HcmV?d00001 diff --git a/files/images/px4/airframes/octo_+.png b/files/images/px4/airframes/octo_+.png new file mode 100755 index 0000000000000000000000000000000000000000..df6eefff2e32ba8179a7d08ad1b583180b8231d6 GIT binary patch literal 74981 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 z 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 literal 0 HcmV?d00001 diff --git a/files/images/px4/airframes/octo_x.png b/files/images/px4/airframes/octo_x.png new file mode 100755 index 0000000000000000000000000000000000000000..41faf992abe13e44e973268bb9ca1c659e391203 GIT binary patch literal 101465 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 Pz`)??>gTe~DWM4fgZ&~p literal 0 HcmV?d00001 diff --git a/files/images/px4/airframes/quad_+.png b/files/images/px4/airframes/quad_+.png new file mode 100755 index 0000000000000000000000000000000000000000..4832def6c73a6a387038774cf270225549400d9f GIT binary patch literal 39977 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 KT-G@yGywn>89ucD literal 0 HcmV?d00001 diff --git a/files/images/px4/airframes/quad_x.png b/files/images/px4/airframes/quad_x.png new file mode 100755 index 0000000000000000000000000000000000000000..ea6835509aa5f58fbc000d018ea72e485ebf5884 GIT binary patch literal 39059 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

_ljnmF-u#n-~alF*B@{`KblDP`;iNSkgLB|2; z>6}UX%*%5j@|lcn)fUMcvW$Lj7YYXa^0Q9#exiN!+@Gq|%OyVS)?L@|OJlps7Llu$ z%(FCl1sFE{s65odIZ+|>=~te^r7gF%=btw+GLqKGVlda2=OmUi6aK7smU(n0nu8+@RV6nuL6{x?t1VcHMZki$PyRITpos zTygxe)XmcK3VHy0v|VZbZ|Vk{eI{15q1$-mqVqYK|w(`R)wy9bGVJS*evhP z4M{n=knXSW7|uA z`@c)HBro3U5)st95*QMa;w)#*zUuJ5EE}ckuJwyb8hO1Q_wZ(IwbC##3E@*(D&n&; z$Y;l^!pFx-88puyPrto9@%WxcbGtJl&asok$D*cZieE$ZDV zd@(2xG$r!*alidGrQQOjdZEf2-BUd}uSD%x^7f1Q#I6O0BI0s{S~)7St4=8|m1eX3 zba~RJHHR)uWjk=+Yi-!=k9W)OPu>6F5cg9%$y;yB+D?|Akyu)=iRGbC=KTXb!g?20 zs2@7HZJ)`PuK`m#p0Z^o#CphvOv}(!xK(R0uftg(N+}{rydz8@PAT%1pZ7*VU7sS( ziD{lWESpppiJq7?jj8NGbgsU@x+dXu-1h(CSwUqAd# z2ubu5lwQldMB8OE)5Wf-Ih`5#y#<=9REu;a?@m*Rv*jq~;0Qm-DXvktQ<-T_&U=oD zA_b`my|0Mr*s?-NRsUS>V4v9 z<)6FPq|~B>JIV}Sxyjn9X)G1U@J!KOF~Lb;lBme)Me0$TCN4>7iJnxzI%#QQ%#thL zmVBw5&mi#b$S$`XNB3Qp_}blgDI)Px^+Txzsz1$t?p;u#8`FC1;P;dAJMMs5MGQ>G z7iBCnE^+v{Np+gbrY|?DIjbb2W))8qo>t;eb#<%g7D*H7DnYN~@0;H>2p>y)DYnvc z(cdSN{d-zlTe%Y}#HQ$JDMdzITD@Y4%O0mG-YVXi%u!vYxeS+2i7Le^MStQ}EOlsE z-6V7}$XfW~rSCU9n+@xaT>1a!x&5l=^XupJX$Bv;k;xXn&@kukg1rlM7d-j>q$_irrItyiwQE*WeOZN3jMrbS>`zXAminYYYJDgE}F}(%*nm$MoY%L zX(h}`i&U3pv~f%e;t26qipdvKiWX9ezBDPt`-oGDvx~M%O=3sE^1a{hRcCD!*89_( zvya`Y?!NpjmR;hzWM6%%)p_}{CvVkMp((yQT%9{NBrm94z`XE@_>7F*R*wOyaR!fm-2Dw65IZ zu2}nG#}U2zv&&LGXHM}x@>poj{5ky{)93t&d*P_z+T*PqEiMzh>Vb^V9|tc#|5YtP zCT{vVA!%0{_gXCa%X&P`Au~v{tAL}pvE*fvh*C6YjKW(;_vRztqQ!d?Odh&_<8IMT z@SLbCsB3$3g3!lHMlvndu{|x^+ZU{;5t;I*UZq63gni1N{}O-tZ}s!u`X~N%X>59Q zRMO|_$YLMa+?mrfmfw8$dduxnKkY@8t79K;xbakI=9Ugk6}6QpkMMD;`7?@LHr5`$ zlX$FU^><0*$-gCngl9#3F23sZU!hyg;LIA{UW4qz(leKM^*S%Scx!3a+SrActWulK*Dlw5>Fit% zJ$7%;CwCUE?Y%uoEqW3+TeL8bZdXvxKfmr+HU6tJrarXVylCP%m8)8BjC$|rT|Bj3 zzxGMl@{4N4Qg4HHb9!$+yLF42XjWHHZ&viKz_&U@9x4A;@kB0owZTU(Hq~bGUY6%2 z6SZ=b_NzQvz98MA#Q2N#pM7$ti&&3m3FhR!zqK{HUD>@)=j8eG^8?>8D*d|n`h?iU zNV7O`-XC8s`|Eywetv(5*uzDEFZ}+Azqr4U^Me0^*B2MK{=FA3Fkw&iTkf5O>FJzB#DnuVRU6j;^F)Qt-_tqYeR&?Cy-0PJ$lc z3eie2N|8#@K}s4yo17<1dVR>uP@i>@s&wlvkBxpif?B*?98*@eatZ1Ru5;M7NFip& zVTT(g+_yNr_U&i*H|0{{Q&_&pe;{dxrk=mrLzV`RtsZwf%6!7eSA|3Ue3S_^zJt zH9w$h-TmfEXCIi|KfX_Ik*sxD&hGH|+R)3p%iov8{7<}bU;D`F6JiP5kNke&ZotT4 zduZeGc~!5>4jr}oa=Z9~_=5HY?-xG&<{P!irLyGVul7&t=G5!Fzx1+?OFlk3;=7}y zqHOi^UuKzZ{fD;dRfr@j#KyjAJnQ)K_;*&tw*d?Ic%n1Sr0tE=kH$8! zpnCi_>$mAD3^}_Z3+C+Z3_Ec>Xx_9b9ne_Ku20wfAqXKFs58G~aaY*>~B#npd)Sx1{{$%bK$Ctw73zS0dX5rTbO~ z7T%h3rbH_^-(tqI_zlLE67weM^9Sf|T=Jy;jfv&@OD7Y4XXwPW3pGx9Yk%l#?2-Qa zc>-_s_y1Wm(QE0M`}gn9m_Gfw-0vfa@fW+dPkd{9d71C;57*=Cm##RZs>&%Y-R5N9 zp4VL0;AUa_V!!sE^?85Z+Djh)=C^ScSLnjIzthZiWT!0K%^_AcMa!>!a_U^mCzFd3 zyaTSSY;N>0os-CQRmb^H>)8^9Ijil(-aEbA_%-s%Q-*2VIll?>UOaTHD4%P)j&bE};rWKL=W`ZhiqCj$yufkV z`B+|!{jV-=Gm<-d;d!nfhn~$0Ifbj*dIq~cr)Dqn{P4GK!~A(3vmNKRy<2{T(RB;c z#U$z3HkCyWA06$EZ@XRVUEdwMrz=PBYTnOJr}f$WXF6q`vwwP0eZG#9*FuiXPvQ?> zJI?s;ouB^R+XkMWVgyPfoT zRC9M;tc&b1zAL#pJ%5?vxi2R6amsdt`3kO8_%Zuo>ZGqXZ{95DzI|lR7pYCGAB>g; zWqSDdggl<@zde!b&{o}u4G;FL3ZDP4s`kMC$>sSoR`Ky|b?K{7&|Fg-|LTt5-hf$( zncsIUXwf~bJmLM>pcSV4Vk+uyT<)$^e#ZMEeqnvH^1q(kIT^MW7B$40v~Wjjq<-Kn zVf`Y{yxlgYqVV&~NK5bJ^r+1~QU3!2S28}Hz05mgUT>22B_Eevth3j#ru~(ZPCUQ; znf01J_ZdgGNejL`XPA7fWQKYEyhSP(gJzn1O)V+eA~;|DlVZ`j6O}eQ`^_ijzMnB; z#@CG-H(r?;vdZS?mEdcv-F1^iPEK*nm9Ns&+Yp-m>cmGc&l`JmRPw&A@10WhU-sCS zBa#KnN@8Np21@SQ;O8{IC5V0MhY0VNZL_3GCvuQ{EJQq_%TT#*+U(mU%i}j#_faZ+mjEu)5BTnNQ|_`?~U&)bdki zb#E-Lt`*EZS?uEG_Do&nPkr@uMtRqZ`@To5dwR)QMP;E{h@gvu;w4U37DiS^>G}Uc zKRDZO?EWRXv7W0#_VjWNjZ4*>u2q6eikzG(Dodt&@4WN$)&I)=Xr2j0p6~Q#pWe6s zezoy-YisMzXWkfZe($%_NJe7Lipn|N|MvfS65|uwYtni2QDDZyj(}HF&QI5$Zevlq z>w@>vB%9l%SFTBJ5S`N@VYsv4!~S}U$G4Zd^UrWJntJf9*g~gRmrMEW(;Ut_usffu zJ0Yy=P%w3Y%nEVW^-q?3Y1|;?^|e<@RjS!1KPac!wO1@tu1)*j`>Ek^7i&MARR8+z zP=@WD(%08cZg}jh|K&~Hv8^VD8gq_>T-&?w%fsvJw~W(nKe74GzAIYE6)~iCgpN?q!W}jN!{xj;`T#LX^`HMjj1x+Hh_X3|h-?e4dytVV^-=D7? zzV3}})t47+hP9toEy7uO&++}M^k+r&=`u}oy$EBe7Usv%(djz#U=Z#zpkIXOEe9+@z|TySbX zhnF);eMgj0O3uOWC*xlfYwdLsyE9Gg{X6%3tF=*QqMA4S*m`+m^6&nDKRX_=f5`az z*YVcPigR-;)w{a8e;3<6UfYxtxN@pc=Ms^_HYzhNB#19_*|9(O?!xZ5+i&P{On;!v2`*LNEn4kSK&KRdncql@mNENks`jsUsSv-@}~NWw};;A+jK3Ael>x$)+nl~#8LR+?uVO>3F*f6^grTB zoBVR)&1L5IEMkmWKDW7;Kl1;3)=gQdsOZ8DyV_qNH@&w^nRebjT5XSg-4>n9liqi~ ziat%bo^#b{vQARknbYt7-8dbYw)dm@nS$T?Mkxo{Z)NqEe{oKod`U_DE2saKuM014 zDK48O5)sVw`c`g`!tU&dh#5T6-faula5KrjQ4+1JdZYE@)t$$U{l`+;^!DsME2KMB z;@*oHa<)|yIMY2YdtE3E-^#V=XwBz}H_u&~w@9m=p02ysZ-?0Aje*yT^bFh@17|T+ z-wU)XxH$b}kpFwlp#1yE6=!=6u`@lKX`DV|#taFzCDGZJDi^I46>FE-(p(TZY3)lh zj~!c9KD)ECc;;N|a-)!A&F}ZChs}=M=>0i8@p(u8d%sUz+5R6dhD^HlQ}s++U2xTw zZQg77j@{R~DERo#hxK8O+YA(Y4xd}r>!mHn(8jSMxMa$K!%L>e-rZ}qBaLyZ*8biM z-85r^4ID?jrYe-3D^7Y}HgVoc$?zp#0@T#hqE40_=@9JkD}Q`j#DB{<{akn9bq5m? zj`d0(U$T6;@yU}XeX_oaK67$gbtP!gcaGo3-==v^xYHx6%-VCa=JWc6RfyQ3fra5-mm-Jdvkt$lcccl@fB7-3=6%N8;a{MovmFuHFQzHPuIqP zghM6H+{z*`(hnPat7B(Bes=%tB6H3wvyGT$sPx7^-RYzsZ*Q+w_a%Zc#3JX00b95K z)oS6Y+0B-Y{U5g_9$2^I-T~c;O{NpxIwwCqUb{2(^RnoDJ&8x<)6UPcJ#+2t?X%I_ z@-`=^aX!AkGkxcpxFKHs8LyVa_$}uL8QqWVlbxbKmrSHUErHS2mwnxwu`D zM>OeJzx?@@wl<@O4x33QS)ePc%0a~8=J3}Jh>q6G=Dq>%ehRVfFAK(7^lDnoO?ktb2#erLkuV!uivQ>w1 zm;9;k8H`QZOF3Jr)i0S#JySTzEx%9eZ{F8_C+=exd1|Vef}_QcVnKI8la z@yq2>Po3L)rE%|jozDS3uh{SFoNQpO6zHoGwTszqfnoOjnrlH*>JF~B9#YfkeC6zX z-dgrqJgH|n{s( zmz%Y1O^$!sJM**D{z;R=_tyLqySzB#WaO&XbA#wXQNBZ8ovWrf^>>EK z)mQa$&5y4$P`CK<^LER`xr)0);hu3tx6_q_iL%p8Qo4spR@%`);Q{hvh z`=@x-qGZQAHSBZB1O=*>g&pvtf^xEqoY)0w3 z%3dmcnNq3cv-8%u2<^xxdWR1+crIpn{BW1V)T`&sUMY#QK9jk5$j@3ZzCtRF;h-zS z&L?JkFD?pQ?0Ry_snH`RfTiuFwg1fMCf1x4mnPo*#+$+aB0%Hp{N?QPrkoQLY~cSO zIYWH8VgUccNps5tzC2xUy!uN({*IFE|C?jGY^+wSVohpf0HyYprn z?3p;-($-@68II)r-W?{AJog{2oNi_NJZ5KOb7z=>$Setsohw&Q`z<=xc2*m&ro3y} z%gt|pU)UG$>ft9BZh;tG^O+(U$0sIVsQ-2UzH0RJ$ZcK^5t1XCI7ogVfx^%(4%Xu#{UtA8Dm%-@deZto^CW_~uP)WDOg~v-@^%$Lh zP`P*WMjJ~hpGMBxtPK)=qFX9W&yVl5= zZ%N7hmGJ-O-A%1Q8#@_KT6GolT88FcYs(fhU{2oVC-dsjqqU#Q<|y3G%oegan|Aq+ zRq)F^^%#dOH})R&X_3B@9xyZ9CA~3X*$?Z4C2?2M18(t5R=+iEZTSCVZ})fqvC!LH zbpGmg)qO^Lzh5X@+QVTRHLL2i!lBTUpPtQ5}e?76ll+R!TgUe~*b&I=LW4j*6#C}}d*R|gA;}(gViw;eEThJV_ z>c`eyd;a`;ma^z-%xxwY@0QhE-B()qEL{&pav?L)?rs+HOIkaoRe87gEx|186AE7VtG4UyU0@mcLjFfZj@h$cvBs|_a5k#Pv`^zWcCTs$e`)~xW2Px> zc6EJ4FJ4@jeM2y^dxGvIQ{k$LFW1|-_AJ`%%B?EY9qoTOH*wL@Dus#KXD22v6XUX3 zvi|m)t)~lrXj&cb_7+q)WB-2JYrFfOWFz@6`t4BC=b!b)Ve;zALtB|1{+NI2aAmPX zXMy&sf5shur8V|O?hc9S%6XZ5W4YSov}0G9qi?zL?AJfPbZ6Pqvlb3pa>{NWzZ-pM zhOhF4RqYRMaJ_K(@%QHEJ+EU}8n&9hGZ6i?^)nLB$F;((Q;*Y6)UH9iz#Q1GH@jyW3jPkp)qU>CL@)aWMeS8w$H*Qgy z`kS-8W7>hK8n$O0YuToA*{1j}Zq+}y@czR7id{NG(! zCpx!(D?h$Fef_j#m($nUI|PHdF7EzoZ&H<_tR8%5@`vlYFK|}tzBiL*tSXHS%QL$l zyia}i-uFi`qWBk=Y87Bj2xO1{@}rJne@dtvuqDytSwJbh$oO1IB8=W~x1XlrfO z_tie{@ij}_yfJK1k^V!Ci$W*vUA()+=zl_#c%o8N#VoBTuH5MCK!wBW#IF2(xMMlr zjQ@fAY(H~OJk?wkWn#1>?;+>*yqsADZWqlr1g-e=;lR?x0eqYVzT1j2opO5jgDiW} z+nhK1!_hd`vO~)P6`9+fdZ%#pu$C%6G`P4)!TBN$+_FdWdo~g%vFA81GpSmT@N#@TU&BgJbE~iYmufw*)-8(jqR>31H@jYo-kVsa*t@w_C*bh?$>%;ks$dED zzFYa4RzmI0Up^;O-W&;Nd@3wmt~{?mx;nTSssbcu@>9F>x4Dt6!q3r;?E!!Nh}v>p4_ma;pF;gi;0 zZJCg5^j&Lj!L94&-?l9awK)FtuA$*pr$tM9et&-xe=uU5{-tx1*CuB<$8NkJeK*fG z_+IqvkVlK($Y1%g>%4GYtiMK+#91939epAqBqqrr;>E_?-(^2%-LL1h*;}=9!{HMr zr`df!yP#>!_6s*`55J1~aeJoAX|*%fR?Bv%{1mylZl6n4aKW5wUKR)DJ&$cyC}2VwU4CBP z)S{vy6;@W(PiJp$t5{c^U%R`Ae{!6evJ!Lmt0|@--?P&eFa7iB-9Oe@k69N7>d7nb zJwCC|;)PiHvg4|^A1N4zJhXE@_RIaKeMMk=*rJZwAM$hF-F$WB=%Xw8_uq*vnR3eh z?+@jRw%_kuPOy}*shCjtZRhiuO1`GXMGvie4lVySb3=?m)G42D`+WDEwAb}KQr8k3 z=qCRlK<-pWOq@&$L&4I!OotwQJEm*%&nbv+ra+CFi)CJpWoe@48L^V&jlacqZR_ET zes!TfXLa*hHP_y|N$&CMlKuAXoI7!a?wR`g|7S?r*X{W#_Vw?dU$57nX=*(`b4%Sc zulv)hmT*iJ^5cJbWQmaLJ@)0r0r!tD>bd7~uY+6s>h$B!<`qvpJ1s8s^6{FTwl3j8 z3#PEPTzI!=j;PYDW^Va6=A~yiTp!I}{#GgK)S1}wyGQ5PlufBD`qq3VU*G0XhF4zg zvK>xaro^R2sF;b0TwX15QZz%QvZ7FfNmd{_ZDFA3vh$ZUY?MO#YVVe9;N2b-d-Tox z-CZ-yzQn10t?7z&@y@tg|NpPgv7@IKWiqR;=n|jz=+6nU%q`;EeIB75>gzgHLUUH&M` z%PzQXpVRR*{r`I^OAmUV`Q3g0_`Zd`tN$tSX#UALnSO}z?ypm);_WV9USnvY$8

tk%2kvr}Es+e95A~JDr))?zIBdFTX-;Lu&!kNIMh?+)?DfVACI-aG zbTgPHOy6258vD^oU*PwtjLp8sy^T4q=a?8DkH2@u#^kl)vz@GOSXM7nEq*<1ZIfqt z@8s!!Ui+ALpS-liV@{1|Z?V`3mn*_uEz6uc7thgJrxcxKddbJln|<%Dh*dnj1vRhV zG0fQXEtfCj{qjkBzdloHfAHyIyS#y5W8ImBTmNr<^7Prv=ugQJu^&8a_P%WHohp!% z7wh=*v9Gg&)b!X@`$Fz{%P17*?agO{l7jEDIWvF z-ke<2|9FmwNlnOi>qBAQ-HDZpEk?cTHe9G55dQb(TY-CtO=CS5KPJFIIn{ zV40NQqsQg;LZNF<_C3jZA10);-0J+djJbJU1y(l~9nzejs2{Q;$2TsGqpikr{~^;w zP8%G%&&dY6y0vh>+xI)~Tfo|P+wa$%_L*VOIMc4yYIELQt78npjNCmRqNtkx)BhAF;%8;``9_1!6XeoS^}C(@$P|xr}A` zWL+a??^%&=L)hlJsZKeSsQzT$l=;@r%u_Gz{rYHQ)>W-%Yq#G^TIMtJkj>{a#%C6} zc1tMTZ%cVqJDFvw`1w;it}ITyoD-dAc;%bD_`1>u*46XMXSX^StUI?%!e^z$HR8XSFASwemp+&>gwv;n`>@M8mDbpp!IuFkM^==>0qr1kL;t>l76gBElrmA z7cVTRpz|`@yslN~SkAWY3u_+AeoR(>D5W2E!eH9AgIiQpRSjQXU!UH_FP~Tb>fKy} zz=WLx)tTB}*=c{Z`<=7k*$%(`j6&|M8MQMEr?{LlG1$Dya%Seat-DSYc_t+M zox5xM{kqvRt;^qiy)9!=aKLNVb^a?47e<=zD%#q?ZFXz+WDS9+_I(>ts`swR<2(L8 zUx=w?_0%I5E_AIk&-CqD)hT|{amS1!3X80w=D+w_^=#vDx#VfO(brZeCW@@z=i}aM z@!Um0>{7J(?GrKj+UcrSmZor5^IL7pxi@F((q%_iYif&b&32deyrOI38on~bC^R&b zr>)Jp<3@!b6{K z8M}FlZkck$c}GOb!HC$<+__D0@t^KhJmyWiw8YbAd*0nw+-0YCetUb{ICSaMJ1WsW ztK6F+`AYORna=LnBFnAry6}_P)2F6;WN-ca{CwuSySt-v!Y2LUl>%SuG9WUx$uQ%JqGeYY<=4z$We?%H-GEN@|`|? z{w#Uq{hUsjulII7oGdZvSy_s<)3)_rGkn=>m6NL9@-{y_C9tV1@TqnAyGh?(UT)8Q znYZ)r{{MgTUr$*7<4476%|@mRQ`~0ylzHEn#s2Nh&E`^$MJCtg>9|*I$@!&|_WFkD zwUUCpi7Dql=WQ1F(VcTv?D5y{?P;zz&va)i#(1_YPy7GxuU+i!vbCl~tKKhJ<1^1@ z=Fac;s%KgjKikm$s^nwrVI_{~mny>EbslwEEO_Jj->OJU?S<`<){O{SV3}5H0`5LPs92&K%r=|4t>9cCB_f|~` z%?`gF{eAYV7xCBD8Fl7;-b`(n4azR_|4wH5F0 zX6fC?$oE^bO`(06M%*UZs|+`rQ;CQ`Mk}A$gpgvuBvrA1vm}eYkPoTFoEp3N3|N zmv3BZ-*&aF+b?#>p^qhdDlh2BOG*h=2|ql_$iZ-0#^o_@&eRzfCZuRQ5V#riFQ-NO z(^RP`%D0~CRvg?|TK}*3{H!UDZ>1NP=0-c0sqQTmFrVn+7`gvz!{YiFuWb_7roDXl zIDYNP(~p*DF1)+Jvo&3BiG~E--pV}pA=5a&@6Ua+r}oo z+}YakXPmA>!3KeCvQK6A`blzcz4P+srkPs=*Il1-;!f`F@)_In?s{!Iopzev{$GM+ z#iI!)(}Pm#HY*ngv9t-vmYNt{kPzZ`n;`$nq)_x`ngaVoCC9I#GyNS*<6b}bDQL{vM3{er{&94mAco&j=fQHw5&>a zBU7lv7AMo)Ff}JNmRUbRVDHU{C8b9>794xZ(4zfq;>rBHXGu7C?re!wND$ZkG&gWYydNZhPk_Z;<^K9LJAc-dQ^EaZr>5XW?`26*^{m18tWq@ zJi0o?#82|S;r*cj+SGHif68(6?x18_C)?Vn`yELn|@2X!#wuYXJ;-R+> z*K^kA2RvHrf8Nx_=zHL9wO;|3GMf&cvD|#7|J>|sj$i)&T`Hfay;FFTVzX+qR>t{N zt6!X*^}x-^c!8g2_(a{eaW}=c3AUDpym@!&ic9|TXQvn^R=1U|c=z?u^7J5`xbWY+ zJ1(2lT#>je9$#}XB_$LWQ6ly6<6C|ww$Z7{CxNPd0)F;Jh`!V znaqUcvlnYvlukHf$+_*Z?E|%&fA&1KU|F%WZ|Mu0Tbh2MbM+oQTcndy*IBUpcQ|W( z#qpcIJAZRomAy@=D!9gTIe-7(V|Q#$ui3I?%EGB1mYtoG_v)JRu`SNED*7)LTc0zj zUR`FU>sNAB+W2Hj!GSXFRllFlt+39%qIWZP`a70IciErY7oOgh#kbF()c^l>XID)ZSy~@QCpz2H)7rOSFQUT>z-X|N?O<+ zlNDCVc_E@ovwQEm%y=cfDbi6EN6YU2yYyym=ndg_?pMCQ4{%E_eE9f-{ATMWHI|a4 z8|%a`nICdit+~8BdCjgDZvyk5p7_@4>#_N?{=p5p!M_(i?w+am_{PEiJ&wVOtG*r% z*H(yP3Yc5x*Qt9Z^Yy2kkZqC{Tg2<;Wyr?tZdfVz5EB0vp%Um_vPH);O~+Zob$do z_fAf4^0ngaF-OiaS04X1%fL8!wQlL+hk4J_yzVN6w!D2Y<)d_0%G}ybrpG_+$n{#m zX~}WjN=|&8gUS|;B}$v!cdVKf^Xq)y)wPwJ*Z+p5Z@9sHSR~M$`CWlVsmUC>tV2^% zyko!gWqAInwf=r*fuHsLUnj&Q3&b_OY?e91mEHJsc=Fm}?r8;buG>F!eDS(4PxIO9 zeZ?QwnSa}KHmq8=^q+^D1E>JrTo>cEEyMD~>UgG-iiqiT_T5X2f^R-e@$2_05PP93 zyWVlNVAyn#ZSGb=7k+$gif;V0@L}a13r5C-Y}s>6Yj&SZ`eT22>GYLnq81={$(p|N+=%yP@@R1L z`LH+Y`h$E^)tK797c%?5&1;>?UX&Go{(@;{=H_xkvDcS$tb*kkHc0o%_v$WpWYS#6 za3s|>Iy$Yc#hQ2K7v6ovPc|(wZf9OG{b^Uvr|&Sy^KljN_ zU2y~BN5ADep6+F;(~PXQyyE%&;o`OIjd%F{FH0ZISGZBMWAnlgJw3tcLb65?Eit(* zc0w0xFXY=@+_*Hd`ugQNHE}U54i|Sm=4#${spIxrhsEOT;ax?E@hfAdbeUDo);(dW zYif0%zG!*5&(f=Mw~i#G&URU})F^k8#Mbn#wnyJi2k@B)z2^M1Tgy^UH9C6Pw8OPU zhm*@ge|?wxQ2kEcx+1t~wU_jF&-m?59f2J4n-Vh1Zri*N62G_a>^-i6%h%s6z3?-0 z^EPpf-|TWavE`ae&N5wMlGOicYRjCgopJ3(=AD0b8AgA^W2TBspR8+C&N1_{Q@eX_ z^#|WKjj9Kx7e>{#i>oUy&^6Qpv+q#O;;s@P5j~i+?eEPOP z+;lm2ZKCrMIWc`dH->G@-XHZ>ehK_xe0%M@RS(NQ-CghczG&0dr(L_=`R7-^cz37a z-S+oq?`@y>{_d^?JA&)~Ms>%%<Kd_@h25EGnJ|T>N?l|)>|PP`rO+uYL%~T;p)(gH@gn@HtzZo?dm=8t^bJ( z8Kb*;3&QuenmpU~<&mY-_mka|1rBV9ahp4BO5cmajnz7LjxYQYb-FuSP+{}g$r{Za zuX;Z5I0sH;H$Gi~%s$?7Eu;JD zC6~?|KjXGn)jDzUe(&P@WqHelPw38n;COsZ!RhJ~W#T*Xx6OT1tiAleJUgGV_TQUA z)P4$_Z}6^;xZ`wq=SoN8WvBn0FEo|Rnz_URwl9+xI9 z_P-x4Q+0jD_eIxI~e|b}>GtXIjeQmc}Z<@DXqh8UWwNgEsmUh0CUUETL!RNho?UkhS z-!9&KnZ2Jk+u&*q!)`%`({+^v>L>Nf;t#NwSTeaC`@k$#aE&gWEMNB)=e?U4dvMmDoUG1@Og*L< z9UU6?qD92rCrea3)L;@np11PYgXjDfv-X6|)G0C2nJ)fD-}MoHQ##)wXLHfIsNA=! zr=1Guo}`;9GjX`Y%BrBE(u~ayOZCYu%9i+ zTEDVeV2454~uved88 zx80-7!Fii4F0%Q*^TXwwHlL%dHqKFqW@0?>hew_9SL&@@`J0=5^HqL%G)sSxR`G_r zX8OI32RbgYuYW(wcFzt&@sEi+8yzmaxL?$&cJOve@e{YMD1WUFVF{-y-Z?CC&F6Ao zHJ|yS&`Y89XV~^X*;3*cv+dzxTS-=nlxR!7rL95xKE1#A-`3af*q(pf|EuGk$sg%= zUBm1Wn>kV9bZAxfrE|a1WN(W%B;0M7?|tpX8fDKv57U$ccIRHIeN}t&zni|xf;ZwJ zdLdpvwohR*(EauC(5y*QGxe1uzNQ5)yuHx1JC0f?@5_)q6tj=?C$~Zuedp%{TY=+bauo&N$r8 zZ=8I*Z|{<@)z(6Nd$#1UglJtAU%&6ytH+<8pBI<2C}_C3D|vS1T2SiNk1qP z)vErVR)6-W@xG@oJ?|+UQeHDtiTCC0Zae>|7K@W5AFMwt>bvRo!s3tps}t3hN_u{ibyEcx{&Dl| zRr1O{$YBK+R59}7#PgC=obK=O62`_Ke ztz5Gv<)$!@uCryTwk>{igp;?P}|MTfRYc_V? z|B8wIz{G{WV_#@8+}dbk{8g~E{=*~T_jcmZlRiCP`~Fg?>yeL-FFsCt=FTHGbAQoS zso;o+$J5(yY|ocxmX25Q-y);`!cC2T@2&gWb8n}8_mJ6i_wbhkdp`b>J|w^YU)-Cg zuT#T%_)cd($=xZlN9p-oVd)$f@BBiSEt4lEygKRkMC+o^f;sBZUMdVrDj(-N{b$(l z*X#26{i+|o%q&fNxu`F5f30j=D|6whuin!w^<(s={ubqxHMy|~hcrdh+jRE+ocK5eBXc3pFW z%IgZaC(_n(Mc9m&LIam;b##5nca!UUkKC zed%qcyL;b0eD?IIVTHue6Q56Bo0D(%cDqu8RsNSRUu;0vbw~SOD>`zwL(KT)r=tIr zNz5J7sy1(VVJ?`bIq(0{g8yu?SEM?`UgpTAv3O}{GklZy^LIh*g7yWnCOgCD8A{Ha zxN`M0?Y_V1apE^hpIY2o)ylEm<=O1|?-LZ;+I+aI%ik?on84oPJ6pQ>&MNMk=Z;LD zHtpZO)YH@0?5lPOUu;V0oh95lJNQ`cln|M7bD3A1$oatOVJ22rRn6USNkjEq&tliA zS5w2TZcZ&`YA9ZK$hcH?LWjba#|JIM67zcDkm! zsY%bZ!rZM%de`Us&EEO=%~kV0odaBgzb8(#tGIXmfn~i=T~yy!8D!OPT6zd~&f;mfsp}X7<;wmY6=fJfphmlm2OI ziPF%(6X#c7kQd=P`drq!Y)*5e%cWa6JM8T2T#ngJ{O-+hzFS(U!CbsFDQQu8Ny!)8 zoyv=3O)>&R+y2{jFO1)AsC2O8eW2jV#{LpvPFvfkv$y*q(=BHHeYG*@ZtJA>i6?C@ zhzBnJ{K3Zk(0|1#^EiLSUDj&fxb@aNd57&>4ff3ZGex#JWV(Lqe;{QjR^H~h{`Kto zocu!z!_&Td{CRbMqJjApTO%3qty3OMJvnFV>+f6k`u9(t^ZVUlMul7NCrs-*ar=8g zb+X%yT!|fVQPKR<;Q)nD?Lc zyT}*+7jrG{X?2QarbpGDpJsHBi>vL8g~`!!r7ylO$~9zUWyMcV)t|xhOMR-M;M9f8 z?itSSWg;If{Iu%(Ri5kCp;ul$=ek@MpBNTzb6x!L?H8**S_f1mobf0&{}JER*S3%6 z@4TuVbFE5e?X3S_r+WJ^Xm6^{`u+cY{r|AxteZsK9TCPW?U5fpemtFE6tppN&rlNXcj=yKqP9)X(|MGpS^J$Orjpn`kRAUvDPlUcd=cV(o~7Hhj9a&rBv{yeefd+aZN zc8a`QEN8`=zqr4Cy~F#aI;PmJ;?#n*P1jHAX9>OAka+miw|94co3})sZF|_&y{AG+ zH+F&R1)U`qZP{G5GaNWz6rwjhzGU=G-cowl5d{);9*p z?(Zt`dN7}H>BE>UJNR;wi#gUscSKLpjW*KQv+hH%w>|4FCa+H$HIP*yG9FIOi{atn?TR{Idn^@C z@b|L)Wbpc#=(vaBf6S84{5xEDI1AdGmwwetzbK+XX#w(rcR@yFc8?{EM~k zvb)gg2R|-<(AoM|wO#Il%ZvYtcRZ~Ef(7Pvyok%lpL6|!rA)O9-`-W1N(!>AURa2; zZu{voLr5v$-kT-H$Mn}_!C*o&IIV!h05)gsu@#@XUi-+fX> zB}}6$bzh_CrvqhDEBogMF8UzS@lWF@q~(|EnaqssmL^=$jG+j z=+C%gt4;~%^saE4^D;nb220SD`8GSk4(4{|tax!F5XlwDE=b!rl|0g!w|6iI;yWC{-Kj+(< zoBnHJb_TV}<*jvzHfBB%&+~7xW)@S4`WN*VVNb3$6z9xcZnR^WlOw0tnv@-9KlX^7%Uh)Rde;BG!F%OPsmEEGM+0YL$-F;&TB}v7x1#9M=14iDg_q zJ>?kF-2F>$UE#bguv4z#-R76`ci7K7dE|#Z(=UY*nG*IdwsUshJMn0LwC8Mv=xs-G zL~{)O1vC1$E_3+qv{FgN&2jOk7~z(sVe>rJ7*APi;xcbuK+)8IO+UjNR$h1T+PjqJ zh3o7zWxp%uvzsiOA9gnfJ(XiteYBjtf#aLj9XC%02Zq|UzU&XzwP$BsIqJuib6WZ7 zQ;ka|6ZZ1<*>nCc()hY*-qHUoKRDZ~s<&~tr+nlq5iPMQFiH`$w4%9i`drQ!fK-{wuF z^J88uop;!F&3T4PibwxjFL?9W{b9J%OKVrYnC)U&vA23|aQ#&<@>wjl;<;;?a@B+T zP50W8uk60VtSYqZ)TFL#y#u*Z6yzB7INJHzr)%ZrYuxSDvK6$}oX8h?OwBtm@ZxUY zeK#t_FCF&!dB5nguEu#4+x3=Z|Ah`da};+x>7S(xJL>oJTG)d;G3jQp?dXt*Wbxd!4r11AWgz+pDJ~FVs7&JU74X^tF@C9MydP^95U! z*ClXD z&e^pEfr>9gCs!qvJFmQM$$yLW_{yt(Z9&;_j7z!P^tL{^5)}N}&o;J5^uo6begRbz zf)~2n3OP83Ui$*;L>Iq&kT7TLG_7WUlk znYlTox;S&O(2Ihc^}g%pySZ{5kzZwTFJM)O>B*^D=R`H41y7!Bk8`Ps+L0S*lsmI8 z!I+eAznB##GoI9$9rgb~d*5}}Z6ed2d@y}J?SB0Oj)|-{C+Iuxcd*JV zVKUv88`aRr$`EjVdWrvRw!@q=*S`-v&AI*Y;*xTfoZidrC)5Si_uAR9*|IH_6Bc|w zJz$dXb(ywp#+AHY`J%N8w=nFI`(J%fp7}1<+d${;2m8gJubh77l+T}dp4fioe20_A zcK6zz+-2dv_mOLWl$4uVZ~4M6JbT!lwz?nK$q|rzOuN5P`87k<8kt=pUbZo>bSJ7g zpS<^-`7XDU{6)J4p_dyI&mHu?Jmq0TI@6?dx3gOw{^!z=ozGHx>)G=EOH6h(SMAwo zx_)J$y;8l@(t^F`9{&lvm-p`>=A+%*f)4(Z;;yeW_f+xN zcE@^Q>WU-JA4ahzs(hGGYaoBTd%f(_`bw5N{EYK*?ymRwDf5xz14n@Xfiles/images/firmware/X8_on.png files/images/firmware/Y6_off.png files/images/firmware/Y6_on.png + files/images/px4/airframes/quad_x.png + files/images/px4/airframes/quad_+.png + files/images/px4/airframes/octo_+.png + files/images/px4/airframes/hexa_+.png + files/images/px4/airframes/hexa_x.png + files/images/px4/airframes/octo_x.png files/styles/Vera.ttf diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index f4fbde4df5..c37c134228 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -465,6 +465,7 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) } } + // Load general calibration for autopilot //TODO: Handle this more gracefully, maybe have it scan the directory for multiple calibration entries? tool = new QGCToolWidget("", ui->sensorContents); @@ -496,11 +497,11 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) delete tool; } - //description.txt - QFile sensortipsfile(autopilotdir.absolutePath() + "/general/calibration/description.txt"); - sensortipsfile.open(QIODevice::ReadOnly); - ui->sensorTips->setHtml(sensortipsfile.readAll()); - sensortipsfile.close(); +// //description.txt +// QFile sensortipsfile(autopilotdir.absolutePath() + "/general/calibration/description.txt"); +// sensortipsfile.open(QIODevice::ReadOnly); +//// ui->sensorTips->setHtml(sensortipsfile.readAll()); +// sensortipsfile.close(); } void QGCPX4VehicleConfig::menuButtonClicked() { diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 058ddfc4a6..9f2942dfc7 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -146,7 +146,7 @@ Config - 2 + 1 @@ -753,54 +753,31 @@ Config true - + - - - Sensor Calibration - - + - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Lucida Grande'; font-size:16pt; font-weight:600; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400;"><br /></p></body></html> - - - - - + + + true + + + + + 0 + 0 + 1039 + 731 + + + - - - true - - - - - 0 - 0 - 98 - 28 - - - - - - - - - + - - + + @@ -1206,6 +1183,12 @@ p, li { white-space: pre-wrap; }
ui/QGCPendingParamWidget.h
1 + + QGCMessageView + QWidget +
QGCMessageView.h
+ 1 +
diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index 6c448b3297..f049fee870 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -1,13 +1,194 @@ #include "QGCPX4AirframeConfig.h" #include "ui_QGCPX4AirframeConfig.h" +#include "UASManager.h" +#include "UAS.h" + QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : QWidget(parent), + mav(NULL), ui(new Ui::QGCPX4AirframeConfig) { ui->setupUi(this); + + // Fill the lists here manually in accordance with the list from: + // https://github.com/PX4/Firmware/blob/master/ROMFS/px4fmu_common/init.d/rcS + + ui->planeComboBox->addItem(tr("Multiplex Easystar 1/2"), 1); + ui->planeComboBox->addItem(tr("Hobbyking Bixler 1/2"), 10); + + connect(ui->planeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(planeSelected(int))); + + ui->flyingWingComboBox->addItem(tr("Bormatec Camflyer Q"), 1); + ui->flyingWingComboBox->addItem(tr("Phantom FPV"), 10); + + connect(ui->flyingWingComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(flyingWingSelected(int))); + + ui->quadXComboBox->addItem(tr("Standard 10\" Quad"), 1); + ui->quadXComboBox->addItem(tr("DJI F330 8\" Quad"), 10); + + connect(ui->quadXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(quadXSelected(int))); + + connect(ui->quadPlusComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(quadPlusSelected(int))); + + connect(ui->hexaXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hexaXSelected(int))); + + connect(ui->hexaPlusComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hexaPlusSelected(int))); + + connect(ui->octoXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(octoXSelected(int))); + + connect(ui->octoPlusComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(octoPlusSelected(int))); + + connect(ui->hComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hSelected(int))); + + connect(ui->applyButton, SIGNAL(clicked()), this, SLOT(applyAndReboot())); + + connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS())); + + setActiveUAS(UASManager::instance()->getActiveUAS()); +} + +void QGCPX4AirframeConfig::setActiveUAS(UASInterface* uas) +{ +// if (mav) + + if (!uas) + return; + + mav = uas; + + //connect(uas->getParamManager(), SIGNAL()) +} + +void QGCPX4AirframeConfig::setAirframeID(int id) +{ + // If UAS is present, get param manager and set SYS_AUTOSTART ID + if (!mav) + return; + + mav->getParamManager()->setParameter(0, "SYS_AUTOSTART", (qint32)id); +} + +void QGCPX4AirframeConfig::applyAndReboot() +{ + UAS* uas = qobject_cast(mav); + + if (!uas) + return; + // Store parameters + uas->executeCommand(MAV_CMD_PREFLIGHT_STORAGE, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); + // Reboot + uas->executeCommand(MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); +} + +void QGCPX4AirframeConfig::setAutoConfig(bool enabled) +{ + if (!mav) + return; + mav->getParamManager()->setParameter(0, "SYS_AUTOCONFIG", (qint32) ((enabled) ? 1 : 0)); +} + +void QGCPX4AirframeConfig::flyingWingSelected() +{ + } +void QGCPX4AirframeConfig::flyingWingSelected(int index) +{ + int system_index = ui->flyingWingComboBox->itemData(index).toInt(); + setAirframeID(system_index); +} + +void QGCPX4AirframeConfig::planeSelected() +{ + +} + +void QGCPX4AirframeConfig::planeSelected(int index) +{ + int system_index = ui->planeComboBox->itemData(index).toInt(); + setAirframeID(system_index); +} + + +void QGCPX4AirframeConfig::quadXSelected() +{ + +} + +void QGCPX4AirframeConfig::quadXSelected(int index) +{ + int system_index = ui->quadXComboBox->itemData(index).toInt(); + setAirframeID(system_index); +} + +void QGCPX4AirframeConfig::quadPlusSelected() +{ + +} + +void QGCPX4AirframeConfig::quadPlusSelected(int index) +{ + int system_index = ui->quadPlusComboBox->itemData(index).toInt(); + setAirframeID(system_index); +} + +void QGCPX4AirframeConfig::hexaXSelected() +{ + +} + +void QGCPX4AirframeConfig::hexaXSelected(int index) +{ + int system_index = ui->hexaXComboBox->itemData(index).toInt(); + setAirframeID(system_index); +} + +void QGCPX4AirframeConfig::hexaPlusSelected() +{ + +} + +void QGCPX4AirframeConfig::hexaPlusSelected(int index) +{ + int system_index = ui->hexaPlusComboBox->itemData(index).toInt(); + setAirframeID(system_index); +} + +void QGCPX4AirframeConfig::octoXSelected() +{ + +} + +void QGCPX4AirframeConfig::octoXSelected(int index) +{ + int system_index = ui->octoXComboBox->itemData(index).toInt(); + setAirframeID(system_index); +} + +void QGCPX4AirframeConfig::octoPlusSelected() +{ + +} + +void QGCPX4AirframeConfig::octoPlusSelected(int index) +{ + int system_index = ui->octoPlusComboBox->itemData(index).toInt(); + setAirframeID(system_index); +} + +void QGCPX4AirframeConfig::hSelected() +{ + +} + +void QGCPX4AirframeConfig::hSelected(int index) +{ + int system_index = ui->hComboBox->itemData(index).toInt(); + setAirframeID(system_index); +} + + QGCPX4AirframeConfig::~QGCPX4AirframeConfig() { delete ui; diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.h b/src/ui/px4_configuration/QGCPX4AirframeConfig.h index 5cad0cb9d0..86ebce8964 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.h +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.h @@ -2,6 +2,7 @@ #define QGCPX4AIRFRAMECONFIG_H #include +#include namespace Ui { class QGCPX4AirframeConfig; @@ -14,8 +15,66 @@ class QGCPX4AirframeConfig : public QWidget public: explicit QGCPX4AirframeConfig(QWidget *parent = 0); ~QGCPX4AirframeConfig(); + +public slots: + + /** + * @brief Set the system currently operated on by this widget + * @param uas The currently active / configured system + */ + void setActiveUAS(UASInterface* uas); + + /** + * @brief Quadrotor in X configuration has been selected + */ + void quadXSelected(); + + /** + * @brief Quadrotor in X configuration has been selected with sub-type + * @param index The autostart index which maps to a particular sub-type + */ + void quadXSelected(int index); + + void flyingWingSelected(); + void flyingWingSelected(int index); + void planeSelected(); + void planeSelected(int index); + + void quadPlusSelected(); + void quadPlusSelected(int index); + void hexaXSelected(); + void hexaXSelected(int index); + void hexaPlusSelected(); + void hexaPlusSelected(int index); + void octoXSelected(); + void octoXSelected(int index); + void octoPlusSelected(); + void octoPlusSelected(int index); + void hSelected(); + void hSelected(int index); + + /** + * @brief Apply changes and reboot system + */ + void applyAndReboot(); + +protected: + + /** + * @brief Set the ID of the current airframe + * @param id the ID as defined by the PX4 SYS_AUTOSTART enum + */ + void setAirframeID(int id); + + /** + * @brief Enable automatic configuration + * @param enabled If true, the system sets the default gains for this platform on the next boot + */ + void setAutoConfig(bool enabled); + private: + UASInterface* mav; Ui::QGCPX4AirframeConfig *ui; }; diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui index f5aa09aa93..f73e0e14ac 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui @@ -6,8 +6,8 @@ 0 0 - 602 - 345 + 803 + 416 @@ -24,8 +24,8 @@ 0 0 - 561 - 299 + 802 + 531 @@ -121,6 +121,16 @@ + + + :/files/images/px4/airframes/quad_x.png:/files/images/px4/airframes/quad_x.png + + + + 120 + 120 + + @@ -159,14 +169,24 @@ - + - PushButton + + + + + :/files/images/px4/airframes/quad_+.png:/files/images/px4/airframes/quad_+.png + + + + 120 + 120 + - + @@ -180,14 +200,24 @@ - + - PushButton + + + + + :/files/images/px4/airframes/hexa_x.png:/files/images/px4/airframes/hexa_x.png + + + + 120 + 120 + - + @@ -201,14 +231,24 @@ - + - PushButton + + + + + :/files/images/px4/airframes/hexa_+.png:/files/images/px4/airframes/hexa_+.png + + + + 120 + 120 + - + @@ -224,12 +264,22 @@ - PushButton + + + + + :/files/images/px4/airframes/octo_x.png:/files/images/px4/airframes/octo_x.png + + + + 120 + 120 + - + @@ -245,12 +295,22 @@ - PushButton + + + + + :/files/images/px4/airframes/octo_+.png:/files/images/px4/airframes/octo_+.png + + + + 120 + 120 + - + @@ -266,12 +326,12 @@ - PushButton + - + Steadydrone @@ -313,6 +373,8 @@ - + + + diff --git a/src/ui/uas/QGCMessageView.cc b/src/ui/uas/QGCMessageView.cc index 67a28216f3..7f4f891c8a 100644 --- a/src/ui/uas/QGCMessageView.cc +++ b/src/ui/uas/QGCMessageView.cc @@ -22,6 +22,7 @@ QGCMessageView::QGCMessageView(QWidget *parent) : ui->horizontalLayout->addWidget(connectWidget); ui->plainTextEdit->hide(); + setActiveUAS(UASManager::instance()->getActiveUAS()); connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); } -- GitLab From 99a8946e0f3a0a6cc1f80f79806db252149d3637 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sat, 17 Aug 2013 23:02:04 +0200 Subject: [PATCH 283/460] Minor cleanup in PFD --- src/ui/PrimaryFlightDisplay.cc | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/ui/PrimaryFlightDisplay.cc b/src/ui/PrimaryFlightDisplay.cc index a68acdf545..5c7fca0f46 100644 --- a/src/ui/PrimaryFlightDisplay.cc +++ b/src/ui/PrimaryFlightDisplay.cc @@ -169,18 +169,13 @@ PrimaryFlightDisplay::PrimaryFlightDisplay(int width, int height, QWidget *paren setMinimumSize(120, 80); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + setActiveUAS(UASManager::instance()->getActiveUAS()); + // Connect with UAS signal //connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(addUAS(UASInterface*))); connect(UASManager::instance(), SIGNAL(UASDeleted(UASInterface*)), this, SLOT(forgetUAS(UASInterface*))); connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); -// // Get a list of all existing UAS and - well attach to one of them. The first one. -// foreach (UASInterface* uas, UASManager::instance()->getUASList()) { -// addUAS(uas); -// } - - setActiveUAS(UASManager::instance()->getActiveUAS()); - // Refresh timer refreshTimer->setInterval(updateInterval); // connect(refreshTimer, SIGNAL(timeout()), this, SLOT(paintHUD())); -- GitLab From 41d76c0cacaecdc864e6d0d6ba01323257578620 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 18 Aug 2013 00:33:01 +0200 Subject: [PATCH 284/460] Minor style fixes --- files/styles/style-dark.css | 11 ++++++----- src/ui/PrimaryFlightDisplay.cc | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/files/styles/style-dark.css b/files/styles/style-dark.css index 3287e307e4..68da19cbe6 100644 --- a/files/styles/style-dark.css +++ b/files/styles/style-dark.css @@ -345,13 +345,14 @@ QPushButton, QToolButton { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #777, stop: 1 #333); } -QPushButton#planePushButton, QPushButton#flyingWingPushButton, QPushButton#quadXPushButton, QPushButton#quadPlusPushButton, QPushButton#hPushButton { +QPushButton#planePushButton, QPushButton#flyingWingPushButton, QPushButton#quadXPushButton, +QPushButton#quadPlusPushButton, QPushButton#hexaXPushButton, QPushButton#hexaPlusPushButton, +QPushButton#octoXPushButton, QPushButton#octoPlusPushButton, QPushButton#hPushButton { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #777, stop: 1 #333); border-radius: 12px; - min-height: 120px; - max-height: 140px; - min-width: 120px; - max-width: 140px; + min-height: 140px; + max-height: 240px; + min-width: 140px; border: 3px solid #465158; } diff --git a/src/ui/PrimaryFlightDisplay.cc b/src/ui/PrimaryFlightDisplay.cc index 7910775fed..cce53d6312 100644 --- a/src/ui/PrimaryFlightDisplay.cc +++ b/src/ui/PrimaryFlightDisplay.cc @@ -357,6 +357,7 @@ void PrimaryFlightDisplay::updateAttitude(UASInterface* uas, double roll, double if (yaw<0) yaw+=360; this->heading = yaw; } + } void PrimaryFlightDisplay::updateAttitude(UASInterface* uas, int component, double roll, double pitch, double yaw, quint64 timestamp) -- GitLab From 32b15c26d4ae6fc6a492ae7eb096fe4e93fa5bed Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sat, 17 Aug 2013 17:38:15 -0700 Subject: [PATCH 285/460] fix emits of comms updates, fix serial error queueing fixed runtime error with a typedef: QObject::connect: Cannot queue arguments of type 'QSerialPort::SerialPortError' (Make sure 'QSerialPort::SerialPortError' is registered using qRegisterMetaType().) --- src/comm/SerialLink.cc | 93 +++++++++++++++++++----------------------- src/comm/SerialLink.h | 6 ++- 2 files changed, 46 insertions(+), 53 deletions(-) diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 1e19bc2a80..d3fe69f869 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -19,6 +19,8 @@ #include "QGC.h" #include + + SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, bool parity, int dataBits, int stopBits) : m_bytesRead(0), @@ -137,8 +139,7 @@ void SerialLink::writeSettings() void SerialLink::run() { // Initialize the connection - if (!hardwareConnect()) - { + if (!hardwareConnect()) { //Need to error out here. emit communicationError(getName(),"Error connecting: " + m_port->errorString()); disconnect(); // This tidies up and sends the necessary signals @@ -155,30 +156,25 @@ void SerialLink::run() qint64 timeout = 5000; int linkErrorCount = 0; - forever - { - { - QMutexLocker locker(&this->m_stoppMutex); - if(m_stopp) - { - m_stopp = false; - break; // exit the thread - } + forever { + QMutexLocker locker(&this->m_stoppMutex); + if(m_stopp) { + m_stopp = false; + break; // exit the thread + } - if (m_reqReset) - { - m_reqReset = false; - communicationUpdate(getName(),"Reset requested via DTR signal"); - m_port->setDataTerminalReady(true); - msleep(250); - m_port->setDataTerminalReady(false); - } + if (m_reqReset) { + m_reqReset = false; + emit communicationUpdate(getName(),"Reset requested via DTR signal"); + m_port->setDataTerminalReady(true); + msleep(250); + m_port->setDataTerminalReady(false); } if (isConnected() && (linkErrorCount > 100)) { qDebug() << "linkErrorCount too high: disconnecting!"; linkErrorCount = 0; - communicationError("SerialLink", tr("Disconnecting on too many link errors")); + emit communicationUpdate(getName(), tr("Disconnecting on too many link errors")); disconnect(); } @@ -186,19 +182,21 @@ void SerialLink::run() QMutexLocker writeLocker(&m_writeMutex); int numWritten = m_port->write(m_transmitBuffer); bool txSuccess = m_port->waitForBytesWritten(1); - if (!txSuccess || (numWritten != m_transmitBuffer.count())) - { + if (!txSuccess || (numWritten != m_transmitBuffer.count())) { linkErrorCount++; qDebug() << "TX Error! wrote" << numWritten << ", asked for " << m_transmitBuffer.count() << "bytes"; - } else { + } + else { linkErrorCount = 0; } m_transmitBuffer = m_transmitBuffer.remove(0, numWritten); } + //wait n msecs for data to be ready + //[TODO][BB] lower to SerialLink::poll_interval? bool success = m_port->waitForReadyRead(10); - if (success) { // Waits for 1/2 second [TODO][BB] lower to SerialLink::poll_interval? + if (success) { QByteArray readData = m_port->readAll(); while (m_port->waitForReadyRead(10)) readData += m_port->readAll(); @@ -210,24 +208,21 @@ void SerialLink::run() m_bitsReceivedTotal += readData.length() * 8; linkErrorCount = 0; } - } else { + } + else { linkErrorCount++; - //qDebug() << "Wait read response timeout" << QTime::currentTime().toString(); + qDebug() << "Wait read response timeout" << QTime::currentTime().toString(); } - if (bytes != m_bytesRead) // i.e things are good and data is being read. - { + if (bytes != m_bytesRead) { // i.e things are good and data is being read. bytes = m_bytesRead; msecs = QDateTime::currentMSecsSinceEpoch(); } - else - { - if (QDateTime::currentMSecsSinceEpoch() - msecs > timeout) - { + else { + if (QDateTime::currentMSecsSinceEpoch() - msecs > timeout) { //It's been 10 seconds since the last data came in. Reset and try again msecs = QDateTime::currentMSecsSinceEpoch(); - if (msecs - initialmsecs > 25000) - { + if (msecs - initialmsecs > 25000) { //After initial 25 seconds, timeouts are increased to 30 seconds. //This prevents temporary silences from things like calibration commands //from screwing things up. In all reality, timeouts should be enabled/disabled @@ -235,25 +230,22 @@ void SerialLink::run() //TODO ^^ timeout = 30000; } - if (!triedDTR && triedreset) - { + if (!triedDTR && triedreset) { triedDTR = true; - communicationUpdate(getName(),"No data to receive on COM port. Attempting to reset via DTR signal"); + emit communicationUpdate(getName(),"No data to receive on COM port. Attempting to reset via DTR signal"); qDebug() << "No data!!! Attempting reset via DTR."; m_port->setDataTerminalReady(true); msleep(250); m_port->setDataTerminalReady(false); } - else if (!triedreset) - { + else if (!triedreset) { qDebug() << "No data!!! Attempting reset via reboot command."; - communicationUpdate(getName(),"No data to receive on COM port. Assuming possible terminal mode, attempting to reset via \"reboot\" command"); + emit communicationUpdate(getName(),"No data to receive on COM port. Assuming possible terminal mode, attempting to reset via \"reboot\" command"); m_port->write("reboot\r\n",8); triedreset = true; } - else - { - communicationUpdate(getName(),"No data to receive on COM port...."); + else { + emit communicationUpdate(getName(),"No data to receive on COM port...."); qDebug() << "No data!!!"; } } @@ -406,8 +398,7 @@ bool SerialLink::connect() **/ bool SerialLink::hardwareConnect() { - if(m_port) - { + if(m_port) { qDebug() << "SerialLink:" << QString::number((long)this, 16) << "closing port"; m_port->close(); delete m_port; @@ -416,21 +407,19 @@ bool SerialLink::hardwareConnect() qDebug() << "SerialLink: hardwareConnect to " << m_portName; m_port = new QSerialPort(m_portName); - if (m_port == NULL) - { + if (m_port == NULL) { emit communicationUpdate(getName(),"Error opening port: " + m_port->errorString()); return false; // couldn't create serial port. } QObject::connect(m_port,SIGNAL(aboutToClose()),this,SIGNAL(disconnected())); - QObject::connect(m_port, SIGNAL(error(QSerialPort::SerialPortError)), - this, SLOT(linkError(QSerialPort::SerialPortError))); + QObject::connect(m_port, SIGNAL(error(SerialLinkPortError_t)), + this, SLOT(linkError(SerialLinkPortError_t))); // port->setCommTimeouts(QSerialPort::CtScheme_NonBlockingRead); m_connectionStartTime = MG::TIME::getGroundTimeNow(); - if (!m_port->open(QIODevice::ReadWrite)) - { + if (!m_port->open(QIODevice::ReadWrite)) { emit communicationUpdate(getName(),"Error opening port: " + m_port->errorString()); m_port->close(); return false; // couldn't open serial port @@ -456,7 +445,7 @@ bool SerialLink::hardwareConnect() return true; // successful connection } -void SerialLink::linkError(QSerialPort::SerialPortError error) +void SerialLink::linkError(SerialLinkPortError_t error) { qDebug() << error; } diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index 9436ec883a..2bde8be22b 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -40,6 +40,9 @@ This file is part of the QGROUNDCONTROL project #include #include "SerialLinkInterface.h" +// convenience type for passing errors +typedef QSerialPort::SerialPortError SerialLinkPortError_t; + /** * @brief The SerialLink class provides cross-platform access to serial links. * It takes care of the link management and provides a common API to higher @@ -53,6 +56,7 @@ class SerialLink : public SerialLinkInterface Q_OBJECT //Q_INTERFACES(SerialLinkInterface:LinkInterface) + public: SerialLink(QString portname = "", int baudrate=57600, @@ -142,7 +146,7 @@ public slots: bool connect(); bool disconnect(); - void linkError(QSerialPort::SerialPortError error); + void linkError(SerialLinkPortError_t error); protected: quint64 m_bytesRead; -- GitLab From 995cf20fe28f317ded4de07c9bf83078000d3fd9 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 18 Aug 2013 16:50:47 +0200 Subject: [PATCH 286/460] Config improvements, added firmware upload capability --- .gitignore | 2 +- qgroundcontrol.pro | 27 +++++-- src/comm/SerialLink.cc | 22 +++--- src/uas/QGCUASParamManager.cc | 5 +- src/uas/QGCUASParamManager.h | 23 ++++++ src/uas/UASParameterDataModel.cc | 13 ++++ src/uas/UASParameterDataModel.h | 7 +- src/ui/QGCPX4VehicleConfig.cc | 35 +++++++-- src/ui/QGCPX4VehicleConfig.h | 4 ++ src/ui/QGCPX4VehicleConfig.ui | 21 +++++- .../px4_configuration/QGCPX4AirframeConfig.cc | 71 ++++++++++++++++--- .../px4_configuration/QGCPX4AirframeConfig.h | 1 + 12 files changed, 196 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 3328a8981f..06aaffca0a 100644 --- a/.gitignore +++ b/.gitignore @@ -52,5 +52,5 @@ user_config.pri thirdParty/qserialport-build-desktop/ thirdParty/qserialport/bin/ thirdParty/qserialport/lib/ -apmplanner2.xcodeproj/ GeneratedFiles/ +/qupgrade/ diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 206cb397d6..371688a7f8 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -142,6 +142,27 @@ INCLUDEPATH += \ include(src/apps/mavlinkgen/mavlinkgen.pri) +# Include QUpgrade tool +exists(qupgrade) { + SOURCES += qupgrade/src/apps/qupgrade/qgcfirmwareupgradeworker.cpp \ + qupgrade/src/apps/qupgrade/uploader.cpp \ + qupgrade/src/apps/qupgrade/dialog_bare.cpp + + HEADERS += qupgrade/src/apps/qupgrade/qgcfirmwareupgradeworker.h \ + qupgrade/src/apps/qupgrade/uploader.h \ + qupgrade/src/apps/qupgrade/dialog_bare.h + + FORMS += qupgrade/src/apps/qupgrade/dialog_bare.ui + + linux*:CONFIG += qesp_linux_udev + + include(qupgrade/libs/qextserialport/src/qextserialport.pri) + + INCLUDEPATH += qupgrade/src/apps/qupgrade + + DEFINES += "QUPGRADE_SUPPORT" +} + # Include QWT plotting library include(libs/qwt/qwt.pri) @@ -153,12 +174,6 @@ INCLUDEPATH += . # Include serial port library (QSerialPort) include(libs/serialport/qserialport.pri) -## Serial port detection (ripped-off from qextserialport library) -#macx|macx-g++|macx-g++42::SOURCES += libs/qextserialport/qextserialenumerator_osx.cpp -#linux-g++::SOURCES += libs/qextserialport/qextserialenumerator_unix.cpp -#linux-g++-64::SOURCES += libs/qextserialport/qextserialenumerator_unix.cpp -#win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += libs/qextserialport/qextserialenumerator_win.cpp - # Input FORMS += src/ui/MainWindow.ui \ src/ui/CommSettings.ui \ diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index d3fe69f869..9935bf33d2 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -157,18 +157,20 @@ void SerialLink::run() int linkErrorCount = 0; forever { + { QMutexLocker locker(&this->m_stoppMutex); - if(m_stopp) { - m_stopp = false; - break; // exit the thread - } + if(m_stopp) { + m_stopp = false; + break; // exit the thread + } - if (m_reqReset) { - m_reqReset = false; - emit communicationUpdate(getName(),"Reset requested via DTR signal"); - m_port->setDataTerminalReady(true); - msleep(250); - m_port->setDataTerminalReady(false); + if (m_reqReset) { + m_reqReset = false; + emit communicationUpdate(getName(),"Reset requested via DTR signal"); + m_port->setDataTerminalReady(true); + msleep(250); + m_port->setDataTerminalReady(false); + } } if (isConnected() && (linkErrorCount > 100)) { diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index d62244e552..68f1ed0dfc 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -48,7 +48,10 @@ void QGCUASParamManager::clearAllPendingParams() paramDataModel.clearAllPendingParams(); } - +QList QGCUASParamManager::getComponentForParam(const QString& parameter) const +{ + return paramDataModel.getComponentForOnboardParam(parameter); +} bool QGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index f4598db0af..81a12575a5 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -23,9 +23,32 @@ public: /** @brief Get the known, confirmed value of a parameter */ virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; + /** + * @brief Get a list of all component IDs using this parameter name + * @param parameter The string encoding the parameter name + * @return A list with all components using this parameter name. Can be empty. + */ + virtual QList getComponentForParam(const QString& parameter) const; + /** @brief Provide tooltips / user-visible descriptions for parameters */ virtual void setParamDescriptions(const QMap& paramDescs); + /** + * @brief Count the pending parameters in the current transmission + * @return The number of pending parameters + */ + virtual int countPendingParams() { + return paramDataModel.countPendingParams(); + } + + /** + * @brief Count the number of onboard parameters + * @return The number of onboard parameters + */ + virtual int countOnboardParams() { + return paramDataModel.countOnboardParams(); + } + /** @brief Get the UAS of this widget * @return The MAV of this mgr. Unless the MAV object has been destroyed, this is never null. */ diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 5ecb37db89..b3aaed28ef 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -192,6 +192,19 @@ bool UASParameterDataModel::getOnboardParamValue(int componentId, const QString& return false; } +QList UASParameterDataModel::getComponentForOnboardParam(const QString& parameter) const +{ + QList components; + // Iterate through all components + foreach (int comp, onboardParameters.keys()) + { + if (onboardParameters.value(comp)->contains(parameter)) + components.append(comp); + } + + return components; +} + void UASParameterDataModel::forgetAllOnboardParams() { onboardParameters.clear(); diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 738e9c36e5..bcff40ab8c 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -34,7 +34,12 @@ public: */ virtual void addComponent(int compId); - + /** + * @brief Return a list of all components for this parameter name + * @param parameter The parameter string to search for + * @return A list with all components, can be potentially empty + */ + virtual QList getComponentForOnboardParam(const QString& parameter) const; /** @brief Save the onboard parameter with a the type specified in the QVariant as fixed */ virtual void setOnboardParamWithType(int componentId, QString& key, QVariant& value); diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index c37c134228..dcd406e582 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include "QGCPX4VehicleConfig.h" @@ -21,12 +22,14 @@ #include "UASParameterCommsMgr.h" #include "ui_QGCPX4VehicleConfig.h" #include "px4_configuration/QGCPX4AirframeConfig.h" +#include -#define WIDGET_INDEX_RC 0 -#define WIDGET_INDEX_SENSOR_CAL 1 -#define WIDGET_INDEX_AIRFRAME_CONFIG 2 -#define WIDGET_INDEX_GENERAL_CONFIG 3 -#define WIDGET_INDEX_ADV_CONFIG 4 +#define WIDGET_INDEX_FIRMWARE 0 +#define WIDGET_INDEX_RC 1 +#define WIDGET_INDEX_SENSOR_CAL 2 +#define WIDGET_INDEX_AIRFRAME_CONFIG 3 +#define WIDGET_INDEX_GENERAL_CONFIG 4 +#define WIDGET_INDEX_ADV_CONFIG 5 #define MIN_PWM_VAL 800 #define MAX_PWM_VAL 2200 @@ -48,6 +51,9 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : rc_mode(RC_MODE_NONE), calibrationEnabled(false), px4AirframeConfig(NULL), + #ifdef QUPGRADE_SUPPORT + firmwareDialog(NULL), + #endif ui(new Ui::QGCPX4VehicleConfig) { doneLoadingConfig = false; @@ -71,6 +77,17 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : px4AirframeConfig = new QGCPX4AirframeConfig(this); ui->airframeLayout->addWidget(px4AirframeConfig); +#ifdef QUPGRADE_SUPPORT + firmwareDialog = new DialogBare(this); + ui->firmwareLayout->addWidget(firmwareDialog); +#else +#error Please check out QUpgrade from http://github.com/LorenzMeier/qupgrade/ into the QGroundControl folder. + + QLabel* label = new QLabel(this); + label->setText("THIS VERSION OF QGROUNDCONTROL WAS BUILT WITHOUT QUPGRADE. To enable firmware upload support, checkout QUpgrade WITHIN the QGroundControl folder"); + ui->firmwareLayout->addWidget(label); +#endif + ui->rollWidget->setOrientation(Qt::Horizontal); ui->rollWidget->setName("Roll"); ui->yawWidget->setOrientation(Qt::Horizontal); @@ -91,6 +108,7 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(ui->generalMenuButton,SIGNAL(clicked()),this,SLOT(generalMenuButtonClicked())); connect(ui->advancedMenuButton,SIGNAL(clicked()),this,SLOT(advancedMenuButtonClicked())); connect(ui->airframeMenuButton, SIGNAL(clicked()), this, SLOT(airframeMenuButtonClicked())); + connect(ui->firmwareMenuButton, SIGNAL(clicked()), this, SLOT(firmwareButtonClicked())); ui->rcCalibrationButton->setCheckable(true); connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool))); @@ -176,6 +194,11 @@ void QGCPX4VehicleConfig::airframeMenuButtonClicked() ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_AIRFRAME_CONFIG); } +void QGCPX4VehicleConfig::firmwareMenuButtonClicked() +{ + ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_FIRMWARE); +} + void QGCPX4VehicleConfig::identifyChannelMapping(int aert_index) { if (chanCount == 0) @@ -1089,7 +1112,7 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) channelWanted = -1; - // Reject + // Confirm found channel QMessageBox msgBox; msgBox.setText(tr("%1 Channel found.").arg(channelNames[chanFound])); msgBox.setInformativeText(tr("Found %1 to be on the raw RC channel %2").arg(channelNames[chanFound]).arg(chan + 1)); diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index 8d735a175d..83b85c927e 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -13,6 +13,7 @@ #include "px4_configuration/QGCPX4AirframeConfig.h" class UASParameterCommsMgr; +class DialogBare; namespace Ui { class QGCPX4VehicleConfig; @@ -40,6 +41,8 @@ public slots: void generalMenuButtonClicked(); void advancedMenuButtonClicked(); void airframeMenuButtonClicked(); + void firmwareMenuButtonClicked(); + void identifyChannelMapping(int aert_index); /** Set the MAV currently being calibrated */ @@ -248,6 +251,7 @@ protected: QMap paramTooltips; ///< Tooltips for the ? button next to a parameter. QGCPX4AirframeConfig* px4AirframeConfig; + DialogBare* firmwareDialog; private: Ui::QGCPX4VehicleConfig *ui; diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 9f2942dfc7..4322884b09 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -52,6 +52,14 @@ QLayout::SetMinAndMaxSize + + + + Firmware +Upgrade + + + @@ -146,8 +154,19 @@ Config - 1 + 0 + + + + + + Firmware Upgrade + + + + + diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index f049fee870..d660035505 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -1,3 +1,5 @@ +#include + #include "QGCPX4AirframeConfig.h" #include "ui_QGCPX4AirframeConfig.h" @@ -7,6 +9,7 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : QWidget(parent), mav(NULL), + selectedId(-1), ui(new Ui::QGCPX4AirframeConfig) { ui->setupUi(this); @@ -62,23 +65,73 @@ void QGCPX4AirframeConfig::setActiveUAS(UASInterface* uas) void QGCPX4AirframeConfig::setAirframeID(int id) { - // If UAS is present, get param manager and set SYS_AUTOSTART ID - if (!mav) - return; - - mav->getParamManager()->setParameter(0, "SYS_AUTOSTART", (qint32)id); + selectedId = id; } void QGCPX4AirframeConfig::applyAndReboot() { - UAS* uas = qobject_cast(mav); + // Guard against the case of an edit where we didn't receive all params yet + if (selectedId < 0) + { + QMessageBox msgBox; + msgBox.setText(tr("No airframe selected")); + msgBox.setInformativeText(tr("Please select an airframe first.")); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + (void)msgBox.exec(); + + return; + } + + if (!mav) + return; + + if (mav->getParamManager()->countOnboardParams() == 0 && + mav->getParamManager()->countPendingParams() == 0) + { + mav->getParamManager()->requestParameterListIfEmpty(); + QGC::SLEEP::msleep(100); + } + + // Guard against the case of an edit where we didn't receive all params yet + if (mav->getParamManager()->countPendingParams() > 0) + { + QMessageBox msgBox; + msgBox.setText(tr("Parameter sync with UAS not yet complete")); + msgBox.setInformativeText(tr("Please wait a few moments and retry")); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + (void)msgBox.exec(); - if (!uas) return; + } + + QList components = mav->getParamManager()->getComponentForParam("SYS_AUTOSTART"); + + // Guard against multiple components responding - this will never show in practice + if (components.count() != 1) { + QMessageBox msgBox; + msgBox.setText(tr("Invalid system setup detected")); + msgBox.setInformativeText(tr("None or more than one component advertised to provide the main system configuration option. This is an invalid system setup - please check your autopilot.")); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + (void)msgBox.exec(); + + return; + } + + qDebug() << "Setting comp" << components.first() << "SYS_AUTOSTART" << (qint32)selectedId; + + mav->getParamManager()->setParameter(components.first(), "SYS_AUTOSTART", (qint32)selectedId); + + // Send pending params + mav->getParamManager()->sendPendingParameters(); + QGC::SLEEP::msleep(300); // Store parameters - uas->executeCommand(MAV_CMD_PREFLIGHT_STORAGE, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); + mav->getParamManager()->copyVolatileParamsToPersistent(); + QGC::SLEEP::msleep(500); // Reboot - uas->executeCommand(MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); + mav->executeCommand(MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); } void QGCPX4AirframeConfig::setAutoConfig(bool enabled) diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.h b/src/ui/px4_configuration/QGCPX4AirframeConfig.h index 86ebce8964..4c3c9a0d1b 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.h +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.h @@ -75,6 +75,7 @@ protected: private: UASInterface* mav; + int selectedId; Ui::QGCPX4AirframeConfig *ui; }; -- GitLab From fb33f69eee476a36dcd93de4a91d7e9b8a73d34b Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 18 Aug 2013 18:35:51 +0200 Subject: [PATCH 287/460] Removed unused file --- qgroundcontrol.pro | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 371688a7f8..383e00dae2 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -404,8 +404,7 @@ HEADERS += src/MG.h \ src/ui/QGCMAVLinkInspector.h \ src/ui/MAVLinkDecoder.h \ src/ui/WaypointViewOnlyView.h \ - src/ui/WaypointEditableView.h \ - src/ui/UnconnectedUASInfoWidget.h \ + src/ui/WaypointEditableView.h \ src/ui/QGCRGBDView.h \ src/ui/mavlink/QGCMAVLinkMessageSender.h \ src/ui/firmwareupdate/QGCFirmwareUpdateWidget.h \ -- GitLab From 4f1df9b3a9dc9aef233794a874e4372918b7ab64 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sun, 18 Aug 2013 18:06:58 -0700 Subject: [PATCH 288/460] pass along important data model signals via param mgr --- src/uas/QGCUASParamManager.cc | 9 +++++++++ src/uas/QGCUASParamManager.h | 6 ++++++ src/ui/QGCBaseParamWidget.cc | 8 ++++---- src/ui/QGCPendingParamWidget.cc | 16 +++++++++++----- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 68f1ed0dfc..aa4bd8174b 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -40,6 +40,15 @@ void QGCUASParamManager::connectToModelAndComms() connect(paramCommsMgr, SIGNAL(parameterListUpToDate()), this, SIGNAL(parameterListUpToDate())); + + // Pass along data model updates + connect(¶mDataModel, SIGNAL(parameterUpdated(int, QString , QVariant )), + this, SIGNAL(parameterUpdated(int, QString , QVariant ))); + + connect(¶mDataModel, SIGNAL(pendingParamUpdate(int , const QString& , QVariant , bool )), + this, SIGNAL(pendingParamUpdate(int , const QString& , QVariant , bool ))); + + } diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 81a12575a5..c0cf6cd21a 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -72,6 +72,12 @@ signals: /** @brief We have received a complete list of all parameters onboard the MAV */ void parameterListUpToDate(); + /** @brief We've received an update of a parameter's value */ + void parameterUpdated(int compId, QString paramName, QVariant value); + + /** @brief Notifies listeners that a param was added to or removed from the pending list */ + void pendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); + public slots: diff --git a/src/ui/QGCBaseParamWidget.cc b/src/ui/QGCBaseParamWidget.cc index d80e53693e..f1d8d60a73 100644 --- a/src/ui/QGCBaseParamWidget.cc +++ b/src/ui/QGCBaseParamWidget.cc @@ -53,10 +53,10 @@ void QGCBaseParamWidget::connectToParamManager() paramMgr = mav->getParamManager(); //TODO route via paramManager instead? // Listen to updated param signals from the data model - connect(paramMgr->dataModel(), SIGNAL(parameterUpdated(int, QString , QVariant )), + connect(paramMgr, SIGNAL(parameterUpdated(int, QString , QVariant )), this, SLOT(handleOnboardParamUpdate(int,QString,QVariant))); - connect(paramMgr->dataModel(), SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), + connect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); // Listen for param list reload finished @@ -71,10 +71,10 @@ void QGCBaseParamWidget::connectToParamManager() void QGCBaseParamWidget::disconnectFromParamManager() { - disconnect(paramMgr->dataModel(), SIGNAL(parameterUpdated(int, QString , QVariant )), + disconnect(paramMgr, SIGNAL(parameterUpdated(int, QString , QVariant )), this, SLOT(handleOnboardParamUpdate(int,QString,QVariant))); - disconnect(paramMgr->dataModel(), SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), + disconnect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); disconnect(paramMgr, SIGNAL(parameterListUpToDate()), diff --git a/src/ui/QGCPendingParamWidget.cc b/src/ui/QGCPendingParamWidget.cc index c5fb5a010f..384547f07e 100644 --- a/src/ui/QGCPendingParamWidget.cc +++ b/src/ui/QGCPendingParamWidget.cc @@ -16,9 +16,9 @@ QGCPendingParamWidget::QGCPendingParamWidget(QObject *parent) : void QGCPendingParamWidget::connectToParamManager() { paramMgr = mav->getParamManager(); - //TODO route via paramManager instead? + // Listen to updated param signals from the data model - connect(paramMgr->dataModel(), SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), + connect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); // Listen to communications status messages so we can display them @@ -29,9 +29,8 @@ void QGCPendingParamWidget::connectToParamManager() void QGCPendingParamWidget::disconnectFromParamManager() { - //TODO route via paramManager instead? // Listen to updated param signals from the data model - disconnect(paramMgr->dataModel(), SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), + disconnect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); // Listen to communications status messages so we can display them @@ -76,7 +75,14 @@ void QGCPendingParamWidget::handlePendingParamUpdate(int compId, const QString& } else { //we don't display non-pending items - paramItem->parent()->removeChild(paramItem); + QTreeWidgetItem* parentItem = paramItem->parent(); + + if (NULL != parentItem && 1 == parentItem->childCount()) { + parentItem->parent()->removeChild(parentItem); + } + else { + paramItem->parent()->removeChild(paramItem); + } } updatingParamNameLock.clear(); -- GitLab From 72f465db33f6e4e0b26e30eb129062c2133b26b0 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sun, 18 Aug 2013 20:20:58 -0700 Subject: [PATCH 289/460] cleanup internal data structures that reference the groupItem --- src/ui/QGCPendingParamWidget.cc | 38 +++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/ui/QGCPendingParamWidget.cc b/src/ui/QGCPendingParamWidget.cc index 384547f07e..35402d995e 100644 --- a/src/ui/QGCPendingParamWidget.cc +++ b/src/ui/QGCPendingParamWidget.cc @@ -75,13 +75,39 @@ void QGCPendingParamWidget::handlePendingParamUpdate(int compId, const QString& } else { //we don't display non-pending items - QTreeWidgetItem* parentItem = paramItem->parent(); + QTreeWidgetItem* groupItem = paramItem->parent(); + if (NULL != groupItem) { + tree->setUpdatesEnabled(false); + QTreeWidgetItem* componentItem = NULL; + if (1 == groupItem->childCount()) { + componentItem = groupItem->parent(); + } + + //always remove the actual paramItem from its parent + groupItem->removeChild(paramItem); + + //now we may need to remove the groupItem if it has no more children + if (NULL != componentItem) { + //remove the group from our internal data structures + QMap* compParamGroups = paramGroups.value(compId); + QString groupStr = paramName.section("_", 0, 0, QString::SectionSkipEmpty); + compParamGroups->remove(groupStr); + //remove the group item from componentItems + componentItems->value(compId)->removeChild(groupItem); + // remove the group item from the tree widget itself + componentItem->removeChild(groupItem); + + if (0 == componentItem->childCount()) { + //the component itself no longer has any pending changes: remove it + paramGroups.remove(compId); + componentItems->remove(compId); + QTreeWidgetItem* compTop = tree->takeTopLevelItem(tree->indexOfTopLevelItem(componentItem)); + delete compTop; //we own it after take + } + } + tree->setUpdatesEnabled(true); + tree->update(); - if (NULL != parentItem && 1 == parentItem->childCount()) { - parentItem->parent()->removeChild(parentItem); - } - else { - paramItem->parent()->removeChild(paramItem); } } -- GitLab From 9947f0466ba6973f11f5d53f70a2937f0cc88b20 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sun, 18 Aug 2013 21:02:17 -0700 Subject: [PATCH 290/460] Fix firmwareMenuButtonClicked wiring --- src/ui/QGCPX4VehicleConfig.cc | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index dcd406e582..9f6695ec4a 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -103,12 +103,18 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : ui->radio8Widget->setOrientation(Qt::Horizontal); ui->radio8Widget->setName("Radio 8"); - connect(ui->rcMenuButton,SIGNAL(clicked()),this,SLOT(rcMenuButtonClicked())); - connect(ui->sensorMenuButton,SIGNAL(clicked()),this,SLOT(sensorMenuButtonClicked())); - connect(ui->generalMenuButton,SIGNAL(clicked()),this,SLOT(generalMenuButtonClicked())); - connect(ui->advancedMenuButton,SIGNAL(clicked()),this,SLOT(advancedMenuButtonClicked())); - connect(ui->airframeMenuButton, SIGNAL(clicked()), this, SLOT(airframeMenuButtonClicked())); - connect(ui->firmwareMenuButton, SIGNAL(clicked()), this, SLOT(firmwareButtonClicked())); + connect(ui->rcMenuButton,SIGNAL(clicked()), + this,SLOT(rcMenuButtonClicked())); + connect(ui->sensorMenuButton,SIGNAL(clicked()), + this,SLOT(sensorMenuButtonClicked())); + connect(ui->generalMenuButton,SIGNAL(clicked()), + this,SLOT(generalMenuButtonClicked())); + connect(ui->advancedMenuButton,SIGNAL(clicked()), + this,SLOT(advancedMenuButtonClicked())); + connect(ui->airframeMenuButton, SIGNAL(clicked()), + this, SLOT(airframeMenuButtonClicked())); + connect(ui->firmwareMenuButton, SIGNAL(clicked()), + this, SLOT(firmwareMenuButtonClicked())); ui->rcCalibrationButton->setCheckable(true); connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool))); -- GitLab From 467a2a11762f0505c24d72ec476e94b74e2a0772 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 19 Aug 2013 08:08:13 +0200 Subject: [PATCH 291/460] Minor UI improvements, WIP --- files/images/px4/airframes/flying_wing.png | Bin 0 -> 12710 bytes files/images/px4/airframes/plane_aert.png | Bin 0 -> 14382 bytes files/images/px4/airframes/plane_ert.png | Bin 0 -> 12613 bytes qgroundcontrol.qrc | 3 + .../px4_configuration/QGCPX4AirframeConfig.cc | 3 + .../px4_configuration/QGCPX4AirframeConfig.ui | 93 ++++-------------- src/ui/uas/UASListWidget.cc | 3 + 7 files changed, 28 insertions(+), 74 deletions(-) create mode 100644 files/images/px4/airframes/flying_wing.png create mode 100644 files/images/px4/airframes/plane_aert.png create mode 100644 files/images/px4/airframes/plane_ert.png diff --git a/files/images/px4/airframes/flying_wing.png b/files/images/px4/airframes/flying_wing.png new file mode 100644 index 0000000000000000000000000000000000000000..b5baa87dd2b6fc1366feaac3ee43b3eea6947280 GIT binary patch literal 12710 zcmeAS@N?(olHy`uVBq!ia0y~yVEoF!z%YY@je&vTZ)kxc0|Ns~v6E*A2L}g74M$1` z0|NtRfk$L90|W1I5N71I>E6V^z#v)T8c`CQpH@mmtT}V z`<;yx1A_vCr;B4q#hkZyGfSqX?lS-J|F4gAwbzLwHYx87G*vV>G&COBbaO;3U$te< z0juRYtJjo&ef3U%dHDX-)ob5<-50;h=32q31D%&v$7n1!soaS|qP={}_K4>?n_1AuIzqO-%zJXKn zsp`Lb*H*Cm)$Ey-v^wmF@!52r%;^2or|oR&kgEE7Rx_CIVa&+&6F z_nAKNsQ2N+&+qXr%$oP)<(jolhj&fADJ=a@uXUAdiTU-tzAlpfOoqqy34*k8D7x6S z{Fo@m^WQ7u*NPL1{eK^``;mM$-s;fnjJr!xAD(%}FBrX7>0VvRex;DN`DI!kqm^#G zEj2qP!C!jJM!jXmYSzR06H;wstcvFeSALlpaFX}4g2>U=8TYk{|C!9X_rLq{hG$#1 z%=I+2e)+^(<*Aoa);BBZ;GE5o9wXf9bKRnF2{Yi=uFP7{5@nbdo8@XpAoA2xYDQ0`Wr%OA@6q{fFJGWyJ$kGLm7M_dH z7jSy9BS65o_>66L;I|W#D}O#-ULpH-mGbdpH*@DJeEX*Tahm@2?5?~uh5FNOzA804 z#wI2As^_bM;t`jt&;LuZ%;TEwD+Ep-=jsKz9)7lpnm-}ew*Rs8KfUDD;VNq@+?P*2 zyT_;Ruaw|ikb{{)4qi7QT3~YozxW?6m&wO$zw9u3_fWm(!HbUT7k_Qpw#qgm;-bj*XQM*T|7OV z)$s4s$)1m|9Qz8&7n1$5%q;f`j9%Us4xD=Zro`*~iWSCXk}U$P0*{VY8T?taNLpE` z-)^$`w?_G_%GwnQ%j~`9iW7fbADu)a)#c{ zSGB6+eIToJs%mcU#(fR#R>=%40?DFxBh*aZ#xoy2CUNojv{v`KA3H8EDXw3&X%TUqzX2DB{tchgV3-reQ*o^!`$Os`n6+3~b)M`Z-R=pK(g+vG2MyKb9xOb^#=2c0ty50#hiF6RT~@=zr)>O=RW(n2bL3?G9_NjrrysA}tgd76slRXL zPi4WY)pL6{-aFzvmp8+y<7Je>m*S!~$GeuDn*uI2@^&?IC$UYec%vb8eeD^u+7IEH zB1>=WjYu;UT)OAnu?YXi3(v91Y*%L}AsaRyvmpBH;i zd&-scsl7tB_p9*Q_OgW!=Uxw9ZoY4|#;%Pw_eMNpR@$`p+_4)^A1yrhOLn`$GdbHS z|GhIKKfB%grZ82v#wwuVZOQt@8|%)TTvG6A^Vb#eTlW}W4DnW|I(jngpM#70o^!`; zlpl4T`&HVhV`JCDYCnxv``O(4t}gbT$KAgtx$(ju$MuUhGOATBlIwka-$eTQ{>T6Q|s0!?Lb$J_? zp4`mNUs@K*srW4O;0OH^+uq4nJ(l%*axvXW_4@gTO%i4W0t+kOryaSrXPU+Kzrvvx zdw9b(eNJVVFZBOF>fWAqtJkGY9f?j?=Y`c)>Pt9xIbT#g?Uej3a?y*2OzRgLUR%A! zh25`iPur_-{r>cGbB&hf{*Q}#R-}~m#Y$RwM#YNFaSz3g+*#fJsa`WT``(G$a+4;u zo@Z%`DV}@%qQqyH^uLKF>tbhG{(E@eW5p}R?@2RFU8a1rl9slpSg~17wMAmN#J=Y( ztNxi-6wQ%~{S;GiMV7l|miPxNspQ(GEjn}V?qdA9I{szO`dh2HLjSIw>-Vp(qpW&v z@7H>pD>p@jog`jpbxb^0n*8p!<2r?9Ig74elz4sF=xq9hFaP4-w3)6?dsDLNrl)$m zl4iJ2;O6T$BmN(8o?Dym)RA4pYWOAPU<+3lC~5qe_ItsLT_DZnQTy&Rww1?u&%61h zan*}spki5`!AxM{<5IJ0^&bM#rytersPy3%{o|#vsOC=7e2K?$bx!;|@{dbRjuG}nFYT4n)-BRbbZSRsFyQJryc(nB4 z!p-@QnvX41m0C#6UEjFlNj;1wwwXQ#<%S!tL_Ife-h23DTAeej z^875vU&_WH;KcJ@tK*~SG?vBQ(^}o`Z;rU=93yZzBK~Swg}l`LO54&;mrI>4et8?V z=&>rpd%=lMOU<6~%DrlyA>ib?PT`qr=IvtlyZ;PMiP^oCH>#X<{h~zj^n)kU3VwYq z58R(s>26ad!T_x~w_d+_(QTc=R+61et-MqkJAix&%0CE^yFSK&k=YOWvc(dSm5uH zghkN;#h>@a2pqnlkaX0#;L+mHO?6khT(&*UiMn;|{gTvuPA^G-k89w4%QvEi{_5}7kCHotVfvOezO&B8CFqVDH=iN)`xO>{la(!Kod zi&B$g5%q2@)AYA1Z+o`&$xU795Lfem594$`^Mk9+|E6-U{&ol??O62kyjI)$%J_>H z625E%H3Id8stoSG&gj|5c+Bru;it=YjvB2D_BHc-&VT8Qp8BGy^_xNMlY7T^vKoGe zb`~T{pDTCh)ZB_U*mww}(^2VOMDwvy?ajXL|K1er3VNHjF51^6bN%Lx>mMz==gz69 zv})pa8Ih;U7a9ht?s~GbY2tRspqaWTZb;pTKy*E(RP(Fex)sxOD=vvkMZYUGIVSPDE9Z5k%>M`L{ocF{4-VV3 z`Rd6facajan>)@`&doJ=yzm}7hvG6&lZt1iP46P_Y0vm)SM!VXawkb7*T&yocsC>B zch##a>F>E*&CPa;pRRFm>AQZDO2`u^4#8tXZbEuK3Ls$IOhCUOTbB_RP@M; zg9U{t7dJO<{Qkc?i%0XDl~i)iSFK4x&&zXN-nH&6b^@5tDE{U)1| z+^fAubUS9QXFa@M<@T=XA7{UxI8BA zoBXA@d!1aC?>T1{@FC!RqEm<9&L)Y+Kle;}*!W`7^Fxc@MV$aeP1(f0WcG_2zJ2}D z*?+%n(W~8e&X&IJIPu9Uy8f8+UiKZVhTmU%{j`^~(x?O!mo#*B_X;`}$7L(%Dl zR>#FJg%ex-C6nc=V!luB166oEyjCB7DQ84%H!A+qyx(i#3ii93-)DDdJTBd~uc`f) zxq#D|YfKBpPiz#Qc4o)XPQ5C#n4-frVE5WN+!8yN_mgAe_V||>t8Xpla)s8F-zw&w z&9=D`o9B4OKcxP{^eTh>7Q0e16VBAy2lO^6fyx<)-7P++BSERZEa$6sruE#MvP&nY zdz_l;a^+E}nLf{}h3~|U+*!u{xn48(^}2`K?`SJ`&*K#Ho%<4$b&{vA{QAJpWKE@Q z<*)AVqORA?qdL$1XZUb2VOK<20AH!%5f9hP^FvD>|J-v)@ZXE%^R4dpcLrn}+yE+~ zdSVqp73TSC!8uput%Z*#^LeK4G}&CQvM6f(=C9ivjj!Bon!$djX@<1>{kF`eX z6}hN-UbJVeSEdoNZ%Ipi!TEgt)|;M?KfpiFS(r2lm;*Q?uiil5%& z?y~Lr&3*lK_8>duUoHF-uer-`S-A!I$Un6}M$ox~IS4 zaHu$Ya@qgM9emYu-xhtjy-=@ZM<91wyu$6OB_+?+`lVdl{P2?Gb_S;kP_B)zpJr7o z4X^;$IE>2+|5i-3ByeLKIiuL=wRmHraR%sif* z&-Tu~_~F~?kHyyZms^(YPgj4e&-`Q2`Z%4-&)auJ3lz7@o%+9Y%NlF9GrQy6P?eC<`PJWQbp>a}rN0h#j^$W*P`5+z z_&nQR^NxZ_3VZviUa+o>>nBWWHI6n@0EN=;iTa`oHS%|gpRRcsy3Ee-N~^%*VphXb zn;&*W3lzU*juAL4k-R4U#2owHW#9iN9ly3`*0h^vB(){$IbHIF0&ibE^YCVXxYLt` zyA{~3_f-EV%)N8i|3}l}Q#L0LOCmO8l{9Jr!rTK{$k5Ydg2KNjll6!bHV52Lm?90^r%_E;!)K5q&vlKj9_1bp* zsQ_`OmW#0hkELZRzr5VDk^i5^X>G}Suiu}QNbafBy%^CAsTlv?WOUhD{jJtiaB20Y z+N#nO+=_XZAZ5dpbF<#Nh}%l*&8#y9m7x1J7vHvb-S*a|ODj#u!s=D2%&~PGmS*Sj z{)>QmR|^{C11F zif#@t$dnR^{cfd{eBXQ9TFK+~e`X6u?^ViFwYojW=T&Oaoa>!0{(S#C%hm{#0YJl- z`b%@~+C93)Ud(EE-EaS+^=EHfb-LuZ=O4$dRo@r=ydbtE^u5!!8sjgU1m=`5UHqw^ zaLM?8_jN<|xvTE~FQ0SrpJd~2ZUt+Zh^>(pr47N}8~lz5YRzw$l(~Jujz?-DzH>SA zW~BTLjQ$#DvgdQvrz`2NTNh={zI(P*USMLeW&HE5wq4Nzn?o*sng6rBe_w#WWB$7L z>rdXeI?1kH>h0C)3qf0%b=$Wo1%`94J;HCg%BfS}%L>NQC43wTTemSMcg=ge@Lgkf z`>*R0JvT^i+K`=l!bB_z4E`d zvU<-)35PFTlh6K97nJ?2xBvepP!{{VKu)h>qD=a;7u90jCzSnv9=>?;zPf#KcY#EMGi! z3Q!V?a%mMaT_CdR{?F`B0pHK1@_x-%u--lG4X2-O!rTsJ5ncC_TPiiy?GSVo-JBpI z^0grASQVdV=jYw_?%-C*?)?F+%hqq6{PDiP#b@jPZ@+H^N*S(IJ065Hs7=@X(Fy93 z_Z~P=xL0ES#?zBC?V7i}+MBWVR_C-;x*gYLn#11cEuJ3uF8GIrY{0(%)gJ=BpPS0} zb-i+T!f~G)Tf_2B?la?4u0P@G{cW>=l=(jQd)*u7rIl@a3~tz5{Zz4St>w!U!x=2F;ACx<f9N#rDxvt&BxU$S5z-w-u}y8@qp!Hy_?rpZphj^!IQl;c-g{|TYv6M`upVd zj%~BPTFRQTU;J=R`sHN#{k~3@%OXGaP2bhNOF&89>5m70TYN~*p1_H&=b!Y}K4_1M z`)JUgy!l|)5|>3ApB*x)`l`3Ye}0>x9*?ThLN}2Yf$~!p-TQxBjlcB$mtO(@*^J&D zSXDUv&1;6&6*31sM3zq7zF@~EH4(qLobib#Lr)*Rv3=sS&dc#N4YvQE`!D2Fe3o(W z1NSQZ_n>ZRxl;E$-sv&+?c7N>LZ|22mM2R7y&zU1XU(>K`@Nf7zfN z<(B?tcfcX7n#;@$)mqcvFuaM7K6h>1p_f@A@$Rx|Gs@Y(>oWnufMmy<>rHDDVJVYlriL9t-er`VSH=#_rn{F zE-Y@mllR5ClqWKb=izhCb9>ZH7;BsOf3@5Zsu8HONY^R3mgDsM+u99bvnCXBJL^Sl z(%YxY&XC4O_846nty?GJPO;3z*O z>79AP-*&5*cB>fnJVpll6sJS0*18724K&I5!+d6$MbqO`0gv=l--@ zk5^xe=s&$}p8M^GwHd4LwLWv6eX;Tj#}!4kEggKSj~uG+I9!y7bK5`V%gxCd)_eHV zs=KcT?wh(u`h>haE9>L+Pou>cH56HomDWjIe_H2T#!%+We(vhNUgPX*2mi=(W*ijg z(oS2Pa%<0>Nwqg!;x?t*cI_9wDO$KmvgC@)ncOt%9h|xC-w&T$Qgr%-p!BU=t2Ucp z7QqLc|9scDu;1c;?;ia%?&hBS>_vZ1)Wt?E3#t8At8g>>y74y-#X~Ajb!MKO(zbZ= zW!1~i*}9gUyTY~n48#2cFZ6Eqe|MDszg6}3t+g5VcgkLi7E4*)*_5pvXq9W%rJa_1 z!t}cH*Qb?p=6p>D4QaTy9QjzaCG@?c_tkB8jDB?r8yss{I7RS^CsX5Z-W94xW_MY`pP0 z?N=q-6W&-%@!2h@I<+{!qEzh%i_mTvn=3a}XTH^am-i($W96-;zQtDq4zq1pvAgG= zGqY=Q8XynHjJ3SIt-|?l-gX zzz0J)_3!ttPk)oho?u$`sOGG-#qV>w4gRMy&9ZM@r%swcvELzEUVCe6C&hh!m;#BW7X<5MSoF8mY?k>%};JKUA(qR|JJJS z7P`N;saj?6J!4c_`r=of_Qju)9c2tRQX}UUuHXF4?9|lwklpLU85}qS`^;tLPR&@g z^W~G{+3$*sUcT&Fx4Jbr?S|^*d_GaXnTl;b^Vm%FA7qxD&t$6F$zS!;)%#m|?vd>6 z3zNU|$^7kRU4GZ)plR^k*l(KyE8do@sI2R6-VExNBwYEbxv5G&YSp&IOS7zlj{6^w z5N#4-yu#`5K#uuUfZp{VYJO_HpmMUVLf`cL?O8di?`gkDi3$D86zZq;b>)^bxhHfN z&;MeT9q;H;$S{A$`v1}lEdo!Um*wqQ`SifKXwlgHSN&9#8wHbtRIi`^DjIt3lc?X! zgXU`(1KKkK+FKiT?u-u(I8CK zHE?5F=)!V^V}UF0zsB#SLL2-eHY7({d}Y~vt>x~V#t)i8Vls+7R+(vbN}BdAd6Ikc zepz=Em27xZ4aacids1B0MAXe~f7zl`Jqfj4Tx zVZEG@%MY#bbiDdGAi_|1>E%4vz@t7-rpKT5{`QxL|Et}bN5*H*hR(hiwpBbV-MS}3 z!s|$z)Ja?6aHl`M<%TmSYtts=}4nEP; zSi48mb*lNIf>S&hb?b`Wovv8%U2$b_@6P8BLT_J;+A4dpjqQbUQ@|poEJ?@iUFUg! zPIfal(zjus{LuXNqc!CmmkRKIBcJ!(zX0<&!kg3HCD}F z{eNL%-0>9ghYQ~cYF}*p_Nq2x?Y-t{&a*GnJrQWp|L(lBTC#Qx-@?x<@6{N8FJZM# zi>u(Pv*UdjtQt8<MAHo zu5LH8;V@m~(0k%e-j|1a5}zkcnX=)PuLUTXBwSNxRBB>47!>3b$Zs+8OVpEj&F>#S zPI;3h=ro17!sFtX_J!RqS*+#7ICFQ%|5B0P@=ghYo&Nz30`)7qyIT?Yr-`7{^ zoqFLm?YE3gn$tDTh|)|8&hD0V0zR8sv#y-VdFDLnll+6nDQo%*xr_2z1iD4@SrzlcMBa3PYmI>2zkTg4dDCli#Wwl1hE8r1u;S8A+hMwW^N&~eK1HJXsT zc=JDlTdTe;TAHODwYuzZPHv+hr(>tbiivm3jrAADw=g`P^0bai{l-?YH=8vzDrZeu z=G&Oi$y(`#=9)P@ye@f; z=XeXvaVQGIe0|04YZ$4}l+C_mXWhe`I=5r!?C?>7C-XtvkzIAE9e?A)2_ zyS=|H+3Edl`=S*|W?X7M4^@BX8)&p!d9r`}rJQH}D{M>Hd#7)ID$C7x?e2-obI^Q{ z`b95Ac#a!)m=1TOe!|tX2PLxtYF15&bl2)y-g^lboXslNY4@2 z6lA_qpueExmW|FK>aI7f%^Gj9woy zvU>0JR_(UT_OPqxuC6juQ7mztG^Js!nrP_V^yR^^;G~uue$tiIl7Ba=<>g)6MQ%SA z`kEA-e|EYyfQ$X-@=DGd>ic$`mg{Re)b&zhZdr8R^uH}D15EC|Ub1&pJb&pVp^t5g zcb?5@-?ngTmb%gNbB8pzoi&wL2u{4+Yj@-SruddiLS<)KLi3+ayZCyN!fXyH4#`ce z&#cup&n)+}n$LXW=<$;hucP&}PDHMd*mrw3cM*^1v6hAlYO8jpe@;ENAb-h}T)s84 zc;-Yk#i}RH_f)h=Ov;;Hd(>BBRu%J?4+o+)y$^S`y$(;m_0^a;EqW7wpVnuqXQD4RJKsIIcqZ1(zF6wm4TC8hj-3ouSJ;L!aq=1K={hGgzfCkeS-(&reL{G|X*2ch zr}u>&TB&?v`DBi%{q8S8V-$0m53Mv#e8T_H>X~Y#(Ur|>pWg|Ze#fXP{j6X{YvqMS zRz>NDYA?8bHmVZ$+Wq`s^3LZE(qg$%yo7csrJkDBHBVgm^q+uR*U~`^+;3LK$!qd= zr#SLGbaM3D$!GhjnS<}1{IMyjH@-$jY*kB{%e7gLZ}AF??WgN**@%RmaVaRd@_NSI zs@fIar=5O3+?%obUiUNS=nHXs`TM38PQRF&A!xdt<%#^B`pkWYe!eO$0JYAhH9op7 zJ9Ashq95m)UT~|={>N~@??a){u?YU1D-@m!x?X=)Ci+CRkwDeo*TJd|{EkDjo8lyd3)q!Kgb>!+^0 zDor~kvHON9cM(&bhwQ7}#FU{hU%)d(w_^@dl2gqMHMQEcsnUHw#Eb-_w4- z_uaII5BksUZP@gLui$bm-#oTdSq|sYluJsk=dBfGo+hi${mZhG@!au~63MmmekUeR z{ryVo#Livc* zOd8JL5pRfb3*4eja90d=G>i4bCl#?3V&`fb3FTX#)q}D?q?P7m2%!t*SWD# zCxvIjE1et9F9$HUDPI<2$t+x$xjRMe@47P)){Jj9uT8o3`bLkTS%BchLWcT+_`9r@ z-*%pHy6N{l?Yo6==MqNF#3?&jEgzR=1j{7w<-0{iV_(pb~PlP)IE#K5jD8Tjkx#dj)q!U1jT6 zHa;fto3G=APQ%o9t9L6L&pd0F^zLZwm!)%@GR`;iF6`%Yn7tx?NAbRd0+A(2Flo84XHm*2C0+djACITCyLGp+?o9o%uT;|} zxySJQPFBnIyVsAhTAJTJ9^CyT^7*$jVcQkli@A%`w02rQKV2iR@88$Vef~V9US1Jj z)#l7#RR^Ui1_70lvxQd1PNtvyxL?e_A^XyQVzirmmYUU13(4f3ji;Z9J*j!HkD)~T ziA_e>ayhr&85ct*ES~nvasG?uYq1k9Z|}bn`*oq8+QGb{?9gPcHM@9H?zBjKu=G>n zR@~yZ@K@Q5l|R@W%GewJhG`uH6&yWZrM4?PzYdNjyUCRy+b+c3j4hiYv(k|x(PcMR zQOOHId6xz6bGE+!x=?Sjn9*#N6y~Q{q32Z=wtZ4b&Gn4TTy6K?(P;Dg=$TK<7_2+j zY`b^vh(vNv?QCz+Ck#8zTTP2fxW0Px(j?J?DhtJaE$~0nY-aa8CryBwszb z@nVgAQ}J!Pw&HtA&vQ?g2}Lga^@q3Xg87ZLC)Y(?ZM#=de@r5I&GOhy3eRiO7QR_f zy}A0Si_-B1=7rN)7y4gWF!l9?Q@k1vR~Ii?=iXNJ>P+F5@b}KI56->$?Ck|DY zqE8OIoSU0C-S*1b3iexk?_Hy>#w}01Kds{TMP@stnL#GW+o!(xA>v}q@TTyLj=Xwu zkD=L$9juo1Me*WXMYqndKC3IVmpvo;B*3l9I9EC);Yq~O54R*gh)(@>;x{+Lmk-PG z?ReF6g=J0KFU0NbpY=VzbGz&<?UcSBbn(R03&|KlJO?SOY>e}v9e)#Kh1e}I8u0ElA zVy31@YM-3ej?*WXEZ4T1A5`&{XL-u6I{_E3NV^=pm5i{>9F7Ze1C z+Ob~>iY}H7(pUE!sByiXzcu*erUxquUp{*M{708|`tNW5;_cfXOf3N=fd7TuMQIKl lv%dr!j4iVY{P~~xnBe>^X9AaPXJBAp@O1TaS?83{1ORgB&9VRh literal 0 HcmV?d00001 diff --git a/files/images/px4/airframes/plane_aert.png b/files/images/px4/airframes/plane_aert.png new file mode 100644 index 0000000000000000000000000000000000000000..583d08d01d25dea95eff062b8eef00ba35668d53 GIT binary patch literal 14382 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 literal 0 HcmV?d00001 diff --git a/files/images/px4/airframes/plane_ert.png b/files/images/px4/airframes/plane_ert.png new file mode 100644 index 0000000000000000000000000000000000000000..64d82d2cbf0793a19f40c19739274b8b095726f8 GIT binary patch literal 12613 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 QU|?YIboFyt=akR{0Lzfiles/images/px4/airframes/hexa_+.png files/images/px4/airframes/hexa_x.png files/images/px4/airframes/octo_x.png + files/images/px4/airframes/flying_wing.png + files/images/px4/airframes/plane_ert.png + files/images/px4/airframes/plane_aert.png files/styles/Vera.ttf diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index d660035505..dbca75cf25 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -44,6 +44,9 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : connect(ui->hComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hSelected(int))); + ui->hComboBox->addItem(tr("TBS Discovery"), 15); + ui->hComboBox->addItem(tr("H Custom"), 16); + connect(ui->applyButton, SIGNAL(clicked()), this, SLOT(applyAndReboot())); connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS())); diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui index f73e0e14ac..e1f64325a1 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui @@ -24,7 +24,7 @@ 0 0 - 802 + 762 531 @@ -36,6 +36,10 @@ + + + :/files/images/px4/airframes/plane_aert.png:/files/images/px4/airframes/plane_aert.png + 120 @@ -45,33 +49,7 @@ - - - - Please select - - - - - EasyStar - - - - - EasyStar 2 - - - - - EasyStar 2 w. Ailerons - - - - - Bixler 2 - - - + @@ -89,21 +67,20 @@ + + + :/files/images/px4/airframes/flying_wing.png:/files/images/px4/airframes/flying_wing.png + + + + 120 + 120 + + - - - - Bormatec CamFlyer Q - - - - - FX-61 Phantom - - - + @@ -134,28 +111,7 @@ - - - - AR.Drone Frame - - - - - Arducopter C Frame - - - - - DJI F330 Frame - - - - - DJI F450 Frame - - - + @@ -331,18 +287,7 @@ - - - - Steadydrone - - - - - H Frame Custom - - - + diff --git a/src/ui/uas/UASListWidget.cc b/src/ui/uas/UASListWidget.cc index 2b000d3769..a3fab70aaf 100644 --- a/src/ui/uas/UASListWidget.cc +++ b/src/ui/uas/UASListWidget.cc @@ -102,6 +102,9 @@ void UASListWidget::updateStatus() while (i.hasNext()) { i.next(); LinkInterface* link = i.key(); + if (!link) + continue; + ProtocolInterface* p = LinkManager::instance()->getProtocolForLink(link); // Build the tooltip out of the protocol parsing data: received, dropped, and parsing errors. -- GitLab From 130debe4a5f74f4738fc979175ff528182193e83 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 19 Aug 2013 15:49:44 +0200 Subject: [PATCH 292/460] Better disarmed labeling --- src/ui/QGCToolBar.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index f5253c2835..96c0a00d55 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -462,7 +462,7 @@ void QGCToolBar::updateView() { toolBarSafetyLabel->setStyleSheet("QLabel {color: #14C814; font-size: 15pt;}"); } - toolBarSafetyLabel->setText(tr("SAFE")); + toolBarSafetyLabel->setText(tr("DISARMED")); } changed = false; -- GitLab From da5eaf93f3b74eef9c224739256dd4b433089c00 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 19 Aug 2013 15:50:16 +0200 Subject: [PATCH 293/460] Make non-moved channels safe, will fail RC check else --- src/ui/QGCPX4VehicleConfig.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index dcd406e582..54fa593c31 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -313,12 +313,21 @@ void QGCPX4VehicleConfig::stopCalibrationRC() ui->radio7Widget->hideMinMax(); ui->radio8Widget->hideMinMax(); + for (int i=0;i 1350) + rcMin[i] = 1000; + + if (rcMax[i] < 1650) + rcMax[i] = 2000; + } + QString statusstr; statusstr = "Below you will find the detected radio calibration information that will be sent to the autopilot\n"; - statusstr += "Normal values are around 1100 to 1900, with disconnected channels reading very close to 1500\n\n"; + statusstr += "Normal values are around 1100 to 1900, with disconnected channels reading 1000, 1500, 2000\n\n"; statusstr += "Channel\tMin\tCenter\tMax\n"; statusstr += "--------------------\n"; - for (int i=0;i<8;i++) + for (int i=0;i Date: Mon, 19 Aug 2013 18:03:48 +0200 Subject: [PATCH 294/460] Rock-solid RC calibration, not leaving out any steps --- src/ui/QGCPX4VehicleConfig.cc | 36 +++++++++++++++++++++++++++++++---- src/ui/QGCPX4VehicleConfig.h | 4 +++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 38ae790c24..4d70c2229f 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -209,6 +209,9 @@ void QGCPX4VehicleConfig::identifyChannelMapping(int aert_index) { if (chanCount == 0) return; + + int oldmapping = rcMapping[aert_index]; + channelWanted = aert_index; for (unsigned i = 0; i < sizeof(channelWantedList) / sizeof(channelWantedList[0]); i++) @@ -220,6 +223,17 @@ void QGCPX4VehicleConfig::identifyChannelMapping(int aert_index) } } + msgBox.setText(tr("Identifying %1 channel").arg(channelNames[channelWanted])); + msgBox.setInformativeText(tr("Please move stick, switch or potentiometer for the %1 channel\n all the way up/down or left/right.").arg(channelNames[channelWanted])); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Cancel); + if (QMessageBox::Cancel == msgBox.exec()) + { + channelWanted = -1; + rcMapping[aert_index] = oldmapping; + return; + } + } QGCPX4VehicleConfig::~QGCPX4VehicleConfig() @@ -289,7 +303,14 @@ void QGCPX4VehicleConfig::detectChannelInversion() void QGCPX4VehicleConfig::startCalibrationRC() { - QMessageBox::information(0,"Warning!","You are about to start radio calibration.\nPlease ensure all motor power is disconnected AND all props are removed from the vehicle.\nAlso ensure transmitter and reciever are powered and connected\n\nClick OK to confirm"); + QMessageBox::warning(0,"Warning!","You are about to start radio calibration.\nPlease ensure all motor power is disconnected AND all props are removed from the vehicle.\nAlso ensure transmitter and receiver are powered and connected\n\nDo not move the RC sticks, then click OK to confirm"); + + for (int i = 0; i < 5; i++) { + identifyChannelMapping(i); + } + + QMessageBox::information(0,"Information","Additional channels have not been mapped, but can be mapped in the channel table below."); + QMessageBox::information(0,"Information","Click OK, then move all sticks to their extreme positions, watching the min/max values to ensure you get the most range from your controller. This includes all switches"); ui->rcCalibrationButton->setText(tr("Stop RC Calibration")); resetCalibrationRC(); @@ -307,6 +328,7 @@ void QGCPX4VehicleConfig::startCalibrationRC() void QGCPX4VehicleConfig::stopCalibrationRC() { QMessageBox::information(0,"Trims","Ensure all sticks are centeres and throttle is in the downmost position, click OK to continue"); + calibrationEnabled = false; ui->rcCalibrationButton->setText(tr("Start RC Calibration")); @@ -322,12 +344,19 @@ void QGCPX4VehicleConfig::stopCalibrationRC() for (int i=0;i 1350) + { rcMin[i] = 1000; + } if (rcMax[i] < 1650) + { rcMax[i] = 2000; + } } + qDebug() << "SETTING TRIM"; + setTrimPositions(); + QString statusstr; statusstr = "Below you will find the detected radio calibration information that will be sent to the autopilot\n"; statusstr += "Normal values are around 1100 to 1900, with disconnected channels reading 1000, 1500, 2000\n\n"; @@ -338,6 +367,8 @@ void QGCPX4VehicleConfig::stopCalibrationRC() statusstr += QString::number(i) +"\t"+ QString::number(rcMin[i]) +"\t"+ QString::number(rcValue[i]) +"\t"+ QString::number(rcMax[i]) +"\n"; } QMessageBox::information(0,"Status",statusstr); + + } void QGCPX4VehicleConfig::loadQgcConfig(bool primary) @@ -1038,8 +1069,6 @@ void QGCPX4VehicleConfig::writeCalibrationRC() { if (!mav) return; - setTrimPositions(); - QString minTpl("RC%1_MIN"); QString maxTpl("RC%1_MAX"); QString trimTpl("RC%1_TRIM"); @@ -1128,7 +1157,6 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) channelWanted = -1; // Confirm found channel - QMessageBox msgBox; msgBox.setText(tr("%1 Channel found.").arg(channelNames[chanFound])); msgBox.setInformativeText(tr("Found %1 to be on the raw RC channel %2").arg(channelNames[chanFound]).arg(chan + 1)); msgBox.setStandardButtons(QMessageBox::Ok); diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index 83b85c927e..f9727d8da7 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "QGCToolWidget.h" #include "UASInterface.h" @@ -209,7 +210,7 @@ protected: bool doneLoadingConfig; UASInterface* mav; ///< The current MAV QGCUASParamManager* paramMgr; ///< params mgr for the mav - static const unsigned int chanMax = 8; ///< Maximum number of channels + static const unsigned int chanMax = 16; ///< Maximum number of channels unsigned int chanCount; ///< Actual channels int rcType; ///< Type of the remote control quint64 rcTypeUpdateRequested; ///< Zero if not requested, non-zero if requested @@ -252,6 +253,7 @@ protected: QGCPX4AirframeConfig* px4AirframeConfig; DialogBare* firmwareDialog; + QMessageBox msgBox; private: Ui::QGCPX4VehicleConfig *ui; -- GitLab From 8917ff1757721c57bc888e03bff4d1f84fc820a0 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 19 Aug 2013 18:08:50 +0200 Subject: [PATCH 295/460] Permanently storing onboard params now --- src/ui/QGCPX4VehicleConfig.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 4d70c2229f..c7c335ca10 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -368,7 +368,8 @@ void QGCPX4VehicleConfig::stopCalibrationRC() } QMessageBox::information(0,"Status",statusstr); - + QMessageBox::information(0,"Uploading the RC Calibration","The configuration will now be uploaded and permanently stored."); + writeCalibrationRC(); } void QGCPX4VehicleConfig::loadQgcConfig(bool primary) @@ -1108,6 +1109,8 @@ void QGCPX4VehicleConfig::writeCalibrationRC() QGC::SLEEP::usleep(50000); mav->setParameter(0, "RC_MAP_AUX3", (int32_t)(rcMapping[7]+1)); QGC::SLEEP::usleep(50000); + + mav->getParamManager()->copyVolatileParamsToPersistent(); } void QGCPX4VehicleConfig::requestCalibrationRC() -- GitLab From 4cfe93ccbb5acad7d450ce0b6bcf2a39243d004f Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 19 Aug 2013 20:22:43 +0200 Subject: [PATCH 296/460] WIP on airframe config --- src/ui/QGCPX4VehicleConfig.ui.autosave | 1214 +++++++++++++++++ .../px4_configuration/QGCPX4AirframeConfig.cc | 47 +- .../px4_configuration/QGCPX4AirframeConfig.h | 9 + .../px4_configuration/QGCPX4AirframeConfig.ui | 35 +- 4 files changed, 1298 insertions(+), 7 deletions(-) create mode 100644 src/ui/QGCPX4VehicleConfig.ui.autosave diff --git a/src/ui/QGCPX4VehicleConfig.ui.autosave b/src/ui/QGCPX4VehicleConfig.ui.autosave new file mode 100644 index 0000000000..93bbce1333 --- /dev/null +++ b/src/ui/QGCPX4VehicleConfig.ui.autosave @@ -0,0 +1,1214 @@ + + + QGCPX4VehicleConfig + + + + 0 + 0 + 1256 + 783 + + + + + 0 + 0 + + + + Form + + + + + + + 135 + 0 + + + + + 135 + 16777215 + + + + true + + + + + 0 + 0 + 133 + 757 + + + + + + + QLayout::SetMinAndMaxSize + + + + + Firmware +Upgrade + + + + + + + + 100 + 75 + + + + + 16777215 + 16777215 + + + + RC +Calibration + + + + + + + + 100 + 75 + + + + Sensor +Calibration + + + + + + + Airframe +Config + + + + + + + + 100 + 75 + + + + General +Config + + + + + + + + 100 + 75 + + + + Advanced +Config + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + 1 + + + + + + + Firmware Upgrade + + + + + + + + + + + + 16 + 75 + true + + + + RC Calibration + + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + + + 1 + 0 + + + + + 50 + 200 + + + + + 50 + 200 + + + + + + + + + 250 + 40 + + + + + 250 + 40 + + + + + + + + + 50 + 200 + + + + + 50 + 200 + + + + + + + + Start Calibration + + + + + + + + + Stick to Channel Mapping and Reverse + + + + + + + + Identify Sub Mode Switch + + + + + + + Identify Throttle Channel + + + + + + + Pitch / Elevator + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Reverse + + + + + + + false + + + 0 + + + 16 + + + + + + + false + + + 0 + + + 16 + + + + + + + false + + + 0 + + + 16 + + + + + + + Yaw / Rudder + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Throttle + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Identify Aux 2 Channel + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Identify Main Mode Switch + + + + + + + Identify Aux 1 Channel + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Reverse + + + + + + + Identify Roll Channel + + + + + + + Reverse Direction / Invert + + + + + + + Identify Yaw Channel + + + + + + + Reverse + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Reverse + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Roll / Ailerons + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Control Channel Name + + + + + + + Normalized Value + + + + + + + Identify Pitch Channel + + + + + + + Aux 2 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + false + + + 0 + + + 16 + + + + + + + Aux 3 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + false + + + 0 + + + 16 + + + + + + + Reverse + + + + + + + false + + + 0 + + + 16 + + + + + + + Reverse + + + + + + + Mode Switch + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Reverse + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Reverse + + + + + + + false + + + 0 + + + 16 + + + + + + + false + + + 0 + + + 16 + + + + + + + Aux 1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + 0000 + + + Qt::AlignCenter + + + + + + + Mapping to Index of RC Channel used for (0 if not used) + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 16 + 75 + true + + + + + + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + + + + + + + + + + + + + + + 16 + 75 + true + + + + + + + General Config + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 13 + 50 + false + + + + Load Platform Defaults + + + + + + + + + + + Configuration + + + + 0 + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + 0 + + + + + + + + + + + + + + + Configuration + + + + 0 + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + 16 + 75 + true + + + + Advanced Configuration + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Load Platform Defaults + + + + + + + + + + + + 3 + 1 + + + + Onboard Configuration + + + + 0 + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + 0 + + + + + + + + + + + + + + false + + + Load parameters currently in non-permanent memory of aircraft. + + + + + + Refresh + + + + + + + false + + + Copy parameters from permanent memory to non-permanent current memory of aircraft. DOES NOT update the parameters in this view, click refresh after copying them to get them. + + + + + + + + + Read ROM + + + + + + + false + + + Copy current parameters in non-permanent memory of the aircraft to permanent memory. Transmit your parameters first to write these. + + + + + + Write ROM + + + + + + + Load File + + + + + + + false + + + Save parameters in this view to a file on this computer. + + + + + + Save to File + + + + + + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + + 2 + 0 + + + + + 329 + 0 + + + + Changes Pending + + + + + 10 + 30 + 381 + 601 + + + + + 0 + + + + + + 0 + 30 + + + + true + + + + + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + + + Status + + + + + + + + + + + + + + QGCRadioChannelDisplay + QWidget +
ui/designer/QGCRadioChannelDisplay.h
+ 1 +
+ + QGCPendingParamWidget + QWidget +
ui/QGCPendingParamWidget.h
+ 1 +
+ + QGCMessageView + QWidget +
QGCMessageView.h
+ 1 +
+
+ + +
diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index dbca75cf25..f9f84436ac 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -54,27 +54,58 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : setActiveUAS(UASManager::instance()->getActiveUAS()); } +void QGCPX4AirframeConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + Q_UNUSED(uas); + Q_UNUSED(component); + + if (parameterName.contains("SYS_AUTOSTART")) + { + int index = value.toInt(); + if (index > 0) { + setAirframeID(index); + ui->statusLabel->setText(tr("Onboard start script ID: #%1").arg(index)); + } else { + ui->statusLabel->setText(tr("System not configured for autostart.")); + } + } +} + void QGCPX4AirframeConfig::setActiveUAS(UASInterface* uas) { -// if (mav) + if (mav) + { + disconnect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); + } if (!uas) return; mav = uas; + connect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); + //connect(uas->getParamManager(), SIGNAL()) } void QGCPX4AirframeConfig::setAirframeID(int id) { selectedId = id; + ui->statusLabel->setText(tr("Ground start script ID: #%1").arg(selectedId)); + + if (id > 0 && id < 10) { + ui->planePushButton->setChecked(true); + } + else if (id > 10 && id < 20) + { + ui->quadXPushButton->setChecked(true); + } } void QGCPX4AirframeConfig::applyAndReboot() { // Guard against the case of an edit where we didn't receive all params yet - if (selectedId < 0) + if (selectedId <= 0) { QMessageBox msgBox; msgBox.setText(tr("No airframe selected")); @@ -125,7 +156,9 @@ void QGCPX4AirframeConfig::applyAndReboot() qDebug() << "Setting comp" << components.first() << "SYS_AUTOSTART" << (qint32)selectedId; - mav->getParamManager()->setParameter(components.first(), "SYS_AUTOSTART", (qint32)selectedId); + mav->setParameter(components.first(), "SYS_AUTOSTART", (qint32)selectedId); + + //mav->getParamManager()->setParameter(components.first(), "SYS_AUTOSTART", (qint32)selectedId); // Send pending params mav->getParamManager()->sendPendingParameters(); @@ -146,7 +179,7 @@ void QGCPX4AirframeConfig::setAutoConfig(bool enabled) void QGCPX4AirframeConfig::flyingWingSelected() { - + ui->flyingWingPushButton->setChecked(true); } void QGCPX4AirframeConfig::flyingWingSelected(int index) @@ -157,24 +190,26 @@ void QGCPX4AirframeConfig::flyingWingSelected(int index) void QGCPX4AirframeConfig::planeSelected() { - + ui->planePushButton->setChecked(true); } void QGCPX4AirframeConfig::planeSelected(int index) { int system_index = ui->planeComboBox->itemData(index).toInt(); + planeSelected(); setAirframeID(system_index); } void QGCPX4AirframeConfig::quadXSelected() { - + ui->quadXPushButton->setChecked(true); } void QGCPX4AirframeConfig::quadXSelected(int index) { int system_index = ui->quadXComboBox->itemData(index).toInt(); + quadXSelected(); setAirframeID(system_index); } diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.h b/src/ui/px4_configuration/QGCPX4AirframeConfig.h index 4c3c9a0d1b..7180d9eb0a 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.h +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.h @@ -24,6 +24,15 @@ public slots: */ void setActiveUAS(UASInterface* uas); + /** + * @brief Handle parameter changes + * @param uas + * @param component + * @param parameterName + * @param value + */ + void parameterChanged(int uas, int component, QString parameterName, QVariant value); + /** * @brief Quadrotor in X configuration has been selected */ diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui index e1f64325a1..e97bfbdb73 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui @@ -23,7 +23,7 @@ 0 - 0 + -175 762 531 @@ -46,6 +46,9 @@ 120 + + true +
@@ -77,6 +80,9 @@ 120 + + true +
@@ -108,6 +114,9 @@ 120 + + true + @@ -139,6 +148,9 @@ 120 + + true + @@ -170,6 +182,9 @@ 120 + + true + @@ -201,6 +216,9 @@ 120 + + true + @@ -232,6 +250,9 @@ 120 + + true + @@ -263,6 +284,9 @@ 120 + + true + @@ -284,6 +308,15 @@ + + + 120 + 120 + + + + true + -- GitLab From ce1e6e140a80a0fce18325fce63fa99a46c5171c Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 19 Aug 2013 21:45:52 -0700 Subject: [PATCH 297/460] Support persist-params-after-send Add persistRcValuesButt to allow mappings to be persisted outside the calibration mode; cleanup const params in param dataq model; add some debug for mapping problems --- src/uas/QGCUASParamManager.cc | 9 +- src/uas/QGCUASParamManager.h | 10 +- src/uas/UASParameterCommsMgr.cc | 26 +- src/uas/UASParameterCommsMgr.h | 3 +- src/uas/UASParameterDataModel.cc | 10 +- src/uas/UASParameterDataModel.h | 10 +- src/ui/QGCPX4VehicleConfig.cc | 247 +++++++++--------- src/ui/QGCPX4VehicleConfig.h | 10 +- src/ui/QGCPX4VehicleConfig.ui | 21 +- src/ui/QGCVehicleConfig.cc | 30 +-- .../px4_configuration/QGCPX4AirframeConfig.cc | 7 +- 11 files changed, 203 insertions(+), 180 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index aa4bd8174b..788a227c29 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -111,12 +111,15 @@ void QGCUASParamManager::setParameter(int compId, QString paramName, QVariant va paramDataModel.updatePendingParamWithValue(compId,paramName,value); } -void QGCUASParamManager::sendPendingParameters() +void QGCUASParamManager::sendPendingParameters(bool persistAfterSend) { - paramCommsMgr->sendPendingParameters(); + paramCommsMgr->sendPendingParameters(persistAfterSend); } -void QGCUASParamManager::setPendingParam(int compId, QString& paramName, const QVariant& value) + + + +void QGCUASParamManager::setPendingParam(int compId, const QString& paramName, const QVariant& value) { paramDataModel.updatePendingParamWithValue(compId,paramName,value); } diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index c0cf6cd21a..6866b2b951 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -84,8 +84,11 @@ public slots: /** @brief Send one parameter to the MAV: changes value in transient memory of MAV */ virtual void setParameter(int component, QString parameterName, QVariant value); - /** @brief Send all pending parameters to the MAV, for storage in transient (RAM) memory */ - virtual void sendPendingParameters(); + /** @brief Send all pending parameters to the MAV, for storage in transient (RAM) memory + * @param persistAfterSend If true, all parameters will be written to persistent storage as well + */ + virtual void sendPendingParameters(bool persistAfterSend = false); + /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); @@ -93,7 +96,8 @@ public slots: /** @brief Request a list of params onboard the MAV if the onboard param list we have is empty */ virtual void requestParameterListIfEmpty(); - virtual void setPendingParam(int componentId, QString& key, const QVariant& value); + /** @brief queue a pending parameter for sending to the MAV */ + virtual void setPendingParam(int componentId, const QString& key, const QVariant& value); /** @brief remove all params from the pending list */ virtual void clearAllPendingParams(); diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index a5ed632ca4..90b2f1c1d5 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -78,9 +78,6 @@ void UASParameterCommsMgr::requestParameterList() return; } - //TODO check: no need to cause datamodel to forget params here? -// paramDataModel->forgetAllOnboardParameters(); - if (!transmissionListMode) { // Clear transmission state receivedParamsList.clear(); @@ -216,11 +213,15 @@ void UASParameterCommsMgr::resendReadWriteRequests() } if ((0 == requestedWriteCount) && (0 == requestedReadCount) ) { - qDebug() << __FILE__ << __LINE__ << "NO re-read or rewrite requests??"; + qDebug() << __FILE__ << __LINE__ << "No pending re-read or rewrite requests"; if (!transmissionListMode) { setRetransmissionGuardEnabled(false); transmissionActive = false; } + if (persistParamsAfterSend) { + writeParamsToPersistentStorage(); + persistParamsAfterSend = false; + } } else { //restart the timer now that we've sent @@ -427,6 +428,8 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para { Q_UNUSED(uas); //this object is assigned to one UAS only + qDebug() << "compId" << compId << "receivedParameterUpdate:" << paramName; + //notify the data model that we have an updated param paramDataModel->handleParamUpdate(compId,paramName,value); @@ -474,6 +477,10 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para // Mark this parameter as received in write ACK list QMap* compMissWritePackets = missingWriteAckPackets.value(compId); + if (!compMissWritePackets) { + //we sometimes send a write request on compId 0 and get a response on a nonzero compId eg 50 + compMissWritePackets = missingWriteAckPackets.value(0); + } if (compMissWritePackets && compMissWritePackets->contains(paramName)) { justWritten = true; if (compMissWritePackets->value(paramName) != value) { @@ -563,12 +570,15 @@ void UASParameterCommsMgr::writeParamsToPersistentStorage() { if (mav) { mav->writeParametersToStorage(); //TODO track timeout, retransmit etc? + persistParamsAfterSend = false; //done } } -void UASParameterCommsMgr::sendPendingParameters() +void UASParameterCommsMgr::sendPendingParameters(bool copyToPersistent) { + persistParamsAfterSend |= copyToPersistent; + // Iterate through all components, through all pending parameters and send them to UAS int parametersSent = 0; QMap*>* changedValues = paramDataModel->getAllPendingParams(); @@ -590,7 +600,11 @@ void UASParameterCommsMgr::sendPendingParameters() // Change transmission status if necessary if (parametersSent == 0) { setParameterStatusMsg(tr("No transmission: No changed values."),ParamCommsStatusLevel_Warning); - } else { + if (persistParamsAfterSend) { + writeParamsToPersistentStorage(); + } + } + else { setParameterStatusMsg(tr("Transmitting %1 parameters.").arg(parametersSent)); // Set timeouts if (transmissionActive) { diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 1320d7187e..958fa42114 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -64,7 +64,7 @@ signals: public slots: /** @brief Iterate through all components, through all pending parameters and send them to UAS */ - virtual void sendPendingParameters(); + virtual void sendPendingParameters(bool copyToPersistent = false); /** @brief Write the current onboard parameters from transient RAM into persistent storage, e.g. EEPROM or harddisk */ virtual void writeParamsToPersistentStorage(); @@ -99,6 +99,7 @@ protected: bool transmissionListMode; ///< Currently requesting list QMap transmissionListSizeKnown; ///< List size initialized? bool transmissionActive; ///< Missing packets, working on list? + bool persistParamsAfterSend; ///< Copy all parameters to persistent storage after sending quint64 transmissionTimeout; ///< Timeout QTimer retransmissionTimer; ///< Timer handling parameter retransmission quint64 lastTimerReset; ///< Last time the guard timer was reset, to prevent premature firing diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index b3aaed28ef..da1a6b9878 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -45,7 +45,7 @@ int UASParameterDataModel::countOnboardParams() } -bool UASParameterDataModel::updatePendingParamWithValue(int compId, QString& key, const QVariant& value) +bool UASParameterDataModel::updatePendingParamWithValue(int compId, const QString& key, const QVariant& value) { bool pending = true; //ensure we have this component in our onboard and pending lists already @@ -76,7 +76,7 @@ bool UASParameterDataModel::isParamChangePending(int compId, const QString& key) return ((NULL != pendingParms) && pendingParms->contains(key)); } -void UASParameterDataModel::setPendingParam(int compId, QString& key, const QVariant &value) +void UASParameterDataModel::setPendingParam(int compId, const QString& key, const QVariant &value) { //ensure we have a placeholder map for this component addComponent(compId); @@ -101,7 +101,7 @@ void UASParameterDataModel::removePendingParam(int compId, const QString& key) } } -void UASParameterDataModel::setOnboardParam(int compId, QString& key, const QVariant& value) +void UASParameterDataModel::setOnboardParam(int compId, const QString &key, const QVariant& value) { //ensure we have a placeholder map for this component addComponent(compId); @@ -109,7 +109,7 @@ void UASParameterDataModel::setOnboardParam(int compId, QString& key, const QVa params->insert(key,value); } -void UASParameterDataModel::setOnboardParamWithType(int compId, QString& key, QVariant& value) +void UASParameterDataModel::setOnboardParamWithType(int compId, const QString& key, const QVariant &value) { switch ((int)value.type()) @@ -155,7 +155,7 @@ void UASParameterDataModel::addComponent(int compId) } -void UASParameterDataModel::handleParamUpdate(int compId, QString& paramName, QVariant& value) +void UASParameterDataModel::handleParamUpdate(int compId, const QString ¶mName, const QVariant &value) { //verify that the value requested by the user matches the set value //if it doesn't match, leave the pending parameter in the pending list! diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index bcff40ab8c..c7c1dd057d 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -42,7 +42,7 @@ public: virtual QList getComponentForOnboardParam(const QString& parameter) const; /** @brief Save the onboard parameter with a the type specified in the QVariant as fixed */ - virtual void setOnboardParamWithType(int componentId, QString& key, QVariant& value); + virtual void setOnboardParamWithType(int componentId, const QString &key, const QVariant& value); /** @brief clears every parameter for every loaded component */ virtual void forgetAllOnboardParams(); @@ -52,8 +52,8 @@ public: /** @brief add this parameter to pending list iff it has changed from onboard value * @return true if the parameter is now pending */ - virtual bool updatePendingParamWithValue(int componentId, QString& key, const QVariant &value); - virtual void handleParamUpdate(int componentId, QString& key, QVariant& value); + virtual bool updatePendingParamWithValue(int componentId, const QString &key, const QVariant &value); + virtual void handleParamUpdate(int componentId, const QString& key, const QVariant& value); virtual bool getOnboardParamValue(int componentId, const QString& key, QVariant& value) const; virtual bool isParamChangePending(int componentId,const QString& key); @@ -89,10 +89,10 @@ public: protected: /** @brief set the confirmed value of a parameter in the onboard params list */ - virtual void setOnboardParam(int componentId, QString& key, const QVariant& value); + virtual void setOnboardParam(int componentId, const QString& key, const QVariant& value); /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ - virtual void setPendingParam(int componentId, QString& key, const QVariant& value); + virtual void setPendingParam(int componentId, const QString &key, const QVariant& value); /** @brief remove a parameter from the pending list */ virtual void removePendingParam(int compId, const QString &key); diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index c7c335ca10..ef7fa279ac 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -16,7 +16,7 @@ #include "QGCPX4VehicleConfig.h" #include "QGC.h" -#include "QGCPendingParamWidget.h" +//#include "QGCPendingParamWidget.h" #include "QGCToolWidget.h" #include "UASManager.h" #include "UASParameterCommsMgr.h" @@ -38,6 +38,7 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : QWidget(parent), mav(NULL), chanCount(0), + channelWanted(-1), rcRoll(0.0f), rcPitch(0.0f), rcYaw(0.0f), @@ -47,7 +48,6 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : rcAux2(0.0f), rcAux3(0.0f), dataModelChanged(true), - channelWanted(-1), rc_mode(RC_MODE_NONE), calibrationEnabled(false), px4AirframeConfig(NULL), @@ -160,13 +160,15 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(ui->subButton, SIGNAL(clicked()), this, SLOT(identifySubModeChannel())); connect(ui->aux1Button, SIGNAL(clicked()), this, SLOT(identifyAux1Channel())); connect(ui->aux2Button, SIGNAL(clicked()), this, SLOT(identifyAux2Channel())); + connect(ui->persistRcValuesButt,SIGNAL(clicked()), this, SLOT(writeCalibrationRC())); + //set rc values to defaults for (unsigned int i = 0; i < chanMax; i++) { rcValue[i] = UINT16_MAX; rcMapping[i] = i; - channelWantedList[i] = UINT16_MAX; - rcMin[i] = 1000; - rcMax[i] = 2000; + channelWantedList[i] = (float)UINT16_MAX;//TODO need to clean these up! + rcMin[i] = 1000.0f; + rcMax[i] = 2000.0f; } updateTimer.setInterval(150); @@ -211,11 +213,9 @@ void QGCPX4VehicleConfig::identifyChannelMapping(int aert_index) return; int oldmapping = rcMapping[aert_index]; - channelWanted = aert_index; - for (unsigned i = 0; i < sizeof(channelWantedList) / sizeof(channelWantedList[0]); i++) - { + for (unsigned i = 0; i < chanMax; i++) { if (i >= chanCount) { channelWantedList[i] = 0; } else { @@ -227,8 +227,7 @@ void QGCPX4VehicleConfig::identifyChannelMapping(int aert_index) msgBox.setInformativeText(tr("Please move stick, switch or potentiometer for the %1 channel\n all the way up/down or left/right.").arg(channelNames[channelWanted])); msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); msgBox.setDefaultButton(QMessageBox::Cancel); - if (QMessageBox::Cancel == msgBox.exec()) - { + if (QMessageBox::Cancel == msgBox.exec()) { channelWanted = -1; rcMapping[aert_index] = oldmapping; return; @@ -264,18 +263,24 @@ void QGCPX4VehicleConfig::toggleCalibrationRC(bool enabled) void QGCPX4VehicleConfig::setTrimPositions() { + int rollMap = rcMapping[0]; + int pitchMap = rcMapping[1]; + int yawMap = rcMapping[2]; + int throttleMap = rcMapping[3]; + int modeSwMap = rcMapping[4]; + int aux1Map = rcMapping[5]; + int aux2Map = rcMapping[6]; + int aux3Map = rcMapping[7]; + // Set trim to min if stick is close to min - if (abs(rcValue[rcMapping[3]] - rcMin[rcMapping[3]]) < 100) - { - rcTrim[rcMapping[3]] = rcMin[rcMapping[3]]; // throttle + if (abs(rcValue[throttleMap] - rcMin[throttleMap]) < 100) { + rcTrim[throttleMap] = rcMin[throttleMap]; // throttle } // Set trim to max if stick is close to max - else if (abs(rcValue[rcMapping[3]] - rcMax[rcMapping[3]]) < 100) - { - rcTrim[rcMapping[3]] = rcMax[rcMapping[3]]; // throttle + else if (abs(rcValue[throttleMap] - rcMax[throttleMap]) < 100) { + rcTrim[throttleMap] = rcMax[throttleMap]; // throttle } - else - { + else { // Reject QMessageBox msgBox; msgBox.setText(tr("Throttle Stick Trim Position Invalid")); @@ -286,14 +291,14 @@ void QGCPX4VehicleConfig::setTrimPositions() } // Set trim for roll, pitch, yaw, throttle - rcTrim[rcMapping[0]] = rcValue[rcMapping[0]]; // roll - rcTrim[rcMapping[1]] = rcValue[rcMapping[1]]; // pitch - rcTrim[rcMapping[2]] = rcValue[rcMapping[2]]; // yaw - - rcTrim[rcMapping[4]] = ((rcMax[rcMapping[4]] - rcMin[rcMapping[4]]) / 2.0f) + rcMin[rcMapping[4]]; // mode sw - rcTrim[rcMapping[5]] = ((rcMax[rcMapping[5]] - rcMin[rcMapping[5]]) / 2.0f) + rcMin[rcMapping[5]]; // aux 1 - rcTrim[rcMapping[6]] = ((rcMax[rcMapping[6]] - rcMin[rcMapping[6]]) / 2.0f) + rcMin[rcMapping[6]]; // aux 2 - rcTrim[rcMapping[7]] = ((rcMax[rcMapping[7]] - rcMin[rcMapping[7]]) / 2.0f) + rcMin[rcMapping[7]]; // aux 3 + rcTrim[rollMap] = rcValue[rollMap]; // roll + rcTrim[pitchMap] = rcValue[pitchMap]; // pitch + rcTrim[yawMap] = rcValue[yawMap]; // yaw + + rcTrim[modeSwMap] = ((rcMax[modeSwMap] - rcMin[modeSwMap]) / 2.0f) + rcMin[modeSwMap]; // mode sw + rcTrim[aux1Map] = ((rcMax[aux1Map] - rcMin[aux1Map]) / 2.0f) + rcMin[aux1Map]; // aux 1 + rcTrim[aux2Map] = ((rcMax[aux2Map] - rcMin[aux2Map]) / 2.0f) + rcMin[aux2Map]; // aux 2 + rcTrim[aux3Map] = ((rcMax[aux3Map] - rcMin[aux3Map]) / 2.0f) + rcMin[aux3Map]; // aux 3 } void QGCPX4VehicleConfig::detectChannelInversion() @@ -341,15 +346,12 @@ void QGCPX4VehicleConfig::stopCalibrationRC() ui->radio7Widget->hideMinMax(); ui->radio8Widget->hideMinMax(); - for (int i=0;i 1350) - { + for (unsigned int i = 0; i < chanCount; i++) { + if (rcMin[i] > 1350) { rcMin[i] = 1000; } - if (rcMax[i] < 1650) - { + if (rcMax[i] < 1650) { rcMax[i] = 2000; } } @@ -362,8 +364,7 @@ void QGCPX4VehicleConfig::stopCalibrationRC() statusstr += "Normal values are around 1100 to 1900, with disconnected channels reading 1000, 1500, 2000\n\n"; statusstr += "Channel\tMin\tCenter\tMax\n"; statusstr += "--------------------\n"; - for (int i=0;isetParameter(0, minTpl.arg(i+1), rcMin[i]); - QGC::SLEEP::usleep(50000); - mav->setParameter(0, trimTpl.arg(i+1), rcTrim[i]); - QGC::SLEEP::usleep(50000); - mav->setParameter(0, maxTpl.arg(i+1), rcMax[i]); - QGC::SLEEP::usleep(50000); - mav->setParameter(0, revTpl.arg(i+1), (rcRev[i]) ? -1.0f : 1.0f); - QGC::SLEEP::usleep(50000); + paramMgr->setPendingParam(0, minTpl.arg(i+1), rcMin[i]); + paramMgr->setPendingParam(0, trimTpl.arg(i+1), rcTrim[i]); + paramMgr->setPendingParam(0, maxTpl.arg(i+1), rcMax[i]); + paramMgr->setPendingParam(0, revTpl.arg(i+1), (rcRev[i]) ? -1.0f : 1.0f); } // Write mappings - mav->setParameter(0, "RC_MAP_ROLL", (int32_t)(rcMapping[0]+1)); - QGC::SLEEP::usleep(50000); - mav->setParameter(0, "RC_MAP_PITCH", (int32_t)(rcMapping[1]+1)); - QGC::SLEEP::usleep(50000); - mav->setParameter(0, "RC_MAP_YAW", (int32_t)(rcMapping[2]+1)); - QGC::SLEEP::usleep(50000); - mav->setParameter(0, "RC_MAP_THROTTLE", (int32_t)(rcMapping[3]+1)); - QGC::SLEEP::usleep(50000); - mav->setParameter(0, "RC_MAP_MODE_SW", (int32_t)(rcMapping[4]+1)); - QGC::SLEEP::usleep(50000); - mav->setParameter(0, "RC_MAP_AUX1", (int32_t)(rcMapping[5]+1)); - QGC::SLEEP::usleep(50000); - mav->setParameter(0, "RC_MAP_AUX2", (int32_t)(rcMapping[6]+1)); - QGC::SLEEP::usleep(50000); - mav->setParameter(0, "RC_MAP_AUX3", (int32_t)(rcMapping[7]+1)); - QGC::SLEEP::usleep(50000); - - mav->getParamManager()->copyVolatileParamsToPersistent(); + paramMgr->setPendingParam(0, "RC_MAP_ROLL", (int32_t)(rcMapping[0]+1)); + paramMgr->setPendingParam(0, "RC_MAP_PITCH", (int32_t)(rcMapping[1]+1)); + paramMgr->setPendingParam(0, "RC_MAP_YAW", (int32_t)(rcMapping[2]+1)); + paramMgr->setPendingParam(0, "RC_MAP_THROTTLE", (int32_t)(rcMapping[3]+1)); + paramMgr->setPendingParam(0, "RC_MAP_MODE_SW", (int32_t)(rcMapping[4]+1)); + paramMgr->setPendingParam(0, "RC_MAP_AUX1", (int32_t)(rcMapping[5]+1)); + paramMgr->setPendingParam(0, "RC_MAP_AUX2", (int32_t)(rcMapping[6]+1)); + paramMgr->setPendingParam(0, "RC_MAP_AUX3", (int32_t)(rcMapping[7]+1)); + + //let the param mgr manage sending all the pending RC_foo updates and persisting after + paramMgr->sendPendingParameters(true); + } void QGCPX4VehicleConfig::requestCalibrationRC() @@ -1122,13 +1111,12 @@ void QGCPX4VehicleConfig::writeParameters() { updateStatus(tr("Writing all onboard parameters.")); writeCalibrationRC(); - mav->writeParametersToStorage(); } -void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) +void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float fval) { // Check if index and values are sane - if (chan < 0 || static_cast(chan) >= chanMax || val < 500 || val > 2500) + if (chan < 0 || static_cast(chan) >= chanMax || fval < 500.0f || fval > 2500.0f) return; if (chan + 1 > (int)chanCount) { @@ -1136,27 +1124,35 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) } // Raw value - rcValue[chan] = val; + int ival = (int)fval; + int delta = abs(ival - rcValue[chan]); + if (delta < 3) { + //ignore tiny jitter values + return; + } + else { + qDebug() << "chan" << chan << " delta:" << delta; + rcValue[chan] = ival; + } + // Update calibration data if (calibrationEnabled) { - if (val < rcMin[chan]) { - rcMin[chan] = val; + if (fval < rcMin[chan]) { + rcMin[chan] = fval; } - if (val > rcMax[chan]) { - rcMax[chan] = val; + if (fval > rcMax[chan]) { + rcMax[chan] = fval; } } if (channelWanted >= 0) { // If the first channel moved considerably, pick it - if (fabsf(channelWantedList[chan] - val) > 300) - { + if (fabsf(channelWantedList[chan] - fval) > 300.0f) { rcMapping[channelWanted] = chan; updateInvertedCheckboxes(chan); int chanFound = channelWanted; - channelWanted = -1; // Confirm found channel @@ -1169,12 +1165,9 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) } // Find correct mapped channel - for (int i = 0; i < chanCount; i++) - { - if (chan == rcMapping[i]) - { - - rcMappedValue[i] = (rcRev[chan]) ? rcMax[chan] - (val - rcMin[chan]) : val; + for (unsigned int i = 0; i < chanCount; i++) { + if (chan == rcMapping[i]) { + rcMappedValue[i] = (rcRev[chan]) ? rcMax[chan] - (fval - rcMin[chan]) : fval; // Copy min / max rcMappedMin[i] = rcMin[chan]; @@ -1184,12 +1177,12 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) // Normalized value float normalized; - - if (val >= rcTrim[chan]) { - normalized = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]); + float chanTrim = rcTrim[chan]; + if (fval >= rcTrim[chan]) { + normalized = (fval - chanTrim)/(rcMax[chan] - chanTrim); } else { - normalized = -(rcTrim[chan] - val)/(rcTrim[chan] - rcMin[chan]); + normalized = -(chanTrim - fval)/(chanTrim - rcMin[chan]); } // Bound @@ -1209,7 +1202,8 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) else if (chan == rcMapping[3]) { if (rcRev[chan]) { rcThrottle = 1.0f + normalized; - } else { + } + else { rcThrottle = normalized; } @@ -1230,7 +1224,7 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float val) dataModelChanged = true; - //qDebug() << "RC CHAN:" << chan << "PPM:" << val << "NORMALIZED:" << normalized; + qDebug() << "RC CHAN:" << chan << "PPM:" << fval << "NORMALIZED:" << normalized; } void QGCPX4VehicleConfig::updateInvertedCheckboxes(int index) @@ -1505,10 +1499,8 @@ void QGCPX4VehicleConfig::setRCType(int type) void QGCPX4VehicleConfig::checktimeOuts() { - if (rcTypeUpdateRequested > 0) - { - if (QGC::groundTimeMilliseconds() - rcTypeUpdateRequested > rcTypeTimeout) - { + if (rcTypeUpdateRequested > 0) { + if (QGC::groundTimeMilliseconds() - rcTypeUpdateRequested > rcTypeTimeout) { updateError(tr("Setting remote control timed out - is the system connected?")); } } @@ -1528,42 +1520,49 @@ void QGCPX4VehicleConfig::updateRcWidgetValues() ui->radio8Widget->setValueAndRange(rcMappedValue[7],rcMin[7],rcMax[7]); } -void QGCPX4VehicleConfig::updateView() +void QGCPX4VehicleConfig::updateRcChanLabels() { - if (dataModelChanged) { - dataModelChanged = false; - - updateRcWidgetValues(); - - //update the channel labels - ui->rollChanLabel->setText(QString("%1").arg(rcRoll, 5, 'f', 2, QChar(' '))); - ui->pitchChanLabel->setText(QString("%1").arg(rcPitch, 5, 'f', 2, QChar(' '))); - ui->yawChanLabel->setText(QString("%1").arg(rcYaw, 5, 'f', 2, QChar(' '))); - ui->throttleChanLabel->setText(QString("%1").arg(rcThrottle, 5, 'f', 2, QChar(' '))); + ui->rollChanLabel->setText(labelForRcValue(rcRoll)); + ui->pitchChanLabel->setText(labelForRcValue(rcPitch)); + ui->yawChanLabel->setText(labelForRcValue(rcYaw)); + ui->throttleChanLabel->setText(labelForRcValue(rcThrottle)); + + QString blankLabel = tr("---"); + if (rcValue[rcMapping[4] != UINT16_MAX]) { + ui->modeChanLabel->setText(labelForRcValue(rcMode)); + } + else { + ui->modeChanLabel->setText(blankLabel); + } - if (rcValue[rcMapping[4] != UINT16_MAX]) { - ui->modeChanLabel->setText(QString("%1").arg(rcMode, 5, 'f', 2, QChar(' '))); - } else { - ui->modeChanLabel->setText(tr("---")); - } + if (rcValue[rcMapping[5]] != UINT16_MAX) { + ui->aux1ChanLabel->setText(labelForRcValue(rcAux1)); + } + else { + ui->aux1ChanLabel->setText(blankLabel); + } - if (rcValue[rcMapping[5]] != UINT16_MAX) { - ui->aux1ChanLabel->setText(QString("%1").arg(rcAux1, 5, 'f', 2, QChar(' '))); - } else { - ui->aux1ChanLabel->setText(tr("---")); - } + if (rcValue[rcMapping[6]] != UINT16_MAX) { + ui->aux2ChanLabel->setText(labelForRcValue(rcAux2)); + } + else { + ui->aux2ChanLabel->setText(blankLabel); + } - if (rcValue[rcMapping[6]] != UINT16_MAX) { - ui->aux2ChanLabel->setText(QString("%1").arg(rcAux2, 5, 'f', 2, QChar(' '))); - } else { - ui->aux2ChanLabel->setText(tr("---")); - } + if (rcValue[rcMapping[7]] != UINT16_MAX) { + ui->aux3ChanLabel->setText(labelForRcValue(rcAux3)); + } + else { + ui->aux3ChanLabel->setText(blankLabel); + } +} - if (rcValue[rcMapping[7]] != UINT16_MAX) { - ui->aux3ChanLabel->setText(QString("%1").arg(rcAux3, 5, 'f', 2, QChar(' '))); - } else { - ui->aux3ChanLabel->setText(tr("---")); - } +void QGCPX4VehicleConfig::updateView() +{ + if (dataModelChanged) { + dataModelChanged = false; + updateRcWidgetValues(); + updateRcChanLabels(); } } diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index f9727d8da7..ff4eb0d35c 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -66,7 +66,7 @@ public slots: void setRCModeIndex(int newRcMode); /** Render the data updated */ void updateView(); - void updateRcWidgetValues(); + void handleRcParameterChange(QString parameterName, QVariant value); @@ -205,6 +205,14 @@ protected slots: void checktimeOuts(); /** Update checkbox status */ void updateInvertedCheckboxes(int index); + /** Update the displayed values */ + void updateRcWidgetValues(); + /** update the channel labels */ + void updateRcChanLabels(); + + QString labelForRcValue(float val) { + return QString("%1").arg(val, 5, 'f', 2, QChar(' ')); + } protected: bool doneLoadingConfig; diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 4322884b09..66f46c185e 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -154,7 +154,7 @@ Config - 0 + 5 @@ -746,6 +746,13 @@ Config
+ + + + Persist RC Mapping and Calibration + + +
@@ -874,8 +881,8 @@ Config 0 0 - 98 - 28 + 16 + 16 @@ -911,8 +918,8 @@ Config 0 0 - 98 - 28 + 16 + 16 @@ -1003,8 +1010,8 @@ Config 0 0 - 98 - 28 + 597 + 569 diff --git a/src/ui/QGCVehicleConfig.cc b/src/ui/QGCVehicleConfig.cc index 171c83ce80..919eec4b4f 100644 --- a/src/ui/QGCVehicleConfig.cc +++ b/src/ui/QGCVehicleConfig.cc @@ -1020,12 +1020,10 @@ void QGCVehicleConfig::remoteControlChannelRawChanged(int chan, float val) // Normalized value float normalized; - if (val >= rcTrim[chan]) - { + if (val >= rcTrim[chan]) { normalized = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]); } - else - { + else { normalized = -(rcTrim[chan] - val)/(rcTrim[chan] - rcMin[chan]); } @@ -1034,22 +1032,18 @@ void QGCVehicleConfig::remoteControlChannelRawChanged(int chan, float val) // Invert normalized = (rcRev[chan]) ? -1.0f*normalized : normalized; - if (chan == rcMapping[0]) - { + if (chan == rcMapping[0]) { // ROLL rcRoll = normalized; } - if (chan == rcMapping[1]) - { + if (chan == rcMapping[1]) { // PITCH rcPitch = normalized; } - if (chan == rcMapping[2]) - { + if (chan == rcMapping[2]) { rcYaw = normalized; } - if (chan == rcMapping[3]) - { + if (chan == rcMapping[3]) { // THROTTLE if (rcRev[chan]) { rcThrottle = 1.0f + normalized; @@ -1059,23 +1053,19 @@ void QGCVehicleConfig::remoteControlChannelRawChanged(int chan, float val) rcThrottle = qBound(0.0f, rcThrottle, 1.0f); } - if (chan == rcMapping[4]) - { + if (chan == rcMapping[4]) { // MODE SWITCH rcMode = normalized; } - if (chan == rcMapping[5]) - { + if (chan == rcMapping[5]) { // AUX1 rcAux1 = normalized; } - if (chan == rcMapping[6]) - { + if (chan == rcMapping[6]) { // AUX2 rcAux2 = normalized; } - if (chan == rcMapping[7]) - { + if (chan == rcMapping[7]) { // AUX3 rcAux3 = normalized; } diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index f9f84436ac..7077e7d064 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -161,11 +161,8 @@ void QGCPX4AirframeConfig::applyAndReboot() //mav->getParamManager()->setParameter(components.first(), "SYS_AUTOSTART", (qint32)selectedId); // Send pending params - mav->getParamManager()->sendPendingParameters(); - QGC::SLEEP::msleep(300); - // Store parameters - mav->getParamManager()->copyVolatileParamsToPersistent(); - QGC::SLEEP::msleep(500); + mav->getParamManager()->sendPendingParameters(true); + // Reboot mav->executeCommand(MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); } -- GitLab From a570c1fa79ee4f776eb30641973f8951da35a113 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 19 Aug 2013 21:51:49 -0700 Subject: [PATCH 298/460] persist params immediately after we know that we've send all pending --- src/uas/UASParameterCommsMgr.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 90b2f1c1d5..abe2072cbc 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -218,10 +218,6 @@ void UASParameterCommsMgr::resendReadWriteRequests() setRetransmissionGuardEnabled(false); transmissionActive = false; } - if (persistParamsAfterSend) { - writeParamsToPersistentStorage(); - persistParamsAfterSend = false; - } } else { //restart the timer now that we've sent @@ -505,6 +501,10 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3 [%5]").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount).arg(missWriteCount)); if (0 == missWriteCount) { setParameterStatusMsg(tr("SUCCESS: WROTE ALL PARAMETERS")); + if (persistParamsAfterSend) { + writeParamsToPersistentStorage(); + persistParamsAfterSend = false; + } } } else { -- GitLab From e98081fe9507668f1346aeb5f5ed522209779b94 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 19 Aug 2013 22:37:51 -0700 Subject: [PATCH 299/460] allow identification of 8 channels during calibration Add "skip" buttons in msg box (instead of cancel); allow user to cancel upload of rc params after reviewing them --- src/ui/QGCPX4VehicleConfig.cc | 44 +++++++++++++++++++++++------------ src/ui/QGCPX4VehicleConfig.h | 1 + 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index ef7fa279ac..75b512ec76 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -218,20 +218,25 @@ void QGCPX4VehicleConfig::identifyChannelMapping(int aert_index) for (unsigned i = 0; i < chanMax; i++) { if (i >= chanCount) { channelWantedList[i] = 0; - } else { + } + else { channelWantedList[i] = rcValue[i]; } } msgBox.setText(tr("Identifying %1 channel").arg(channelNames[channelWanted])); msgBox.setInformativeText(tr("Please move stick, switch or potentiometer for the %1 channel\n all the way up/down or left/right.").arg(channelNames[channelWanted])); - msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); - msgBox.setDefaultButton(QMessageBox::Cancel); - if (QMessageBox::Cancel == msgBox.exec()) { + msgBox.setStandardButtons(QMessageBox::Ok); + skipActionButton = msgBox.addButton(tr("Skip"),QMessageBox::RejectRole); + msgBox.setDefaultButton(QMessageBox::Ok); + msgBox.exec(); + skipActionButton->hide(); + msgBox.removeButton(skipActionButton); + if (msgBox.clickedButton() == skipActionButton ){ channelWanted = -1; rcMapping[aert_index] = oldmapping; - return; } + skipActionButton = NULL; } @@ -282,12 +287,12 @@ void QGCPX4VehicleConfig::setTrimPositions() } else { // Reject - QMessageBox msgBox; - msgBox.setText(tr("Throttle Stick Trim Position Invalid")); - msgBox.setInformativeText(tr("The throttle stick is not in the min position. Please set it to the minimum value")); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setDefaultButton(QMessageBox::Ok); - (void)msgBox.exec(); + QMessageBox warnMsgBox; + warnMsgBox.setText(tr("Throttle Stick Trim Position Invalid")); + warnMsgBox.setInformativeText(tr("The throttle stick is not in the min position. Please set it to the minimum value")); + warnMsgBox.setStandardButtons(QMessageBox::Ok); + warnMsgBox.setDefaultButton(QMessageBox::Ok); + (void)warnMsgBox.exec(); } // Set trim for roll, pitch, yaw, throttle @@ -310,14 +315,15 @@ void QGCPX4VehicleConfig::startCalibrationRC() { QMessageBox::warning(0,"Warning!","You are about to start radio calibration.\nPlease ensure all motor power is disconnected AND all props are removed from the vehicle.\nAlso ensure transmitter and receiver are powered and connected\n\nDo not move the RC sticks, then click OK to confirm"); - for (int i = 0; i < 5; i++) { + //go ahead and try to map first 8 channels, now that user can skip channels + for (int i = 0; i < 8; i++) { identifyChannelMapping(i); } - QMessageBox::information(0,"Information","Additional channels have not been mapped, but can be mapped in the channel table below."); + //QMessageBox::information(0,"Information","Additional channels have not been mapped, but can be mapped in the channel table below."); QMessageBox::information(0,"Information","Click OK, then move all sticks to their extreme positions, watching the min/max values to ensure you get the most range from your controller. This includes all switches"); - ui->rcCalibrationButton->setText(tr("Stop RC Calibration")); + ui->rcCalibrationButton->setText(tr("Save RC Calibration")); resetCalibrationRC(); calibrationEnabled = true; ui->rollWidget->showMinMax(); @@ -367,7 +373,15 @@ void QGCPX4VehicleConfig::stopCalibrationRC() for (unsigned int i=0; i < chanCount; i++) { statusstr += QString::number(i) +"\t"+ QString::number(rcMin[i]) +"\t"+ QString::number(rcValue[i]) +"\t"+ QString::number(rcMax[i]) +"\n"; } - QMessageBox::information(0,"Status",statusstr); + + + msgBox.setText(tr("Confirm Calibration")); + msgBox.setInformativeText(statusstr); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);//allow user to cancel upload after reviewing values + int msgBoxResult = msgBox.exec(); + if (QMessageBox::Cancel == msgBoxResult) { + return;//don't commit these values + } QMessageBox::information(0,"Uploading the RC Calibration","The configuration will now be uploaded and permanently stored."); writeCalibrationRC(); diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index ff4eb0d35c..5edde67660 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -262,6 +262,7 @@ protected: QGCPX4AirframeConfig* px4AirframeConfig; DialogBare* firmwareDialog; QMessageBox msgBox; + QPushButton* skipActionButton; private: Ui::QGCPX4VehicleConfig *ui; -- GitLab From 2dfe72e5644f6fd4093234f01ef6b275841233d0 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 19 Aug 2013 23:15:21 -0700 Subject: [PATCH 300/460] Change message view styling based on severity --- src/ui/uas/QGCMessageView.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ui/uas/QGCMessageView.cc b/src/ui/uas/QGCMessageView.cc index 7f4f891c8a..0e9d23d822 100644 --- a/src/ui/uas/QGCMessageView.cc +++ b/src/ui/uas/QGCMessageView.cc @@ -53,7 +53,7 @@ void QGCMessageView::setActiveUAS(UASInterface* uas) activeUAS = uas; } -void QGCMessageView::handleTextMessage(int uasid, int componentid, int severity, QString text) +void QGCMessageView::handleTextMessage(int uasid, int compId, int severity, QString text) { // XXX color messages according to severity @@ -64,7 +64,16 @@ void QGCMessageView::handleTextMessage(int uasid, int componentid, int severity, QScrollBar *scroller = msgWidget->verticalScrollBar(); UASInterface *uas = UASManager::instance()->getUASForId(uasid); - msgWidget->appendHtml(QString("[%2:%3] %4\n").arg(uas->getColor().name()).arg(uas->getUASName()).arg(componentid).arg(text)); + QString uasName(uas->getUASName()); + QString colorName(uas->getColor().name()); + //change styling based on severity + if (160 == severity ) { //TODO where is the constant for "critical" severity? + msgWidget->appendHtml(QString("

[%1:%2] %3

").arg(uasName).arg(compId).arg(text)); + } + else { + msgWidget->appendHtml(QString("

[%2:%3] %4

").arg(colorName).arg(uasName).arg(compId).arg(text)); + } + // Ensure text area scrolls correctly scroller->setValue(scroller->maximum()); msgWidget->setUpdatesEnabled(true); -- GitLab From 6865e01c8c3cd3c7e52230709e2e82c1e14d12fe Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 19 Aug 2013 23:20:07 -0700 Subject: [PATCH 301/460] support speaking critical messages --- src/ui/uas/QGCMessageView.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ui/uas/QGCMessageView.cc b/src/ui/uas/QGCMessageView.cc index 0e9d23d822..a1fdcce52b 100644 --- a/src/ui/uas/QGCMessageView.cc +++ b/src/ui/uas/QGCMessageView.cc @@ -1,11 +1,15 @@ #include "QGCMessageView.h" -#include "ui_QGCMessageView.h" -#include "UASManager.h" -#include "QGCUnconnectedInfoWidget.h" #include #include + +#include "GAudioOutput.h" +#include "QGCUnconnectedInfoWidget.h" +#include "UASManager.h" +#include "ui_QGCMessageView.h" + + QGCMessageView::QGCMessageView(QWidget *parent) : QWidget(parent), activeUAS(NULL), @@ -68,7 +72,8 @@ void QGCMessageView::handleTextMessage(int uasid, int compId, int severity, QStr QString colorName(uas->getColor().name()); //change styling based on severity if (160 == severity ) { //TODO where is the constant for "critical" severity? - msgWidget->appendHtml(QString("

[%1:%2] %3

").arg(uasName).arg(compId).arg(text)); + GAudioOutput::instance()->say(text.toLower()); + msgWidget->appendHtml(QString("

[%1:%2] %3

").arg(uasName).arg(compId).arg(text)); } else { msgWidget->appendHtml(QString("

[%2:%3] %4

").arg(colorName).arg(uasName).arg(compId).arg(text)); -- GitLab From 2708e439496578ecff987d00ac47094a208b1a91 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Tue, 20 Aug 2013 09:11:29 +0200 Subject: [PATCH 302/460] UI fixes / changes --- src/ui/QGCPX4VehicleConfig.ui | 380 ++++---- src/ui/QGCPX4VehicleConfig.ui.autosave | 1214 ------------------------ 2 files changed, 190 insertions(+), 1404 deletions(-) delete mode 100644 src/ui/QGCPX4VehicleConfig.ui.autosave diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 4322884b09..93bbce1333 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -154,7 +154,7 @@ Config - 0 + 1 @@ -340,161 +340,105 @@ Config - - - - false - - - 1 - - - 8 - - - - - - - Aux 3 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - false - - - 1 - - - 8 - - - - - + + - Reverse - - - - - - - false - - - 1 - - - 8 + Identify Sub Mode Switch - - + + - Reverse + Identify Throttle Channel - - + + - Mode Switch + Pitch / Elevator Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + Reverse - - - - 0000 - - - Qt::AlignCenter - - - - - - - 0000 + + + + false - - Qt::AlignCenter + + 0 - - - - - - Reverse + + 16 - - + + false - 1 + 0 - 8 + 16 - - + + false - 1 + 0 - 8 + 16 - - + + - Aux 1 + Yaw / Rudder Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - 0000 + Throttle - Qt::AlignCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + + + Identify Aux 2 Channel + + + + + 0000 @@ -503,13 +447,17 @@ Config - - + + - Aux 2 + Identify Main Mode Switch - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + Identify Aux 1 Channel @@ -530,50 +478,53 @@ Config - + Identify Roll Channel - - + + - Identify Pitch Channel + Reverse Direction / Invert - + Identify Yaw Channel - - + + - Identify Main Mode Switch + Reverse - - + + - Identify Aux 1 Channel + 0000 + + + Qt::AlignCenter - - + + - Identify Aux 2 Channel + Reverse - - + + 0000 @@ -582,122 +533,129 @@ Config - - + + - Identify Sub Mode Switch + Roll / Ailerons + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - Identify Throttle Channel + Control Channel Name - - + + - Reverse + Normalized Value - - + + - Reverse + Identify Pitch Channel - - - - false - - - 1 + + + + Aux 2 - - 8 + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + false - 1 + 0 - 8 + 16 - - + + - Yaw / Rudder + Aux 3 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - Throttle + + + + false - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + 0 + + + 16 - - + + + + Reverse + + + + + false - 1 + 0 - 8 + 16 - - + + - Pitch / Elevator - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Reverse - - + + - 0000 + Mode Switch - Qt::AlignCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + Reverse - - + + 0000 @@ -706,41 +664,83 @@ Config - - + + - Roll / Ailerons + 0000 - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignCenter - - + + - Control Channel Name + Reverse - - + + + + false + + + 0 + + + 16 + + + + + + + false + + + 0 + + + 16 + + + + + - Normalized Value + Aux 1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - Reverse Direction / Invert + 0000 + + + Qt::AlignCenter + + + + + + + 0000 + + + Qt::AlignCenter - + - Index of RC Channel used + Mapping to Index of RC Channel used for (0 if not used) @@ -786,8 +786,8 @@ Config 0 0 - 1039 - 731 + 98 + 28 diff --git a/src/ui/QGCPX4VehicleConfig.ui.autosave b/src/ui/QGCPX4VehicleConfig.ui.autosave deleted file mode 100644 index 93bbce1333..0000000000 --- a/src/ui/QGCPX4VehicleConfig.ui.autosave +++ /dev/null @@ -1,1214 +0,0 @@ - - - QGCPX4VehicleConfig - - - - 0 - 0 - 1256 - 783 - - - - - 0 - 0 - - - - Form - - - - - - - 135 - 0 - - - - - 135 - 16777215 - - - - true - - - - - 0 - 0 - 133 - 757 - - - - - - - QLayout::SetMinAndMaxSize - - - - - Firmware -Upgrade - - - - - - - - 100 - 75 - - - - - 16777215 - 16777215 - - - - RC -Calibration - - - - - - - - 100 - 75 - - - - Sensor -Calibration - - - - - - - Airframe -Config - - - - - - - - 100 - 75 - - - - General -Config - - - - - - - - 100 - 75 - - - - Advanced -Config - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - 1 - - - - - - - Firmware Upgrade - - - - - - - - - - - - 16 - 75 - true - - - - RC Calibration - - - - - - - - - - 250 - 40 - - - - - 250 - 40 - - - - - - - - - - - 250 - 40 - - - - - 250 - 40 - - - - - - - - - 250 - 40 - - - - - 250 - 40 - - - - - - - - - 250 - 40 - - - - - 250 - 40 - - - - - - - - - 250 - 40 - - - - - 250 - 40 - - - - - - - - - - - 1 - 0 - - - - - 50 - 200 - - - - - 50 - 200 - - - - - - - - - 250 - 40 - - - - - 250 - 40 - - - - - - - - - 50 - 200 - - - - - 50 - 200 - - - - - - - - Start Calibration - - - - - - - - - Stick to Channel Mapping and Reverse - - - - - - - - Identify Sub Mode Switch - - - - - - - Identify Throttle Channel - - - - - - - Pitch / Elevator - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Reverse - - - - - - - false - - - 0 - - - 16 - - - - - - - false - - - 0 - - - 16 - - - - - - - false - - - 0 - - - 16 - - - - - - - Yaw / Rudder - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Throttle - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Identify Aux 2 Channel - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - Identify Main Mode Switch - - - - - - - Identify Aux 1 Channel - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - Reverse - - - - - - - Identify Roll Channel - - - - - - - Reverse Direction / Invert - - - - - - - Identify Yaw Channel - - - - - - - Reverse - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - Reverse - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - Roll / Ailerons - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Control Channel Name - - - - - - - Normalized Value - - - - - - - Identify Pitch Channel - - - - - - - Aux 2 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - false - - - 0 - - - 16 - - - - - - - Aux 3 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - false - - - 0 - - - 16 - - - - - - - Reverse - - - - - - - false - - - 0 - - - 16 - - - - - - - Reverse - - - - - - - Mode Switch - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Reverse - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - Reverse - - - - - - - false - - - 0 - - - 16 - - - - - - - false - - - 0 - - - 16 - - - - - - - Aux 1 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - 0000 - - - Qt::AlignCenter - - - - - - - Mapping to Index of RC Channel used for (0 if not used) - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - 16 - 75 - true - - - - - - - - - - true - - - - - 0 - 0 - 98 - 28 - - - - - - - - - - - - - - - - - - - 16 - 75 - true - - - - - - - General Config - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 13 - 50 - false - - - - Load Platform Defaults - - - - - - - - - - - Configuration - - - - 0 - - - - - true - - - - - 0 - 0 - 98 - 28 - - - - - 0 - - - - - - - - - - - - - - - Configuration - - - - 0 - - - - - true - - - - - 0 - 0 - 98 - 28 - - - - - 0 - - - - - - - - - - - - - - - - - - - - - - 16 - 75 - true - - - - Advanced Configuration - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - Load Platform Defaults - - - - - - - - - - - - 3 - 1 - - - - Onboard Configuration - - - - 0 - - - - - true - - - - - 0 - 0 - 98 - 28 - - - - - 0 - - - - - - - - - - - - - - false - - - Load parameters currently in non-permanent memory of aircraft. - - - - - - Refresh - - - - - - - false - - - Copy parameters from permanent memory to non-permanent current memory of aircraft. DOES NOT update the parameters in this view, click refresh after copying them to get them. - - - - - - - - - Read ROM - - - - - - - false - - - Copy current parameters in non-permanent memory of the aircraft to permanent memory. Transmit your parameters first to write these. - - - - - - Write ROM - - - - - - - Load File - - - - - - - false - - - Save parameters in this view to a file on this computer. - - - - - - Save to File - - - - - - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - - 2 - 0 - - - - - 329 - 0 - - - - Changes Pending - - - - - 10 - 30 - 381 - 601 - - - - - 0 - - - - - - 0 - 30 - - - - true - - - - - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - - - Status - - - - - - - - - - - - - - QGCRadioChannelDisplay - QWidget -
ui/designer/QGCRadioChannelDisplay.h
- 1 -
- - QGCPendingParamWidget - QWidget -
ui/QGCPendingParamWidget.h
- 1 -
- - QGCMessageView - QWidget -
QGCMessageView.h
- 1 -
-
- - -
-- GitLab From e0cf53eb9b80056df0902e232f55ede0297aaa83 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Tue, 20 Aug 2013 23:15:43 +0200 Subject: [PATCH 303/460] Buggy WIP on airframe selection --- files/styles/style-dark.css | 7 +++ .../px4_configuration/QGCPX4AirframeConfig.cc | 60 ++++++++++++++----- .../px4_configuration/QGCPX4AirframeConfig.h | 3 +- 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/files/styles/style-dark.css b/files/styles/style-dark.css index 68da19cbe6..4a336100ed 100644 --- a/files/styles/style-dark.css +++ b/files/styles/style-dark.css @@ -356,6 +356,13 @@ QPushButton#octoXPushButton, QPushButton#octoPlusPushButton, QPushButton#hPushBu border: 3px solid #465158; } +QPushButton:checked#planePushButton, QPushButton:checked#flyingWingPushButton, QPushButton:checked#quadXPushButton, +QPushButton:checked#quadPlusPushButton, QPushButton:checked#hexaXPushButton, QPushButton:checked#hexaPlusPushButton, +QPushButton:checked#octoXPushButton, QPushButton:checked#octoPlusPushButton, QPushButton:checked#hPushButton { + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #77F, stop: 1 #33A); + border: 3px solid #4651A8; +} + QPushButton#viewModeGeneric, QPushButton#viewModePX4, QPushButton#viewModeAPM, QPushButton#viewModeAR { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #73D95D, stop: 1 #18A154); border-radius: 12px; diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index 7077e7d064..fcd2e5a4ea 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -17,13 +17,13 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : // Fill the lists here manually in accordance with the list from: // https://github.com/PX4/Firmware/blob/master/ROMFS/px4fmu_common/init.d/rcS - ui->planeComboBox->addItem(tr("Multiplex Easystar 1/2"), 1); - ui->planeComboBox->addItem(tr("Hobbyking Bixler 1/2"), 10); + ui->planeComboBox->addItem(tr("Multiplex Easystar 1/2"), 100); + ui->planeComboBox->addItem(tr("Hobbyking Bixler 1/2"), 101); connect(ui->planeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(planeSelected(int))); - ui->flyingWingComboBox->addItem(tr("Bormatec Camflyer Q"), 1); - ui->flyingWingComboBox->addItem(tr("Phantom FPV"), 10); + ui->flyingWingComboBox->addItem(tr("Bormatec Camflyer Q"), 30); + ui->flyingWingComboBox->addItem(tr("Phantom FPV"), 31); connect(ui->flyingWingComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(flyingWingSelected(int))); @@ -76,6 +76,7 @@ void QGCPX4AirframeConfig::setActiveUAS(UASInterface* uas) if (mav) { disconnect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); + mav = NULL; } if (!uas) @@ -84,8 +85,19 @@ void QGCPX4AirframeConfig::setActiveUAS(UASInterface* uas) mav = uas; connect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); +} - //connect(uas->getParamManager(), SIGNAL()) +void QGCPX4AirframeConfig::uncheckAll() +{ + ui->planePushButton->setChecked(false); + ui->flyingWingPushButton->setChecked(false); + ui->quadXPushButton->setChecked(false); + ui->quadPlusPushButton->setChecked(false); + ui->hexaXPushButton->setChecked(false); + ui->hexaPlusPushButton->setChecked(false); + ui->octoXPushButton->setChecked(false); + ui->octoPlusPushButton->setChecked(false); + ui->hPushButton->setChecked(false); } void QGCPX4AirframeConfig::setAirframeID(int id) @@ -93,12 +105,24 @@ void QGCPX4AirframeConfig::setAirframeID(int id) selectedId = id; ui->statusLabel->setText(tr("Ground start script ID: #%1").arg(selectedId)); - if (id > 0 && id < 10) { - ui->planePushButton->setChecked(true); + // XXX too much boilerplate code here - this widget is really just + // a quick hack to get started + uncheckAll(); + + if (id > 0 && id < 15) { + ui->quadXPushButton->setChecked(true); } - else if (id > 10 && id < 20) + else if (id >= 15 && id < 20) { - ui->quadXPushButton->setChecked(true); + ui->hPushButton->setChecked(true); + } + else if (id >= 30 && id < 50) + { + ui->flyingWingPushButton->setChecked(true); + } + else if (id >= 100 && id < 150) + { + ui->planePushButton->setChecked(true); } } @@ -176,6 +200,7 @@ void QGCPX4AirframeConfig::setAutoConfig(bool enabled) void QGCPX4AirframeConfig::flyingWingSelected() { + uncheckAll(); ui->flyingWingPushButton->setChecked(true); } @@ -187,6 +212,7 @@ void QGCPX4AirframeConfig::flyingWingSelected(int index) void QGCPX4AirframeConfig::planeSelected() { + uncheckAll(); ui->planePushButton->setChecked(true); } @@ -200,6 +226,7 @@ void QGCPX4AirframeConfig::planeSelected(int index) void QGCPX4AirframeConfig::quadXSelected() { + uncheckAll(); ui->quadXPushButton->setChecked(true); } @@ -212,7 +239,8 @@ void QGCPX4AirframeConfig::quadXSelected(int index) void QGCPX4AirframeConfig::quadPlusSelected() { - + uncheckAll(); + ui->quadPlusPushButton->setChecked(true); } void QGCPX4AirframeConfig::quadPlusSelected(int index) @@ -223,7 +251,8 @@ void QGCPX4AirframeConfig::quadPlusSelected(int index) void QGCPX4AirframeConfig::hexaXSelected() { - + uncheckAll(); + ui->hexaPlusPushButton->setChecked(true); } void QGCPX4AirframeConfig::hexaXSelected(int index) @@ -234,7 +263,7 @@ void QGCPX4AirframeConfig::hexaXSelected(int index) void QGCPX4AirframeConfig::hexaPlusSelected() { - + uncheckAll(); } void QGCPX4AirframeConfig::hexaPlusSelected(int index) @@ -245,7 +274,7 @@ void QGCPX4AirframeConfig::hexaPlusSelected(int index) void QGCPX4AirframeConfig::octoXSelected() { - + uncheckAll(); } void QGCPX4AirframeConfig::octoXSelected(int index) @@ -256,7 +285,7 @@ void QGCPX4AirframeConfig::octoXSelected(int index) void QGCPX4AirframeConfig::octoPlusSelected() { - + uncheckAll(); } void QGCPX4AirframeConfig::octoPlusSelected(int index) @@ -267,7 +296,8 @@ void QGCPX4AirframeConfig::octoPlusSelected(int index) void QGCPX4AirframeConfig::hSelected() { - + uncheckAll(); + ui->hPushButton->setChecked(true); } void QGCPX4AirframeConfig::hSelected(int index) diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.h b/src/ui/px4_configuration/QGCPX4AirframeConfig.h index 7180d9eb0a..0b18e6fa69 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.h +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.h @@ -81,7 +81,8 @@ protected: */ void setAutoConfig(bool enabled); - + void uncheckAll(); + private: UASInterface* mav; int selectedId; -- GitLab From f643bdea2ed26a4568c3dec3e76e6246c4cd92b3 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Wed, 21 Aug 2013 09:03:33 +0200 Subject: [PATCH 304/460] Fixed states of airframe UI, not tested with system yet --- .../px4_configuration/QGCPX4AirframeConfig.cc | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index fcd2e5a4ea..9ac954fd16 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -1,4 +1,5 @@ #include +#include #include "QGCPX4AirframeConfig.h" #include "ui_QGCPX4AirframeConfig.h" @@ -20,18 +21,22 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : ui->planeComboBox->addItem(tr("Multiplex Easystar 1/2"), 100); ui->planeComboBox->addItem(tr("Hobbyking Bixler 1/2"), 101); + connect(ui->planePushButton, SIGNAL(clicked()), this, SLOT(planeSelected())); connect(ui->planeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(planeSelected(int))); ui->flyingWingComboBox->addItem(tr("Bormatec Camflyer Q"), 30); ui->flyingWingComboBox->addItem(tr("Phantom FPV"), 31); + connect(ui->flyingWingPushButton, SIGNAL(clicked()), this, SLOT(flyingWingSelected())); connect(ui->flyingWingComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(flyingWingSelected(int))); ui->quadXComboBox->addItem(tr("Standard 10\" Quad"), 1); ui->quadXComboBox->addItem(tr("DJI F330 8\" Quad"), 10); + connect(ui->quadXPushButton, SIGNAL(clicked()), this, SLOT(quadXSelected())); connect(ui->quadXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(quadXSelected(int))); + connect(ui->quadPlusPushButton, SIGNAL(clicked()), this, SLOT(quadPlusSelected())); connect(ui->quadPlusComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(quadPlusSelected(int))); connect(ui->hexaXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hexaXSelected(int))); @@ -103,6 +108,7 @@ void QGCPX4AirframeConfig::uncheckAll() void QGCPX4AirframeConfig::setAirframeID(int id) { selectedId = id; + qDebug() << "ID" << id; ui->statusLabel->setText(tr("Ground start script ID: #%1").arg(selectedId)); // XXX too much boilerplate code here - this widget is really just @@ -119,10 +125,12 @@ void QGCPX4AirframeConfig::setAirframeID(int id) else if (id >= 30 && id < 50) { ui->flyingWingPushButton->setChecked(true); + ui->statusLabel->setText(tr("Selected flying wing (ID: #%1)").arg(selectedId)); } else if (id >= 100 && id < 150) { ui->planePushButton->setChecked(true); + ui->statusLabel->setText(tr("Selected plane (ID: #%1)").arg(selectedId)); } } @@ -200,8 +208,7 @@ void QGCPX4AirframeConfig::setAutoConfig(bool enabled) void QGCPX4AirframeConfig::flyingWingSelected() { - uncheckAll(); - ui->flyingWingPushButton->setChecked(true); + flyingWingSelected(ui->flyingWingComboBox->currentIndex()); } void QGCPX4AirframeConfig::flyingWingSelected(int index) @@ -212,35 +219,30 @@ void QGCPX4AirframeConfig::flyingWingSelected(int index) void QGCPX4AirframeConfig::planeSelected() { - uncheckAll(); - ui->planePushButton->setChecked(true); + planeSelected(ui->planeComboBox->currentIndex()); } void QGCPX4AirframeConfig::planeSelected(int index) { int system_index = ui->planeComboBox->itemData(index).toInt(); - planeSelected(); setAirframeID(system_index); } void QGCPX4AirframeConfig::quadXSelected() { - uncheckAll(); - ui->quadXPushButton->setChecked(true); + quadXSelected(ui->quadXComboBox->currentIndex()); } void QGCPX4AirframeConfig::quadXSelected(int index) { int system_index = ui->quadXComboBox->itemData(index).toInt(); - quadXSelected(); setAirframeID(system_index); } void QGCPX4AirframeConfig::quadPlusSelected() { - uncheckAll(); - ui->quadPlusPushButton->setChecked(true); + quadPlusSelected(ui->quadPlusComboBox->currentIndex()); } void QGCPX4AirframeConfig::quadPlusSelected(int index) @@ -251,8 +253,7 @@ void QGCPX4AirframeConfig::quadPlusSelected(int index) void QGCPX4AirframeConfig::hexaXSelected() { - uncheckAll(); - ui->hexaPlusPushButton->setChecked(true); + hexaXSelected(ui->hexaXComboBox->currentIndex()); } void QGCPX4AirframeConfig::hexaXSelected(int index) @@ -263,7 +264,7 @@ void QGCPX4AirframeConfig::hexaXSelected(int index) void QGCPX4AirframeConfig::hexaPlusSelected() { - uncheckAll(); + hexaPlusSelected(ui->hexaPlusComboBox->currentIndex()); } void QGCPX4AirframeConfig::hexaPlusSelected(int index) @@ -274,7 +275,7 @@ void QGCPX4AirframeConfig::hexaPlusSelected(int index) void QGCPX4AirframeConfig::octoXSelected() { - uncheckAll(); + octoXSelected(ui->octoXComboBox->currentIndex()); } void QGCPX4AirframeConfig::octoXSelected(int index) @@ -285,7 +286,7 @@ void QGCPX4AirframeConfig::octoXSelected(int index) void QGCPX4AirframeConfig::octoPlusSelected() { - uncheckAll(); + octoPlusSelected(ui->octoPlusComboBox->currentIndex()); } void QGCPX4AirframeConfig::octoPlusSelected(int index) @@ -296,8 +297,7 @@ void QGCPX4AirframeConfig::octoPlusSelected(int index) void QGCPX4AirframeConfig::hSelected() { - uncheckAll(); - ui->hPushButton->setChecked(true); + hSelected(ui->hComboBox->currentIndex()); } void QGCPX4AirframeConfig::hSelected(int index) -- GitLab From f5e0d9e29dc2dc9de6d87fa7163c6588726500ad Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 21 Aug 2013 11:59:23 -0700 Subject: [PATCH 305/460] reduce debug log noise --- src/comm/SerialLink.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 9935bf33d2..1fcb664f11 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -213,7 +213,7 @@ void SerialLink::run() } else { linkErrorCount++; - qDebug() << "Wait read response timeout" << QTime::currentTime().toString(); + //qDebug() << "Wait read response timeout" << QTime::currentTime().toString(); } if (bytes != m_bytesRead) { // i.e things are good and data is being read. -- GitLab From a6fcb12098d176f86b738f1264934b77994f3d50 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 21 Aug 2013 18:23:35 -0700 Subject: [PATCH 306/460] setAutoConfig when setting autostart - minor refactor of airframeconfig.cc - add placeholder for new scratch build multirotor --- src/ui/QGCPX4VehicleConfig.cc | 10 ++++--- .../px4_configuration/QGCPX4AirframeConfig.cc | 28 +++++++++++-------- .../px4_configuration/QGCPX4AirframeConfig.h | 1 + 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 75b512ec76..91fcd8a88c 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -176,6 +176,11 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : updateTimer.start(); } +QGCPX4VehicleConfig::~QGCPX4VehicleConfig() +{ + delete ui; +} + void QGCPX4VehicleConfig::rcMenuButtonClicked() { //TODO eg ui->stackedWidget->findChild("rcConfig"); @@ -240,10 +245,7 @@ void QGCPX4VehicleConfig::identifyChannelMapping(int aert_index) } -QGCPX4VehicleConfig::~QGCPX4VehicleConfig() -{ - delete ui; -} + void QGCPX4VehicleConfig::setRCModeIndex(int newRcMode) { diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index 9ac954fd16..c7cc61d3bf 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -32,6 +32,7 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : ui->quadXComboBox->addItem(tr("Standard 10\" Quad"), 1); ui->quadXComboBox->addItem(tr("DJI F330 8\" Quad"), 10); + ui->quadXComboBox->addItem(tr("Turnigy Talon v2 X550 Quad"), 666); connect(ui->quadXPushButton, SIGNAL(clicked()), this, SLOT(quadXSelected())); connect(ui->quadXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(quadXSelected(int))); @@ -88,6 +89,7 @@ void QGCPX4AirframeConfig::setActiveUAS(UASInterface* uas) return; mav = uas; + paramMgr = mav->getParamManager(); connect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); } @@ -108,7 +110,7 @@ void QGCPX4AirframeConfig::uncheckAll() void QGCPX4AirframeConfig::setAirframeID(int id) { selectedId = id; - qDebug() << "ID" << id; + qDebug() << "setAirframeID" << selectedId; ui->statusLabel->setText(tr("Ground start script ID: #%1").arg(selectedId)); // XXX too much boilerplate code here - this widget is really just @@ -117,6 +119,7 @@ void QGCPX4AirframeConfig::setAirframeID(int id) if (id > 0 && id < 15) { ui->quadXPushButton->setChecked(true); + ui->statusLabel->setText(tr("Selected quad X (ID: #%1)").arg(selectedId)); } else if (id >= 15 && id < 20) { @@ -152,15 +155,15 @@ void QGCPX4AirframeConfig::applyAndReboot() if (!mav) return; - if (mav->getParamManager()->countOnboardParams() == 0 && - mav->getParamManager()->countPendingParams() == 0) + if (paramMgr->countOnboardParams() == 0 && + paramMgr->countPendingParams() == 0) { - mav->getParamManager()->requestParameterListIfEmpty(); + paramMgr->requestParameterListIfEmpty(); QGC::SLEEP::msleep(100); } // Guard against the case of an edit where we didn't receive all params yet - if (mav->getParamManager()->countPendingParams() > 0) + if (paramMgr->countPendingParams() > 0) { QMessageBox msgBox; msgBox.setText(tr("Parameter sync with UAS not yet complete")); @@ -172,7 +175,7 @@ void QGCPX4AirframeConfig::applyAndReboot() return; } - QList components = mav->getParamManager()->getComponentForParam("SYS_AUTOSTART"); + QList components = paramMgr->getComponentForParam("SYS_AUTOSTART"); // Guard against multiple components responding - this will never show in practice if (components.count() != 1) { @@ -188,14 +191,17 @@ void QGCPX4AirframeConfig::applyAndReboot() qDebug() << "Setting comp" << components.first() << "SYS_AUTOSTART" << (qint32)selectedId; - mav->setParameter(components.first(), "SYS_AUTOSTART", (qint32)selectedId); + paramMgr->setPendingParam(components.first(),"SYS_AUTOSTART", (qint32)selectedId); - //mav->getParamManager()->setParameter(components.first(), "SYS_AUTOSTART", (qint32)selectedId); + //need to set autoconfig in order for PX4 to pick up the selected airframe params + setAutoConfig(true); - // Send pending params - mav->getParamManager()->sendPendingParameters(true); + // Send pending params and then write them to persistent storage when done + paramMgr->sendPendingParameters(true); // Reboot + //TODO right now this relies upon the above send & persist finishing before the reboot command is received... + QGC::SLEEP::msleep(3000); mav->executeCommand(MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); } @@ -203,7 +209,7 @@ void QGCPX4AirframeConfig::setAutoConfig(bool enabled) { if (!mav) return; - mav->getParamManager()->setParameter(0, "SYS_AUTOCONFIG", (qint32) ((enabled) ? 1 : 0)); + paramMgr->setPendingParam(0, "SYS_AUTOCONFIG", (qint32) ((enabled) ? 1 : 0)); } void QGCPX4AirframeConfig::flyingWingSelected() diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.h b/src/ui/px4_configuration/QGCPX4AirframeConfig.h index 0b18e6fa69..346076e184 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.h +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.h @@ -85,6 +85,7 @@ protected: private: UASInterface* mav; + QGCUASParamManager *paramMgr; int selectedId; Ui::QGCPX4AirframeConfig *ui; }; -- GitLab From c8e4621763959b2b283cc9d83a6c91533397a09e Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 22 Aug 2013 09:26:45 +0200 Subject: [PATCH 307/460] Minor improvements in airframe config, param transfer / reboot are still not quite doing what we want --- .../px4_configuration/QGCPX4AirframeConfig.cc | 7 ++-- .../px4_configuration/QGCPX4AirframeConfig.ui | 35 +++++++++++++++---- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index c7cc61d3bf..59d97c7c65 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -58,6 +58,8 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS())); setActiveUAS(UASManager::instance()->getActiveUAS()); + + uncheckAll(); } void QGCPX4AirframeConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) @@ -194,14 +196,15 @@ void QGCPX4AirframeConfig::applyAndReboot() paramMgr->setPendingParam(components.first(),"SYS_AUTOSTART", (qint32)selectedId); //need to set autoconfig in order for PX4 to pick up the selected airframe params - setAutoConfig(true); + if (ui->defaultGainsCheckBox->checkState() == Qt::Checked) + setAutoConfig(true); // Send pending params and then write them to persistent storage when done paramMgr->sendPendingParameters(true); // Reboot //TODO right now this relies upon the above send & persist finishing before the reboot command is received... - QGC::SLEEP::msleep(3000); + QGC::SLEEP::sleep(5); mav->executeCommand(MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); } diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui index e97bfbdb73..0b87de0ebc 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui @@ -14,7 +14,17 @@ Form - + + + + Set default airframe settings + + + true + + + + true @@ -23,7 +33,7 @@ 0 - -175 + 0 762 531 @@ -335,6 +345,13 @@
+ + + + Apply and Restart + + + @@ -343,11 +360,17 @@ - - - Apply and Restart + + + Qt::Horizontal - + + + 40 + 20 + + +
-- GitLab From cbd12e144314c32b4dd6b25fb5a01e610279eb69 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 22 Aug 2013 09:48:47 +0200 Subject: [PATCH 308/460] Show message box, handle USB link disconnect for user --- .../px4_configuration/QGCPX4AirframeConfig.cc | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index 59d97c7c65..350ea65b92 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -5,6 +5,7 @@ #include "ui_QGCPX4AirframeConfig.h" #include "UASManager.h" +#include "LinkManager.h" #include "UAS.h" QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : @@ -111,9 +112,14 @@ void QGCPX4AirframeConfig::uncheckAll() void QGCPX4AirframeConfig::setAirframeID(int id) { + + qDebug() << "setAirframeID" << id; + ui->statusLabel->setText(tr("Start script ID: #%1").arg(id)); + + if (selectedId == id) + return; + selectedId = id; - qDebug() << "setAirframeID" << selectedId; - ui->statusLabel->setText(tr("Ground start script ID: #%1").arg(selectedId)); // XXX too much boilerplate code here - this widget is really just // a quick hack to get started @@ -121,20 +127,25 @@ void QGCPX4AirframeConfig::setAirframeID(int id) if (id > 0 && id < 15) { ui->quadXPushButton->setChecked(true); + ui->quadXComboBox->setCurrentIndex(ui->quadXComboBox->findData(id)); ui->statusLabel->setText(tr("Selected quad X (ID: #%1)").arg(selectedId)); } else if (id >= 15 && id < 20) { ui->hPushButton->setChecked(true); + ui->hComboBox->setCurrentIndex(ui->hComboBox->findData(id)); + ui->statusLabel->setText(tr("Selected H Frame (ID: #%1)").arg(selectedId)); } else if (id >= 30 && id < 50) { ui->flyingWingPushButton->setChecked(true); + ui->flyingWingComboBox->setCurrentIndex(ui->flyingWingComboBox->findData(id)); ui->statusLabel->setText(tr("Selected flying wing (ID: #%1)").arg(selectedId)); } else if (id >= 100 && id < 150) { ui->planePushButton->setChecked(true); + ui->planeComboBox->setCurrentIndex(ui->planeComboBox->findData(id)); ui->statusLabel->setText(tr("Selected plane (ID: #%1)").arg(selectedId)); } } @@ -204,8 +215,19 @@ void QGCPX4AirframeConfig::applyAndReboot() // Reboot //TODO right now this relies upon the above send & persist finishing before the reboot command is received... - QGC::SLEEP::sleep(5); + QMessageBox msgBox(this); + msgBox.setText(tr("Storing Parameters and Rebooting Autopilot")); + msgBox.setInformativeText(tr("Please wait a few seconds for the reboot to complete.")); + msgBox.setStandardButtons(QMessageBox::NoButton); + msgBox.setModal(false); + msgBox.show(); + QGC::SLEEP::sleep(2); mav->executeCommand(MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); + QGC::SLEEP::msleep(200); + LinkManager::instance()->disconnectAll(); + QGC::SLEEP::sleep(8); + LinkManager::instance()->connectAll(); + msgBox.close(); } void QGCPX4AirframeConfig::setAutoConfig(bool enabled) -- GitLab From a87e00e13654c1b3bcfd367142e69cfa29ca1a5f Mon Sep 17 00:00:00 2001 From: tstellanova Date: Thu, 22 Aug 2013 14:56:01 -0700 Subject: [PATCH 309/460] use a real component ID when we know what it is --- src/uas/QGCUASParamManager.cc | 33 ++++++++++++++++++++++++++++++++- src/uas/QGCUASParamManager.h | 4 ++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 788a227c29..1a967e79d3 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -11,7 +11,8 @@ QGCUASParamManager::QGCUASParamManager(QObject *parent) : QObject(parent), mav(NULL), paramDataModel(this), - paramCommsMgr(NULL) + paramCommsMgr(NULL), + defaultComponentId(-1) { @@ -57,6 +58,27 @@ void QGCUASParamManager::clearAllPendingParams() paramDataModel.clearAllPendingParams(); } + +int QGCUASParamManager::getDefaultComponentId() +{ + int result = 0; + + if (-1 != defaultComponentId) + return defaultComponentId; + + QList components = getComponentForParam("SYS_AUTOSTART");//TODO is this the best way to find the right component? + + // Guard against multiple components responding - this will never show in practice + if (1 == components.count()) { + result = components.first(); + defaultComponentId = result; + } + + qDebug() << "Default compId: " << result; + + return result; +} + QList QGCUASParamManager::getComponentForParam(const QString& parameter) const { return paramDataModel.getComponentForOnboardParam(parameter); @@ -95,6 +117,7 @@ void QGCUASParamManager::requestParameterListIfEmpty() if (mav) { int totalOnboard = paramDataModel.countOnboardParams(); if (totalOnboard < 2) { //TODO arbitrary constant, maybe 0 is OK? + defaultComponentId = -1; //reset this ...we have no idea what the default component ID is requestParameterList(); } } @@ -108,6 +131,10 @@ void QGCUASParamManager::setParamDescriptions(const QMap& param void QGCUASParamManager::setParameter(int compId, QString paramName, QVariant value) { + if ((0 == compId) || (-1 == compId)) { + //attempt to get an actual component ID + compId = getDefaultComponentId(); + } paramDataModel.updatePendingParamWithValue(compId,paramName,value); } @@ -121,6 +148,10 @@ void QGCUASParamManager::sendPendingParameters(bool persistAfterSend) void QGCUASParamManager::setPendingParam(int compId, const QString& paramName, const QVariant& value) { + if ((0 == compId) || (-1 == compId)) { + //attempt to get an actual component ID + compId = getDefaultComponentId(); + } paramDataModel.updatePendingParamWithValue(compId,paramName,value); } diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 6866b2b951..2c31136e26 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -23,6 +23,9 @@ public: /** @brief Get the known, confirmed value of a parameter */ virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const; + /** @brief determine which component is the root component for the UAS and return its ID or 0 if unknown */ + virtual int getDefaultComponentId(); + /** * @brief Get a list of all component IDs using this parameter name * @param parameter The string encoding the parameter name @@ -122,6 +125,7 @@ protected: UASInterface* mav; ///< The MAV this manager is controlling UASParameterDataModel paramDataModel;///< Shared data model of parameters UASParameterCommsMgr* paramCommsMgr; ///< Shared comms mgr for parameters + int defaultComponentId; ///< Cached default component ID }; -- GitLab From f87953f077501597c7efbfa14e82369f8e4fb431 Mon Sep 17 00:00:00 2001 From: Anton Babushkin Date: Fri, 23 Aug 2013 23:05:06 +0200 Subject: [PATCH 310/460] Indicate AUTO submodes. --- qgroundcontrol.pro | 3 ++- src/comm/px4_custom_mode.h | 30 ++++++++++++++++++++++++++++++ src/uas/UAS.cc | 33 +++++++++++++++++++++------------ src/ui/uas/UASControlWidget.cc | 26 ++++++++++++++++---------- src/ui/uas/UASControlWidget.h | 8 +------- 5 files changed, 70 insertions(+), 30 deletions(-) create mode 100644 src/comm/px4_custom_mode.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 383e00dae2..c281da9093 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -488,7 +488,8 @@ HEADERS += src/MG.h \ src/uas/UASParameterCommsMgr.h \ src/ui/QGCPendingParamWidget.h \ src/ui/px4_configuration/QGCPX4AirframeConfig.h \ - src/ui/QGCBaseParamWidget.h + src/ui/QGCBaseParamWidget.h \ + src/comm/px4_custom_mode.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h diff --git a/src/comm/px4_custom_mode.h b/src/comm/px4_custom_mode.h new file mode 100644 index 0000000000..9c0c8ae91e --- /dev/null +++ b/src/comm/px4_custom_mode.h @@ -0,0 +1,30 @@ +#ifndef PX4_CUSTOM_MODE_H +#define PX4_CUSTOM_MODE_H + +enum PX4_CUSTOM_MAIN_MODE { + PX4_CUSTOM_MAIN_MODE_MANUAL = 1, + PX4_CUSTOM_MAIN_MODE_SEATBELT, + PX4_CUSTOM_MAIN_MODE_EASY, + PX4_CUSTOM_MAIN_MODE_AUTO, +}; + +enum PX4_CUSTOM_SUB_MODE_AUTO { + PX4_CUSTOM_SUB_MODE_AUTO_READY = 1, + PX4_CUSTOM_SUB_MODE_AUTO_TAKEOFF, + PX4_CUSTOM_SUB_MODE_AUTO_LOITER, + PX4_CUSTOM_SUB_MODE_AUTO_MISSION, + PX4_CUSTOM_SUB_MODE_AUTO_RTL, + PX4_CUSTOM_SUB_MODE_AUTO_LAND, +}; + +union px4_custom_mode { + struct { + uint16_t reserved; + uint8_t main_mode; + uint8_t sub_mode; + }; + uint32_t data; + float data_float; +}; + +#endif // PX4_CUSTOM_MODE_H diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index b258059376..2c92ff6e89 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -28,6 +28,7 @@ #include "SerialLink.h" #include "UASParameterCommsMgr.h" #include +#include #ifdef QGC_PROTOBUF_ENABLED #include @@ -1837,7 +1838,7 @@ void UAS::setMode(uint8_t newBaseMode, uint32_t newCustomMode) mavlink_message_t msg; mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, (uint8_t)uasId, newBaseMode, newCustomMode); sendMessage(msg); - qDebug() << "SENDING REQUEST TO SET MODE TO SYSTEM" << uasId << ", REQUEST TO SET MODE " << newBaseMode; + qDebug() << "SENDING REQUEST TO SET MODE TO SYSTEM" << uasId << ", MODE " << newBaseMode << " " << newCustomMode; } /** @@ -3318,24 +3319,32 @@ QString UAS::getShortModeTextFor(uint8_t base_mode, uint32_t custom_mode, int au { QString mode = ""; - enum PX4_CUSTOM_MODE { - PX4_CUSTOM_MODE_MANUAL = 1, - PX4_CUSTOM_MODE_SEATBELT, - PX4_CUSTOM_MODE_EASY, - PX4_CUSTOM_MODE_AUTO - }; - if (base_mode & MAV_MODE_FLAG_CUSTOM_MODE_ENABLED) { // use custom_mode - autopilot-specific if (autopilot == MAV_AUTOPILOT_PX4) { - if (custom_mode == PX4_CUSTOM_MODE_MANUAL) { + union px4_custom_mode px4_mode; + px4_mode.data = custom_mode; + if (px4_mode.main_mode == PX4_CUSTOM_MAIN_MODE_MANUAL) { mode += "|MANUAL"; - } else if (custom_mode == PX4_CUSTOM_MODE_SEATBELT) { + } else if (px4_mode.main_mode == PX4_CUSTOM_MAIN_MODE_SEATBELT) { mode += "|SEATBELT"; - } else if (custom_mode == PX4_CUSTOM_MODE_EASY) { + } else if (px4_mode.main_mode == PX4_CUSTOM_MAIN_MODE_EASY) { mode += "|EASY"; - } else if (custom_mode == PX4_CUSTOM_MODE_AUTO) { + } else if (px4_mode.main_mode == PX4_CUSTOM_MAIN_MODE_AUTO) { mode += "|AUTO"; + if (px4_mode.sub_mode == PX4_CUSTOM_SUB_MODE_AUTO_READY) { + mode += "|READY"; + } else if (px4_mode.sub_mode == PX4_CUSTOM_SUB_MODE_AUTO_TAKEOFF) { + mode += "|TAKEOFF"; + } else if (px4_mode.sub_mode == PX4_CUSTOM_SUB_MODE_AUTO_LOITER) { + mode += "|LOITER"; + } else if (px4_mode.sub_mode == PX4_CUSTOM_SUB_MODE_AUTO_MISSION) { + mode += "|MISSION"; + } else if (px4_mode.sub_mode == PX4_CUSTOM_SUB_MODE_AUTO_RTL) { + mode += "|RTL"; + } else if (px4_mode.sub_mode == PX4_CUSTOM_SUB_MODE_AUTO_LAND) { + mode += "|LAND"; + } } } } diff --git a/src/ui/uas/UASControlWidget.cc b/src/ui/uas/UASControlWidget.cc index ebc1934c3a..91c2d0605c 100644 --- a/src/ui/uas/UASControlWidget.cc +++ b/src/ui/uas/UASControlWidget.cc @@ -52,16 +52,7 @@ static struct full_mode_s modes_list_common[] = { 0 }, }; -static struct full_mode_s modes_list_px4[] = { - { (MAV_MODE_FLAG_CUSTOM_MODE_ENABLED | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED), - PX4_CUSTOM_MODE_MANUAL }, - { (MAV_MODE_FLAG_CUSTOM_MODE_ENABLED | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED), - PX4_CUSTOM_MODE_SEATBELT }, - { (MAV_MODE_FLAG_CUSTOM_MODE_ENABLED | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED | MAV_MODE_FLAG_GUIDED_ENABLED), - PX4_CUSTOM_MODE_EASY }, - { (MAV_MODE_FLAG_CUSTOM_MODE_ENABLED | MAV_MODE_FLAG_AUTO_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED | MAV_MODE_FLAG_GUIDED_ENABLED), - PX4_CUSTOM_MODE_AUTO }, -}; +static struct full_mode_s modes_list_px4[4]; UASControlWidget::UASControlWidget(QWidget *parent) : QWidget(parent), uasID(-1), @@ -83,6 +74,21 @@ UASControlWidget::UASControlWidget(QWidget *parent) : QWidget(parent), void UASControlWidget::updateModesList() { + union px4_custom_mode px4_cm; + px4_cm.data = 0; + modes_list_px4[0].baseMode = MAV_MODE_FLAG_CUSTOM_MODE_ENABLED | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED; + px4_cm.main_mode = PX4_CUSTOM_MAIN_MODE_MANUAL; + modes_list_px4[0].customMode = px4_cm.data; + modes_list_px4[1].baseMode = MAV_MODE_FLAG_CUSTOM_MODE_ENABLED | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED; + px4_cm.main_mode = PX4_CUSTOM_MAIN_MODE_SEATBELT; + modes_list_px4[1].customMode = px4_cm.data; + modes_list_px4[2].baseMode = MAV_MODE_FLAG_CUSTOM_MODE_ENABLED | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED | MAV_MODE_FLAG_GUIDED_ENABLED; + px4_cm.main_mode = PX4_CUSTOM_MAIN_MODE_EASY; + modes_list_px4[2].customMode = px4_cm.data; + modes_list_px4[3].baseMode = MAV_MODE_FLAG_CUSTOM_MODE_ENABLED | MAV_MODE_FLAG_AUTO_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED | MAV_MODE_FLAG_GUIDED_ENABLED; + px4_cm.main_mode = PX4_CUSTOM_MAIN_MODE_AUTO; + modes_list_px4[3].customMode = px4_cm.data; + // Detect autopilot type int autopilot = 0; if (this->uasID >= 0) { diff --git a/src/ui/uas/UASControlWidget.h b/src/ui/uas/UASControlWidget.h index 7f9a5652b7..9601bf506d 100644 --- a/src/ui/uas/UASControlWidget.h +++ b/src/ui/uas/UASControlWidget.h @@ -38,13 +38,7 @@ This file is part of the QGROUNDCONTROL project #include #include #include - -enum PX4_CUSTOM_MODE { - PX4_CUSTOM_MODE_MANUAL = 1, - PX4_CUSTOM_MODE_SEATBELT, - PX4_CUSTOM_MODE_EASY, - PX4_CUSTOM_MODE_AUTO -}; +#include struct full_mode_s { uint8_t baseMode; -- GitLab From a4d7f1007d7023981e3efbdbe979b5905858f32f Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sat, 24 Aug 2013 17:33:55 +0200 Subject: [PATCH 311/460] Completely overhauled RC config, automated *everything* --- src/ui/QGCPX4VehicleConfig.cc | 539 +++++++++++++----- src/ui/QGCPX4VehicleConfig.h | 129 +++-- src/ui/QGCPX4VehicleConfig.ui | 471 +++++++++------ .../px4_configuration/QGCPX4AirframeConfig.cc | 2 +- 4 files changed, 789 insertions(+), 352 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 91fcd8a88c..2e458ea7af 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -39,17 +39,21 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : mav(NULL), chanCount(0), channelWanted(-1), + channelReverseStateWanted(-1), rcRoll(0.0f), rcPitch(0.0f), rcYaw(0.0f), rcThrottle(0.0f), rcMode(0.0f), + rcAssist(0.0f), + rcMission(0.0f), + rcReturn(0.0f), + rcFlaps(0.0f), rcAux1(0.0f), rcAux2(0.0f), - rcAux3(0.0f), dataModelChanged(true), - rc_mode(RC_MODE_NONE), calibrationEnabled(false), + configEnabled(false), px4AirframeConfig(NULL), #ifdef QUPGRADE_SUPPORT firmwareDialog(NULL), @@ -62,14 +66,19 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : channelNames << "Pitch / Elevator"; channelNames << "Yaw / Rudder"; channelNames << "Throttle"; - channelNames << "SW1 / Main Mode Switch"; - channelNames << "SW2 / Sub Mode Switch"; - channelNames << "Aux1 / Flaps"; + channelNames << "Main Mode Switch"; + channelNames << "Assist Switch"; + channelNames << "Mission Switch"; + channelNames << "Return Switch"; + channelNames << "Flaps"; + channelNames << "Aux1"; channelNames << "Aux2"; channelNames << "Aux3"; channelNames << "Aux4"; channelNames << "Aux5"; channelNames << "Aux6"; + channelNames << "Aux7"; + channelNames << "Aux8"; setObjectName("QGC_VEHICLECONFIG"); ui->setupUi(this); @@ -116,6 +125,9 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(ui->firmwareMenuButton, SIGNAL(clicked()), this, SLOT(firmwareMenuButtonClicked())); + connect(ui->advancedCheckBox, SIGNAL(clicked(bool)), ui->advancedGroupBox, SLOT(setVisible(bool))); + ui->advancedGroupBox->setVisible(false); + ui->rcCalibrationButton->setCheckable(true); connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool))); connect(ui->writeButton, SIGNAL(clicked()), @@ -138,9 +150,12 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(ui->yawSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setYawChan(int))); connect(ui->throttleSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setThrottleChan(int))); connect(ui->modeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setModeChan(int))); + connect(ui->assistSwSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAssistChan(int))); + connect(ui->missionSwSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setMissionChan(int))); + connect(ui->returnSwSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setReturnChan(int))); + connect(ui->flapsSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setFlapsChan(int))); connect(ui->aux1SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux1Chan(int))); connect(ui->aux2SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux2Chan(int))); - connect(ui->aux3SpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAux3Chan(int))); // Connect RC reverse assignments connect(ui->invertCheckBox, SIGNAL(clicked(bool)), this, SLOT(setRollInverted(bool))); @@ -148,16 +163,22 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(ui->invertCheckBox_3, SIGNAL(clicked(bool)), this, SLOT(setYawInverted(bool))); connect(ui->invertCheckBox_4, SIGNAL(clicked(bool)), this, SLOT(setThrottleInverted(bool))); connect(ui->invertCheckBox_5, SIGNAL(clicked(bool)), this, SLOT(setModeInverted(bool))); - connect(ui->invertCheckBox_6, SIGNAL(clicked(bool)), this, SLOT(setAux1Inverted(bool))); - connect(ui->invertCheckBox_7, SIGNAL(clicked(bool)), this, SLOT(setAux2Inverted(bool))); - connect(ui->invertCheckBox_8, SIGNAL(clicked(bool)), this, SLOT(setAux3Inverted(bool))); + connect(ui->assistSwInvertCheckBox, SIGNAL(clicked(bool)), this, SLOT(setAssistInverted(bool))); + connect(ui->missionSwInvertCheckBox, SIGNAL(clicked(bool)), this, SLOT(setMissionInverted(bool))); + connect(ui->returnSwInvertCheckBox, SIGNAL(clicked(bool)), this, SLOT(setReturnInverted(bool))); + connect(ui->flapsInvertCheckBox, SIGNAL(clicked(bool)), this, SLOT(setFlapsInverted(bool))); + connect(ui->aux1InvertCheckBox, SIGNAL(clicked(bool)), this, SLOT(setAux1Inverted(bool))); + connect(ui->aux2InvertCheckBox, SIGNAL(clicked(bool)), this, SLOT(setAux2Inverted(bool))); connect(ui->rollButton, SIGNAL(clicked()), this, SLOT(identifyRollChannel())); connect(ui->pitchButton, SIGNAL(clicked()), this, SLOT(identifyPitchChannel())); connect(ui->yawButton, SIGNAL(clicked()), this, SLOT(identifyYawChannel())); connect(ui->throttleButton, SIGNAL(clicked()), this, SLOT(identifyThrottleChannel())); connect(ui->modeButton, SIGNAL(clicked()), this, SLOT(identifyModeChannel())); - connect(ui->subButton, SIGNAL(clicked()), this, SLOT(identifySubModeChannel())); + connect(ui->assistSwButton, SIGNAL(clicked()), this, SLOT(identifyAssistChannel())); + connect(ui->missionSwButton, SIGNAL(clicked()), this, SLOT(identifyMissionChannel())); + connect(ui->returnSwButton, SIGNAL(clicked()), this, SLOT(identifyReturnChannel())); + connect(ui->flapsButton, SIGNAL(clicked()), this, SLOT(identifyFlapsChannel())); connect(ui->aux1Button, SIGNAL(clicked()), this, SLOT(identifyAux1Channel())); connect(ui->aux2Button, SIGNAL(clicked()), this, SLOT(identifyAux2Channel())); connect(ui->persistRcValuesButt,SIGNAL(clicked()), this, SLOT(writeCalibrationRC())); @@ -165,10 +186,26 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : //set rc values to defaults for (unsigned int i = 0; i < chanMax; i++) { rcValue[i] = UINT16_MAX; + rcValueReversed[i] = UINT16_MAX; rcMapping[i] = i; + rcToFunctionMapping[i] = i; channelWantedList[i] = (float)UINT16_MAX;//TODO need to clean these up! rcMin[i] = 1000.0f; rcMax[i] = 2000.0f; + + // Mapping not established here, so can't pick values via mapping yet! + rcMappedMin[i] = 1000; + rcMappedMax[i] = 2000; + rcMappedValue[i] = UINT16_MAX; + rcMappedNormalizedValue[i] = 0.0f; + } + + for (unsigned int i = chanMax -1; i < chanMappedMax; i++) { + rcMapping[i] = -1; + rcMappedMin[i] = 1000; + rcMappedMax[i] = 2000; + rcMappedValue[i] = UINT16_MAX; + rcMappedNormalizedValue[i] = 0.0f; } updateTimer.setInterval(150); @@ -214,7 +251,7 @@ void QGCPX4VehicleConfig::firmwareMenuButtonClicked() void QGCPX4VehicleConfig::identifyChannelMapping(int aert_index) { - if (chanCount == 0) + if (chanCount == 0 || aert_index < 0) return; int oldmapping = rcMapping[aert_index]; @@ -245,17 +282,6 @@ void QGCPX4VehicleConfig::identifyChannelMapping(int aert_index) } - - -void QGCPX4VehicleConfig::setRCModeIndex(int newRcMode) -{ - newRcMode += 1; //promote from an index to a mode enum - if (newRcMode > 0 && newRcMode < 5) { - rc_mode = (enum RC_MODE) (newRcMode); - dataModelChanged = true; - } -} - void QGCPX4VehicleConfig::toggleCalibrationRC(bool enabled) { if (enabled) @@ -274,10 +300,11 @@ void QGCPX4VehicleConfig::setTrimPositions() int pitchMap = rcMapping[1]; int yawMap = rcMapping[2]; int throttleMap = rcMapping[3]; - int modeSwMap = rcMapping[4]; - int aux1Map = rcMapping[5]; - int aux2Map = rcMapping[6]; - int aux3Map = rcMapping[7]; + + // Reset all trims, as some might not be touched + for (unsigned i = 0; i < chanCount; i++) { + rcTrim[i] = 1500; + } // Set trim to min if stick is close to min if (abs(rcValue[throttleMap] - rcMin[throttleMap]) < 100) { @@ -302,28 +329,79 @@ void QGCPX4VehicleConfig::setTrimPositions() rcTrim[pitchMap] = rcValue[pitchMap]; // pitch rcTrim[yawMap] = rcValue[yawMap]; // yaw - rcTrim[modeSwMap] = ((rcMax[modeSwMap] - rcMin[modeSwMap]) / 2.0f) + rcMin[modeSwMap]; // mode sw - rcTrim[aux1Map] = ((rcMax[aux1Map] - rcMin[aux1Map]) / 2.0f) + rcMin[aux1Map]; // aux 1 - rcTrim[aux2Map] = ((rcMax[aux2Map] - rcMin[aux2Map]) / 2.0f) + rcMin[aux2Map]; // aux 2 - rcTrim[aux3Map] = ((rcMax[aux3Map] - rcMin[aux3Map]) / 2.0f) + rcMin[aux3Map]; // aux 3 + // Mode switch and optional modes, might not be mapped (== -1) + for (unsigned i = 4; i < chanMappedMax; i++) { + if (rcMapping[i] >= 0 && rcMapping[i] < (int)chanCount) { + rcTrim[rcMapping[i]] = ((rcMax[rcMapping[i]] - rcMin[rcMapping[i]]) / 2.0f) + rcMin[rcMapping[i]]; + } else if (rcMapping[i] != -1){ + qDebug() << "RC MAPPING FAILED #" << i << "VAL:" << rcMapping[i]; + } + } } -void QGCPX4VehicleConfig::detectChannelInversion() +void QGCPX4VehicleConfig::detectChannelInversion(int aert_index) { + if (chanCount == 0 || aert_index < 0 || aert_index >= (int)chanMappedMax) + return; + + bool oldstatus = rcRev[rcMapping[aert_index]]; + channelReverseStateWanted = aert_index; + + // Reset search list + for (unsigned i = 0; i < chanMax; i++) { + if (i >= chanCount) { + channelReverseStateWantedList[i] = 0; + } + else { + channelReverseStateWantedList[i] = rcValue[i]; + } + } + QStringList instructions; + instructions << "ROLL: Move stick left"; + instructions << "PITCH: Move stick up"; + instructions << "YAW: Move stick left"; + instructions << "THROTTLE: Move stick down"; + instructions << "MODE SWITCH: Push down / towards you"; + instructions << "ASSISTED SWITCH: Push down / towards you"; + instructions << "MISSION SWITCH: Push down / towards you"; + instructions << "RETURN SWITCH: Push down / towards you"; + instructions << "FLAPS: Push down / towards you or turn dial to the leftmost position"; + instructions << "AUX1: Push down / towards you or turn dial to the leftmost position"; + instructions << "AUX2: Push down / towards you or turn dial to the leftmost position"; + + msgBox.setText(tr("Identifying DIRECTION of %1 channel").arg(channelNames[channelReverseStateWanted])); + msgBox.setInformativeText(tr("%2").arg((aert_index < instructions.length()) ? instructions[aert_index] : "")); + msgBox.setStandardButtons(QMessageBox::Ok); + skipActionButton = msgBox.addButton(tr("Skip"),QMessageBox::RejectRole); + msgBox.setDefaultButton(QMessageBox::Ok); + msgBox.exec(); + skipActionButton->hide(); + msgBox.removeButton(skipActionButton); + if (msgBox.clickedButton() == skipActionButton ){ + channelReverseStateWanted = -1; + rcRev[rcMapping[aert_index]] = oldstatus; + } + skipActionButton = NULL; } void QGCPX4VehicleConfig::startCalibrationRC() { - QMessageBox::warning(0,"Warning!","You are about to start radio calibration.\nPlease ensure all motor power is disconnected AND all props are removed from the vehicle.\nAlso ensure transmitter and receiver are powered and connected\n\nDo not move the RC sticks, then click OK to confirm"); + configEnabled = true; + QMessageBox::warning(0,"Warning!","You are about to start radio calibration.\nPlease ensure all motor power is disconnected AND all props are removed from the vehicle.\nAlso ensure transmitter and receiver are powered and connected.\nRESET ALL TRIMS TO CENTER!\n\nDo not move the RC sticks, then click OK to confirm"); //go ahead and try to map first 8 channels, now that user can skip channels for (int i = 0; i < 8; i++) { identifyChannelMapping(i); } - //QMessageBox::information(0,"Information","Additional channels have not been mapped, but can be mapped in the channel table below."); + // Try to identify inverted channels, but only for R/P/Y/T + for (int i = 0; i < 4; i++) { + detectChannelInversion(i); + } + //QMessageBox::information(0,"Information","Additional channels have not been mapped, but can be mapped in the channel table below."); + configEnabled = false; QMessageBox::information(0,"Information","Click OK, then move all sticks to their extreme positions, watching the min/max values to ensure you get the most range from your controller. This includes all switches"); ui->rcCalibrationButton->setText(tr("Save RC Calibration")); resetCalibrationRC(); @@ -343,6 +421,7 @@ void QGCPX4VehicleConfig::stopCalibrationRC() QMessageBox::information(0,"Trims","Ensure all sticks are centeres and throttle is in the downmost position, click OK to continue"); calibrationEnabled = false; + configEnabled = false; ui->rcCalibrationButton->setText(tr("Start RC Calibration")); ui->rollWidget->hideMinMax(); @@ -1109,9 +1188,12 @@ void QGCPX4VehicleConfig::writeCalibrationRC() paramMgr->setPendingParam(0, "RC_MAP_YAW", (int32_t)(rcMapping[2]+1)); paramMgr->setPendingParam(0, "RC_MAP_THROTTLE", (int32_t)(rcMapping[3]+1)); paramMgr->setPendingParam(0, "RC_MAP_MODE_SW", (int32_t)(rcMapping[4]+1)); - paramMgr->setPendingParam(0, "RC_MAP_AUX1", (int32_t)(rcMapping[5]+1)); - paramMgr->setPendingParam(0, "RC_MAP_AUX2", (int32_t)(rcMapping[6]+1)); - paramMgr->setPendingParam(0, "RC_MAP_AUX3", (int32_t)(rcMapping[7]+1)); + paramMgr->setPendingParam(0, "RC_MAP_ASSIST_SW", (int32_t)(rcMapping[5]+1)); + paramMgr->setPendingParam(0, "RC_MAP_MISSIO_SW", (int32_t)(rcMapping[6]+1)); + paramMgr->setPendingParam(0, "RC_MAP_RETURN_SW", (int32_t)(rcMapping[7]+1)); + paramMgr->setPendingParam(0, "RC_MAP_FLAPS", (int32_t)(rcMapping[8]+1)); + paramMgr->setPendingParam(0, "RC_MAP_AUX1", (int32_t)(rcMapping[9]+1)); + paramMgr->setPendingParam(0, "RC_MAP_AUX2", (int32_t)(rcMapping[10]+1)); //let the param mgr manage sending all the pending RC_foo updates and persisting after paramMgr->sendPendingParameters(true); @@ -1140,15 +1222,13 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float fval) } // Raw value - int ival = (int)fval; - int delta = abs(ival - rcValue[chan]); - if (delta < 3) { + int delta = abs(fval - rcMappedValue[rcToFunctionMapping[chan]]); + if (!configEnabled && !calibrationEnabled && delta < 12 && delta >= 0 && rcValue[chan] > 800 && rcValue[chan] < 2200) { //ignore tiny jitter values return; } else { - qDebug() << "chan" << chan << " delta:" << delta; - rcValue[chan] = ival; + rcValue[chan] = fval; } @@ -1166,7 +1246,7 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float fval) // If the first channel moved considerably, pick it if (fabsf(channelWantedList[chan] - fval) > 300.0f) { rcMapping[channelWanted] = chan; - updateInvertedCheckboxes(chan); + updateMappingView(channelWanted); int chanFound = channelWanted; channelWanted = -1; @@ -1177,20 +1257,48 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float fval) msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); (void)msgBox.exec(); - } - } - // Find correct mapped channel - for (unsigned int i = 0; i < chanCount; i++) { - if (chan == rcMapping[i]) { - rcMappedValue[i] = (rcRev[chan]) ? rcMax[chan] - (fval - rcMin[chan]) : fval; - - // Copy min / max - rcMappedMin[i] = rcMin[chan]; - rcMappedMax[i] = rcMax[chan]; + // XXX fuse with parameter update handling + switch (chanFound) { + case 0: + ui->rollSpinBox->setValue(chan + 1); + break; + case 1: + ui->pitchSpinBox->setValue(chan + 1); + break; + case 2: + ui->yawSpinBox->setValue(chan + 1); + break; + case 3: + ui->throttleSpinBox->setValue(chan + 1); + break; + case 4: + ui->modeSpinBox->setValue(chan + 1); + break; + case 5: + ui->assistSwSpinBox->setValue(chan + 1); + break; + case 6: + ui->missionSwSpinBox->setValue(chan + 1); + break; + case 7: + ui->returnSwSpinBox->setValue(chan + 1); + break; + case 8: + ui->flapsSpinBox->setValue(chan + 1); + break; + case 9: + ui->aux1SpinBox->setValue(chan + 1); + break; + case 10: + ui->aux2SpinBox->setValue(chan + 1); + break; + } } } + rcValueReversed[chan] = (rcRev[chan]) ? rcMax[chan] - (fval - rcMin[chan]) : fval; + // Normalized value float normalized; float chanTrim = rcTrim[chan]; @@ -1206,6 +1314,19 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float fval) // Invert normalized = (rcRev[chan]) ? -1.0f*normalized : normalized; + // Find correct mapped channel + for (unsigned int i = 0; i < chanCount; i++) { + if (chan == rcMapping[i]) { + rcMappedValue[i] = (rcRev[chan]) ? rcMax[chan] - (fval - rcMin[chan]) : fval; + + // Copy min / max + rcMappedMin[i] = rcMin[chan]; + rcMappedMax[i] = rcMax[chan]; + + rcMappedNormalizedValue[i] = normalized; + } + } + if (chan == rcMapping[0]) { rcRoll = normalized; } @@ -1226,16 +1347,50 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float fval) rcThrottle = qBound(0.0f, rcThrottle, 1.0f); } else if (chan == rcMapping[4]) { - rcMode = normalized;// MODE SWITCH + rcMode = normalized; // MODE SWITCH } else if (chan == rcMapping[5]) { - rcAux1 = normalized; // AUX1 + rcAssist = normalized; // ASSIST SWITCH } else if (chan == rcMapping[6]) { - rcAux2 = normalized;// AUX2 + rcMission = normalized; // MISSION SWITCH } else if (chan == rcMapping[7]) { - rcAux3 = normalized; // AUX3 + rcReturn = normalized; // RETURN SWITCH + } + else if (chan == rcMapping[8]) { + rcFlaps = normalized; // FLAPS + } + else if (chan == rcMapping[9]) { + rcAux1 = normalized; // AUX2 + } + else if (chan == rcMapping[10]) { + rcAux2 = normalized; // AUX3 + } + + if (channelReverseStateWanted >= 0) { + // If the *right* channel moved considerably, evaluate it + if (fabsf(fval - 1500) > 350.0f && + rcMapping[channelReverseStateWanted] == chan) { + + // Check if the output is positive + if (fval > 1750) { + rcRev[rcMapping[channelReverseStateWanted]] = true; + } else { + rcRev[rcMapping[channelReverseStateWanted]] = false; + } + + unsigned currRevFunc = channelReverseStateWanted; + + channelReverseStateWanted = -1; + + // Confirm found channel + msgBox.setText(tr("Direction of %1 Channel assigned").arg(channelNames[currRevFunc])); + msgBox.setInformativeText(tr("%1").arg((rcRev[rcMapping[currRevFunc]]) ? "Reversed channel." : "Did not reverse channel.")); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + (void)msgBox.exec(); + } } dataModelChanged = true; @@ -1243,36 +1398,98 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float fval) qDebug() << "RC CHAN:" << chan << "PPM:" << fval << "NORMALIZED:" << normalized; } -void QGCPX4VehicleConfig::updateInvertedCheckboxes(int index) +void QGCPX4VehicleConfig::updateAllInvertedCheckboxes() { - unsigned int mapindex = rcMapping[index]; + for (unsigned function_index = 0; function_index < chanMappedMax; function_index++) { - switch (mapindex) - { - case 0: - ui->invertCheckBox->setChecked(rcRev[index]); - break; - case 1: - ui->invertCheckBox_2->setChecked(rcRev[index]); - break; - case 2: - ui->invertCheckBox_3->setChecked(rcRev[index]); - break; - case 3: - ui->invertCheckBox_4->setChecked(rcRev[index]); - break; - case 4: - ui->invertCheckBox_5->setChecked(rcRev[index]); - break; - case 5: - ui->invertCheckBox_6->setChecked(rcRev[index]); - break; - case 6: - ui->invertCheckBox_7->setChecked(rcRev[index]); - break; - case 7: - ui->invertCheckBox_8->setChecked(rcRev[index]); - break; + int rc_input_index = rcMapping[function_index]; + + if (rc_input_index < 0 || rc_input_index > chanMax) + continue; + + // Map index to checkbox. + // TODO(lm) Would be better to stick the checkboxes into a vector upfront + switch (function_index) + { + case 0: + ui->invertCheckBox->setChecked(rcRev[rc_input_index]); + ui->rollWidget->setName(tr("Roll (#%1)").arg(rcMapping[0] + 1)); + break; + case 1: + ui->invertCheckBox_2->setChecked(rcRev[rc_input_index]); + ui->pitchWidget->setName(tr("Pitch (#%1)").arg(rcMapping[1] + 1)); + break; + case 2: + ui->invertCheckBox_3->setChecked(rcRev[rc_input_index]); + ui->yawWidget->setName(tr("Yaw (#%1)").arg(rcMapping[2] + 1)); + break; + case 3: + ui->invertCheckBox_4->setChecked(rcRev[rc_input_index]); + ui->throttleWidget->setName(tr("Throt. (#%1)").arg(rcMapping[3] + 1)); + break; + case 4: + ui->invertCheckBox_5->setChecked(rcRev[rc_input_index]); + //ui->radio5Widget->setName(tr("Mode Switch (#%1)").arg(rcMapping[4] + 1)); + break; + case 5: + ui->assistSwInvertCheckBox->setChecked(rcRev[rc_input_index]); + break; + case 6: + ui->missionSwInvertCheckBox->setChecked(rcRev[rc_input_index]); + break; + case 7: + ui->returnSwInvertCheckBox->setChecked(rcRev[rc_input_index]); + break; + case 8: + ui->flapsInvertCheckBox->setChecked(rcRev[rc_input_index]); + break; + case 9: + ui->aux1InvertCheckBox->setChecked(rcRev[rc_input_index]); + break; + case 10: + ui->aux2InvertCheckBox->setChecked(rcRev[rc_input_index]); + break; + } + } +} + +void QGCPX4VehicleConfig::updateMappingView(int function_index) +{ + Q_UNUSED(function_index); + updateAllInvertedCheckboxes(); + + QStringList assignments; + + for (unsigned i = 0; i < chanMax; i++) { + assignments << ""; + } + + for (unsigned i = 0; i < chanMappedMax; i++) { + if (rcMapping[i] >= 0 && rcMapping[i] < (int)chanMax) { + assignments.replace(rcMapping[i], assignments[rcMapping[i]].append(QString(" / ").append(channelNames[i]))); + } + } + + for (unsigned i = 0; i < chanMax; i++) { + if (assignments[i] == "") + assignments[i] = "UNUSED"; + } + + for (unsigned i = 0; i < chanMax; i++) { + switch (i) { + case 4: + ui->radio5Widget->setName(tr("%1 (#5)").arg(assignments[4])); + break; + case 5: + ui->radio6Widget->setName(tr("%1 (#6)").arg(assignments[5])); + break; + case 6: + ui->radio7Widget->setName(tr("%1 (#7)").arg(assignments[6])); + break; + case 7: + ui->radio8Widget->setName(tr("%1 (#8)").arg(assignments[7])); + break; + } } } @@ -1284,46 +1501,62 @@ void QGCPX4VehicleConfig::handleRcParameterChange(QString parameterName, QVarian // Order is: roll, pitch, yaw, throttle, mode sw, aux 1-3 int intValue = value.toInt() - 1; + if (parameterName.startsWith("RC_MAP_ROLL")) { - rcMapping[0] = intValue; + setChannelToFunctionMapping(0, intValue); ui->rollSpinBox->setValue(rcMapping[0]+1); ui->rollSpinBox->setEnabled(true); } else if (parameterName.startsWith("RC_MAP_PITCH")) { - rcMapping[1] = intValue; + setChannelToFunctionMapping(1, intValue); ui->pitchSpinBox->setValue(rcMapping[1]+1); ui->pitchSpinBox->setEnabled(true); } else if (parameterName.startsWith("RC_MAP_YAW")) { - rcMapping[2] = intValue; + setChannelToFunctionMapping(2, intValue); ui->yawSpinBox->setValue(rcMapping[2]+1); ui->yawSpinBox->setEnabled(true); } else if (parameterName.startsWith("RC_MAP_THROTTLE")) { - rcMapping[3] = intValue; + setChannelToFunctionMapping(3, intValue); ui->throttleSpinBox->setValue(rcMapping[3]+1); ui->throttleSpinBox->setEnabled(true); } else if (parameterName.startsWith("RC_MAP_MODE_SW")) { - rcMapping[4] = intValue; + setChannelToFunctionMapping(4, intValue); ui->modeSpinBox->setValue(rcMapping[4]+1); ui->modeSpinBox->setEnabled(true); } + else if (parameterName.startsWith("RC_MAP_ASSIST_SW")) { + setChannelToFunctionMapping(5, intValue); + ui->assistSwSpinBox->setValue(rcMapping[5]+1); + ui->assistSwSpinBox->setEnabled(true); + } + else if (parameterName.startsWith("RC_MAP_MISSIO_SW")) { + setChannelToFunctionMapping(6, intValue); + ui->missionSwSpinBox->setValue(rcMapping[6]+1); + ui->missionSwSpinBox->setEnabled(true); + } + else if (parameterName.startsWith("RC_MAP_RETURN_SW")) { + setChannelToFunctionMapping(7, intValue); + ui->returnSwSpinBox->setValue(rcMapping[7]+1); + ui->returnSwSpinBox->setEnabled(true); + } + else if (parameterName.startsWith("RC_MAP_FLAPS")) { + setChannelToFunctionMapping(8, intValue); + ui->flapsSpinBox->setValue(rcMapping[8]+1); + ui->flapsSpinBox->setEnabled(true); + } else if (parameterName.startsWith("RC_MAP_AUX1")) { - rcMapping[5] = intValue; - ui->aux1SpinBox->setValue(rcMapping[5]+1); + setChannelToFunctionMapping(9, intValue); + ui->aux1SpinBox->setValue(rcMapping[9]+1); ui->aux1SpinBox->setEnabled(true); } else if (parameterName.startsWith("RC_MAP_AUX2")) { - rcMapping[6] = intValue; - ui->aux2SpinBox->setValue(rcMapping[6]+1); + setChannelToFunctionMapping(10, intValue); + ui->aux2SpinBox->setValue(rcMapping[10]+1); ui->aux2SpinBox->setEnabled(true); } - else if (parameterName.startsWith("RC_MAP_AUX3")) { - rcMapping[7] = intValue; - ui->aux3SpinBox->setValue(rcMapping[7]+1); - ui->aux3SpinBox->setEnabled(true); - } } else if (parameterName.startsWith("RC_SCALE_")) { // Scaling @@ -1337,30 +1570,16 @@ void QGCPX4VehicleConfig::handleRcParameterChange(QString parameterName, QVarian else if (parameterName.startsWith("RC_SCALE_YAW")) { rcScaling[2] = floatVal; } - else if (parameterName.startsWith("RC_SCALE_THROTTLE")) { - rcScaling[3] = floatVal; - } - else if (parameterName.startsWith("RC_SCALE_MODE_SW")) { - rcScaling[4] = floatVal; - } - else if (parameterName.startsWith("RC_SCALE_AUX1")) { - rcScaling[5] = floatVal; - } - else if (parameterName.startsWith("RC_SCALE_AUX2")) { - rcScaling[6] = floatVal; - } - else if (parameterName.startsWith("RC_SCALE_AUX3")) { - rcScaling[7] = floatVal; - } - } - else if (parameterName.startsWith("RC_TYPE")) { - if (0 != rcTypeUpdateRequested) { - rcTypeUpdateRequested = 0; - updateStatus(tr("Received RC type update, setting parameters based on model.")); - rcType = value.toInt(); - // Request all other parameters as well - requestCalibrationRC(); - } + // Not implemented at this point +// else if (parameterName.startsWith("RC_SCALE_THROTTLE")) { +// rcScaling[3] = floatVal; +// } +// else if (parameterName.startsWith("RC_SCALE_AUX1")) { +// rcScaling[5] = floatVal; +// } +// else if (parameterName.startsWith("RC_SCALE_AUX2")) { +// rcScaling[6] = floatVal; +// } } } else { @@ -1404,11 +1623,24 @@ void QGCPX4VehicleConfig::handleRcParameterChange(QString parameterName, QVarian index = parameterName.mid(2, 1).toInt(&ok) - 1; if (ok && index < chanMax) { rcRev[index] = (intVal == -1) ? true : false; - updateInvertedCheckboxes(index); + + for (unsigned i = 0; i < chanMappedMax; i++) + { + if (rcMapping[i] == (int)index) + updateMappingView(i); + } } } } +} +void QGCPX4VehicleConfig::setChannelToFunctionMapping(int function, int channel) +{ + if (function >= 0 && function < (int)chanMappedMax) + rcMapping[function] = channel; + + if (channel >= 0 && channel < (int)chanMax) + rcToFunctionMapping[channel] = function; } void QGCPX4VehicleConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) @@ -1501,25 +1733,9 @@ void QGCPX4VehicleConfig::updateError(const QString& str) ui->advancedStatusLabel->setStyleSheet(QString("QLabel { margin: 0px 2px; font: 14px; color: %1; background-color: %2; }").arg(QGC::colorDarkWhite.name()).arg(QGC::colorMagenta.name())); } - -void QGCPX4VehicleConfig::setRCType(int type) -{ - if (!mav) return; - - // XXX TODO Add handling of RC_TYPE vs non-RC_TYPE here - - mav->setParameter(0, "RC_TYPE", type); - rcTypeUpdateRequested = QGC::groundTimeMilliseconds(); - QTimer::singleShot(rcTypeTimeout+100, this, SLOT(checktimeOuts())); -} - void QGCPX4VehicleConfig::checktimeOuts() { - if (rcTypeUpdateRequested > 0) { - if (QGC::groundTimeMilliseconds() - rcTypeUpdateRequested > rcTypeTimeout) { - updateError(tr("Setting remote control timed out - is the system connected?")); - } - } + } @@ -1530,10 +1746,10 @@ void QGCPX4VehicleConfig::updateRcWidgetValues() ui->yawWidget->setValueAndRange(rcMappedValue[2],rcMappedMin[2],rcMappedMax[2]); ui->throttleWidget->setValueAndRange(rcMappedValue[3],rcMappedMin[3],rcMappedMax[3]); - ui->radio5Widget->setValueAndRange(rcMappedValue[4],rcMin[4],rcMax[4]); - ui->radio6Widget->setValueAndRange(rcMappedValue[5],rcMin[5],rcMax[5]); - ui->radio7Widget->setValueAndRange(rcMappedValue[6],rcMin[6],rcMax[6]); - ui->radio8Widget->setValueAndRange(rcMappedValue[7],rcMin[7],rcMax[7]); + ui->radio5Widget->setValueAndRange(rcValueReversed[4],rcMin[4],rcMax[4]); + ui->radio6Widget->setValueAndRange(rcValueReversed[5],rcMin[5],rcMax[5]); + ui->radio7Widget->setValueAndRange(rcValueReversed[6],rcMin[6],rcMax[6]); + ui->radio8Widget->setValueAndRange(rcValueReversed[7],rcMin[7],rcMax[7]); } void QGCPX4VehicleConfig::updateRcChanLabels() @@ -1544,7 +1760,7 @@ void QGCPX4VehicleConfig::updateRcChanLabels() ui->throttleChanLabel->setText(labelForRcValue(rcThrottle)); QString blankLabel = tr("---"); - if (rcValue[rcMapping[4] != UINT16_MAX]) { + if (rcValue[rcMapping[4]] != UINT16_MAX) { ui->modeChanLabel->setText(labelForRcValue(rcMode)); } else { @@ -1552,24 +1768,45 @@ void QGCPX4VehicleConfig::updateRcChanLabels() } if (rcValue[rcMapping[5]] != UINT16_MAX) { - ui->aux1ChanLabel->setText(labelForRcValue(rcAux1)); + ui->assistSwChanLabel->setText(labelForRcValue(rcAssist)); } else { - ui->aux1ChanLabel->setText(blankLabel); + ui->assistSwChanLabel->setText(blankLabel); } if (rcValue[rcMapping[6]] != UINT16_MAX) { - ui->aux2ChanLabel->setText(labelForRcValue(rcAux2)); + ui->missionSwChanLabel->setText(labelForRcValue(rcMission)); } else { - ui->aux2ChanLabel->setText(blankLabel); + ui->missionSwChanLabel->setText(blankLabel); } if (rcValue[rcMapping[7]] != UINT16_MAX) { - ui->aux3ChanLabel->setText(labelForRcValue(rcAux3)); + ui->returnSwChanLabel->setText(labelForRcValue(rcReturn)); + } + else { + ui->returnSwChanLabel->setText(blankLabel); + } + + if (rcValue[rcMapping[8]] != UINT16_MAX) { + ui->flapsChanLabel->setText(labelForRcValue(rcFlaps)); } else { - ui->aux3ChanLabel->setText(blankLabel); + ui->flapsChanLabel->setText(blankLabel); + } + + if (rcValue[rcMapping[9]] != UINT16_MAX) { + ui->aux1ChanLabel->setText(labelForRcValue(rcAux1)); + } + else { + ui->aux1ChanLabel->setText(blankLabel); + } + + if (rcValue[rcMapping[10]] != UINT16_MAX) { + ui->aux2ChanLabel->setText(labelForRcValue(rcAux2)); + } + else { + ui->aux2ChanLabel->setText(blankLabel); } } diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index 5edde67660..b5f7e69534 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -61,9 +61,7 @@ public slots: /** Set trim positions */ void setTrimPositions(); /** Detect which channels need to be inverted */ - void detectChannelInversion(); - /** Change the mode setting of the control inputs */ - void setRCModeIndex(int newRcMode); + void detectChannelInversion(int aert_index); /** Render the data updated */ void updateView(); @@ -73,75 +71,113 @@ public slots: /** Set the RC channel */ void setRollChan(int channel) { rcMapping[0] = channel - 1; - updateInvertedCheckboxes(channel - 1); + updateMappingView(0); } /** Set the RC channel */ void setPitchChan(int channel) { rcMapping[1] = channel - 1; - updateInvertedCheckboxes(channel - 1); + updateMappingView(1); } /** Set the RC channel */ void setYawChan(int channel) { rcMapping[2] = channel - 1; - updateInvertedCheckboxes(channel - 1); + updateMappingView(2); } /** Set the RC channel */ void setThrottleChan(int channel) { rcMapping[3] = channel - 1; - updateInvertedCheckboxes(channel - 1); + updateMappingView(3); } /** Set the RC channel */ void setModeChan(int channel) { rcMapping[4] = channel - 1; - updateInvertedCheckboxes(channel - 1); + updateMappingView(4); } /** Set the RC channel */ - void setAux1Chan(int channel) { + void setAssistChan(int channel) { rcMapping[5] = channel - 1; - updateInvertedCheckboxes(channel - 1); + updateMappingView(5); } /** Set the RC channel */ - void setAux2Chan(int channel) { + void setMissionChan(int channel) { rcMapping[6] = channel - 1; - updateInvertedCheckboxes(channel - 1); + updateMappingView(6); } /** Set the RC channel */ - void setAux3Chan(int channel) { + void setReturnChan(int channel) { rcMapping[7] = channel - 1; - updateInvertedCheckboxes(channel - 1); + updateMappingView(7); + } + /** Set the RC channel */ + void setFlapsChan(int channel) { + rcMapping[8] = channel - 1; + updateMappingView(8); + } + /** Set the RC channel */ + void setAux1Chan(int channel) { + rcMapping[9] = channel - 1; + updateMappingView(9); + } + /** Set the RC channel */ + void setAux2Chan(int channel) { + rcMapping[10] = channel - 1; + updateMappingView(10); } /** Set channel inversion status */ void setRollInverted(bool inverted) { rcRev[rcMapping[0]] = inverted; + updateMappingView(0); } /** Set channel inversion status */ void setPitchInverted(bool inverted) { rcRev[rcMapping[1]] = inverted; + updateMappingView(1); } /** Set channel inversion status */ void setYawInverted(bool inverted) { rcRev[rcMapping[2]] = inverted; + updateMappingView(2); } /** Set channel inversion status */ void setThrottleInverted(bool inverted) { rcRev[rcMapping[3]] = inverted; + updateMappingView(3); } /** Set channel inversion status */ void setModeInverted(bool inverted) { rcRev[rcMapping[4]] = inverted; + updateMappingView(4); } /** Set channel inversion status */ - void setAux1Inverted(bool inverted) { + void setAssistInverted(bool inverted) { rcRev[rcMapping[5]] = inverted; + updateMappingView(5); } /** Set channel inversion status */ - void setAux2Inverted(bool inverted) { + void setMissionInverted(bool inverted) { rcRev[rcMapping[6]] = inverted; + updateMappingView(6); } /** Set channel inversion status */ - void setAux3Inverted(bool inverted) { + void setReturnInverted(bool inverted) { rcRev[rcMapping[7]] = inverted; + updateMappingView(7); + } + /** Set channel inversion status */ + void setFlapsInverted(bool inverted) { + rcRev[rcMapping[8]] = inverted; + updateMappingView(8); + } + /** Set channel inversion status */ + void setAux1Inverted(bool inverted) { + rcRev[rcMapping[9]] = inverted; + updateMappingView(9); + } + /** Set channel inversion status */ + void setAux2Inverted(bool inverted) { + rcRev[rcMapping[10]] = inverted; + updateMappingView(10); } /** Identify roll */ @@ -169,19 +205,34 @@ public slots: identifyChannelMapping(4); } - /** Identify sub mode */ - void identifySubModeChannel() { + /** Identify assist channel */ + void identifyAssistChannel() { identifyChannelMapping(5); } + /** Identify mission channel */ + void identifyMissionChannel() { + identifyChannelMapping(6); + } + + /** Identify return channel */ + void identifyReturnChannel() { + identifyChannelMapping(7); + } + + /** Identify flaps channel */ + void identifyFlapsChannel() { + identifyChannelMapping(8); + } + /** Identify aux 1 */ void identifyAux1Channel() { - identifyChannelMapping(6); + identifyChannelMapping(9); } /** Identify aux 2 */ void identifyAux2Channel() { - identifyChannelMapping(7); + identifyChannelMapping(10); } protected slots: @@ -200,11 +251,12 @@ protected slots: void parameterChanged(int uas, int component, QString parameterName, QVariant value); void updateStatus(const QString& str); void updateError(const QString& str); - void setRCType(int type); /** Check timeouts */ void checktimeOuts(); /** Update checkbox status */ - void updateInvertedCheckboxes(int index); + void updateAllInvertedCheckboxes(); + /** Update mapping view state */ + void updateMappingView(int index); /** Update the displayed values */ void updateRcWidgetValues(); /** update the channel labels */ @@ -215,42 +267,51 @@ protected slots: } protected: + + void setChannelToFunctionMapping(int function, int channel); + bool doneLoadingConfig; UASInterface* mav; ///< The current MAV QGCUASParamManager* paramMgr; ///< params mgr for the mav - static const unsigned int chanMax = 16; ///< Maximum number of channels + static const unsigned int chanMax = 14; ///< Maximum number of channels + static const unsigned int chanMappedMax = 16; ///< Maximum number of mapped channels (can be higher than input channel count) unsigned int chanCount; ///< Actual channels - int rcType; ///< Type of the remote control - quint64 rcTypeUpdateRequested; ///< Zero if not requested, non-zero if requested - static const unsigned int rcTypeTimeout = 5000; ///< 5 seconds timeout, in milliseconds float rcMin[chanMax]; ///< Minimum values float rcMax[chanMax]; ///< Maximum values float rcTrim[chanMax]; ///< Zero-position (center for roll/pitch/yaw, 0 throttle for throttle) - int rcMapping[chanMax]; ///< PWM to function mappings + int rcMapping[chanMappedMax]; ///< PWM to function mappings + int rcToFunctionMapping[chanMax]; float rcScaling[chanMax]; ///< Scaling of channel input to control commands bool rcRev[chanMax]; ///< Channel reverse - int rcValue[chanMax]; ///< Last values - float rcMappedMin[chanMax]; ///< Mapped channels in default order - float rcMappedMax[chanMax]; ///< Mapped channels in default order - float rcMappedValue[chanMax]; ///< Mapped channels in default order + int rcValue[chanMax]; ///< Last values, RAW + float rcValueReversed[chanMax]; ///< Last values, accounted for reverse + float rcMappedMin[chanMappedMax]; ///< Mapped channels in default order + float rcMappedMax[chanMappedMax]; ///< Mapped channels in default order + float rcMappedValue[chanMappedMax]; ///< Mapped channels in default order + float rcMappedNormalizedValue[chanMappedMax]; ///< Mapped channels in default order int channelWanted; ///< During channel assignment search the requested default index + int channelReverseStateWanted; float channelWantedList[chanMax]; ///< During channel assignment search the start values + float channelReverseStateWantedList[chanMax]; QStringList channelNames; ///< List of channel names in standard order float rcRoll; ///< PPM input channel used as roll control input float rcPitch; ///< PPM input channel used as pitch control input float rcYaw; ///< PPM input channel used as yaw control input float rcThrottle; ///< PPM input channel used as throttle control input float rcMode; ///< PPM input channel used as mode switch control input + float rcAssist; ///< PPM input channel used as assist switch control input + float rcMission; ///< PPM input channel used as mission switch control input + float rcReturn; ///< PPM input channel used as return switch control input + float rcFlaps; ///< PPM input channel used as flaps control input float rcAux1; ///< PPM input channel used as aux 1 input float rcAux2; ///< PPM input channel used as aux 2 input - float rcAux3; ///< PPM input channel used as aux 3 input bool rcCalChanged; ///< Set if the calibration changes (and needs to be written) bool dataModelChanged; ///< Set if any of the input data changed QTimer updateTimer; ///< Controls update intervals - enum RC_MODE rc_mode; ///< Mode of the remote control, according to usual convention QList toolWidgets; ///< Configurable widgets QMap toolWidgetsByName; ///< bool calibrationEnabled; ///< calibration mode on / off + bool configEnabled; ///< config mode on / off QMap paramToWidgetMap; ///< Holds the current active MAV's parameter widgets. QList additionalTabs; ///< Stores additional tabs loaded for this vehicle/autopilot configuration. Used for cleaning up. diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 6c47d41ebd..ba2407e0ba 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -7,7 +7,7 @@ 0 0 1256 - 783 + 889 @@ -43,7 +43,7 @@ 0 0 133 - 757 + 863 @@ -154,7 +154,7 @@ Config - 5 + 1 @@ -332,6 +332,13 @@ Config
+ + + + Show Advanced Configuration Options + + + @@ -340,39 +347,35 @@ Config - - + + - Identify Sub Mode Switch + Assist Switch - - - - - - Identify Throttle Channel + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - Pitch / Elevator + 0000 - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignCenter - - + + Reverse - - + + false @@ -384,21 +387,66 @@ Config - - - - false + + + + Identify Aux 1 Channel - - 0 + + + + + + Mapping to Index of RC Channel used for (0 if not used) - - 16 + + + + + + Return Switch + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + + + 0000 + + + Qt::AlignCenter + + + + + + + Aux 1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Identify Mode Switch + + + + + + + Identify Yaw Channel + + + + + false @@ -410,59 +458,65 @@ Config - - + + - Yaw / Rudder + 0000 - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignCenter - - + + - Throttle + Pitch / Elevator Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - Identify Aux 2 Channel + Reverse / Invert - - + + - 0000 + Yaw / Rudder - Qt::AlignCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - Identify Main Mode Switch + + + + false + + + 0 + + + 16 - - + + - Identify Aux 1 Channel + Reverse - - + + 0000 @@ -471,43 +525,51 @@ Config - - + + - Reverse + 0000 - - - - - - Identify Roll Channel + + Qt::AlignCenter - - - - Reverse Direction / Invert + + + + false + + + 0 + + + 16 - - - - Identify Yaw Channel + + + + false + + + 0 + + + 16 - - + + Reverse - - + + 0000 @@ -516,20 +578,33 @@ Config - - + + - Reverse + Mode Switch + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - 0000 + Identify Aux 2 Channel - - Qt::AlignCenter + + + + + + false + + + 0 + + + 16 @@ -543,29 +618,49 @@ Config + + + + Identify Throttle Channel + + + - Control Channel Name + Channel Name + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Reverse - - + + - Normalized Value + 0000 + + + Qt::AlignCenter - - + + - Identify Pitch Channel + Identify Assist Switch - - + + Aux 2 @@ -574,8 +669,15 @@ Config + + + + Reverse + + + - + false @@ -587,38 +689,66 @@ Config - - + + - Aux 3 + 0000 - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignCenter - - - - false + + + + Reverse - - 0 + + + + + + Normalized Value - - 16 + + Qt::AlignCenter - - + + Reverse - - + + + + Identify Pitch Channel + + + + + + + Reverse + + + + + + + 0000 + + + Qt::AlignCenter + + + + + false @@ -630,42 +760,55 @@ Config - - + + - Reverse + Identify Roll Channel - - + + - Mode Switch + Mission Switch Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - Reverse + 0000 + + + Qt::AlignCenter - - + + - 0000 + Throttle - Qt::AlignCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + + + Flaps + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + 0000 @@ -675,72 +818,68 @@ Config - + Reverse - - - - false - - - 0 + + + + Reverse - - 16 + + + + + + Reverse - + false - - 0 - - - 16 + + + + + + false - - - - Aux 1 + + + + false - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + ArrowCursor - - + + - 0000 - - - Qt::AlignCenter + Identify Mission Switch - - + + - 0000 - - - Qt::AlignCenter + Identify Return Switch - - + + - Mapping to Index of RC Channel used for (0 if not used) + Identify Flaps Channel @@ -881,8 +1020,8 @@ Config 0 0 - 16 - 16 + 98 + 28 @@ -918,8 +1057,8 @@ Config 0 0 - 16 - 16 + 98 + 28 @@ -1010,8 +1149,8 @@ Config 0 0 - 597 - 569 + 98 + 28 diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index 350ea65b92..be3c9386e9 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -56,7 +56,7 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : connect(ui->applyButton, SIGNAL(clicked()), this, SLOT(applyAndReboot())); - connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS())); + connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); setActiveUAS(UASManager::instance()->getActiveUAS()); -- GitLab From d8fd4852a09028132bee13ceaeec60e53f355605 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sat, 24 Aug 2013 18:34:47 +0200 Subject: [PATCH 312/460] Further cleanup --- src/ui/MainWindow.cc | 23 +++++-------------- src/ui/MainWindow.h | 2 -- .../px4_configuration/QGCPX4AirframeConfig.cc | 18 +++++++-------- 3 files changed, 15 insertions(+), 28 deletions(-) diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 93e3da8b27..3b6fa50648 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -57,7 +57,6 @@ This file is part of the QGROUNDCONTROL project #include "MAVLinkDecoder.h" #include "QGCMAVLinkMessageSender.h" #include "QGCRGBDView.h" -#include "QGCFirmwareUpdate.h" #include "QGCStatusBar.h" #include "UASQuickView.h" #include "QGCDataPlot2D.h" @@ -1414,8 +1413,9 @@ void MainWindow::connectCommonActions() perspectives->addAction(ui.actionMissionView); //perspectives->addAction(ui.actionConfiguration_2); perspectives->addAction(ui.actionHardwareConfig); - perspectives->addAction(ui.actionSoftwareConfig); - perspectives->addAction(ui.actionFirmwareUpdateView); + if (getCustomMode() == CUSTOM_MODE_APM) { + perspectives->addAction(ui.actionSoftwareConfig); + } perspectives->addAction(ui.actionTerminalView); perspectives->addAction(ui.actionUnconnectedView); perspectives->setExclusive(true); @@ -2027,9 +2027,9 @@ void MainWindow::loadViewState() case VIEW_MAVLINK: centerStack->setCurrentWidget(mavlinkView); break; - case VIEW_FIRMWAREUPDATE: - centerStack->setCurrentWidget(firmwareUpdateWidget); - break; +// case VIEW_FIRMWAREUPDATE: +// centerStack->setCurrentWidget(firmwareUpdateWidget); +// break; case VIEW_MISSION: centerStack->setCurrentWidget(plannerView); break; @@ -2190,17 +2190,6 @@ void MainWindow::loadMAVLinkView() } } -void MainWindow::loadFirmwareUpdateView() -{ - if (currentView != VIEW_FIRMWAREUPDATE) - { - storeViewState(); - currentView = VIEW_FIRMWAREUPDATE; - ui.actionFirmwareUpdateView->setChecked(true); - loadViewState(); - } -} - //void MainWindow::loadDataView(QString fileName) //{ // // Plot is now selected, now load data from file diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 08b8937ce8..c5db0bc26b 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -240,8 +240,6 @@ public slots: void loadOperatorView(); /** @brief Load MAVLink XML generator view */ void loadMAVLinkView(); - /** @brief Load firmware update view */ - void loadFirmwareUpdateView(); /** @brief Load Terminal Console views */ void loadTerminalView(); diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index be3c9386e9..82694e6b82 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -23,33 +23,33 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : ui->planeComboBox->addItem(tr("Hobbyking Bixler 1/2"), 101); connect(ui->planePushButton, SIGNAL(clicked()), this, SLOT(planeSelected())); - connect(ui->planeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(planeSelected(int))); + connect(ui->planeComboBox, SIGNAL(activated(int)), this, SLOT(planeSelected(int))); ui->flyingWingComboBox->addItem(tr("Bormatec Camflyer Q"), 30); ui->flyingWingComboBox->addItem(tr("Phantom FPV"), 31); connect(ui->flyingWingPushButton, SIGNAL(clicked()), this, SLOT(flyingWingSelected())); - connect(ui->flyingWingComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(flyingWingSelected(int))); + connect(ui->flyingWingComboBox, SIGNAL(activated(int)), this, SLOT(flyingWingSelected(int))); ui->quadXComboBox->addItem(tr("Standard 10\" Quad"), 1); ui->quadXComboBox->addItem(tr("DJI F330 8\" Quad"), 10); ui->quadXComboBox->addItem(tr("Turnigy Talon v2 X550 Quad"), 666); connect(ui->quadXPushButton, SIGNAL(clicked()), this, SLOT(quadXSelected())); - connect(ui->quadXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(quadXSelected(int))); + connect(ui->quadXComboBox, SIGNAL(activated(int)), this, SLOT(quadXSelected(int))); connect(ui->quadPlusPushButton, SIGNAL(clicked()), this, SLOT(quadPlusSelected())); - connect(ui->quadPlusComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(quadPlusSelected(int))); + connect(ui->quadPlusComboBox, SIGNAL(activated(int)), this, SLOT(quadPlusSelected(int))); - connect(ui->hexaXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hexaXSelected(int))); + connect(ui->hexaXComboBox, SIGNAL(activated(int)), this, SLOT(hexaXSelected(int))); - connect(ui->hexaPlusComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hexaPlusSelected(int))); + connect(ui->hexaPlusComboBox, SIGNAL(activated(int)), this, SLOT(hexaPlusSelected(int))); - connect(ui->octoXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(octoXSelected(int))); + connect(ui->octoXComboBox, SIGNAL(activated(int)), this, SLOT(octoXSelected(int))); - connect(ui->octoPlusComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(octoPlusSelected(int))); + connect(ui->octoPlusComboBox, SIGNAL(activated(int)), this, SLOT(octoPlusSelected(int))); - connect(ui->hComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hSelected(int))); + connect(ui->hComboBox, SIGNAL(activated(int)), this, SLOT(hSelected(int))); ui->hComboBox->addItem(tr("TBS Discovery"), 15); ui->hComboBox->addItem(tr("H Custom"), 16); -- GitLab From eccfcb0a762e30b254054b0a745a5d3e9a106201 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sat, 24 Aug 2013 11:27:53 -0700 Subject: [PATCH 313/460] workaround for QVariants incoming as QString meta type --- src/uas/UASParameterDataModel.cc | 31 +++++++++++++++++++------------ src/uas/UASParameterDataModel.h | 5 +++-- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index da1a6b9878..4493758a30 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -80,11 +80,8 @@ void UASParameterDataModel::setPendingParam(int compId, const QString& key, con { //ensure we have a placeholder map for this component addComponent(compId); - QMap *pendParams = getPendingParamsForComponent(compId); - if (pendParams) { - pendParams->insert(key,value); - emit pendingParamUpdate(compId, key, value, true); - } + setParamWithTypeInMap(compId,key,value,pendingParameters); + emit pendingParamUpdate(compId, key, value, true); } void UASParameterDataModel::removePendingParam(int compId, const QString& key) @@ -105,11 +102,12 @@ void UASParameterDataModel::setOnboardParam(int compId, const QString &key, con { //ensure we have a placeholder map for this component addComponent(compId); + //TODO use setParamWithTypeInMap instead and verify QMap *params = getOnboardParamsForComponent(compId); params->insert(key,value); } -void UASParameterDataModel::setOnboardParamWithType(int compId, const QString& key, const QVariant &value) +void UASParameterDataModel::setParamWithTypeInMap(int compId, const QString& key, const QVariant &value, QMap* >& map) { switch ((int)value.type()) @@ -117,25 +115,35 @@ void UASParameterDataModel::setOnboardParamWithType(int compId, const QString& k case QVariant::Int: { QVariant fixedValue(value.toInt()); - onboardParameters.value(compId)->insert(key, fixedValue); + map.value(compId)->insert(key, fixedValue); } break; case QVariant::UInt: { QVariant fixedValue(value.toUInt()); - onboardParameters.value(compId)->insert(key, fixedValue); + map.value(compId)->insert(key, fixedValue); } break; case QMetaType::Float: { QVariant fixedValue(value.toFloat()); - onboardParameters.value(compId)->insert(key, fixedValue); + map.value(compId)->insert(key, fixedValue); } break; case QMetaType::QChar: { QVariant fixedValue(QChar((unsigned char)value.toUInt())); - onboardParameters.value(compId)->insert(key, fixedValue); + map.value(compId)->insert(key, fixedValue); + } + break; + case QMetaType::QString: + { + QString strVal = value.toString(); + float floatVal = strVal.toFloat(); + QVariant fixedValue( floatVal ); + //TODO track down WHY we're getting unexpected QString values here...this is a workaround + qDebug() << "Unexpected string QVariant:" << key << " val:" << value << "fixedVal:" << fixedValue; + map.value(compId)->insert(key, fixedValue); } break; default: @@ -165,8 +173,7 @@ void UASParameterDataModel::handleParamUpdate(int compId, const QString ¶mNa QVariant reqVal = pendingParams->value(paramName); if (reqVal == value) { //notify everyone that this item is being removed from the pending parameters list since it's now confirmed - emit pendingParamUpdate(compId, paramName, value, false); - pendingParams->remove(paramName); + removePendingParam(compId,paramName); } else { qDebug() << "Pending commit for " << paramName << " want: " << reqVal << " got: " << value; diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index c7c1dd057d..84761a9680 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -41,8 +41,6 @@ public: */ virtual QList getComponentForOnboardParam(const QString& parameter) const; - /** @brief Save the onboard parameter with a the type specified in the QVariant as fixed */ - virtual void setOnboardParamWithType(int componentId, const QString &key, const QVariant& value); /** @brief clears every parameter for every loaded component */ virtual void forgetAllOnboardParams(); @@ -91,6 +89,9 @@ protected: /** @brief set the confirmed value of a parameter in the onboard params list */ virtual void setOnboardParam(int componentId, const QString& key, const QVariant& value); + /** @brief Save the parameter with a the type specified in the QVariant as fixed */ + void setParamWithTypeInMap(int compId, const QString& key, const QVariant &value, QMap* >& map); + /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ virtual void setPendingParam(int componentId, const QString &key, const QVariant& value); /** @brief remove a parameter from the pending list */ -- GitLab From 3dece82d54c639b0f777ed1991bdc10730aafbf1 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sat, 24 Aug 2013 21:49:40 +0200 Subject: [PATCH 314/460] Adding signals for auto-link handling --- src/ui/QGCPX4VehicleConfig.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 2e458ea7af..c962d524ba 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -19,6 +19,7 @@ //#include "QGCPendingParamWidget.h" #include "QGCToolWidget.h" #include "UASManager.h" +#include "LinkManager.h" #include "UASParameterCommsMgr.h" #include "ui_QGCPX4VehicleConfig.h" #include "px4_configuration/QGCPX4AirframeConfig.h" @@ -89,6 +90,9 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : #ifdef QUPGRADE_SUPPORT firmwareDialog = new DialogBare(this); ui->firmwareLayout->addWidget(firmwareDialog); + + connect(firmwareDialog, SIGNAL(connectLinks()), LinkManager::instance(), SLOT(connectAll())); + connect(firmwareDialog, SIGNAL(disconnectLinks()), LinkManager::instance(), SLOT(disconnectAll())); #else #error Please check out QUpgrade from http://github.com/LorenzMeier/qupgrade/ into the QGroundControl folder. -- GitLab From 1ef980dafbe91cb239a53fc5e76eb19ef8492732 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sat, 24 Aug 2013 13:03:40 -0700 Subject: [PATCH 315/460] Respect component id passed to UAS::setParameter --- src/uas/UAS.cc | 12 ++++++------ src/uas/UAS.h | 2 +- src/uas/UASParameterCommsMgr.cc | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 2c92ff6e89..3ba41583fd 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -2368,9 +2368,9 @@ void UAS::enableExtra3Transmission(int rate) * @param component The component to set the parameter * @param id Name of the parameter */ -void UAS::setParameter(const int component, const QString& id, const QVariant& value) +void UAS::setParameter(const int compId, const QString& paramId, const QVariant& value) { - if (!id.isNull()) + if (!paramId.isNull()) { mavlink_message_t msg; mavlink_param_set_t p; @@ -2431,7 +2431,7 @@ void UAS::setParameter(const int component, const QString& id, const QVariant& v p.param_value = union_value.param_float; p.target_system = (uint8_t)uasId; - p.target_component = (uint8_t)component; + p.target_component = (uint8_t)compId; //qDebug() << "SENT PARAM:" << value; @@ -2439,9 +2439,9 @@ void UAS::setParameter(const int component, const QString& id, const QVariant& v for (unsigned int i = 0; i < sizeof(p.param_id); i++) { // String characters - if ((int)i < id.length()) + if ((int)i < paramId.length()) { - p.param_id[i] = id.toAscii()[i]; + p.param_id[i] = paramId.toAscii()[i]; } else { @@ -2449,7 +2449,7 @@ void UAS::setParameter(const int component, const QString& id, const QVariant& v p.param_id[i] = 0; } } - mavlink_msg_param_set_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &p); + mavlink_msg_param_set_encode(mavlink->getSystemId(), compId, &msg, &p); sendMessage(msg); } } diff --git a/src/uas/UAS.h b/src/uas/UAS.h index 02d8159aee..6b5d34f8d6 100644 --- a/src/uas/UAS.h +++ b/src/uas/UAS.h @@ -842,7 +842,7 @@ public slots: void requestParameter(int component, int id); /** @brief Set a system parameter */ - void setParameter(const int component, const QString& id, const QVariant& value); + void setParameter(const int compId, const QString& paramId, const QVariant& value); /** @brief Write parameters to permanent storage */ void writeParametersToStorage(); diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index abe2072cbc..a62ab19c5d 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -156,11 +156,11 @@ void UASParameterCommsMgr::emitPendingParameterCommit(int compId, const QString& } break; default: - qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE"; + qCritical() << "ABORTED PARAM SEND, INVALID QVARIANT TYPE" << paramType; return; } - setParameterStatusMsg(tr("Requested write of: %1: %2").arg(key).arg(value.toDouble())); + setParameterStatusMsg(tr("Writing %1: %2 for comp. %3").arg(key).arg(value.toDouble()).arg(compId)); } -- GitLab From 7bb12dd288a01118f894a0aefed447fa26e45b30 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sat, 24 Aug 2013 13:19:45 -0700 Subject: [PATCH 316/460] ignore autosave files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 06aaffca0a..6a777bb495 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,5 @@ thirdParty/qserialport/bin/ thirdParty/qserialport/lib/ GeneratedFiles/ /qupgrade/ + +*.autosave -- GitLab From c45feb280fecd2c1ca04bfdcb7330055b8775328 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sat, 24 Aug 2013 16:13:44 -0700 Subject: [PATCH 317/460] Begin migration to integrated param widget don't process updates to unmapped rc channels when we're not in calibration mode --- src/uas/QGCUASParamManager.cc | 2 + src/ui/QGCPX4VehicleConfig.cc | 141 ++++++++++++--------------- src/ui/QGCPX4VehicleConfig.ui | 166 +++++++++----------------------- src/ui/QGCPendingParamWidget.cc | 10 +- 4 files changed, 111 insertions(+), 208 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 1a967e79d3..38450eb81a 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -56,6 +56,8 @@ void QGCUASParamManager::connectToModelAndComms() void QGCUASParamManager::clearAllPendingParams() { paramDataModel.clearAllPendingParams(); + emit parameterStatusMsgUpdated(tr("Cleared all pending params"), UASParameterCommsMgr::ParamCommsStatusLevel_OK); + } diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 2e458ea7af..a494b1ab0c 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -16,7 +16,6 @@ #include "QGCPX4VehicleConfig.h" #include "QGC.h" -//#include "QGCPendingParamWidget.h" #include "QGCToolWidget.h" #include "UASManager.h" #include "UASParameterCommsMgr.h" @@ -130,8 +129,6 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : ui->rcCalibrationButton->setCheckable(true); connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool))); - connect(ui->writeButton, SIGNAL(clicked()), - this, SLOT(writeParameters())); //TODO connect buttons here to save/clear actions? UASInterface* tmpMav = UASManager::instance()->getActiveUAS(); @@ -516,26 +513,29 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) } } - // Generate widgets for the Advanced tab. - foreach (QString file,vehicledir.entryList(QDir::Files | QDir::NoDotAndDotDot)) - { - if (file.toLower().endsWith(".qgw")) { - QWidget* parent = ui->advanceColumnContents; - tool = new QGCToolWidget("", parent); - if (tool->loadSettings(vehicledir.absoluteFilePath(file), false)) - { - toolWidgets.append(tool); - QGroupBox *box = new QGroupBox(parent); - box->setTitle(tool->objectName()); - box->setLayout(new QVBoxLayout(box)); - box->layout()->addWidget(tool); - ui->advancedColumnLayout->addWidget(box); - } else { - delete tool; - } - } - } + //TODO fix and reintegrate the Advanced parameter editor +// // Generate widgets for the Advanced tab. +// foreach (QString file,vehicledir.entryList(QDir::Files | QDir::NoDotAndDotDot)) +// { +// if (file.toLower().endsWith(".qgw")) { +// QWidget* parent = ui->advanceColumnContents; +// tool = new QGCToolWidget("", parent); +// if (tool->loadSettings(vehicledir.absoluteFilePath(file), false)) +// { +// toolWidgets.append(tool); +// QGroupBox *box = new QGroupBox(parent); +// box->setTitle(tool->objectName()); +// box->setLayout(new QVBoxLayout(box)); +// box->layout()->addWidget(tool); +// ui->advancedColumnLayout->addWidget(box); + +// } else { +// delete tool; +// } +// } +// } + // Load tabs for general configuration foreach (QString dir,generaldir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) @@ -1023,17 +1023,6 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) { // Hide items if NULL and abort if (!active) { - ui->refreshButton->setEnabled(false); - ui->refreshButton->show(); - ui->readButton->setEnabled(false); - ui->readButton->show(); - ui->writeButton->setEnabled(false); - ui->writeButton->show(); - ui->loadFileButton->setEnabled(false); - ui->loadFileButton->show(); - ui->saveFileButton->setEnabled(false); - ui->saveFileButton->show(); - return; } @@ -1051,8 +1040,6 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) //TODO use paramCommsMgr instead disconnect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); - disconnect(ui->refreshButton,SIGNAL(clicked()), - paramMgr,SLOT(requestParameterList())); // Delete all children from all fixed tabs. foreach(QWidget* child, ui->generalLeftContents->findChildren()) { @@ -1093,6 +1080,7 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) paramMgr = mav->getParamManager(); ui->pendingCommitsWidget->setUAS(mav); + ui->paramTreeWidget->setUAS(mav); // Reset current state resetCalibrationRC(); @@ -1106,8 +1094,7 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) SLOT(remoteControlChannelRawChanged(int,float))); connect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); - connect(ui->refreshButton, SIGNAL(clicked()), - paramMgr,SLOT(requestParameterList())); + if (systemTypeToParamMap.contains(mav->getSystemTypeName())) { paramToWidgetMap = systemTypeToParamMap[mav->getSystemTypeName()]; @@ -1131,22 +1118,7 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) updateStatus(QString("Reading from system %1").arg(mav->getUASName())); // Since a system is now connected, enable the VehicleConfig UI. - ui->refreshButton->setEnabled(true); - ui->refreshButton->show(); - ui->readButton->setEnabled(true); - ui->readButton->show(); - ui->writeButton->setEnabled(true); - ui->writeButton->show(); - ui->loadFileButton->setEnabled(true); - ui->loadFileButton->show(); - ui->saveFileButton->setEnabled(true); - ui->saveFileButton->show(); - - //TODO never true? - if (mav->getAutopilotTypeName() == "ARDUPILOTMEGA") { - ui->readButton->hide(); - ui->writeButton->hide(); - } + //TODO anything? } void QGCPX4VehicleConfig::resetCalibrationRC() @@ -1222,8 +1194,13 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float fval) } // Raw value - int delta = abs(fval - rcMappedValue[rcToFunctionMapping[chan]]); - if (!configEnabled && !calibrationEnabled && delta < 12 && delta >= 0 && rcValue[chan] > 800 && rcValue[chan] < 2200) { + float mappedVal = rcMappedValue[rcToFunctionMapping[chan]]; + bool isMapped = (((float)UINT16_MAX) != mappedVal); + float delta = fabsf(fval - mappedVal); + if (!configEnabled && !calibrationEnabled && + (!isMapped || + (delta < 12.0f && rcValue[chan] > 800 && rcValue[chan] < 2200) ) + ) { //ignore tiny jitter values return; } @@ -1690,33 +1667,33 @@ void QGCPX4VehicleConfig::parameterChanged(int uas, int component, QString param break; } } - if (!found) { - //New param type, create a QGroupBox for it. - QWidget* parent = ui->advanceColumnContents; - - // Create the tool, attaching it to the QGroupBox - QGCToolWidget *tool = new QGCToolWidget("", parent); - QString tooltitle = parameterName; - if (parameterName.split("_").size() > 1) { - tooltitle = parameterName.split("_")[0] + "_"; - } - tool->setTitle(tooltitle); - tool->setObjectName(tooltitle); - //tool->setSettings(set); - libParamToWidgetMap.insert(parameterName,tool); - toolWidgets.append(tool); - tool->addParam(uas, component, parameterName, value); - QGroupBox *box = new QGroupBox(parent); - box->setTitle(tool->objectName()); - box->setLayout(new QVBoxLayout(box)); - box->layout()->addWidget(tool); - - libParamToWidgetMap.insert(parameterName,tool); - toolWidgets.append(tool); - ui->advancedColumnLayout->addWidget(box); - - toolToBoxMap[tool] = box; - } +// if (!found) { +// //New param type, create a QGroupBox for it. +// QWidget* parent = ui->advanceColumnContents; + +// // Create the tool, attaching it to the QGroupBox +// QGCToolWidget *tool = new QGCToolWidget("", parent); +// QString tooltitle = parameterName; +// if (parameterName.split("_").size() > 1) { +// tooltitle = parameterName.split("_")[0] + "_"; +// } +// tool->setTitle(tooltitle); +// tool->setObjectName(tooltitle); +// //tool->setSettings(set); +// libParamToWidgetMap.insert(parameterName,tool); +// toolWidgets.append(tool); +// tool->addParam(uas, component, parameterName, value); +// QGroupBox *box = new QGroupBox(parent); +// box->setTitle(tool->objectName()); +// box->setLayout(new QVBoxLayout(box)); +// box->layout()->addWidget(tool); + +// libParamToWidgetMap.insert(parameterName,tool); +// toolWidgets.append(tool); +// ui->advancedColumnLayout->addWidget(box); + +// toolToBoxMap[tool] = box; +// } } } diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index ba2407e0ba..608402afc3 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -7,7 +7,7 @@ 0 0 1256 - 889 + 912 @@ -43,7 +43,7 @@ 0 0 133 - 863 + 886 @@ -154,7 +154,7 @@ Config - 1 + 5 @@ -932,8 +932,8 @@ Config 0 0 - 98 - 28 + 39 + 26 @@ -1020,8 +1020,8 @@ Config 0 0 - 98 - 28 + 16 + 16 @@ -1057,8 +1057,8 @@ Config 0 0 - 98 - 28 + 16 + 16 @@ -1149,8 +1149,8 @@ Config 0 0 - 98 - 28 + 597 + 740 @@ -1158,90 +1158,20 @@ Config 0 - + + + + + true + + + + - - - - - - false - - - Load parameters currently in non-permanent memory of aircraft. - - - - - - Refresh - - - - - - - false - - - Copy parameters from permanent memory to non-permanent current memory of aircraft. DOES NOT update the parameters in this view, click refresh after copying them to get them. - - - - - - - - - Read ROM - - - - - - - false - - - Copy current parameters in non-permanent memory of the aircraft to permanent memory. Transmit your parameters first to write these. - - - - - - Write ROM - - - - - - - Load File - - - - - - - false - - - Save parameters in this view to a file on this computer. - - - - - - Save to File - - - - - @@ -1275,34 +1205,28 @@ Config Changes Pending - - - - 10 - 30 - 381 - 601 - - - - - 0 - - - - - - 0 - 30 - - - - true - - - - - + + + + + -1 + + + + + + 0 + 0 + + + + true + + + + + + @@ -1354,6 +1278,12 @@ Config
QGCMessageView.h
1 + + QGCParamWidget + QWidget +
ui/QGCParamWidget.h
+ 1 +
diff --git a/src/ui/QGCPendingParamWidget.cc b/src/ui/QGCPendingParamWidget.cc index 35402d995e..aaafc42192 100644 --- a/src/ui/QGCPendingParamWidget.cc +++ b/src/ui/QGCPendingParamWidget.cc @@ -10,6 +10,8 @@ QGCPendingParamWidget::QGCPendingParamWidget(QObject *parent) : QGCParamWidget((QWidget*)parent) { + //this subclass doesn't display status updates + statusLabel->hide(); } @@ -20,10 +22,6 @@ void QGCPendingParamWidget::connectToParamManager() // Listen to updated param signals from the data model connect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); - - // Listen to communications status messages so we can display them - connect(paramMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), - this, SLOT(handleParamStatusMsgUpdate(QString , int ))); } @@ -33,10 +31,6 @@ void QGCPendingParamWidget::disconnectFromParamManager() disconnect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); - // Listen to communications status messages so we can display them - disconnect(paramMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), - this, SLOT(handleParamStatusMsgUpdate(QString , int ))); - paramMgr = NULL; } -- GitLab From 1ce0285306217d9e1edf5c311543d9cd4b006112 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 25 Aug 2013 08:17:54 +0200 Subject: [PATCH 318/460] Instantiate a PX4 config view in PX4 mode from start, since boards with just the bootloader (or no working telemetry) cannot be flashed else. --- files/images/px4/airframes/quad_h.png | Bin 0 -> 44745 bytes qgroundcontrol.pro | 11 +- qgroundcontrol.qrc | 1 + src/ui/QGCConfigView.cc | 32 ++++- src/ui/QGCConfigView.h | 1 + src/ui/QGCPX4VehicleConfig.cc | 11 +- .../px4_configuration/QGCPX4AirframeConfig.ui | 8 +- .../QGCPX4MulticopterConfig.cc | 14 ++ .../QGCPX4MulticopterConfig.h | 22 ++++ .../QGCPX4MulticopterConfig.ui | 123 ++++++++++++++++++ 10 files changed, 213 insertions(+), 10 deletions(-) create mode 100644 files/images/px4/airframes/quad_h.png create mode 100644 src/ui/px4_configuration/QGCPX4MulticopterConfig.cc create mode 100644 src/ui/px4_configuration/QGCPX4MulticopterConfig.h create mode 100644 src/ui/px4_configuration/QGCPX4MulticopterConfig.ui diff --git a/files/images/px4/airframes/quad_h.png b/files/images/px4/airframes/quad_h.png new file mode 100644 index 0000000000000000000000000000000000000000..1c5efb6e8a54c169b8c3e6b22095b997927465af GIT binary patch literal 44745 zcmeAS@N?(olHy`uVBq!ia0y~yV4TIk!05uk#=yWJXY|8{fq{Xuz$3Dlfq`2Xgc%uT z&5>YWV7!_c5>XQ2>tmIipR1RclAn~SSCL!500K4@Ru#Dgxv3?I3Kh9IdBs*0wn|_X zR(Zu%AYpwa1+bEmY+I!W-v9;Y{GwC^Q$0gHBPBa71qB70qLehNAQv~N_M((DTcwPW zk^(Dz{qpj1y>er{{GxPyLrY6beFGzXBO~3Slr-Jq%Dj@q3f;V7Wr!g#b6ir3lZ!G7 zN;32F6hP)CCgqow*eWT3EK-00h&xL%(-1c06+^w1oS&-?lF>KRGth^d4Kf}iYUP}t zTTql*T%4JoXJ={yR*52pu*U|hJ|H8%BtJK`q$o4lGp{7IsGumdBoX8~J0qxW+$zw` z@-NCv&4cPTgz82XgQ~aD2YDPRARwU(77cQ7v*WVS2ge5}ZtS>nS-IyiFgP%Hx;TbZ zFusXpuLwDM%kK83*}m^vC$wCMUeVO$AuO;owp#q_qB!lCH+#k3?0x+{^o^*1OTelx z_pB9{eBU+u?f>6-Wd)oqISRXPsywfrm;d~YW^vj*$YygI{*bo29@HfY!o4wUaA$Wl_?X1ChWEulUE-i7wUY6z0UTXb0*bQYfYSTLQ>`3CDQ zDX$<4235~D%$6dGUm^tbJ2g2^{qP8rU3hrm-G#3gcrQFHsg$RE$V}Df;+B=ib<@M# z7Ccpau>ihk= z_qS(tY~54Ruyl{b*}Sc-R&TZ`v|n9xeA~S=Q+AE3v$B>(8C9$lRp@it9I>;HVI7oG@Vme{fLHI_sJrA1(ZeDQz@hzj4p!w?e``1S7{?j$<(4E4zKgzb*T3(BFMN@Az ze9#C^NQvpS)4RBWhhxj?QmffPt2eLSS~XiOAm3P8>*}^yQcKq!Td-+nk5>1_s8pR3 zd?sQ~*`sWf&EKjZfvVD=>Qyw|J z_W$0j=S{rgBDt~Un-%Sg6H4>add!TrsVz$G@9N0=d%AgYPr0j&14<-c*3-m8C z`W=vPbm87#m-a?GX&ZfOiQ>K5b>PL1+F2V`++2E-Rp0s)-*lt0C7aosvKMT3sBhla zQj+I<VRWk#09$pp?REROcMc87w6j`&|ve0U+eT5QVqgo9Ds zPivnk*8R#$ohUd#(1MexV*0I@Uw{2o5TAQBYpR;hjD#P*-|wIP_&>`YXTR;@=K>YF zPG0!EQ1HU@g_|q(ysw}4E__e&*S$|AtB*-=6(3HzbY7?HmFWtdRnHHcYM2lpeeUxr ziS8oPqt<3E&+;S0LhBOJGZK6r`S}KXP*456t-j}rWVK^YPm`sU@^r(99F*}F}k z{pz~OI%RY3Ch>2Wy(X(QDm5@mB&{_nQhDW6w^pyfr59H6YniNC%XM<&x~kfPT1ULS zPiXG2znk~m!P823q0|cEsI(rxwy*af;RXjN?3RA+nQ z>D!x|(=TT$MCwdSKEbxT%ISXdss;K^^-}+iB!%Al7oT@3e*c$!UCz~$4qJWG@RzXJ zq*3-@gV9vA1C7PAT+d7uU3KRww=%bxPVc%?=PtYy4t^GOT6?*4*XDkO`HUVSx^s>% zSiRu;qr2yvZaiA*E5IxFpulFOWI))5&kN(7GXrP1>+EzaPxyE)aq8`E{f*B;=I5ST zXU{>~oWq4_WNXWu)c2H7s?(sbyDIzYUnJWpN4vp#yVVzaXYvmoc^;}fI;^2&_YNc!HrfWrfUcPn7v+Uxqt7&&`YkFLF$cf=q z{kSpzx$}$vGxS=%a;@X$<>QMpO*=EguUlOIpRnu_@hjDvY8>1av?>b-3V!^2W~Q;a z|6HrD8GbA`b>jE!IgwyckaxPdBHymDS|{PNIrlQryhzivTIR-9nJ-v(YCeyj$j*JJ z?n{#WO^5k?&koG_uPT-oBe%4>FFtW&#PZpn`g4x{Uh69K^4D(RUs7K}pY+O27t>xl zE#t$6DHU2Jy?5D{syYV$Vz=Ay@3VgQ$;b`qSznhe^3E=sUbZoG26M^W!&=PMZecHe z9}QtC>oz!`l{qP_-*UIrf-2{_6@}S_D+>KHSM0r|m6`N)w#wGOvY!vW%AY8=T6^u{ z3Hx?0P?;aT;Qiwpf!Q4Y=PG$TyOq7(xBAIM_ma%aOt#4B*)Iv>FT|HdJvM5F6+|2|3H=W?vqQ(;NtorEDqiau{K3%-)?5k(JDaLh&T4tF_ zn@3+vU;NhMKo6${_Ex28?#zT%0{4U*M8QeGd+W=Qm^k6UVK_S#U^B<&U2~D2fH>ba4b|! zTs)~OVW&*Gu8HXm-lOd1Q4T-lXI>1|E>g~A%bx1BzV6nf^dAkZoRyx3zkYXW4gDs3 zH+4%2%SnTOxAS(N{c@09-X?ML&A12kktr-u!b}zX%kCE(<~?8c>*ey2{<#5jrk(xq zu`l;#tLWYQ>a^`%i$7LtKWmXJe9Lk$qrCoanOEvFMo(dplGO_pzE?jG=sq0pV0rdY z))hha*yYaWW`IYaGbs`eF?-b<-&jg+>tGc|wo$nPiD z)_k4m$L#)|+FyLgYv0}Z2`AT1n{x2g%xiyUnNQ&F^LW|5!|u?E+3&8$*YD+0asK}{ zaHes3pGoSeDWyk`9&PS>H^n@KC5n?NFfj1+#R*o=Cwc2xX7Yb(&N1?!F`8>kRLF-g0EaPK_N;X7BAhwl`I( zHLQ03-a97U)6SS)kGcGF@ArF;HMS-%*|aI>(CLh0-C}J`;l*bhfA;q{aJwAGM;jX0iZ4l>JQftY^47PDn=?aaviGEIE?jdsr%X!R$1K!*=HM-dv!&PLR$EG*{BWmJSe-3< z>#ff_b-Q~UvK0E~2=bnVO z#}p#udMYqi}FHe$s+~zFR#sBzN%>3TK@Z=_lE~bTkT&e!|(ep zr1;t4_iv8P$`0Q0FwkD{?$Qf+7mNe+>sWI)tjk!pXPd-zNr#lvEy}CaoZFY{@7SjF ze)?H?vD%%#CtWBO=1$IgTf1cGm&0@3B>s0cn*QQm_3zkzF23nc9qjug^&^x{Z2yt+ z@$~T&mMA8sio4EM8!=q_b#@y9LYHL?J&c3x* zW#(j4=H{r9!<+M-ZR}WH^mg<1?+2I`xUVs7i?cW<$|~lt{o&tq=R5D0xC-!c$%gM- zTsebF_Ws}g?!}wa*UgOGyG}tjFKYhZgUye39!Tw;9;_%i@nzs*x6nUdug3=mUf3u6 z`$>S?f~86g<#nGX6t~rFO!~R$f$-DB>+51K9ctxX8vp#<=Cv^!V+5t7^Z9(<#!21U zTOV1n-ceLHanZBRPfuUkwVzd6JOAhXytbw{&C_0WZ7!5OnWkC7_p0HzZSV2$=Np;6 zXBST7ai3CHmQ(fWdh)LnyFGuzvpYTKe|ooJ?JJJCSJxXqNPM)xs&Um1#a*Xuwx`@# z>}KzKVpr+wW6AS)(7U927K3wERx#^xAuW zSijwwlauN*Jx=u2mU*hN?<$trSZr)w>6*5VQ+RE_swH1;&$HU`aOwY|9iPLWo!WFd zF#XfxENOvv>^BQy-S-RZFP+P%u}<-$@f719>-~NweGz3}ANwOT;d;j>l}SDQ(|SH$ z4KBJN6LfXe9fQ-$E*1QKw~E8rG4+7u;d2}PrOX3)g(e!D*?e%xgW0lepFVxMr;#8t zQK`Gfq1!p(QM>md?NwcN(N>QyedN4b75*}4*L0UJQW0_&cb1!Kheh_eH`JQFj^D9+ z^UghQw2MoB%C4|(f4nAtL2aP;6WRLK_uqf0US!ZH`%};MbQAYvs~U?pU2BeC+q?d? zVC2LC|NT5~vcD$jt_uubdy>C6XLXOkI}JYW09K9T4FzgF((A3>@AUjRE zto4RITW9&)U&!_J&aA+YE9__Yna$cSbapjEhxe);&!0I*KHO0^uUY(BDo(P#e7?_{ z?8!}~w@R*Ne?B~AH_ybU*4$1)lZ9jzWRLz#J{Qg>ZRT@G$n=tUe2wDW+V6L{Kip)v z*?LXQ+w=6fFEjeZ?r}}pxi9tkqMt$WyYhF}U4G49vL*V=OAlAJDZ*CaO&M~|H`Y8V zcVSlBC)F{bmwnOW{ptULUq4%|v~^lbJDc1Z(~?=D`ulfS-px6dd-UM3udRuvY>%DT z^tZL~<=@M1pZ80xu6o!io@2J!xBJl5Rc$4|SU(gg?P)u3ga5xoPPj(g_glQTJdUu} z&la7&^8x$nt;=Q|o@Y6uN%;29&PG*^*}i|eG8|N58;*Fr@Zd=_OS9XNvs23{y?^)a z^AE3GQ@=dL|4!Z(4Z|zeS2iuxxwB)hiOQc@=N50C7rl9v=6l8Cs>%;^S`VHv%M9xM>>9|`Px4x{_VW>YSrw3<#Anm?3vzPpVRBVUr~x-5wk@0!u({T zXKUV^57S>AG4HbJ*SU$eMH$zomq>nkUh2pmKF@bk-2VJKd%_I&pLpGH(mW%K#jXC& zapOtO2mi4|&SGGkeR4&_zXPUs*Iu0}?5O7*xLwbAOMKGoY-h9X3X{)w+%>D2zu$B; z=$iJnZg0uAh4(u9dG2UW_IZ4Nuqw`Ub^_mDE%7a=Vvz4S`f&ZrY% z3hYhlXV=^y@eik4`0aMcvt7E<7Q!A zBYR%2={FZG`pJIZC_S9@xc~e4jkTNRs4*2RT&c3PFHWV#*mU2 zwM@-B*5?z~oheKn4d&fCj-iv$L!&fqWJ-@i_Y0~a~=h>+#@teaOG)g|6u(0>G z+WYzYV>OZ5&E+mp8D4 zKCNc^e^=i*_aut)k}CJEoXS5(i|PN%tq(Sx2;Lj9&(Cc^r@)MkicM-Y2I;AnK74dM z_NXS-A;V?!`KbIwdw!;x?E0XQ{X6jgso*RoxyI1Lt?rhe-k8O!Z@bySw&v8;8J5j| zGqaZ^y4~E<G z-qP~?`rzAMLhOq)OK-dtUwrQA3S*(Op*Q%xrGA^$n=#>}`NIEi|NVAVbd7(rSG6J| zsd1ZgMz6l{{cZ1_N?cFAcT`g&A@jogg_m!K{d;=HOr1$1zvOz!bgSOqJ5$bYo1N{& zRoa=}JB|I%j|U4ctm=GoZ@tgTvOb5?2X+6q#Jz5gmf!2TS%8--wtk6%;IG`9j}CvA z-X`XHKaF#pAI|GiPVQ_9gtYqSrm zmz)S>V?U8yT={e1?9Hp)y`zq5{m7bsXzjhWuBPWttxsRvp2~7z0jKjn{nmZ?Iw$t7 zs5t)X#FWo^S{bKj{IGg|(Uv_d^UFai8}4<_e7f6iJJ(F*n=j03MP) zQ(;NNjm`_#8{L`qUbwRGxKeAZq0o5+MvEFI+5WdXw)J$*DW9)Up!janmrL)(r2BPd zn_I5>{@~HJZ>~P`7u-4Ed#is=$g%)-pW?a4rbguDJ(#3s{ib-4mxhYg zr`?k;B)$Rr@l>=fnDhpjMX})(`y^Ke_j(hLYd)!Z$jhK9!4@kIt zcF)|I8S?SkRzuEa_aeV`9Xq!Le?4}bm-!}`5##poTD^n&FD=fqjwU6u_s)(Fuw3+L z{Th`BI^WK38Ycp{M3=x6y; z`N-{yT5~zy$cDcC8gt6rqN~A7ca7SDS^@k1TFH5b`C4`_C`mn~qOr!g*;9FA~#i^ZvSKAUYmqPK{)5a-VB{%kbs2*CB?6hCxY5i>Az;EgcaNp>cNZ|LPx2&-1-` zJ$(#S;wp08QnuHXc>dn1F@=ls-RY)HwYSe7-u>TlUZ9we4a2FQrE$XZ1$m1c;vdXU zU%yLdLt1`h{+F{SvS(Gk-DoCLcp~y++2d_VeAa&%b}^iq_FQO%juDe@tAn^p35#e{ z>G96%yd5uY9e;l}&8*vXoUns+|2yEev{Uw zWm^nX46N?0Un@EL=9-9_->uD;o32i@bT^v1{qDEzoq zxNc-u-`odDqO#`gX}TX769~HT<-j z{PlY+by88Yr|`V+$g2pJ;(ej1mZq@ow2Nw3z}}@9ISJoS6oq6hmzerquQ(#7>(Wj3 z#l_3ly^uG(f9L7DMDt_k{%4gv`1UpW%CW5GBX$|#kRBVKXW}Nc6;RC6NmdX&RIO> z(NtA+y_8{cuHeCe#!Jrpc1v#TDVtpN@sGV}=5FU;?*F^>?oJ9{`|;ah>$^Xk+qW*( zpQ-12ic7mg!owSS*Z|FUP!wm&;F z78*Haa-WO*x%++{vzCI!8WBm~=51PwJYCz2s&#f)+zU#$l0Dh!&!z*4y?%-(pPY}l z{CuADGS<9^y>X@AZl-rTtMhtVt)9L<$hPdd^Q}LU*{%FvmRvV^?wH#yFnP%Y3#kc3 z0$$laEL2 zgZsrc_o78L>=njZ0<#kDx>Os_^=*H1GI(a!VaZ8%Cnf2wx|ntArLVgE-k*I@+`Y4! zgT;6&UN1Gj!f*TGf#yTwzwa_n_22&)Ft_}07vr>=|66lz_%kor*_Ewvh&dpPXVVFe zIc7{6!CPKDUf8~>PsZnh>yclnk2hr;Z+j3B+wkmBw|<_%`I|RyPEvnvxM*YYaj&<+ zk3v~z|9f`oYMuJ74vB9Qm+umq_Hf(VTUWOn)C^s+d;-fa2L72|zOrxKR!7OM{(hR% z@6BY*%Bt+|lHbo2B)oW}neutQ_qsiwyk2&)%Lh-j+qt#<@RR+uW~U}Fl>NIrX=3NI z`N!4s=h`tfb~Jr{mh)^?mw~T_n&q#BQ}W`)4Kok@n0&2y>eQ*1s^9NbkF9#S^wOuN zr)|$2Jvv!kOS>$$rf0)k^ZfdthS?vE`7JVhul;&)-=&!s zZe<=?F&Oj3Q6}F^ zzDpiCx2#WW+#1O8gU_=1u%Tywy5*eN|5#fOFI;i*hGgNzCnwd{vU{3Te}7l{?WCC+ z^JF!@kTCgMFQ>aSr!Oi!&Arxt{jVQ>TpOaD{3?Y-#of&^0w;>jELt_$^rF@NlG%kz zW;|T3d@_IEC%4HZ99#$PRs1Xs{rYCjw+&Bbwd`@(<15N`g!N*Jn4a;?Rhe1|Pb>Z@ zN_noF{AXn$XA|Q`%>Z@Hgxt(Wj~@B`+Ok9HK=%5*YJb1)|8M)UvXuYW@#Egdx{ONi z{;m5Mzfxr<$2a?5YxYbvTQAHjG>+9!FnKw@_bnPkL^84@gZ@(%#Xms(%>BAYZ zFALW1+3=y$DJ1LcbZ_&f!W(bB+V3t~bto$BE(c-KpQ9#$|r?aqnBvWd-%BQlDo%TH&o0TN9L>_Uz2eOaAtMRX{!A zbAAV3uiNc+Ykz%xtWW>%`kzm{L$`fhdgS1H6$Q;3JuaN(k$T(qTKzimo?(LU6J3^w z?H1ZbCKn8LZJhZ!YC5ZP(?Zkco4+5n-8pk_*8+i+D^{G)mbmbASx~l&R`0T(p4
f)Kz`>Z!hjP9;7rt4~XIuZ~r@HU$X}Zx%(&tsW?RwC}Jtxff z|G&RW?f?JTeDF?>q_JD#y?Dv4<6M(vU%5B2Y`h${q;qQXjcC&)YkLs3x3GfwlLCH?mQexyvd z=r6n)UhLZIwaI#l15?G0S4Gdunx|KPXW2SwZd2&G*?&H-*;5^E`R!Ui1NY9&leR|d zq%FO4Tzl)}1cf*4h2M_fSeq3bS-9wGfav9QvDU6mHG7&qryaUoJ|S#vl-<*VirwYL#a5LZN0?^*IM?DHSo7^>dQfKON)Z_u9ovsbgn8qfm&0FzX7RqQ{`O|!t1Bxf8!0F>ESH)3?Pc?ludlCpMn*=u zf4{o@;M3(?TwJfLYtGc|`&@r;t(;4p>yZU_ONvGJzIC{yl_?CJRY%9NDcs`vL+Em*KX*li^*-^5Gm zF^azP3(s@*&wq99w_L>qG2?`YMm?iztEU}Wx$JyMl*1xRhVIFFl6(wVGcx_ZrtLVl z+@<-d&sq1?TP}NSG1m)S^76E}Ud)NEZE>8uyi@Ph{mwm^V&uuz?D*?pyZoHZt*`eU zC}sHQ^>FVa)n6@>Z>ehj`ucV`PbmBG8T{d2w@sUs)K|RxXUTyEC$(8^atmtygb1EE z(7IA;tC_Nb&ZV3a=d+?#FXKCCkrQSr_TFdJxzle%r6uL87Sz|LmV|^fKe_h#Pxn&$ z={ggiot<62>Zi>!t8YJR{y*;TD@)ctZTYN0{_n<+&`B{F7ne91C$M%cJQwG=RKKHb zZlcUhm6c3ar*1Qv9KSAWjif~2ueJf6$kiZ~N!Df8Oi;{M@N|cdJ*Jy17=Lp7?6s4>$jg%e~JY|C9D!IPu?2q3}mH z-aPhV+;oD&gq6v!`&e4J%(XW6**vT_eVt88IoygC$S>QZv&u?c+16umPpZAo?{9A} zuKT>E>T+v~XLDX%z@p{7uZ8m}X z{%^m4hfdaW*UbMCb$;Fv&&3%Z9@x#f*qgpGiFxw_qpVqnu06<=E_eDc^W)R%@9!s@ z<=zT;-#X`vXZ*WGuH8$R+4(#+r=6YT=3#x_%QMMHklI~bM%-bI~1qmg!i&idt@XG0tKOE2 zeO$W8vGKu$n_54Z9-9_A-ri{CaQN^R8?UO%^N#2zzf#|NeoykRx$0Z9EKaRSKR+)h zVZmjOYy-i|@8;^2?%B0}37^e2;Y)uH&3GZ<`oHe))QyRTiO-Zn_cjDhI{Yl)_oDx7 z--DHPb1H+Z9FA@)ZvUgKTp-1l;^_KtZgqI+&OEn=`}OwT>9dn| z_v|$Ia(BH=-E3iF`Klj@zi)6KkKP?u|2{7@;D_hy36GOMyq&k|O^=kp)(uHf>=$<^ zq%5;y{l*>NuegtqukQX?e$^VMtcT|gSD(q>`?+lL5AFEMr=ppk=j8^qckY!sqr2aB z-lREe-rQck-Y8^g|5llGZ*sNGT`PD0KNgfC5`QyUDs@rj2hWr0CQOXG*x43MloYtN z@b;xiw$al2d4gq|9&R!;UE11tb!U6EdwXlkW_dL|GqLRjQdYcby{A1=pFgoM%f0nR zWAzG?RbLObYV}@g;0uvw`IGe>r8$ zD!tP3T71jnN--q_g<+cUyn_qt1Sm>q4UAM}p`diM+dDZVG zTG?4&$=eid5WKan``BMOli$0`UanfTVnu+gMTx=Dpu~<~*KB@m=BpB)`I^EK&T8<9 zt(g1&QQb?;+}o>kVx-iW^|N%Gnol#?F5U5@JB8(rphM&;hn=_jYSWK@mA9%szh--$ zbNb$6izh~u#-#LI4~i9R{MY*Afx_NZ?p3=kO}5N=_wwPCmgaW8n;%tO->d0cy`A^{{Ce%fqcw+bO}G$Ho#WKBSV7-E zFfwjgPtNott~Ybyu6+HL-sLpe`sdT{Wp_U7Z`0;`>v`-O)05fC=h>X6cP8KCs`WAn z?|b+EXt&|%o@Z;c=GqJKI`U{BzH;_70;3f0Q(0WkKbeD$|<}7XC{w?iHDJZSA6r*Rw7xc_{2> z*SV4J`Vm}?;?`dG!8@VtzT(jA< zRaJE9G2hwdmPJLy23PKH{?yr|aP;Ug%isBnnw6Aq)F85$!*2|ch7@YXG_3Y}KUu}w(r+$95K-XHh*toq%Cd;<^hvhZ%dliQ_ zW?x^oc=cW}adGe6NsFWNp2oXc{{6-ssj@ai@&sw@P zIi4)`vj3A;n0vah$01npz`lmK6&sunTYdYnH|PJi$M^qQu^fJQYT2hp7S87$-g{UT z8?t|2?bMjrJ-qteV~2ke7c; zmQ_p0>R)YB+2;y|uf3u*wL#>|p|59DRNeYlUTAu7EA7WW)^CefJeqvb>f{>^-b?J7 zm#j(xs;ruPRW`3#pfw%EeuWz1DKAH96KZz2VV9>$eZ4*sos0+Lj-{W_Qr| zR)_Zc1KVDxl(?z>2UoNj(Q9tpll}Q@&)d`T`-+Y?NE(;3sh6#IyLjzmwapS*hjmhq zYFf<=>n(RaDrzC6{PgM5b9EA{ucigFWtZQd3W`iYl{jev9Fa9;tlspL_cKBb|N8HThRuJw2rU_OJf1@Az+}nRbd&X)OHjyji?2 zi^u%F`fla^CvNwz*c$)nvDh!09jE`}O-H+hPuNnY=AC_8^|{18Fwb1D!pd2Q`(JZJ zOLzD0jlPQx)*U-|A%(kW##_e-)2NGfEB7`{>t23{%_%Q#9rNcZnNtd-8?~hVnro?A zncJ$**(-kL;e}(y3uKz=1f*Ik)^dP`h>Tc1yt8jO@hEWHvZM12lXhDfXe|0|S}yyL zcSHaCrbB6lFV8G>)tq!y=*mLpRa!k&6*{}dD`)&w!xJdEQ?Ftx35&?iBQ{` zXAq^Wr_H*~Fx{S)gSFOpOH2&QXa1WCoNF6WI8x5t=U!uNU+>C#=DeF-{?T=tH`Lnp zS4P)7wMw@8*U)#<=vn>MU40ALd0v0&H($7S?(JnA_ai4RZe0@EY<8pY1k)*|H5)v& zcAU7vHRHjG4-2_Ow~MaJefQYxn`La4MR@nW*$TdaiJpPHzwAR0tha?k4hB*^NMZ~OrCvtIh`<(k}aLZwa z@wt6dqm&d6UYXR@9dpag{!FJ_!qJC&8<$-=lp*t5u78R7p?MeP`<1LS|Ms&dBf#K? zr1iFW?3urg?@QM-c(LZi^3QI|YNXUT+Ye3apIz#_h_SO^$CAkf9#(#j5?6#p%(?BA z__d+nio~`x;o^}~u65Z~f4@=w{^r{S)(3(gzS^?4`diS_r6m`vy3Wkiv1~i1{#(ZJ z>#rIyD@VO887wa=s=R;NNH$gpDjal(*uP>y&3XH_dz+sAb?*_JTa|M<(oVni^!M*C z?#14feEsig>^}MD*R-(`Ke?YxbI-Rs2*pxtbCh-564`^ z750U!*c>d7Xl)~Y{!f`jq?lymFM$F<9$iVXs7bt?ZNewEB|Y#?%SbBv-!)0;?ULhh z;YUhdG~J!oc{67kUuud)!bfY7Sq)xi+6^}qK7W(Ga=rYqm)D-1Ff4ns{a@V-Va3dK zYXWq4Kfjc>qTlMVh5hPUj$4xJt?xd!6PzDuvhL2Gjt^NPF0KLlZ}gvfmcF6+g1Y3_ zlfE%uimvSXdHm494Ghauo3Dxd&blzGDAIy!tB|hVJL_%#-Bt#NFZ#c1!-5?bwiI4= zW8a_oSTk(veC3SgPo8rex}vyIf^Tl$()vZM*1F$&&#qy}Fe_ek&G&-5V7Ydcz=?@E zcJ2-DO!Hwr%-Tq|9gthYOCW9~hExup|%mn%zrIh2~L zwTg%BTzg@>*|C>;#qZl!ZjFg~XB=gG=+Z+MpR#}3@72u^W~|CM_uprQ&9euh>5Ko} zzYxFit?{J9Sv6iJC+c#53mwZ)lyV;$e~KlCWzodi3V( z1^yUO7Bf&OEW_kiwNh0gap!~trUg3j(~~+rJ=>Uk{9pRtUtedPIpZT5d#L~KcfFSf zUa1CE)_wELKejV#4*%r&@d;tCn=Ry*9lH76>H2hq>1@9evpScSo^7|(%*bPZXgKkc z`ML+cvX@r)eTlonSbO=c$o!mNQ!-*Klhocnda?Pzzm5B+p0#^2x$usiB#d&4>Y4U5 z??sf!5Az>Z)9v0aPJ9+%5Gl~_aNf5jvBB{DOWohM_nV~b-oLK)n2CAkoCW{c&S{-n z-MIF#+5fi72C>3+{x|BIe_HTOwvE_y>uYCc=Q+i5^ZKp?9$G!|^9L!-2=SDoU0cMq z=yXrm{(QlGhm$d88tN+o1LgMqzG{2Nd74-k!@cBh2Ln6}ayD>ftI6@sUjCu}&uRVr zG6touLPXBj-`ZSRSsBzXXR8unE+lq+N>#~gHQxPS?KF4ZpSgpDJ3YzQkT1MV_3?os z!_cjIMqk!$;BU)Yf6Gp??APvPq8DV3O`JD}*?D@z?Kka(P2tbk{ZF)=tP8H&pZTLs zj>#{xVmbdc%d_hBwSFe+cs47zDP1manIpMBVqtKp_l|mpHvghKcg!v46=bOwSh4e1 zs25*br*(jH{??YoOb-j@XSXu)=`CPBw{DtGUqH`P&KDDIIX1dlOP`4}ceZ{x_w@XU zn>KG=DykjkAs$oE$lT21)#LVTA}^>G5?F=T*G_zr=iAWz4Qmy^%qV zfg6=ydrWJYdD_iq*P4<@rLA-SZe=;VG$Bhp&dT%n&Fi1eFY&(K;xkETtysvK{}m#) z9vnX0{Oei&%Ek9Tw68H2zo??{dG`Wk2P1tJe$N-8_2u`^OxvX5JK4sPJ)XCmz8Ud0s`aGYs>`feJLmAWTV7XZoG;?>c9F2kz88OVOtqUnpR@Mg z_3@bWYHlvBZ;Ssw-@l{Gc#5-vr^S{WiAmWzbiJir8K!PikeH?Zj>UPBWP8zf(6Yos z_v-)G)=t-p_3IM4yDxTkS!tcv-#ZVLmu#tPRw+%IWm|W_Lwn7Pu3M?e7PHQHN+^gw zUtu`?DAS@sUD3xXO4rMDHy$|EXt7rId0Tge->g~JssaL+T)DYEqTsDWP27^7OCvkl zZn`P%Vm~vK)wOq9K`|g^Rwd(W#cKN!D{qOhv_K|pK%>M7= z@sA3h7QDO0t1C0J;8qxC=`*qSS|?jmC$k*ReW>=jv2I5Ag@l*ApBBrT=gII@s_p;x zYqd%8F`kvNyUV7kf463<$&-@TCP z=2SQ-X!iCbmR|)5cAt*xF8(j_f3|gw*`mZ_fev3*?Bsd5zqj8&bL#!1aF1fGS&*zw>hxCtVesF=dL1>JfE@q*jp?m%MJj{}H?E@iyxvn!(FF zKFs$1bB}jF!z;a*HJ>NC%dPzR<8lAnh+B_UbvFNF>?>w%-1XPI%&718)=y=xoexA- zWO23~dE{p>QNr_^#<$piUoQJ+zuWWKZ|d^HPM8Ht=5Ke?9;3g`W>&FXaD)E`@h*sr8PAr>woVv z+y2(iqGbBUna66k)|xCjf9z&Eb2fXe**Zs-b^m5Zy=HrU`;8RmJCmtFXGII9?)`q; z)BFE+hp63UYqw-xR{M6=LRWgy+0K;n^K37jHNPLTH}P;ASA_W%oBs`R*Xx_PoXVEZ z%!~1G|)7O)ym=-53cl~B{cv98Br%T^-TW0Mnm@U>_FjH}g?hN6>e49T9Soc0V zc77SpddrWJXE$HZ?|A0<((~!{&*n8fX+__kH6HSR_sY-g&a%+M+gIiN?>$>rQWCZI zulWy|#>)CskBhT!hs4+YT-r2$nVeAy$M2LSv-5VXJjio?w)uHaiyv#gnCbjJ_;0pt zz{Ps!@L6yCvIUM#D{hiLxM8BR>O~Ion+7{h#=X9_Hu{UZe67flg{OKaF7=+i=}hDW z@rbrfTO_VObMn1VcVXRyaOc~l9Y#~c>~1`sm3dRp_Sfgr)3(0boct>>>uySsJ&%BO zoR3%Q<2Kg+a>XxxIG^2pJinvOpk%J~MrpBGDmOPYY|qVXDCm2+f93OH76k>(&+|l6 zw*?ii30uu8Z#+A!Y4bdn#}mGK96t1L*^KWA)o(T)*U6Yz*Q|Ka|M4oJ6)*M+ zHnSx>_;Kw}VQ9}8mXkY7x#lJ09-pz@m|bVCn8~}t<^8vt5-vFy=)Wx4b@2VZ-|PNO z^47}?3EEJyzvOoA_DBblu$rJsNxih>)@z2IZF!OF{0f=BaC}+(!Y+Mo{J#3*z3DbT zp2g)xs9aN-+^)?m-tV$B#O~*B-^F#`U!=&-e-iF;cu)C!^N(J;5AA$0yMN(_%eUt? z6!g8`zwkAWSbwqo@63$93;r*AvbwhYRGs~q_h)NZQ;!z%*1Ybz9#`$#s<pLNl+3pOsJh4V`42|Bf0J3t z4=GOk@U~cpEACRg$FZ-CrtO>3>MP5>C1?M7WOJ@R@u4-p6!YBd)?c zKCe4=-sx$&(Jz=*9#db#9XRvC+-)LWn*>{&H$6;fRC~FG1-`fHn@?Ss z>$BtRsR^g}nqDtRciQb3X}QfzF;U$4W}=<=FXJr?uT+X!YWnWD-F>vP^|715kzkFF zi}{?CpL~7t(bdi5r!(_yG}`T<^Eef zslda?-1&U_Gq&yi(UJl}g7?3#TmD^h>Z@R-kRz8DvEF|ZI5A??x7^MZH})&b#4CjM z${8OseArZ|b*?d4IpOxU+)Fpp=g(z7BmBp7bDgIN%j)M%owm7UFJ-6bt=->rJ?Etr z=feYwbI^TsS7i5x4X0WC$9WC zF+9Gu^xoF%anij9c^`VzXRAnYif+riyQ?&H{r-QuGSAL3ohXs_Pv+Bq%_*XrceB0} z+^6^G*iygKtt!eoGgN$b)bKe^aX;8}kult~O->kg7Ql7o2P=8K^YYf2CzP&+~dxkAmXG{9^NSGg)L+j~?M&yk8|twYjagq_TTP?@V5c9C_xP1Me zdWkK@Pj@ueZ91Ia+4iGkwtc3@&wh6M?Urx4798C8l<}=|L`A9~#}!qX-Odxg-+Fdm zds@o}%zY-o>D*D{wp~-m_b#-^9 zKuH6yvpszG-3zap2ZYHiGEzBNapzZAXvd)@!KsP%I{BY$pD|o~FMoMPrSy*SZtMCRO}WOt9gTe6-u4ravi0e&+6oX8w?fmZlxeAJ4pZikDq>=+4SR4gCyy2VSjQ zkf^x#%O&q`&*xS1#g=`O{js0z`XmpQ$_rkF>XMEoJe7SG{i&`~#GkeEE-rZyvBFhW zWLD=guPYbC_upA^iEW$J>18GN`D#!0nIE|w`2XCLdOGjW=l_BgKbQV6y(qA8!;KSjjDPWWxSsY?WYx%FysLcb%3f#huL^Rd zEqzm`>*yWQ{FQY6z3Tlpdzl+9_-=Ajl`OCk{^KJ__T+Fy}UF*q*Ci$dqe}5z%U%CBG(*A-w7OF8f&z-z7FRgE}(?t&x zNzjWE2Uzhjo{q6DeXzHo`;(FI@Y(B1gv2M50rA^EAY$?|v%{LnTFFbEg+I`~o{3 zdvLcs|M=(Mj1{{%j(mD{XJ_%^#8$JelpFE}6(16~IrcLZC)F{Z{L^Cbd7+H$v7)e7 zLDP)CZ&LfVdCtd}#Ge;dSst@0j!e6rP%l@aZnDPe`3K7%2@m#|p1*r@@h*kgm6@WG zOp1a6Yt}P9jf}j>=eJ~CzEElH%-EepOIftPOt7EKbNStOG2XZt3nP}~^QEnB-`VV| zmd;)Euj#&Qaozmv+nbZO8}0G-*}Aqm!Slj_9YwMI9L=xi7VlpZnisBfZr1$omzG&i z-1*-j-C4hBADimU6z88wmy!})olm>1C|Jztef;h&&O;xr89xkr+4*p-7f*iZBYVBC zJ^_rL{iLveZ_~Nss!ux+b z>MqDR&BW57Yt^WmA<}a+{#*NoP0Lc1*D&SCsmeE|>va6*JYd85H|th(-cHu}g^K?x z)c!C?rhSRt|Lc{uwa%)m6=}B%mTpMM*c;$#&$Cu+66bf$*KM~CxgIOw@@~7veKnF# zKu+1?efJGRPAf5W89pzMx+@`Je*&hT&O4h^e(q z0~0rjTrytf^hz{D$i!lu%zU?Ps~4B7J@!ORV8v9~*7@(E0zMu7r~aW_rG)c~%?q6u z7BBcTbUDM!QaBwgngTp5no{m;KUx?k+$eULBP59P{oe2Me#QU)C0rhfe^1NSL;o6P ze-e8Vx?^!f<>pJv1l(8gi9OW4@H>CUL$<4%&)cnTH9hiJj+0HnV?)5(2%V_(_S8(<6K-~1JAR5KbLQNp zrf<^UdJlXn4~Q~ZBaorE;gguCg=hN{$5dB8)s+)cT;}&$f9!Z{V?Xt;`HzgLeBKi> zs=mMLjh)9W&G=^j!6WDQW=!-yJ~c;h_x3DLi!~B6-R@0)xuf{ckB{LACc#SEQVX3K z7GGG>t-o)F$bB)Xrn_5IB4%!8Qtx}Tv)`5Z;nTXmzgi#9e7UiPhp$qPTTJJHkju15 zlO`qEY~Ejxs(9sYm*5g59m$XJ0uvM@KF(nk>^jEUwKm;(bKtg{hki2rV$l03^1u1( z#!ma2I?py&``12ks8}wivQ134S9SKMPenXux)cBVa2P0d{$9I1^PA_- zo0_zkh1=On`J8knfBlB*eFyFZ)(A%J(Gcx=bf)@$T;`29pYoe7BAZGNyr|0gFTX|o z-}@u=VP+x^SBooZ7cE?KfpsQFciTeij|H=Le74bTcRGAZqGw{J){cabc{K&R*DYCf zlU_FS+iiGQ%o20%SvXH?tql98g@-PsNU>g=@M9m-$r8q!1<_*WEI)k3e|&yhFq7v{ zUf{v*t~sZV?cvehpg;XRdtF|**`A&G_wCBQL_4I3`J9Sv(*EWgIdP(ehtj)g-0yYY zo&S5N>ETZmRlDeA-V?Z;MFP)rusxR(6?s|mXC~`i*1268r1n+Kf`33 z&<$p#85TarCaFnZU@tLW$J=Ptc}8^74UYoZkA}KYW_615Yd-8d@_xmS<_%0v-qU(H zCvDi^^w?q&&oA+q*k(ii<$)^B-;LA0+`e@AvaW>QZbp^QmXGc+t4{pzbF<6_n+-V| z<`|UdtLu2{1UFT5C z3*N1WlUoF2g|J!zs?zV=+ zNpU~d#qM?r4i2_GbbfA%le@}C*364d(@({1v?z{ycjj!kqVnv8<&TbPAN=RO!FN$& z`b)bOb&)y8y*hch1-Z(le&^oESybI~`%qJ2s=n67U1EI-trA=2xF32h-#Tq`+M632 zcN{4`Xk>Qo>cWjD(k->NvKKt%(zu(x$NXeE>!+3lKU-gN9Eysc8#HO@+UnP>H}H zq$3ff9r94^u^FeUNmRz(g4w3ZQ`hpF6}2!OT2?*dg!SjYhF{oUBzMeu?^N#VaYJ0I z)FJBA4DYVnbFKGD*uMT3*f8P5WY1JTw|jm3^Czz=GCFs(Qr;oH!Sxrjn*`rn+v;ua zT&D5bNriX*41KQjehvShs3@L`2|M2O|M+**^@F52N5*PpNzcLuAGW0a&i*#-Zs!?) z_k+LW<5mUa?B{>WCEH%h%HglIqfNzG@gaw3i}H!K7H6fzRDB)pZ8JR07CqJZ_Bkd? z{R=D4@eSd;zb=`~wJtxVcmC=2`*n|x-{5({exq+<$oYq-oHX8lW&iZF(k0Gj^65MG zOJBMMty}08wYPNklxfqR9o=0iw)J(PT_abfmRp)z(z{@VU&%JRZvq-(@#$Pcl)-Q!r?7u>l|iUG3c-*|CWAH^TPJV@#*)H4}N{u;=D-l zrNI+h@EEd&imao_yAp6Mg@FG~!{&)Ywq8ewAS{(+i~oLE2$DOAkK0uz&IU zht_w>r|sY4Y#v`f_e$kgCC$rStUuQ653PD)crE*^c1_O#QMz7NJUo5v+enAVV+Lc2|RLhpP%M?xGPxf!3A#d z{j9w$n-sr^DT=L?AV!`cKtT$_ZyKWIRO#o&llM*W404r3mVXt{%gs!qrm5W?RVMd*(^%^J6u0=S>F?0q_kAG_O@rF zT6c+aqwlS$g*z&RTX%o{*r@U%?3;zIjlA=mx9j))(rVYvXFIt5_|YZ{iAf0(VY{3h zja0NMycGve9d)x76zuDPs^bYQw-|%Vge9pgoCm&c(?g?dG7s!&4=VI93 zD_!6h`Dnst@57gNN!Dzwn{_oJ_iXfD4g1I6-z#N%akDGrdN0_#pm>6t@+FDx+GJt4sSBuQ-&@u)FZwa+~A#mmU@1ZEX3iBdojO8#6nf4PUtU zNr{JbJGt0*FZfmCa9_PD{!V?Bw&~mEpGrUWE^xT1+j>ki^84C=S)Y5ZD<6z^n(vaR zb$nw<&VEK!#hBLGn;ibp0_!vG8OAwU9h$4ABQuF(d*tGY84{CncK9w5T%z1JagLCM zjFqCIV$bQD4^$88olpJz?5xmThZD=6i&wt%;bW+HyKUvANpfqrRWx&*r+s-mzkBY> z&zE#*8N_v@`CunEj^Y2jZ@3`Yw8|IE%mBxJ)GCioi{y7;%ah(tx)`zo)?qi zu7(^*HVm=mx~8vrI(oZHH^PpnQ?ul~5^v|7(}H~AYHzPaw_dsJ*^1u9AE?+K~;S^BB&bLa9O zAO1F^W?EK!NZ6WfcSdl@tZN*d%__MYrWQ*l|DQJ~YuZPTsctH`gJ>lN^Tx*O@Hq zoYt!#TYl(aw`z!hK>z1Ii{~rPu&doAbULl#izSm9Yvr-0XVnX?dU;A5oN8zh+I2xd z$n#cg?j*Ojx)b|EL>3j+_{=`OoHLhW{+~ZJoE6a*nU+aUQvOk<)cB4i`9OVnQsI3u zl_Q@c9VaEMDAk>zmjC5}oUhh_&aX#Z1H#@lFSK_Ocb?85JZW8Uf!yg*sV$qmtrdIP z*_vf9lslEOEDR80-zC;5KK1s@3$=Q8yA7lZtv5RE(NX!k;P8Uy&g@Pz+afP4wK)IS z>D-P7H-C!#o#F0a@@D?m>OT|R|Hr@X=@em_(0oxcjHzMn{HdkNl2L}m6>{f1oj%Bv z*nCNTvD#u<``z!iOA>nz^H1}3mXzMRu+d35u) zV>h+Vs7!ahkiTHQ(%h1XtqH%=H2!W~Be5*e-g!RPCC5V#xs{yqCTDn9HRZ58oDk8m zUO`H*>u*!RocYQJW@WnDyEkON5>;cYT>pKCK3~GojF-=kznfn7QmFRK+h6&oC&&H# zRo%Jzt=aS|?fk!|T(D1jzI=+J^+T=bUXx2%f=>=k_#f%X)!p`gr|;83EzULej-Aq~c)S`#M2dmPfKi>UyFXlUs?Eg2DExnB1`SYHi&Hr2OMd^k7 zh5C;kZVFPDJgS)Ry6u*)sNe?Y`Es!`W~*u&_SO4rSW>dhq2R?A7S+D3DQQPP-MO=A zXM4!8SXIp*ubxKU2~9iGbqeBeQbYO0>T4zwnXCzV`8>hj6@9m-WL9k@_dx z1o-Zzs0g>Ih&!4nJ+Uj~JJ~s3S)x<%kmH;EmVxu7&nc>%^)pFso1^Qy)pw32TwnZW4u?EX^V2&j+JC zp76@gAZP337zwVX#Ezt!pE%fF+AU-_yw1Xa$IIwJnfMA`uh%K&TV%YP#Kd^^a_O9Y zvsmQRr@1VuJ1=l)wSD@v_Cjhvlx_`QZdjDe#RH2fxs21~|2*!u*ZDfJ=l5k7$0XJ| z^Dk*H7+>hT*#79??!L_n0^6M@i!h#YUR4mA=nxbzb)9!h=zZHmYq~CJT|LMsmAb;M znbj)tf(Bdr(Y!6wu0`ZNOKw#TGW;UMgqTj73RKcalWK@ljG3EgxM|5J}XpYvSJTCtS{_IWLWgJ zQ!x0s&ny$q&cJ|IKYmoa`R85{o$&EIpM3tsuUAY>Lr+<+Ze9{>c>BLcS+DD>y_(*q zv^A$11b&*&YQl3rdkv8Kx!yV$D%~E_%tG)c2IXZa_MZAPgwNHxq#;BI0)h*4W+m{i* zQKj(LdO^(N(=YXkPy6qky`xX`QRRiz3xyYGFNk-Zt~k%9#qVI{n~zUzT^wIOx|KG0 z8f)*WwoR$b^VeS98qzqSwQsHbq?wx!>^wBLV?V=fKgT~?mYr*iW3-juCGktNMDJX( zOr5sJZUvc1JlSztg{pEqk&iDWDL$MK(XuPr?2cH=;o@covvlQG?<8I53hd z)(K6)v)u1h{4LGAEUoYH|GMU{7EXzss{?j@Ui*FNv2_`>hfeqzXn}zN|Y2i8F$G)y%P~Sae8c)2LM}cyQb>S$(nO~`j?ib&k=&^ zj_ppB^NSa%NKLx4{(^jgE$3=i&QGp~67RWaaJWzCRgiJiII>&s<_G)l+(BIjKb$Q# z++@JEntO%1|GYbI)@?qxx5~qxU1Eu0U{17*zI^(0FYZgfyzZa>`}Rk(-HpS?8P4QH zWb1Ly{rkG`bdW}8%c-z!3NnIRO^Q1?CavsGU^!_be_46rrY(FdQ7RWrOutkl?pE{@ zV*KipVf`X;#Ri{m3A6Q={r2|JK6ZCbTJDjq&B{}*3Fs~~$&f3NouaahXP4-cOON8? z#BVBCyK^pIXWe_PYeOE(%n218!p=gy2YPmJ>R2!MB-3+VAR~Nj)Y2@y72n?9*PnZN z{rV}k7Ot!E*Lci4s)`J&{5|uj@ryfy?N!3}TyRS#de$x+5rkt7ED-T+4l~xF_SCFV^ylEuf;&|x= zXX;XoDN~iSz4jeg^i|`K&zs-UyTo_N7j8a!rc_m z%oDb5`{S=uId8=czQz3uS-h`&Kd|rJg|vy0|9{8qQZm~SHz{$^A;UYBDLFH~T=uv3 zjOg7Jd8u=DQOlGJmW!p{tKBB>o?fzBRQW@>x`dGHza&>ZY2w`}_S1n+nU9U!0^^xp{qeZGzy1g6n4AH_G!hzF+G7yX?{$mboQv z5|g9%|Ctc4S1T|_MK@;Ws(+LBlpIODSkwH%)9gx8xW^{NmlIN2Se=v94{}VhTqe)< z`({~&+=jy9$S8BBO|F-B&0l}MNL@=aq%KF1`*hpd+}j0Nv-b_ zGg_W{++qD!qvw>`#3-?;LY#5m70_-5NhZBRiK=c%f=>>GZFwQTz`EV*J74tOMMWvy zF*)7;Sl@iwd*;`h;Fqs7q~dwG+im@i$;{5*_iNR|$$N|26eJ(&318#csCrIC$?-)E z-=mo~KCF4OsIlQM=vZG~&?(Mrxwm_7+;lm{FHo>OgI1xtbDBa83Fh z>G>A8(ZlPM&p&y^G1uhv<9-|KoiEP|Ezv1>T%Y7Ey3Y8Ko{rSa1co-9 zeXb5_QuiO-UG^@ly}-qLmgu|(ITj+D-x+5H>eIeOwg~$CTbZJ5tUCqVg?OBIX|CKfn@8cqr9T`eTrU4Pzrc6tf@yhu zLVcT!SQtv)cX&-&xWcBk>+BrM;w8pPO-n0sAL~e|O**_lwk@ku`C5%mQ$ok>z@~%S z6w2h)-S^GyIq;F=giEoF+9x@Ag$HgHhxQ)!n$)7~=3)3{WzE-%?UzCy_Nq%xJh58Y zP=f)a|A1)TvWT{^!59I>rtA(qdp^zWv=}xTNaCpJKDv+zl~*KIV9-w-tMgGm-}_UdwY9%(j1F!Y2UJV z`D%TVY)H|z!pFysv0m7*+v1=JpLt!lvC@IgWs(P<^=BC{o%J)}-v6iRuGp;)s%N(@ zZ3$bWJLi9C?)073?g!KbAGkc8eDj>}+pYsQH>ck`sO)}Yt6<5SsLM~n)q!aknK?E(fEZNv?)*Wsp?+fkmv`H$={y)mZ9VFPm}n)&c?E=#5FPkChI;f5frH zk!9Auw5^T-6_aYX8(BZ^KXfy#WWtv86sfRvx(5Pe#QPZBAILDx$*A!Bkjc^~Z-4Gn zQPGVP0p|sIzxMsRwQK4{FEc$E#=ZkP^VY~smmF+p?tJ`2g;&N?skI4< zr{=_1Fv&3bne5^DVZp?`@BcL4?j`(nRbd&dw-4#tf6rN9W76lK?b^UUck88|#~1Ug zn5@g+rDSdHxw5Di$!x|ESUE7F{n$$>oeNT`PX{?%=Z)bX3kPr zBAQcj>cDyXzaf`X-yIYDpvhu!@kdD6=ObJk5jtYqeoT+QvBho96`hvA`IXXPn=Yoa z?;0`K%Cq*&G?6oNKcEYWd{*)AcfzS?+uF-r{>qo0Z0)VnqtTMjho+a+JNDF`ZdzBos$i+|Ba;knXW;@_{c2|jSS z%w{}QePtO-S6A1KYq7g;E;(`FmTl#aQ(I;z9Op8RdU>o>`9U{F!J>~xW4=E$`M;~e zP+DH{h>7oy12cDjxOi%tULBX4_FYh52!aA*#%sGdX;z_?Q8S+VGp*pil&R=dx2U*Q z;p6LEF;J2+%dR}MN_oP}nI|XtFWXS~(D(m=$gdk-|Mu6uGc9@P?6~#o&ui~LCzw&p zQLrepIP#Qmh%^&-{f~KfTXsseUMW^Lz5Z>@t9M%t<+{vh(~aJ?=9lWf`N|ibfjshT z^9=O>hlGQFe#Tj@jO5sFce!xUXYoHS&wmv>x_(=ZX->wixOtyMt~NLX1qo?u>m^NR zseZ?tZfdj4Z~4g=zPShMW<7fJ$m;LMZkfhyZ4BzOwoO}XV{59k;lb>D3E3jgAKWs)4~vw!ZW8%CCOTq2>8}ixL7dVb8&Dw%oSt7q}$5y%x6Wo@AI#h^-eKp$gY%O z>uu0`_*7Wqiqg5C%VrnsWbo4F>G0HEuqE<1%bOg7odqmWGK_X5*B(Va_$>H9ckVJ# z#zX!WmbD&v|BRyo@_GDjP)x%j^uRS<5*MjMhOM`H)#pk2q$*KZ8OJg^rzrVNl_Ji((E7Q|{J!uG9 zsWK-jFFBxg;*;x^OnxjD7e6dgU}IrPTDXIw%!vQ&T6SC|@Z(}era2jU4K3DN7?@nNR7`x_wEo=RT>HDM{#S(L^v{A3`|E5Ef4J$nTzg`# zwj=kCx%I;Tj|*lfvRGW)BJknQMsWp&2|W%bDbr^9ER(&w%=htLDe)aI)@-pXeimU^ zzg6hm7e3*O6Er9Au8FZ=dgRz3+*|SKka}{{UOA_y8Z%m$C-xYqlw`cVwzg}gar&n) zD+j~bXLW3B=4gs=DaFs)uQaDcuJ?o8?xfDspvdTM2r!5?6Z`XWU!TL*u0VyE4;mU8 zs^?d|()@OiUEag0{M{KIw)?Tt0YO2B^maZGGRwPTVU~JIM0G=@2y469&P&xg&0I^E zwZ;1ypaK5jh)fREyvn;Bo7G*3Egm)uRX#i zWAPy4?)KCR8Jxyn6UyG*Ihl5T-q~GcZ%-ZTlRX`_KJM(kf4{PSuHAl5inAw`9bu|MZhuE~81Ubb<4iJsu|!T7w5^VGDd z7s^xZ{(NxW#(lrk)7v}QZSlmdN0YNMjMW}CtDaetetzDYOWyja5_T!F)@5rBHR*i6 zTRy+?;v&~{Ep6@hNADX4=x!0pYK!`5XyVZ5-K~6}bJ@|&2h5cpI2pO9EGfArDd?-@ zk!I+jw#Dk?gIkqJn{VE@vNAYVJ8X@?i;`U-F-uN`1_-}d^5y=cMJE59cgwEkzkcv! zwh~Wfpw-Ibjz_$_()UahI=O3>R(<_{J$~CS6CVBjeqX$*=0nith8&-6as6{^R;<{; zYqx3PmNzq>6==+zlf%F?eVS{7uzD*0A&59SA%yfPEJcU_c#}*x?IT=x6_4BK%bXA!9Oevc2~C1E0-0^#n)VK*>d@>?$B6!VbMadsKk(WNz)G2 zNmWhq(aB%>vs+Awi<_r(Ei$xq0c?EgD z=EPK+x|lIt43Oh)aaPMsnEOaYde?TpOkG>)DHAPJT257pYb>2P<sGJA3YJ5G5l=WFnM;w_1)`P8?k7X&Z3XiP0W<*v0@ zeZiFJ>v+|5|LtBj-#|fWS@p`E;|`Y>e(8JDoY(j+Yn@SFdSNC5)0_+`hDqjo9xPql z^)%~+X@Jsu4ChTx7h1x&SEGcT% z9jO(np=;E7iRZG)RBfK1rK_ACF87?g@^Am?r=R|Y?apz(cdyrE$}<6%#;E4Q3%@+N z&$!g#GZD#<%tbdkFAN982NH77;hxL90aS~gE^BF|FL zgyf>v6JA9GKGmGiYtZ6yc!i6}m1fmP3ze(##FcL<{J*VOx7}&E)8mEQ3tjZ0Te*IB zon3z__}f}v6M0R^G`&mwTQbhxU8~v_vHPM}f_dasv(2%o=8;p%Hv6hg^wjlHH1!k> zYGyf=GO1|ge4Efk(_{}`Te5f8lRb04ZL04)5P7V#WJS;AYPZh`+#VnQh|J&>YjL$* zCX-Qr$NRnZbT@?qoy!ClJp6L!Yx$kR;~I0!r?z_)7;q_w9*JUYH5Cz;Z@tH_+ZwcR zd6zA>n)Ht=bNXD}%l)rDf8Nvj?dsFi)>D6(&(=M>$hQAPM00(~9z}&^&2h_uZa=AG z4BNSXf9N{C4JQ+}hfF(pW|!B@(Djoed8Qf#yUyHWq<-0d{`|FOBF|QQb*;>@IsQyu zwAyPW=gq9CUSiYbZtiByE2}blWG2EE$`N8Xr*$9yU)Jf;rtf+`thlr$uF!01N=E|A zB*i~0))RR$v(+SB?kiq36h6^bW$I$)qUU1fV$#&rmNVz4onYZ_{Vn`o_+OmAa5m&0 zTka0aA7^d_KlasB74E&cOL5tkO%dKJ1DAGuFxE)=!&|gsmGgo)F@^0Ore3QYM5uZzn)cYUR5P^YWhQaioN8s?Fw zbnItuKJ{(al#ktl{8@JbE$x~Aa{ZEB7rb~$nB%M@hiCswUS3kwv$g%3zBa77dhNWQ ztyY2$T!PhY#N%8ZPJZ-f<*7AmbiV%i`T1=Ao{w&Ixhc&1H*zGZeX+lAe}VkMg2ke3 zjj!C}q+<$FuKVP^>eMdTIrHJai*HL0cJ4iOXjgoQ*v0aKnLbaSD=>Y!9dc3pnI;$C zdoDfOQk8(&vt(SJv^_jyU)TDe&abD8J%XNOEQ_YiO^p2Wku z{fd`S$M)kNvI8F3J~%m(-9*IA%Q<6Rit}E{ixYVt`4ldh_wjN-7Rw&ir4O}&r;8?A zh3K5G^O+uE<5<7P;$YrZ?>|*7(|&&C(&m>CSsGf#XEaCKXvgBtq?6aRwaT8ey`I$7 z#B(g^GgLe3KkU#n}{4($jQn1Iw&~!<q;|M#awBErrU*L|VQ}hb;^EZQXYE!S&Zk8oHCx z^P`35?a$9{*=GzR1ml`MuBXmfv4m{aVET%uR)PTsBV%H9~K(FL=MGCuiY2?`xBu{C3nUf5k6e zHhoe1B1yq$iIULWN}eA^3w)fCf0|G8c8S@gl4VYvahK!Gn%_Em$31mBGMP{3 zZF`3eyDalx9WYdKU0kN5xnf5;{egE&=(axYQ_5H&le!smf z;=f#FLj869+68Xz`S6G6g0EkZRX}&Uzd0P)(W1<(hO{E+1nU*O}t|}uYQcU%e&GS z1urHSEPgnFo8_Oy$(RPO$FdB|SDa+~xR_Pv3WI0UzMi7OCGU56zWrS1S-CdH`XpfY9&C9$^HWwFIk?pS;k@%N?Zv+fJaBm|7pJ46lk>lcm7A?c-u~Yn zYr~eb%Fk!bB~LulkD1ZOH1pc;d6CmaW$%9WOT1*?>@56yO4+P}=rWJzaVGN>yiVTS zX=jpr_kE#T?m|~lp^t?}XI|MpfloQ^SYXG8m<+oq9M1)O+8;=%OEU8C&uR!QNoltD z>LQfMr!V-+;?%)edhxyQ!Zw-xl?{26Z0MQKKX=9iS(|;q6J6YnI@JX2v$ft)@o{BD zv7hSXtS9fIKJmya%TD#Ut#IU<_M8J3KL30^fBLRTJWC%fpI?_`oOULn{d`8haQvzx z^2&ZDc~1nn7TZ^uyl|YZ6`-KMWAX{My|ec$P)t@cTKw+tpTD=;T))T$%`r%f+NQQG zc{8tcjDVrJEZ5|3ENN^0>u$4oy(L6c=%35cnOojZER&ivlW(b_W7gSyyh|$uRt3J0 z(){{qkLkzw#tpZx%;C8dyquvpa02fm$4Z~QC0RfBGyknPuxhr`IX(M-`yZ(;SJOUp z<=6zxxy4NSoy9!14|lzAE#D9j{HNG!&A*hDL92pnQm;x)3-*6@Gktz<<;SDqPp=A3 zm_6J3KGUU#%r%V)%hIHut&{7&_G`Xyue4?R_qVSanc4MjZO@lq`)g(3y^7DiuV?4) zQw?<4uK&9Bz46L_frX{(a#k7&OtcV_xgl5bX!?2UN2ilA%_di_+PLQjhe3zKmyASa z&b5b5HWy7&G})tYVE59KZJ&O#uaN(8EO54)=)7AIKRqsPx*~o-o1t z!vA^K1+V_<^`h!U-HQ~B_a_-x@;f$v^(n4gawTKoJj1iq0q@tzM6oUHn)k^yz{>UE za)0~3TavD=iTrwwx$fuF=~^`o>lV8$j%+eeTDWCW&!-ZmFA62rB`L?}yC0XU`26MH z8-Bh${a2HJwX9!nb7ht%TV~RW-kE#WU6SY>l+{nhE2Q8U9n{JCf6Z*LR)@e;TGwc9U_JxeTm zKDYdxww9JuNU~bt@hDKer)}~){y?|f(y-Mpi+5_x>~ZUQHGP|#*_20DrgAU39IoFL z`h(pzSx5H=pP$K=O(HW&KuhRkgjb69aXN&N8x=Y`?&c4?5#F2C9%6aeS-TolaeSP_E6=zLH{fP@VW^RhmQGAiP z?MIf?$3@kNXI`a#F;w;7ob&jF3-lS{6x$mxNne1uw?#E(^`OwZ*e9w0x`D#K}HuFPOY&+TMOq(DsPqux^dU0VP4||Ex7q6R> zgkRrymMT5v-$lnuD}MjhSnAay8vO6}o9C~(!+gwAxq}~HHETVTV&b(e_x7<5al5B# zCLiyc`jBJQ>pQzTtDh}5H($b&kh90##pTGorY0t<2OGi+XP?bE-Y1)L_SV*KqN}e* z1W%g0bYg5(h?ezNExz~0F4B`U?wy^rRjo@eL|Jn6%_T-p(!Y0fcTYWj{HW)(`Y&46 z`!Yq9HysR=ee?0Sd^$UyOhWecb*UClXC=A{&!4&Hc3if&?$<;1s85yiR8&7 zmN@o9(r@%DzG}*4^^;Wx#nVUDKpBLJ= z!9INLw!Db_aY~^pbsb}?rn9Mh)9!s^@3WeRXJz^QLq8XG|A@D>o%zb}{{9li)4!@k zPo$Y2p2u^`GuK)FLPywx=O0dcF0)FI`*lBJ)4@a2eou7o5?1%~m^Sa$fp>eWq+Zv= z#$Wrp?V$LPHM)~~vy)aH58kP+A5j$|zsz=)xP+|qVYQgrwJCpgtX{g3S@QR1zJ7iDY9p4ZRyET5dxvZ3tH2TtQTc87MAdu~WLAGokM@qk^-eTJvMQ&<+* zTua#{X-9g~%PLP5%!tygN21CASr={~I``U5MJV#rL_|q%$Xj zm%o`Y+fe>*U0-PYgw5BpOfD>EeX%9}R%)HS3Hzz?Kg=xo9?U1y_|7k7JCKyRM=kuW z_Lu#~z8LwQQU051Xn1i`pR85Urp$z69y3(DRk`;)zi>ldOS+=_eAVOAv$Ie9nqB`l zbXoecn{!gm#m9y*hlKiFnXEYJ;jF3ZOYP+jelA1@+}QBQI~9Z zpzCONp=-mgb8f%&*X2*uOs!|{&9q;d6rNY`MY*eQB*`@cDJ?_S1LyT|Wp_q~`e?901z-Bq^#?58c*uN16&YgM^G z-C0FB__w&{5~G^)YIp7=-%4%`YWgG>#k;umvE}cD-(7s)FTRv#^SL?xd_e7wD|xCnIy5&& z=YA?)7JE)>tzckaV2#AuMoHyVAz^_%zkl3#n#sH8=<_`v<$ArR?cY_oc}`^R`GQG5 z%Z->6Sl4U!4 zX2rEz4So}U=Za37{zh%J%AdY>JAd5bm0}fI?V`4Ij&bGrV|Q&f8t$GHsrp4SLvO3X zfzD&BGv2D74K_@w_V;jL%cM;*4CbR zt(b=8MT^Fr-*%rhoWZ(xyV#st^NNip@YwNn)?N$Bt~lTLH1Y0l>8FfRN;8cEe!cr6 z<7ad>Y>nNK$@gA;`#W{prKyse|5UeUGyiG}H;}9{Dw)HhF5REPa_pA;>y0%^_oIWE zXW99iNE|QAX+E}cYd^F6uY0w(r>Ch%3h=7^QvH?}EN_`@JX4Ng$J+(P3&a_JYu~oJ zp*!0tp~f`n0`IShisyeM{k-<(#tQc8^h+~SXSA}MEZFohgm2+ODXl;Qt;aE|6dzo6 zX`cR}{=nnnou~4*@3XkSck#^Cj5o9XZDTkoaPx=zv6;7ecdZjBww%96-Fd$9va1>L ziu^U{7hR3Tg&e${r^-7n{~lp!x$wjB$J<+CuD@JkbL##Z3yH~-dyf~hIA=`$l{ZI% z_swr-b7#ws45{-~r9>E_T8qs~V(xTobZxh*UAj6l{^qui8H$q@UNbH@me~6}CHY;N z#s+!TO_99nzoee0mh^Uq3+&)p_^RRSu}N2#|2sb=d?nxhwb6QFv#mchPwstgxc%na zPjBS?_Vi7-?l9dcees^}AO1{^3h&6>owU|kKV$kY`Rg@%4INemeEHU&w?6y_>xH_$ zZJN41Ml4!$Q|21{o0c>)$hX*3<@17mi=02lr8xrDf4n>|TdiE{_v)iZY|O!M`5VW}q8CiD zLH~r0^?Yi0P$=7Vj(hIpvy}xEul#>pS;rcYWXM`6&}H!Q$*0>1{GUR8tTmLGuOgLl zMJ40c*7@sBoVd3$aaDXukDbNB_I;*l340601WyLUh-TGCe_1f`XwcFuwy2tt9nX?9 zzUu9)5Nl)?ywkt;`kf`$@+^uMKijl}sq@m!*@d-y>eAsRHc8Xne??x~{&AGcrNw4lnY2{jz|F8PCo$zq$$oYLSnCpY* zi{BSd1s`}D{Gxe7u>Rz3c7cLNRq{>0&IE**Ev$(y3%Rl6+}7!Zer9qGfBz^r<-Z8( z=#RH=+_S){Oz%tJjoPw@-RA{)Kkd>t+AI8J`y%D)JoBvXDTRmK9y6RUQ&Uovbh2FG zyy&34R^K`6*-c{i6=y_V;0(~4=a|6NWXYD(pM8Cq{Q@tJRRLujOQzOsK)fN+)Zy6;}G`eP*|e+c)F8$=J%)mo2N-kZ45sWoV_dY(8*_5_%;U)bKn^ zd2LGyhyO1x&9)0%iF<{dxziIab*=appy%t{aO%5eLevubu%flQ+%B+#L)8y&m81m$a#tZw&`|d8$ zuq#`TpRv8}mf7UpYdca{&M5!l-I~NNEIZL@lVH`ym9rjv}=!;dRP3I^F!*QMcY}e-e=w2{qj70FKP=9w~M$$ znE0fsK3AI_rFc?c&coWaDGw*}B+tE&*I;=o^SRq&K?NT32%cq*zn(mL(6I1gud-Ct zK8_Q|@@%*7-}13w%bU53hZk#a=njrx*}%6^@Kp6_w>2~8`#s*dPsPO~*mu{bk56Z+ zGb{f(Z+A0FC|^r|>eF{OMON8ww0D|4b=67@&1pZgP0C_ZTU~@@vUp$J*m`LH?}kSw z{waUCc4|{zVd2J4KX&Y}dTw)J?)vZ5MkT*C6>x1Xa9DP@L{9s%$e)a_l440K442I8 zC@^!}-yYjpaq+tO&K;c$8@LbXGB1oSwf=m68ruooQ#TrxC3>bLvp>C{dEV^Lqty*% zJe+|CHyPI?G4z#4$|c-7w{!mQAoW_`t@rwuUrb*ZsTC~xT%>$5i?(0ryR+Xn%WCkN zE`Moq?2^~cjh8e+*?&b&Jy;i3xyWs`gh_5$8z=5a=HGDT_2h21pI`a1Yx0kMy%_iI zW=Th;`qpsOzD&+E>b|LCS*qi@FZCze)yv7t-H+u? zReg46dv3zXNtY*n`Dk`Mqw8v4jfTUWV~X(^p8xY+h$i)}-u~#Ru?sW9%BwY>p2gRP zPD@=A#*q`A?m6A5Kf17bIWx{Nq37rihqJ2bnj8o}Pa4-M-&>*Ve^aFALF< zEngX;b!}g5b=mv9-#3|R|C=IvXM6ai$Ys-YDxbxL6`5^5HX-mq^cMBUQY$;U-DZ4@ zpE3I;qxIGkJ5Bf+9e3p3?wD)-ThedJHhu|_w>uXm>QD6jIa6rc*MCRXxO=WCdEaL{ zNp|-3lWAvWD89VBod59iC9>)5M~@xbRQLDS#>mZSp5OBBE64wT9_4yy;{m@`|F>_m zHLrBng{ZywRH60w(8~|E6Xh@Lc$2%g{HN5#Ia(_@vePwAg+II@8MxkzS@PH0%D)f0 z@72ByJ^FsX&NNjO6_XWHRMpfrE#3eBSb==>uRFDCOn%pF5)?ie(8QEU@ zO)`!hy(t<&C)kxY-?Xy2?4hryE~PHfYhd+oUWxSPk_{r#p{L5E&YLf@aWNB3_qzFN z_VdlH_x~Pwx9{~kHx<$QOY7cMzFd3#-hxy6Ucc`?dS`RsHhzO7rq!}-?^8WqWNKV> zwNtfoH!%yzdU0_Db5g*;&VVyhpKcP4-+S-%YyEu_`XrUVY?Bth$SJJ0VP~;@V)p&2 zSu?*_UF4a*bD5j0P~O3u&0PA43U@9qoVy@Ks-0nC$t=sIYvx~x&zra+%fe-I;lp|L z;ld}6tufwsck{oL|G!_<_ngWIesbC0KJ~oK$0=)`d_8RYHm&g7%?ryVRk9>=d6u(@ zs?S=MQlY)$`o+bDVbjXDNoYN-6Wr(<-TQbcOM31Pv0Hss&n(i_$^Ks(vM89GBMGs;yOLcdWDlR?-t|OoTPPYCOpfH zmi&K_y?8};?BbBHuuaS7RdvM{9ua!f$#P1MWyUnwfR(U6F7#)9m@% z@2`AidB5JP`~5cOXqV{MUvt0j_fPp{f39T9;(8soiSECGCEquh1hQmy+*mFZV&`bG zVn>GWe#Xj}sELy$---(=pZYoT5A$s&Ha?k*<(z+SJz2N=T~a&0eA?#p^J#y7e@{Q$ z&YxacSvr5F$K*A8tG{oXzD(uh(JPY$FRkF~UehqQ%0%Uh5La0{^Z!f%rWVP><2tOr zI9#VpuQqX-az{n_?m?%Y7Zy6dxx1VDwS7y2p2_obb5Ga(erp~U;-dZF^)zq2oh?V* zk9ul_x`7C znj+VwTBV#p3li_w{np+6X47ezwR;aXvu{@Qo_6KM{i`3RN#{)nnP>GzecD5#>pK$X zwN0ycv$~sc-m&9#XM+eenXT(W-hB%tZBHdLuPBs$UZe7Kaz^{lJ&fLaCExY7Z*!Po z;^!6{))xD2l~_exv)szlepfF{h{$zv*_?mhPE20@{fD5qxOWm(%9mF9uiNv9t5eZD zShdY^=BvW3k4+eMSbkzxtL5>X!rS=jqu9;*L+3Ag9Q=9KC{6f5&aw!z2{}B=PltTf zEi#nm zy>>DY5|v$|=yoyF`{@?XwPp*auk)T>y!XAZy59zG{k>Cqy_>Q+g?8@xw!u}Kg8o}9?qD(Fqlb9H!7t5!3RNE*|Q~2Q!h=6i4Dtk zk^Q_l)K<#RWGhqXbJka^VSCS)I7D`P$fhJ4-^vM^d1l?kjI7>U_W%Dp*0_9S^Zotx z_LsA^>L@EWr>3P{tLiUk^b@!+{gsQSiC@>p$VGzb%Q#ez7pH|jP2E0ocK(}Ny+1C8 z+x<0ZH1m0LIw>hBYwzdT`TG*LlsCkAEG!RRoj#pA{rtStk{`>q^PMQEoN_yC_f@B2 zlS2iOp>aE9C*pWJ283Ho~(s0OnxWV zwq|HF%Zf^J?cx+RJR$ZoIg%XIzNB@?7G$QY*zNV#3fBWGmTn(=U7a-| zawld*#lN$we+gZ6TgT0F+ig;Cwvoo%u;ZahQWL!#j_2J9T^+_L`i^y@P0Z4h~b#%`|?_wEwDXm{QFCZ?RkXiUb8u2H3nUlYZJcAW{##@I4UD(f;db@_kRsJws#CtBhs4nM(^^QmP>&Djg31ok8R=;uS)aF;e&KRG+^5A#P^83?ux3hj- z#J{(5xw`U^3oCSk4*Q*+<(VPhqM^<0{^rPU=ieqw8dX8{kvrF3@mT#mDsI)}vkeO# z9rdnTxwR*}|ATz}pNk9b@!b9X`qKTJQ;LEmSGr#u30koD&jNqT$rn^abN#+ae&k$K zxa~v6+p66MW|T>`Jz`pQ!$ti^M&!-TDI(j7pZoP6d;5O>|FoBqGq;`iclg}b3>Sl# zXR{pU*t+ZA%Umu!w@CX&?B2rayBq>(EwaHaKc7D+VfZ+uP<#{T9-Vb1=jYYm`1ttv zYro#v;VXNdi#&^BW^=v7S96iGk9E->k8-!3X?^C!J8!z1w7@DHu{Ly@x=;eFu zmtPbfJ9uSL;)CFLc@-WTg>(To3xh9{-B$I@{3Ihfo4x64fPmkoiJ4Qx{(mgI`M>s; zXaBU1$LGyS{5t!J9=G#hxvmZA&4%gWzZ6|oHG2pxXuA9G!nOJ%GqvwI-gPu7TB+nL zDU)^S>0H6PA0)LntN%O|?z&Xe-P3RPZN^<;gFPP}d2gFjv{&)prjM;jDw5j!7GxMp zWtf|9{UEe(xy{79cy8t=K2KFeZ>cVbK4ItG=xAdrrD!}SMc8I%@w;!#yLCSApZR{G zk=^6Y<8LEHEsrhO_}0}j$L-|ytg|76sXKXOH5p zJvuoHrp|M<^<3SW;nB!H+f**&(7J9dLlepNW4Cl&mG11}*ffzNm_8(a*^z)Fn{_U{8 zTaVs(ezUTD3di}ivu9u2tYyIkaDRvWj zS0zs{{B>8+b4$t3!~bh;?cjtFf#;ee5nMSDsYwB-@?+n+a7lPljR9jtHzT{nOT`qT5tj9Tpo{4N< z=Kec%Y|7Ek^8{i)ec0q7pt+^yfT_al2L{FOkKgw@dGl}hizm_f{k;5qQ|=j5PWtky zFj=)^opA20Gw05wwYIkQd^`DPU&_q2TY}PiC2NDz=08mCT2iz#Bi@ejcT=-zvOrO>h6{a8EqkTjdd;d!iJr59w`J%3%tnf(jNDXBXyejhU0@8NUsxx#tj7^vR>)+lhG!!G61rg+!_ySDX{{e}cej zBZU)-dR{N$eQmzRWQ+U$BF%FlBE{VP470=jW=m}+;iZfZ5GF&dk z@hVO8+qju6X7=}&6MuH@kJ-Ck(9!h0t_#1w>T^1)Z%mcWxg9T+=6yZ$i>lSmg)!=1 z`S~_zHvL_*Nsm$VQ={UohQ`3BK~vAP9WKnZc+z}o*Wq^^TR1wOebLR%xmNVKTI06& zM0b--Mp9*oJ8lTR-S+RXx2@DE?<~vyX&P_!+f}}4>Duhkwn#YBd&teP@X6K-s~vMx zdipvTUp{ytInybT|GnjcIa5xwcO3aR>EL0@-#Z_t1Wbr#Jt=U*)w4R|$0vihT|q~F zo87oR(R%tZMFyFdua{gYl9RRBc6n7({$$->$w&Xy?LBmEZs?UA3480sCo+4jJrkeE zyKhk}r?jNMblJrVi~ez%?m8zJ80zw%=_sE`dF8q_llg@Xmi!Ss-hVg6v@vCc_-4+^ z%TtqHW~(?`KJ+d&nR2i9!s=`H47VAraNhn{^(4FN&$nI0M-&CvI9#<3OQtTlRID{Q z^4v|?yo{?`?ItZebK-CMW>L|TQk$HQIbOHQ`LkS;L!j;Pr1ifRd(4%nTJ~waP2seU zuQWwGnxwp3lwK@dpqQ%cH1UMWwa+118!wes`Om47of2Z}VfbhL59`@gGu$2ZT;?ra zc*tO*#G>mtg&#~8{bWB;=5$)gXiN0}rAwFhvpo*En#O#4ExTovj*HQ`W_?GszRA;L zeX?W>fAQOUT;6$YZZv;pH+RajQ%0*;zB{x# z2T!nnGh``{fen&$@KV#BA@*Qd14qM+=O6Q-Weo-d*UIB$RnC zq2~4~f4#i+7i-?*GpwRSMfFOOqD(#aDHQ{ zXXtyk7f-JwblJG>THLC6Cd=Q!q})Nj>C&+jtKy5#my~WTv6*aZuQcOiMxx7+_@b|O z4k=e3@_CwSbe`p`b0!B<+3cyQ?<1}=*F9H~&u~0tdm&!BNdNm~1s0Ce)+d+8|35L` z>;IXK+zYXHCc6us_^r}8?cI6yoih^dv46d3^sd;Y*=PCZ33bbR_+Q>lj*Qs;&oy%P zbk|4r)6<+3%Ad2<&%RnDRq6PfQ_cBg-Hw@Z_n*l#>tt4_F{so<9?*@wcl5$cpYjC@ zzP(r9UgQCZU$4TOuOgKm7O?)=!>yN(KWqQGBct}(H2cc+ z%Op>|_{ci{f~56lhi_swd2CbOY>}GK%`V8WtfcJ@|AqGAd-sa3tWSS&aM4lCJ>icX zd$PG#y)WU4QFuQpBo{w>*EW)r!ICS=dcKZr5(|?x=_s{+DbhFm{_k<~zS=`Q3iu_ym5}dzDiBqBrI-aTPDS+zZ>^VUCBS834)P7<{VmoD&$>nkzz+;{viH{o3P=_esSU+(>3ai8y2 zj;`jPcQ-^C64^eO9bRH7W#x1Expc6duZaeOl}O9-g~j3LcPv|US2cY9q=lyr)boHhNech|^ ztWNU03cnofKSVmj2)(=P;%u=X;15r8+r@XDaVGh31<&Ku{r~$gioo$8IKM>dN$*eXsD&OWpJ?;32Qa4PgaIOCKq@I+?HBx!1l_eym(n zIIZD$!oEf(A&JZRFKmCZZ)<;ix<6~azU(~411qL@Wp+&J<`B4Hk~P^?apL~wO?B@a zyabP|-0IGF_|UO0>f3%P%HD5|@H?=Cl_7G&|C_fiKU?|Z@^(QR(XiEg?E3e@Jsc!I z%#bv%`7-CxlqKzLdq25OI;7vQe}eDH$dymNe*G`Gcax^$hicn?hyJU=?~l4Cy!&2r zVxM@@zi{{P>3W`f`8Ai}bJ+D6y@9SUDKH$F}38^3#gOH0PR z>>26rR__$7Xx*C>>~ZCP`!R>YV*A}^ZO&(%K2?$QTGfMptd*i7!0^9fU^XxvnaJoT-E7qFiBqTxpKnxsK}F@ zhi5%Xu5RvqdEBWesE_TCyZ(dY$5)(h_nPv*YR%jV*N=Z5-@pBL>9mH07niQ`bKEoM z`ov(DGwJhg@7wh$;Ue<~GoC26yUc$%QvYSoh*_n0pmUj&!WVH?O~zw>OLPzmH-#5*|OjeEzCnj(AKADv_cNVK}_E=+9x?W)I690nEw2Uoba_g2AzudvV z_$B2{`u)56Hzj?Jj9Td>{7*eF{(_TI{f*^?6SCYIqTa`>Qfy$F+;+(MdBMe+vs-`s zJNX!!e?P3h+e>GoEuc=$f=6h9vjrJ`@M#dyc3Cl3SOzFd5;Xr+r)*_(*6yKB@_ z7Q6SS1qKH8CEmEYI(+ki0|%6k9z8lIWz|$|!~a`n=W^>yT0J^A^>moW`q{Lw8D;R-DZaQc3~bZ7cH>3{X{a$)VRTX)Xuz1#NpchHub z3So=mf@Xa2pYZL+KY`k+q72u>eV;C!cE7c5f7zZn9ZTK$e>psBHA+6l^EiEe?YFj@ zIdyLjt-j;BhGW4Re+i?M6aKr)-}9CADpxJbIX}-f=j^Vn+n%oezeU!%Bt+_xX;Avx zm*H>f3zuA5UtY0Pf6jb2+nI;t``7FI`uU{3k^k)B9LBWEiOVOux;?0$r=54F&W>qL z#<}B#-mkLBx>jKE`_ z|Ly+%y1j09+Mbd-H#P=^IQgip{+}}M++6GFOP4MU%+CMLnoz`kQK_M5U7&`@(bUvb zuC2Si?L8$bDw^~8+1Z?{x2|rRdg0HU7|(?DCyJ``|0kWjAh9+?cl*i3e{O{+^W2zm ze&4p=@4I9x^%a_Mh|BuJ~CubNY&v1Ku?|S{`&z~cA zm%aV+;%r8P@ckEBukP$KC`wFBY!}mwy3*g~BCTaBGED* zFS)8qSM9&?ccJ>?(^YBD#bSdL-%g#`QRI7iMrX>4j+qyK%vbql(xF&aQ(4Sh#Ms(7 zP4^y)ZJ$%w#&1_PPG^2(Wn1)N^7LI#-`#YPx5yG+#K*b4WaqPMYmWc_y<}?Cx_763 zeSID2;Bdgq&*+_!I^X}PQ>UK3wl4PdwVN>;H*S2>XZN3-vW ziLIEBn&srO`)#%gGphxqzQ%N<%xkVSEHO}@*_M2!b6I1=!T{aI>z)_3YUG4ZpXW1c z{fFy4mir3wzD)f2zGTxZpXX}kQWEnb_Nw~qGLODledDI$;kM}F;^Mnq&rVI%*7o-H zp1!M8_`8l2i;vpnSx-+-zs$Hf@8q#w>6>4J)uIlkef7=L_FjCJ_19YUb-#o2PF?F~ zmT>;~Z~240%RB35O@G<;KesL5?x{C!RnMH$^O)KXxxIci-EqE4Vsyj*gLQ(2^|w?f zHU5>Wco-6JJTEtCa?-6!`Hy_u%a6Xlxiwf!SopHS6oW5|v^6zf^2hj@zF>Rj8N#tZ z=d_`JaNk3N(u#_T=10%GjQ%kz-+j+!{zCKYbI(&M%bHk^hl}faENnLX-(c7NX$`yC z=Y;(tRi^)*A9(VJjcJejW44GVqOCdNJX!_%3qSm2xV%dH#LgJC;C;Kk?_IuY`MMa1 z-0j=`T|NKqTMp+cy)UO2Vs z<$>mDhU^b*;~6KH{k!}@QeBea;ktrFh2n-k+!Gg{Ja;faD$Sy$$zp|)`d{1GColXz zvuvsA?f5;*%MUinI_|i(s`Z51wWa@8IySRKzLIuZ{8Ms`SM>E&!e^AvUr_$b?7ZOX zw^O%;PCodntNX*O^5)7;?e^K9zKSoD2v|SIF3#<68vDZE3m!iVMe7l62482Loo6)~^i?G~GyA8WQRebM;BM3ZCp(WC>@ z-Oi`w$J$Q0nR}F@=h>odzkmKb+t<-i@oj$nzrc|Bn>RjMW4y-9ShDw6#gC=VY&*9k zu}qkLw4G0u%h$(ekAkS*q>C@VR^2*d!<4?s=IMR=MSkXW5eGZ-*~%o?(kwEcMVU%Wb24UeEGV$%(pYOXo9Qou z*KE=GPKsw+ig(J>i!GV|*0-8;MZLcF)r zpZiXK%nvWwd_S+@qoG>Y=S7Pb?{3cd6MHi4c%ST>S=s9>dqva5ula~DOb=^y@bEaH zpTGC(HD7+)FBd95id7jYNLsOf;G5E4GNsqzMtVbmTu3RmXK&?_`My&nbi587R?fCxv!uN@N#vbn0o1EPp(huee`sm3yH3;{%H;6PjHijPdJDl0? zY~Os&b>Z3O-CnB#?wnn+>3OQxR<)`RE4qGouh-+txjyq*Wt7VrvCUu4EPHA>Q+j%f zWcO!wMWO74E(YuxP94TuqcZP17<^IO5q$oc>zAB)#j3Nz<7=<}I%oa9X3^!B8K1Ts zW&POas3m5au0L)#eN%wd278aE>>vn4rs`1?^~P@9nyKSw(BzoEW}Tk_E*x~9+H+zgnsyL$2-o6jn`SMAth8UC_< z)ONd*aqnH4h9J+$=zv{eTQBdoy2&G9;86YH!NJ)N)8{_!6Z_?Or~2W=c;}Tyf-Ot>xwHA>|DsLoJERlOw?v1FZ|~c%-1`4zz7M^6*Ub*w1^wXP%&|-Am&TvW z*gLXeE&Ii$ecj=vo7R3nS42!|Ru233&Cg?we(c`i`dDHXPtJo7&!s`noQz7gTqx^O z{ZrEL(W->$i}nll9d5i@_BU4k@p08p-(jTq!sEshy{CeYqyv*Q-`;nO~ z&3X^7>u#LYGwIWr;Axw_2;bVXH(KOrx?lO0nLZmiTH5T)oW;5H#UDA@HmtnBz92+0 z_sd%%?UpMAWk!Y?zmB z^6M4IVwl%<@+kNa7o{ER92YkPd%u@^VUkg<@wKSVP4U0upvNFDsmAIhtY{YOmB+n>z94tZeg2omTm6UMe8?2f0-)O9p|29Eb^RfmiDO) z^N)LV3kNM!UwB36F3;We^r*y3-pd;cji)>^Vfe-VB|4^jOH|_e;Eo)F{Le;T0s;ds zKCrT_{;71yDaFrO$yl&{mU=PAo&Qa(Rr=E%{T)6po1V!E^MCLJsot=QffmsmmKT-sL+rXp3VzqFX$6zY5l+F zn&_WjkEKFOOfJgtsun5mmdr|%y5>5`0s$Ss>3$V{Qf++&-K6MveX@a z7DGX=md|Scf)}S7mvEP8e^L1JzAbX~13CL27q7o!6o25(y4d*4N(24&Amy%4jUBai zB|)``2l&PHl@4?s>waLSlCg)uMPo_)g!(-?SA-T%Z;h%jcamLeyF>h--j-J}(PddX zf=~NjV7PJHd1dKzCeagJQMbPwRO4E#>(yo)D4W1_*!0Sz-ojnW51UxOt-bEWnbzPId4t9veZe)z5Mq4+ENbFGCn$~TM8?RZem_^vj-z%|0e$IA7GzMJsJ z((aU1%Nf51=eJY|E@?6S8sX;H$uY03tRQd2y#mA|Cg{5J8?Qvw}<<6-2~!4@|ms|?+fdFUU+zJ z_=w>v=+L{RcU-{KXH(yCus&BGW=aCgb zGMu6+ywk1*Sgkv*VZo*LPW@80>FGb2`(Dyv3Ebt=XP&Uevrswaj`-oKu*TJLHU5-1CBZU47{ub4><~0 zKqsR0HCzYPil!Nr2V@xg7~C6_9XJXWJ$wpLTfnlXi$Ps#{h`y$&!HOpO!n}=w1$I9 zsnCkb2T-jCI@_j03^^e9L5pcl#vU$x{yAV<3qS`q8G-BvX^wMk5bh0s__VPY;s^$H zsW>*Ua~RwYtOlJGrnSeW0PLItf)88{p9VP$q`5+r(a$8VbvpYw!3SUm&B>^cgs@~7 z*MoA@>JOg|STaEzB+RSN3}Goh2n7X$Xq=n{G#CmNJxoP-^1y%Q3(v3I%wu+W!N9=4 N;OXk;vd$@?2>@Ww8HxY^ literal 0 HcmV?d00001 diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index c281da9093..9767e36af2 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -163,6 +163,9 @@ exists(qupgrade) { DEFINES += "QUPGRADE_SUPPORT" } +# Include GLC library +#include(libs/GLC_lib/glc_lib.pri) + # Include QWT plotting library include(libs/qwt/qwt.pri) @@ -285,7 +288,8 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/terminalconsole.ui \ src/ui/configuration/SerialSettingsDialog.ui \ src/ui/configuration/ApmFirmwareConfig.ui \ - src/ui/px4_configuration/QGCPX4AirframeConfig.ui + src/ui/px4_configuration/QGCPX4AirframeConfig.ui \ + src/ui/px4_configuration/QGCPX4MulticopterConfig.ui INCLUDEPATH += src \ src/ui \ @@ -489,7 +493,7 @@ HEADERS += src/MG.h \ src/ui/QGCPendingParamWidget.h \ src/ui/px4_configuration/QGCPX4AirframeConfig.h \ src/ui/QGCBaseParamWidget.h \ - src/comm/px4_custom_mode.h + src/ui/px4_configuration/QGCPX4MulticopterConfig.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -709,7 +713,8 @@ SOURCES += src/main.cc \ src/uas/UASParameterCommsMgr.cc \ src/ui/QGCPendingParamWidget.cc \ src/ui/px4_configuration/QGCPX4AirframeConfig.cc \ - src/ui/QGCBaseParamWidget.cc + src/ui/QGCBaseParamWidget.cc \ + src/ui/px4_configuration/QGCPX4MulticopterConfig.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 4556712eb2..8137b7cc70 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -166,6 +166,7 @@ files/images/px4/airframes/flying_wing.png files/images/px4/airframes/plane_ert.png files/images/px4/airframes/plane_aert.png + files/images/px4/airframes/quad_h.png files/styles/Vera.ttf diff --git a/src/ui/QGCConfigView.cc b/src/ui/QGCConfigView.cc index 16fc3ecf94..fbf5bb8abe 100644 --- a/src/ui/QGCConfigView.cc +++ b/src/ui/QGCConfigView.cc @@ -4,18 +4,26 @@ #include "QGCPX4VehicleConfig.h" #include "QGCVehicleConfig.h" #include "QGCPX4VehicleConfig.h" +#include "MainWindow.h" QGCConfigView::QGCConfigView(QWidget *parent) : QWidget(parent), ui(new Ui::QGCConfigView), + config(NULL), mav(NULL) { ui->setupUi(this); connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(activeUASChanged(UASInterface*))); - //don't show a configuration widget if no vehicle is connected - //show a placeholder informational widget instead + // The config screens are required for firmware uploading + if (MainWindow::instance()->getCustomMode() == MainWindow::CUSTOM_MODE_PX4) { + config = new QGCPX4VehicleConfig(); + ui->gridLayout->addWidget(config); + } else { + //don't show a configuration widget if no vehicle is connected + //show a placeholder informational widget instead + } } @@ -49,10 +57,26 @@ void QGCConfigView::activeUASChanged(UASInterface* uas) int autopilotType = mav->getAutopilotType(); switch (autopilotType) { case MAV_AUTOPILOT_PX4: - ui->gridLayout->addWidget(new QGCPX4VehicleConfig()); + { + QGCPX4VehicleConfig* px4config = qobject_cast(config); + if (!px4config) { + if (config) + delete config; + config = new QGCPX4VehicleConfig(); + ui->gridLayout->addWidget(config); + } + } break; default: - ui->gridLayout->addWidget(new QGCVehicleConfig()); + { + QGCVehicleConfig* generalconfig = qobject_cast(config); + if (!generalconfig) { + if (config) + delete config; + config = new QGCVehicleConfig(); + ui->gridLayout->addWidget(config); + } + } break; } } diff --git a/src/ui/QGCConfigView.h b/src/ui/QGCConfigView.h index 0c1bda9a57..a1bd34075e 100644 --- a/src/ui/QGCConfigView.h +++ b/src/ui/QGCConfigView.h @@ -21,6 +21,7 @@ public slots: private: Ui::QGCConfigView *ui; + QWidget *config; UASInterface* mav; }; diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index a494b1ab0c..d08fdf9584 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -82,6 +82,11 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : setObjectName("QGC_VEHICLECONFIG"); ui->setupUi(this); + ui->advancedMenuButton->setEnabled(false); + ui->airframeMenuButton->setEnabled(false); + ui->sensorMenuButton->setEnabled(false); + ui->rcMenuButton->setEnabled(false); + px4AirframeConfig = new QGCPX4AirframeConfig(this); ui->airframeLayout->addWidget(px4AirframeConfig); @@ -1118,7 +1123,11 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) updateStatus(QString("Reading from system %1").arg(mav->getUASName())); // Since a system is now connected, enable the VehicleConfig UI. - //TODO anything? + // Enable buttons + ui->advancedMenuButton->setEnabled(true); + ui->airframeMenuButton->setEnabled(true); + ui->sensorMenuButton->setEnabled(true); + ui->rcMenuButton->setEnabled(true); } void QGCPX4VehicleConfig::resetCalibrationRC() diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui index 0b87de0ebc..045df39b17 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui @@ -33,9 +33,9 @@ 0 - 0 + -291 762 - 531 + 647 @@ -318,6 +318,10 @@ + + + :/files/images/px4/airframes/quad_h.png:/files/images/px4/airframes/quad_h.png + 120 diff --git a/src/ui/px4_configuration/QGCPX4MulticopterConfig.cc b/src/ui/px4_configuration/QGCPX4MulticopterConfig.cc new file mode 100644 index 0000000000..920d708364 --- /dev/null +++ b/src/ui/px4_configuration/QGCPX4MulticopterConfig.cc @@ -0,0 +1,14 @@ +#include "QGCPX4MulticopterConfig.h" +#include "ui_QGCPX4MulticopterConfig.h" + +QGCPX4MulticopterConfig::QGCPX4MulticopterConfig(QWidget *parent) : + QWidget(parent), + ui(new Ui::QGCPX4MulticopterConfig) +{ + ui->setupUi(this); +} + +QGCPX4MulticopterConfig::~QGCPX4MulticopterConfig() +{ + delete ui; +} diff --git a/src/ui/px4_configuration/QGCPX4MulticopterConfig.h b/src/ui/px4_configuration/QGCPX4MulticopterConfig.h new file mode 100644 index 0000000000..7a9140b74c --- /dev/null +++ b/src/ui/px4_configuration/QGCPX4MulticopterConfig.h @@ -0,0 +1,22 @@ +#ifndef QGCPX4MULTICOPTERCONFIG_H +#define QGCPX4MULTICOPTERCONFIG_H + +#include + +namespace Ui { +class QGCPX4MulticopterConfig; +} + +class QGCPX4MulticopterConfig : public QWidget +{ + Q_OBJECT + +public: + explicit QGCPX4MulticopterConfig(QWidget *parent = 0); + ~QGCPX4MulticopterConfig(); + +private: + Ui::QGCPX4MulticopterConfig *ui; +}; + +#endif // QGCPX4MULTICOPTERCONFIG_H diff --git a/src/ui/px4_configuration/QGCPX4MulticopterConfig.ui b/src/ui/px4_configuration/QGCPX4MulticopterConfig.ui new file mode 100644 index 0000000000..6a10dfc26d --- /dev/null +++ b/src/ui/px4_configuration/QGCPX4MulticopterConfig.ui @@ -0,0 +1,123 @@ + + + QGCPX4MulticopterConfig + + + + 0 + 0 + 605 + 449 + + + + Form + + + + + 130 + 150 + 341 + 22 + + + + Qt::Horizontal + + + + + + 130 + 400 + 351 + 22 + + + + Qt::Horizontal + + + + + + 30 + 160 + 62 + 16 + + + + TextLabel + + + + + + 510 + 160 + 62 + 16 + + + + TextLabel + + + + + + 40 + 400 + 62 + 16 + + + + TextLabel + + + + + + 520 + 400 + 62 + 16 + + + + TextLabel + + + + + + 30 + 10 + 62 + 16 + + + + TextLabel + + + + + + 30 + 200 + 62 + 16 + + + + TextLabel + + + + + + -- GitLab From d560305233d3c565cafb821524894a75fb2b3886 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 25 Aug 2013 10:10:40 +0200 Subject: [PATCH 319/460] Fixes, working on uploading story --- qgroundcontrol.pro | 9 ++++++--- src/ui/MainWindow.cc | 6 ------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 9767e36af2..e70764a348 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -146,13 +146,16 @@ include(src/apps/mavlinkgen/mavlinkgen.pri) exists(qupgrade) { SOURCES += qupgrade/src/apps/qupgrade/qgcfirmwareupgradeworker.cpp \ qupgrade/src/apps/qupgrade/uploader.cpp \ - qupgrade/src/apps/qupgrade/dialog_bare.cpp + qupgrade/src/apps/qupgrade/dialog_bare.cpp \ + qupgrade/src/apps/qupgrade/boardwidget.cpp HEADERS += qupgrade/src/apps/qupgrade/qgcfirmwareupgradeworker.h \ qupgrade/src/apps/qupgrade/uploader.h \ - qupgrade/src/apps/qupgrade/dialog_bare.h + qupgrade/src/apps/qupgrade/dialog_bare.h \ + qupgrade/src/apps/qupgrade/boardwidget.h - FORMS += qupgrade/src/apps/qupgrade/dialog_bare.ui + FORMS += qupgrade/src/apps/qupgrade/dialog_bare.ui \ + qupgrade/src/apps/qupgrade/boardwidget.ui linux*:CONFIG += qesp_linux_udev diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 3b6fa50648..23893f5269 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -1456,11 +1456,6 @@ void MainWindow::connectCommonActions() ui.actionSoftwareConfig->setChecked(true); ui.actionSoftwareConfig->activate(QAction::Trigger); } - if (currentView == VIEW_FIRMWAREUPDATE) - { - ui.actionFirmwareUpdateView->setChecked(true); - ui.actionFirmwareUpdateView->activate(QAction::Trigger); - } if (currentView == VIEW_TERMINAL) { ui.actionTerminalView->setChecked(true); @@ -1509,7 +1504,6 @@ void MainWindow::connectCommonActions() connect(ui.actionTerminalView,SIGNAL(triggered()),this,SLOT(loadTerminalView())); } - connect(ui.actionFirmwareUpdateView, SIGNAL(triggered()), this, SLOT(loadFirmwareUpdateView())); connect(ui.actionMavlinkView, SIGNAL(triggered()), this, SLOT(loadMAVLinkView())); // Help Actions -- GitLab From 1ca53ab02bbb08c552a51af2f714be8c1fa2cf18 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 25 Aug 2013 13:24:42 +0200 Subject: [PATCH 320/460] Re-did sensor calibration, WIP --- files/images/px4/calibration/accel_x+.png | Bin 0 -> 51710 bytes files/images/px4/calibration/accel_x-.png | Bin 0 -> 44570 bytes files/images/px4/calibration/accel_y+.png | Bin 0 -> 49496 bytes files/images/px4/calibration/accel_y-.png | Bin 0 -> 59419 bytes files/images/px4/calibration/accel_z+.png | Bin 0 -> 61063 bytes files/images/px4/calibration/accel_z-.png | Bin 0 -> 53850 bytes files/images/px4/calibration/arrows.png | Bin 0 -> 5968 bytes .../calibration/mag_calibration_figure8.png | Bin 0 -> 109177 bytes qgroundcontrol.pro | 9 +- qgroundcontrol.qrc | 8 + src/ui/QGCPX4VehicleConfig.cc | 45 +----- src/ui/QGCPX4VehicleConfig.h | 2 + src/ui/QGCPX4VehicleConfig.ui | 44 +----- .../QGCPX4SensorCalibration.cc | 99 ++++++++++++ .../QGCPX4SensorCalibration.h | 54 +++++++ .../QGCPX4SensorCalibration.ui | 143 ++++++++++++++++++ 16 files changed, 324 insertions(+), 80 deletions(-) create mode 100644 files/images/px4/calibration/accel_x+.png create mode 100644 files/images/px4/calibration/accel_x-.png create mode 100644 files/images/px4/calibration/accel_y+.png create mode 100644 files/images/px4/calibration/accel_y-.png create mode 100644 files/images/px4/calibration/accel_z+.png create mode 100644 files/images/px4/calibration/accel_z-.png create mode 100644 files/images/px4/calibration/arrows.png create mode 100644 files/images/px4/calibration/mag_calibration_figure8.png create mode 100644 src/ui/px4_configuration/QGCPX4SensorCalibration.cc create mode 100644 src/ui/px4_configuration/QGCPX4SensorCalibration.h create mode 100644 src/ui/px4_configuration/QGCPX4SensorCalibration.ui diff --git a/files/images/px4/calibration/accel_x+.png b/files/images/px4/calibration/accel_x+.png new file mode 100644 index 0000000000000000000000000000000000000000..86c5e44e84473111982acf5cd74e319850755e3f GIT binary patch literal 51710 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 GGywn#s~t7~ literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/accel_y+.png b/files/images/px4/calibration/accel_y+.png new file mode 100644 index 0000000000000000000000000000000000000000..956f9645e0cacb8ff2a4a2814db338b89e2277bd GIT binary patch literal 49496 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õ=FXj)#MhcBaXNqhVMU2uk3$xyuC2A!pCos5 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 eW}pd>Ncb)4-$_k7>&yeXD>E(4v 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%0AmMfY_p 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 C=vP|+ literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/accel_z+.png b/files/images/px4/calibration/accel_z+.png new file mode 100644 index 0000000000000000000000000000000000000000..ab2422a00ee6c9f49b4228b869f7fe8b2365bcc1 GIT binary patch literal 61063 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 literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/accel_z-.png b/files/images/px4/calibration/accel_z-.png new file mode 100644 index 0000000000000000000000000000000000000000..4abe01e173f93db77a0032774e0da2f24a15f03b GIT binary patch literal 53850 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 F1ONi`zMB95 literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/arrows.png b/files/images/px4/calibration/arrows.png new file mode 100644 index 0000000000000000000000000000000000000000..bfcc76cfdf954dd2a5591f64afa76bcddb9abd8d GIT binary patch literal 5968 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 literal 0 HcmV?d00001 diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index e70764a348..0240dec9f5 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -292,7 +292,8 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/SerialSettingsDialog.ui \ src/ui/configuration/ApmFirmwareConfig.ui \ src/ui/px4_configuration/QGCPX4AirframeConfig.ui \ - src/ui/px4_configuration/QGCPX4MulticopterConfig.ui + src/ui/px4_configuration/QGCPX4MulticopterConfig.ui \ + src/ui/px4_configuration/QGCPX4SensorCalibration.ui INCLUDEPATH += src \ src/ui \ @@ -496,7 +497,8 @@ HEADERS += src/MG.h \ src/ui/QGCPendingParamWidget.h \ src/ui/px4_configuration/QGCPX4AirframeConfig.h \ src/ui/QGCBaseParamWidget.h \ - src/ui/px4_configuration/QGCPX4MulticopterConfig.h + src/ui/px4_configuration/QGCPX4MulticopterConfig.h \ + src/ui/px4_configuration/QGCPX4SensorCalibration.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -717,7 +719,8 @@ SOURCES += src/main.cc \ src/ui/QGCPendingParamWidget.cc \ src/ui/px4_configuration/QGCPX4AirframeConfig.cc \ src/ui/QGCBaseParamWidget.cc \ - src/ui/px4_configuration/QGCPX4MulticopterConfig.cc + src/ui/px4_configuration/QGCPX4MulticopterConfig.cc \ + src/ui/px4_configuration/QGCPX4SensorCalibration.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 8137b7cc70..d19abb7000 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -167,6 +167,14 @@ files/images/px4/airframes/plane_ert.png files/images/px4/airframes/plane_aert.png files/images/px4/airframes/quad_h.png + files/images/px4/calibration/arrows.png + files/images/px4/calibration/accel_x+.png + files/images/px4/calibration/accel_x-.png + files/images/px4/calibration/accel_y-.png + files/images/px4/calibration/accel_z+.png + files/images/px4/calibration/accel_z-.png + files/images/px4/calibration/accel_y+.png + files/images/px4/calibration/mag_calibration_figure8.png files/styles/Vera.ttf diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index d08fdf9584..81f850c248 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -21,6 +21,7 @@ #include "UASParameterCommsMgr.h" #include "ui_QGCPX4VehicleConfig.h" #include "px4_configuration/QGCPX4AirframeConfig.h" +#include "px4_configuration/QGCPX4SensorCalibration.h" #include #define WIDGET_INDEX_FIRMWARE 0 @@ -54,6 +55,7 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : calibrationEnabled(false), configEnabled(false), px4AirframeConfig(NULL), + px4SensorCalibration(NULL), #ifdef QUPGRADE_SUPPORT firmwareDialog(NULL), #endif @@ -90,6 +92,9 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : px4AirframeConfig = new QGCPX4AirframeConfig(this); ui->airframeLayout->addWidget(px4AirframeConfig); + px4SensorCalibration = new QGCPX4SensorCalibration(this); + ui->sensorLayout->addWidget(px4SensorCalibration); + #ifdef QUPGRADE_SUPPORT firmwareDialog = new DialogBare(this); ui->firmwareLayout->addWidget(firmwareDialog); @@ -635,44 +640,6 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) } } } - - - // Load general calibration for autopilot - //TODO: Handle this more gracefully, maybe have it scan the directory for multiple calibration entries? - tool = new QGCToolWidget("", ui->sensorContents); - tool->addUAS(mav); - if (tool->loadSettings(autopilotdir.absolutePath() + "/general/calibration/calibration.qgw", false)) - { - toolWidgets.append(tool); - QGroupBox *box = new QGroupBox(ui->sensorContents); - box->setTitle(tool->objectName()); - box->setLayout(new QVBoxLayout(box)); - box->layout()->addWidget(tool); - ui->sensorLayout->addWidget(box); - } else { - delete tool; - } - - // Load vehicle-specific autopilot configuration - tool = new QGCToolWidget("", ui->sensorContents); - tool->addUAS(mav); - if (tool->loadSettings(autopilotdir.absolutePath() + "/" + mav->getSystemTypeName().toLower() + "/calibration/calibration.qgw", false)) - { - toolWidgets.append(tool); - QGroupBox *box = new QGroupBox(ui->sensorContents); - box->setTitle(tool->objectName()); - box->setLayout(new QVBoxLayout(box)); - box->layout()->addWidget(tool); - ui->sensorLayout->addWidget(box); - } else { - delete tool; - } - -// //description.txt -// QFile sensortipsfile(autopilotdir.absolutePath() + "/general/calibration/description.txt"); -// sensortipsfile.open(QIODevice::ReadOnly); -//// ui->sensorTips->setHtml(sensortipsfile.readAll()); -// sensortipsfile.close(); } void QGCPX4VehicleConfig::menuButtonClicked() { @@ -1056,7 +1023,7 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) foreach(QWidget* child, ui->advanceColumnContents->findChildren()) { child->deleteLater(); } - foreach(QWidget* child, ui->sensorContents->findChildren()) { + foreach(QWidget* child, ui->sensorLayout->findChildren()) { child->deleteLater(); } diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index b5f7e69534..1be13079cb 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -15,6 +15,7 @@ class UASParameterCommsMgr; class DialogBare; +class QGCPX4SensorCalibration; namespace Ui { class QGCPX4VehicleConfig; @@ -322,6 +323,7 @@ protected: QGCPX4AirframeConfig* px4AirframeConfig; DialogBare* firmwareDialog; + QGCPX4SensorCalibration* px4SensorCalibration; QMessageBox msgBox; QPushButton* skipActionButton; diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 608402afc3..458e0046e7 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -154,7 +154,7 @@ Config - 5 + 2 @@ -918,33 +918,7 @@ Config true - - - - - - - - true - - - - - 0 - 0 - 39 - 26 - - - - - - - - - - - + @@ -1020,8 +994,8 @@ Config 0 0 - 16 - 16 + 98 + 28 @@ -1057,8 +1031,8 @@ Config 0 0 - 16 - 16 + 98 + 28 @@ -1272,12 +1246,6 @@ Config
ui/QGCPendingParamWidget.h
1 - - QGCMessageView - QWidget -
QGCMessageView.h
- 1 -
QGCParamWidget QWidget diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc new file mode 100644 index 0000000000..a979a575a2 --- /dev/null +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc @@ -0,0 +1,99 @@ +#include "QGCPX4SensorCalibration.h" +#include "ui_QGCPX4SensorCalibration.h" +#include +#include +#include + +QGCPX4SensorCalibration::QGCPX4SensorCalibration(QWidget *parent) : + QWidget(parent), + activeUAS(NULL), + clearAction(new QAction(tr("Clear Text"), this)), + ui(new Ui::QGCPX4SensorCalibration) +{ + ui->setupUi(this); + connect(clearAction, SIGNAL(triggered()), ui->textView, SLOT(clear())); + + setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + + setObjectName("PX4_SENSOR_CALIBRATION"); + + setStyleSheet("QScrollArea { border: 0px; } QPlainTextEdit { border: 0px }"); + + setActiveUAS(UASManager::instance()->getActiveUAS()); + connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); +} + +QGCPX4SensorCalibration::~QGCPX4SensorCalibration() +{ + delete ui; +} + +void QGCPX4SensorCalibration::setInstructionImage(const QString &path) +{ + instructionIcon.load(path); + + int w = ui->iconLabel->width(); + int h = ui->iconLabel->height(); + + ui->iconLabel->setPixmap(instructionIcon.scaled(w, h, Qt::KeepAspectRatio)); +} + +void QGCPX4SensorCalibration::resizeEvent(QResizeEvent* event) +{ + + int w = ui->iconLabel->width(); + int h = ui->iconLabel->height(); + + ui->iconLabel->setPixmap(instructionIcon.scaled(w, h, Qt::KeepAspectRatio)); + + QWidget::resizeEvent(event); +} + +void QGCPX4SensorCalibration::setActiveUAS(UASInterface* uas) +{ + if (!uas) + return; + + if (activeUAS) { + disconnect(uas, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(handleTextMessage(int,int,int,QString))); + ui->textView->clear(); + } + + connect(uas, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(handleTextMessage(int,int,int,QString))); + activeUAS = uas; +} + +void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int severity, QString text) +{ + // XXX color messages according to severity + + QPlainTextEdit *msgWidget = ui->textView; + + //turn off updates while we're appending content to avoid breaking the autoscroll behavior + msgWidget->setUpdatesEnabled(false); + QScrollBar *scroller = msgWidget->verticalScrollBar(); + + UASInterface *uas = UASManager::instance()->getUASForId(uasid); + QString uasName(uas->getUASName()); + QString colorName(uas->getColor().name()); + //change styling based on severity + if (160 == severity ) { //TODO where is the constant for "critical" severity? + //GAudioOutput::instance()->say(text.toLower()); + msgWidget->appendHtml(QString("

[%1:%2] %3

").arg(uasName).arg(compId).arg(text)); + } + else { + msgWidget->appendHtml(QString("

[%2:%3] %4

").arg(colorName).arg(uasName).arg(compId).arg(text)); + } + + // Ensure text area scrolls correctly + scroller->setValue(scroller->maximum()); + msgWidget->setUpdatesEnabled(true); + +} + +void QGCPX4SensorCalibration::contextMenuEvent(QContextMenuEvent* event) +{ + QMenu menu(this); + menu.addAction(clearAction); + menu.exec(event->globalPos()); +} diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.h b/src/ui/px4_configuration/QGCPX4SensorCalibration.h new file mode 100644 index 0000000000..48d0093f5b --- /dev/null +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.h @@ -0,0 +1,54 @@ +#ifndef QGCPX4SENSORCALIBRATION_H +#define QGCPX4SENSORCALIBRATION_H + +#include +#include +#include + +namespace Ui { +class QGCPX4SensorCalibration; +} + +class QGCPX4SensorCalibration : public QWidget +{ + Q_OBJECT + +public: + explicit QGCPX4SensorCalibration(QWidget *parent = 0); + ~QGCPX4SensorCalibration(); + +public slots: + /** + * @brief Set currently active UAS + * @param uas the current active UAS + */ + void setActiveUAS(UASInterface* uas); + /** + * @brief Handle text message from current active UAS + * @param uasid + * @param componentid + * @param severity + * @param text + */ + void handleTextMessage(int uasid, int componentid, int severity, QString text); + + /** + * @brief Hand context menu event + * @param event + */ + virtual void contextMenuEvent(QContextMenuEvent* event); + + void setInstructionImage(const QString &path); + +protected: + UASInterface* activeUAS; + QAction* clearAction; + QPixmap instructionIcon; + + virtual void resizeEvent(QResizeEvent* event); + +private: + Ui::QGCPX4SensorCalibration *ui; +}; + +#endif // QGCPX4SENSORCALIBRATION_H diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui new file mode 100644 index 0000000000..eaca16b7c0 --- /dev/null +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui @@ -0,0 +1,143 @@ + + + QGCPX4SensorCalibration + + + + 0 + 0 + 531 + 448 + + + + Form + + + QPushButton#magButton { + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #73D95D, stop: 1 #18A154); + border-radius: 8px; + min-height: 25px; + max-height: 30px; + min-width: 60px; + max-width: 140px; + margin: 5px; + border: 2px solid #465158; +} + +QPushButton#gyroButton, QPushButton#accelButton { + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #D3795D, stop: 1 #A81154); + border-radius: 8px; + min-height: 25px; + max-height: 30px; + min-width: 60px; + max-width: 140px; + margin: 5px; + border: 2px solid #465158; +} + + + + + + Magnetometer Calibration + + + + + + + + + + + + + true + + + + + + + To calibrate the system, execute the three calibration steps below. + + + + + + + Qt::Vertical + + + + 498 + 21 + + + + + + + + 24 + + + + + + + + + Magnetometer + + + + :/files/images/px4/calibration/arrows.png:/files/images/px4/calibration/arrows.png + + + + + + + Gyroscope + + + + :/files/images/px4/calibration/arrows.png:/files/images/px4/calibration/arrows.png + + + + + + + Accelerometer + + + + :/files/images/px4/calibration/arrows.png:/files/images/px4/calibration/arrows.png + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + -- GitLab From 363c46b6468e02ab68ba206de4a16e31bf59434f Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 25 Aug 2013 13:36:46 +0200 Subject: [PATCH 321/460] Added QUpgrade Resources --- qgroundcontrol.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index e70764a348..f64ca72235 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -157,6 +157,8 @@ exists(qupgrade) { FORMS += qupgrade/src/apps/qupgrade/dialog_bare.ui \ qupgrade/src/apps/qupgrade/boardwidget.ui + RESOURCES += qupgrade/qupgrade.qrc + linux*:CONFIG += qesp_linux_udev include(qupgrade/libs/qextserialport/src/qextserialport.pri) -- GitLab From bd2ecaaf1196841293a042204760bc1f9e0d64ae Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 25 Aug 2013 15:19:02 +0200 Subject: [PATCH 322/460] Reasonably nice firmware upgrade --- files/styles/style-dark.css | 6 ++++++ src/ui/HSIDisplay.cc | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/files/styles/style-dark.css b/files/styles/style-dark.css index 4a336100ed..270e01c427 100644 --- a/files/styles/style-dark.css +++ b/files/styles/style-dark.css @@ -373,6 +373,12 @@ QPushButton#viewModeGeneric, QPushButton#viewModePX4, QPushButton#viewModeAPM, Q border: 3px solid #465158; } +QWidget#containerWidget { + background-color: qlineargradient(spread:pad, x1:0.527222, y1:0.961, x2:0.536946, y2:0.198864, stop:0.103448 rgba(65, 65, 65, 255), stop:1 rgba(119, 119, 119, 255)); + border-radius: 16px; + border: 2px solid #CCCCCC; +} + QPushButton#connectButton, QPushButton#controlButton { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #73D95D, stop: 1 #18A154); } diff --git a/src/ui/HSIDisplay.cc b/src/ui/HSIDisplay.cc index 8974032bfa..a1e0cc1c89 100644 --- a/src/ui/HSIDisplay.cc +++ b/src/ui/HSIDisplay.cc @@ -176,7 +176,8 @@ HSIDisplay::HSIDisplay(QWidget *parent) : setToolTip(tr("View from top in body frame. Scroll with mouse wheel to change the horizontal field of view of the widget.")); setStatusTip(tr("View from top in body frame. Scroll with mouse wheel to change the horizontal field of view of the widget.")); - connect(&statusClearTimer, SIGNAL(timeout()), this, SLOT(clearStatusMessage())); + // XXX this looks a potential recursive issue + //connect(&statusClearTimer, SIGNAL(timeout()), this, SLOT(clearStatusMessage())); if (UASManager::instance()->getActiveUAS()) { -- GitLab From 1aa7b9b9186c1d7d81dc58aba0fcd747663aba99 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 25 Aug 2013 16:33:59 +0200 Subject: [PATCH 323/460] Many more fixes on calibration, starts to actually do something --- files/styles/style-dark.css | 13 ++ src/ui/QGCPX4VehicleConfig.cc | 6 +- .../QGCPX4SensorCalibration.cc | 141 ++++++++++++++++-- .../QGCPX4SensorCalibration.h | 9 ++ .../QGCPX4SensorCalibration.ui | 75 +++++----- 5 files changed, 196 insertions(+), 48 deletions(-) diff --git a/files/styles/style-dark.css b/files/styles/style-dark.css index 270e01c427..db24be2584 100644 --- a/files/styles/style-dark.css +++ b/files/styles/style-dark.css @@ -248,6 +248,19 @@ QLabel#noUas { font-size: 30pt; } +QMessageBox QLabel { + font-size: 12pt; +} + +QLabel#calibrationExplanationLabel { + font-size: 20pt; +} + +QLabel#instructionLabel { + color: #FEC654; + font-size: 26pt; +} + QLineEdit { border: 1px solid #777; border-radius: 2px; diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 5fc4d96c13..740b147149 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -1027,9 +1027,9 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) foreach(QWidget* child, ui->advanceColumnContents->findChildren()) { child->deleteLater(); } - foreach(QWidget* child, ui->sensorLayout->findChildren()) { - child->deleteLater(); - } +// foreach(QWidget* child, ui->sensorLayout->findChildren()) { +// child->deleteLater(); +// } foreach(QWidget* child, ui->airframeLayout->findChildren()) { diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc index a979a575a2..f0d328eb29 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc @@ -3,16 +3,35 @@ #include #include #include +#include QGCPX4SensorCalibration::QGCPX4SensorCalibration(QWidget *parent) : QWidget(parent), activeUAS(NULL), clearAction(new QAction(tr("Clear Text"), this)), + accelStarted(false), + gyroStarted(false), + magStarted(false), ui(new Ui::QGCPX4SensorCalibration) { + accelAxes << "x+"; + accelAxes << "x-"; + accelAxes << "y+"; + accelAxes << "y-"; + accelAxes << "z+"; + accelAxes << "z-"; + ui->setupUi(this); connect(clearAction, SIGNAL(triggered()), ui->textView, SLOT(clear())); + connect(ui->gyroButton, SIGNAL(clicked()), this, SLOT(gyroButtonClicked())); + connect(ui->magButton, SIGNAL(clicked()), this, SLOT(magButtonClicked())); + connect(ui->accelButton, SIGNAL(clicked()), this, SLOT(accelButtonClicked())); + + ui->gyroButton->setEnabled(false); + ui->magButton->setEnabled(false); + ui->accelButton->setEnabled(false); + setInstructionImage("./files/images/px4/calibration/accel_z-.png"); setObjectName("PX4_SENSOR_CALIBRATION"); @@ -21,6 +40,7 @@ QGCPX4SensorCalibration::QGCPX4SensorCalibration(QWidget *parent) : setActiveUAS(UASManager::instance()->getActiveUAS()); connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); + ui->progressBar->setValue(0); } QGCPX4SensorCalibration::~QGCPX4SensorCalibration() @@ -59,12 +79,90 @@ void QGCPX4SensorCalibration::setActiveUAS(UASInterface* uas) ui->textView->clear(); } + ui->gyroButton->setEnabled(true); + ui->magButton->setEnabled(true); + ui->accelButton->setEnabled(true); + connect(uas, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(handleTextMessage(int,int,int,QString))); activeUAS = uas; } void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int severity, QString text) { + if (text.startsWith("[cmd]") || + text.startsWith("[mavlink pm]")) + return; + + if (text.contains("progress")) { + qDebug() << "PROGRESS:" << text; + QString percent = text.split("<").last().split(">").first(); + qDebug() << "PERCENT CANDIDATE" << percent; + bool ok; + int p = percent.toInt(&ok); + if (ok) + ui->progressBar->setValue(p); + return; + } + + + if (text.contains("accel")) { + qDebug() << "ACCEL" << text; + + if (text.startsWith("accel meas started: ")) { + QString axis = text.split("meas started: ").last().right(2); + qDebug() << "AXIS" << axis << "STR" << text; + setInstructionImage(QString("./files/images/px4/calibration/accel_%1.png").arg(axis)); + + } + } + + if (text.startsWith("meas result for")) { + + QString axis = text.split("meas result for ").last().left(2); + + qDebug() << "ACCELDONE AXIS" << axis << "STR" << text; + + for (int i = 0; i < 6; i++) + { + if (accelAxes[i] == axis) + accelDone[i] = true; + + if (!accelDone[i]) { + setInstructionImage(QString("./files/images/px4/calibration/accel_%1.png").arg(accelAxes[i])); + ui->calibrationExplanationLabel->setText(tr("Axis %1 completed. Please rotate to a different axis, e.g. the one shown here.").arg(axis)); + } + } + } + + if (text.contains("please rotate in a figure 8")) { + ui->calibrationExplanationLabel->setText(tr("Rotate the system around all its axes, e.g. in a figure eight.")); + setInstructionImage("./files/images/px4/calibration/mag_calibration_figure8.png"); + } + + if (text.contains("accel calibration done")) { + accelStarted = false; + // XXX use a confirmation image or something + setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + ui->calibrationExplanationLabel->setText(tr("Accelerometer calibration completed. Parameters permanently stored.")); + } + + if (text.contains("gyro calibration done")) { + gyroStarted = false; + // XXX use a confirmation image or something + setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + ui->calibrationExplanationLabel->setText(tr("Gyroscope calibration completed. Parameters permanently stored.")); + } + + if (text.contains("mag calibration done")) { + magStarted = false; + // XXX use a confirmation image or something + setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + ui->calibrationExplanationLabel->setText(tr("Magnetometer calibration completed. Parameters permanently stored.")); + } + + ui->instructionLabel->setText(QString("%1").arg(text)); + + // XXX color messages according to severity QPlainTextEdit *msgWidget = ui->textView; @@ -73,22 +171,43 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever msgWidget->setUpdatesEnabled(false); QScrollBar *scroller = msgWidget->verticalScrollBar(); - UASInterface *uas = UASManager::instance()->getUASForId(uasid); - QString uasName(uas->getUASName()); - QString colorName(uas->getColor().name()); - //change styling based on severity - if (160 == severity ) { //TODO where is the constant for "critical" severity? - //GAudioOutput::instance()->say(text.toLower()); - msgWidget->appendHtml(QString("

[%1:%2] %3

").arg(uasName).arg(compId).arg(text)); - } - else { - msgWidget->appendHtml(QString("

[%2:%3] %4

").arg(colorName).arg(uasName).arg(compId).arg(text)); - } + msgWidget->appendHtml(QString("%4").arg(text)); // Ensure text area scrolls correctly scroller->setValue(scroller->maximum()); msgWidget->setUpdatesEnabled(true); +} +void QGCPX4SensorCalibration::gyroButtonClicked() +{ + setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + activeUAS->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); + ui->progressBar->setValue(0); + ui->calibrationExplanationLabel->setText(tr("Please do not move the system at all and wait for calibration to complete.")); +} + +void QGCPX4SensorCalibration::magButtonClicked() +{ + setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + activeUAS->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); + ui->progressBar->setValue(0); + ui->calibrationExplanationLabel->setText(tr("Please put the system in a rest position and wait for instructions.")); +} + +void QGCPX4SensorCalibration::accelButtonClicked() +{ + setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + activeUAS->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0); + ui->progressBar->setValue(0); + accelStarted = true; + accelDone[0] = false; + accelDone[1] = false; + accelDone[2] = false; + accelDone[3] = false; + accelDone[4] = false; + accelDone[5] = false; + + ui->calibrationExplanationLabel->setText(tr("Please hold the system very still in the shown orientations. Start with the one shown.")); } void QGCPX4SensorCalibration::contextMenuEvent(QContextMenuEvent* event) diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.h b/src/ui/px4_configuration/QGCPX4SensorCalibration.h index 48d0093f5b..b6cfd1bd22 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.h +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.h @@ -32,6 +32,10 @@ public slots: */ void handleTextMessage(int uasid, int componentid, int severity, QString text); + void gyroButtonClicked(); + void magButtonClicked(); + void accelButtonClicked(); + /** * @brief Hand context menu event * @param event @@ -44,6 +48,11 @@ protected: UASInterface* activeUAS; QAction* clearAction; QPixmap instructionIcon; + bool accelStarted; + bool accelDone[6]; + bool gyroStarted; + bool magStarted; + QStringList accelAxes; virtual void resizeEvent(QResizeEvent* event); diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui index eaca16b7c0..95ca42e8cf 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui @@ -36,35 +36,28 @@ QPushButton#gyroButton, QPushButton#accelButton { border: 2px solid #465158; } - - - - - Magnetometer Calibration - - - - - - - - - - + + + + + Qt::Horizontal - - true + + + 40 + 20 + - + - - + + - To calibrate the system, execute the three calibration steps below. + Magnetometer Calibration - + Qt::Vertical @@ -77,14 +70,24 @@ QPushButton#gyroButton, QPushButton#accelButton { - + + + + + + + + 24 - + + + + @@ -121,18 +124,22 @@ QPushButton#gyroButton, QPushButton#accelButton { - - - - Qt::Horizontal + + + + - - - 40 - 20 - + + true - + + + + + + To calibrate the system, execute the three calibration steps below. + +
-- GitLab From 7048ce946c6925e84b4b9de367202a81e414fbdd Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 25 Aug 2013 19:11:56 +0200 Subject: [PATCH 324/460] Checkpoint: This is looking sweet --- files/images/px4/menu/cogwheels.png | Bin 0 -> 14695 bytes files/images/px4/menu/firmware_upgrade.png | Bin 0 -> 14033 bytes files/images/px4/menu/plane.png | Bin 0 -> 25579 bytes files/images/px4/menu/remote.png | Bin 0 -> 15068 bytes files/images/px4/menu/sensors.png | Bin 0 -> 10167 bytes files/styles/style-dark.css | 16 ++ qgroundcontrol.qrc | 5 + src/ui/QGCConfigView.cc | 35 ++- src/ui/QGCConfigView.ui | 3 + src/ui/QGCPX4VehicleConfig.cc | 5 +- src/ui/QGCPX4VehicleConfig.ui | 303 ++++++++++++--------- 11 files changed, 229 insertions(+), 138 deletions(-) create mode 100644 files/images/px4/menu/cogwheels.png create mode 100644 files/images/px4/menu/firmware_upgrade.png create mode 100644 files/images/px4/menu/plane.png create mode 100644 files/images/px4/menu/remote.png create mode 100644 files/images/px4/menu/sensors.png diff --git a/files/images/px4/menu/cogwheels.png b/files/images/px4/menu/cogwheels.png new file mode 100644 index 0000000000000000000000000000000000000000..8079ca4169aca274ab014c0fb82f51f1c387b33b GIT binary patch literal 14695 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 F0RZjx#Ww%| literal 0 HcmV?d00001 diff --git a/files/images/px4/menu/firmware_upgrade.png b/files/images/px4/menu/firmware_upgrade.png new file mode 100644 index 0000000000000000000000000000000000000000..83397753376d9e9234d6cd1698d1d1c74bf5ea65 GIT binary patch literal 14033 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/images/px4/calibration/accel_z-.png files/images/px4/calibration/accel_y+.png files/images/px4/calibration/mag_calibration_figure8.png + files/images/px4/menu/sensors.png + files/images/px4/menu/firmware_upgrade.png + files/images/px4/menu/plane.png + files/images/px4/menu/remote.png + files/images/px4/menu/cogwheels.png
files/styles/Vera.ttf diff --git a/src/ui/QGCConfigView.cc b/src/ui/QGCConfigView.cc index fbf5bb8abe..8e647cd804 100644 --- a/src/ui/QGCConfigView.cc +++ b/src/ui/QGCConfigView.cc @@ -18,8 +18,14 @@ QGCConfigView::QGCConfigView(QWidget *parent) : // The config screens are required for firmware uploading if (MainWindow::instance()->getCustomMode() == MainWindow::CUSTOM_MODE_PX4) { + + ui->gridLayout->removeWidget(ui->waitingLabel); + ui->waitingLabel->setVisible(false); + delete ui->waitingLabel; + config = new QGCPX4VehicleConfig(); ui->gridLayout->addWidget(config); + } else { //don't show a configuration widget if no vehicle is connected //show a placeholder informational widget instead @@ -37,23 +43,28 @@ void QGCConfigView::activeUASChanged(UASInterface* uas) if (mav == uas) return; - //remove all child widgets since they could contain stale data - //for example, when we switch from one PX4 UAS to another UAS - foreach (QObject* obj, ui->gridLayout->children()) { - QWidget* w = dynamic_cast(obj); - if (w) { - if (obj != ui->waitingLabel) { - ui->gridLayout->removeWidget(w); - delete obj; - } - } - } + int type = -1; + if (mav) + type = mav->getAutopilotType(); mav = uas; - if (NULL != mav) { + if (NULL != uas && type != uas->getAutopilotType()) { + ui->gridLayout->removeWidget(ui->waitingLabel); ui->waitingLabel->setVisible(false); + //remove all child widgets since they could contain stale data + //for example, when we switch from one PX4 UAS to another UAS + foreach (QObject* obj, ui->gridLayout->children()) { + QWidget* w = dynamic_cast(obj); + if (w) { + if (obj != ui->waitingLabel) { + ui->gridLayout->removeWidget(w); + delete obj; + } + } + } + int autopilotType = mav->getAutopilotType(); switch (autopilotType) { case MAV_AUTOPILOT_PX4: diff --git a/src/ui/QGCConfigView.ui b/src/ui/QGCConfigView.ui index cd4b9c98fe..38ce1ce777 100644 --- a/src/ui/QGCConfigView.ui +++ b/src/ui/QGCConfigView.ui @@ -14,6 +14,9 @@ Form + + 0 + diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 740b147149..4cdf530311 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -89,6 +89,7 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : ui->airframeMenuButton->setEnabled(false); ui->sensorMenuButton->setEnabled(false); ui->rcMenuButton->setEnabled(false); + ui->generalMenuButton->hide(); px4AirframeConfig = new QGCPX4AirframeConfig(this); ui->airframeLayout->addWidget(px4AirframeConfig); @@ -554,7 +555,7 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) // Load tabs for general configuration foreach (QString dir,generaldir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { - QPushButton *button = new QPushButton(ui->leftNavScrollAreaWidgetContents); + QPushButton *button = new QPushButton(this); connect(button,SIGNAL(clicked()),this,SLOT(menuButtonClicked())); ui->navBarLayout->insertWidget(2,button); button->setMinimumHeight(75); @@ -598,7 +599,7 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) // Load additional tabs for vehicle specific configuration foreach (QString dir,vehicledir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { - QPushButton *button = new QPushButton(ui->leftNavScrollAreaWidgetContents); + QPushButton *button = new QPushButton(this); connect(button,SIGNAL(clicked()),this,SLOT(menuButtonClicked())); ui->navBarLayout->insertWidget(2,button); diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 458e0046e7..9793992d73 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -19,134 +19,187 @@ Form - + + + 0 + - - - - 135 - 0 - - - - - 135 - 16777215 - - - - true - - - - - 0 - 0 - 133 - 886 - + + + + 0 - - - - - QLayout::SetMinAndMaxSize - - - - - Firmware + + + + QLayout::SetMinAndMaxSize + + + 12 + + + 12 + + + 24 + + + 12 + + + + + Firmware Upgrade - - - - - - - - 100 - 75 - - - - - 16777215 - 16777215 - - - - RC + + + + :/files/images/px4/menu/firmware_upgrade.png:/files/images/px4/menu/firmware_upgrade.png + + + + 64 + 64 + + + + + + + + + 100 + 75 + + + + + 16777215 + 16777215 + + + + Radio Calibration - - - - - - - - 100 - 75 - - - - Sensor + + + + :/files/images/px4/menu/remote.png:/files/images/px4/menu/remote.png + + + + 64 + 64 + + + + + + + + + 100 + 75 + + + + Sensor Calibration - - - - - - - Airframe + + + + :/files/images/px4/menu/sensors.png:/files/images/px4/menu/sensors.png + + + + 64 + 64 + + + + + + + + Airframe Config - - - - - - - - 100 - 75 - - - - General + + + + :/files/images/px4/menu/plane.png:/files/images/px4/menu/plane.png + + + + 64 + 64 + + + + + + + + + 100 + 75 + + + + General Config - - - - - - - - 100 - 75 - - - - Advanced + + + + :/files/images/px4/menu/cogwheels.png:/files/images/px4/menu/cogwheels.png + + + + 64 + 64 + + + + + + + + + 100 + 75 + + + + Advanced Config - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - + + + + :/files/images/px4/menu/cogwheels.png:/files/images/px4/menu/cogwheels.png + + + + 64 + 64 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + @@ -154,7 +207,7 @@ Config - 2 + 5 @@ -1123,8 +1176,8 @@ Config 0 0 - 597 - 740 + 571 + 764 @@ -1253,6 +1306,8 @@ Config 1 - + + + -- GitLab From 18a3503dd15e3cd8c4d93d4e5d948e995e4859ce Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 25 Aug 2013 19:36:28 +0200 Subject: [PATCH 325/460] More config fixes --- files/styles/style-dark.css | 11 +- src/ui/QGCPX4VehicleConfig.cc | 6 + src/ui/QGCPX4VehicleConfig.ui | 425 ++++++++++++++++------------------ 3 files changed, 213 insertions(+), 229 deletions(-) diff --git a/files/styles/style-dark.css b/files/styles/style-dark.css index fc653de737..a0b8d91087 100644 --- a/files/styles/style-dark.css +++ b/files/styles/style-dark.css @@ -256,6 +256,13 @@ QLabel#calibrationExplanationLabel { font-size: 20pt; } +QLabel#tabTitleLabel { + font-size: 28pt; + font-weight: lighter; + margin-top: 16px; + margin-bottom: 8px; +} + QLabel#instructionLabel { color: #FEC654; font-size: 26pt; @@ -372,11 +379,11 @@ QPushButton#planePushButton, QPushButton#flyingWingPushButton, QPushButton#quadX QPushButton#quadPlusPushButton, QPushButton#hexaXPushButton, QPushButton#hexaPlusPushButton, QPushButton#octoXPushButton, QPushButton#octoPlusPushButton, QPushButton#hPushButton { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #777, stop: 1 #333); - border-radius: 12px; + border-radius: 5px; min-height: 140px; max-height: 240px; min-width: 140px; - border: 3px solid #465158; + border: 1px solid #465158; } QPushButton:checked#planePushButton, QPushButton:checked#flyingWingPushButton, QPushButton:checked#quadXPushButton, diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 4cdf530311..593f410ed3 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -234,31 +234,37 @@ void QGCPX4VehicleConfig::rcMenuButtonClicked() { //TODO eg ui->stackedWidget->findChild("rcConfig"); ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_RC); + ui->tabTitleLabel->setText(tr("Radio Calibration")); } void QGCPX4VehicleConfig::sensorMenuButtonClicked() { ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_SENSOR_CAL); + ui->tabTitleLabel->setText(tr("Sensor Calibration")); } void QGCPX4VehicleConfig::generalMenuButtonClicked() { ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_GENERAL_CONFIG); + ui->tabTitleLabel->setText(tr("General Configuration Options")); } void QGCPX4VehicleConfig::advancedMenuButtonClicked() { ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_ADV_CONFIG); + ui->tabTitleLabel->setText(tr("Advanced Configuration Options")); } void QGCPX4VehicleConfig::airframeMenuButtonClicked() { ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_AIRFRAME_CONFIG); + ui->tabTitleLabel->setText(tr("Airframe Configuration")); } void QGCPX4VehicleConfig::firmwareMenuButtonClicked() { ui->stackedWidget->setCurrentIndex(WIDGET_INDEX_FIRMWARE); + ui->tabTitleLabel->setText(tr("Firmware Upgrade")); } void QGCPX4VehicleConfig::identifyChannelMapping(int aert_index) diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 9793992d73..a9f062e9cf 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -7,7 +7,7 @@ 0 0 1256 - 912 + 918 @@ -19,223 +19,36 @@ Form - + 0 - - - - - 0 - - - - - QLayout::SetMinAndMaxSize - - - 12 - - - 12 - - - 24 - - - 12 - - - - - Firmware -Upgrade - - - - :/files/images/px4/menu/firmware_upgrade.png:/files/images/px4/menu/firmware_upgrade.png - - - - 64 - 64 - - - - - - - - - 100 - 75 - - - - - 16777215 - 16777215 - - - - Radio -Calibration - - - - :/files/images/px4/menu/remote.png:/files/images/px4/menu/remote.png - - - - 64 - 64 - - - - - - - - - 100 - 75 - - - - Sensor -Calibration - - - - :/files/images/px4/menu/sensors.png:/files/images/px4/menu/sensors.png - - - - 64 - 64 - - - - - - - - Airframe -Config - - - - :/files/images/px4/menu/plane.png:/files/images/px4/menu/plane.png - - - - 64 - 64 - - - - - - - - - 100 - 75 - - - - General -Config - - - - :/files/images/px4/menu/cogwheels.png:/files/images/px4/menu/cogwheels.png - - - - 64 - 64 - - - - - - - - - 100 - 75 - - - - Advanced -Config - - - - :/files/images/px4/menu/cogwheels.png:/files/images/px4/menu/cogwheels.png - - - - 64 - 64 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - + + + + + 16 + 75 + true + + + + Configuration + - + - 5 + 0 - - - - - Firmware Upgrade - - - - + - - - - - 16 - 75 - true - - - - RC Calibration - - - @@ -985,13 +798,6 @@ Config - - - - General Config - - - @@ -1108,20 +914,6 @@ Config - - - - - 16 - 75 - true - - - - Advanced Configuration - - - @@ -1176,8 +968,8 @@ Config 0 0 - 571 - 764 + 98 + 28 @@ -1284,6 +1076,185 @@ Config + + + + + 0 + + + + + QLayout::SetMinAndMaxSize + + + 12 + + + 12 + + + 24 + + + 12 + + + + + Firmware +Upgrade + + + + :/files/images/px4/menu/firmware_upgrade.png:/files/images/px4/menu/firmware_upgrade.png + + + + 64 + 64 + + + + + + + + + 100 + 75 + + + + + 16777215 + 16777215 + + + + Radio +Calibration + + + + :/files/images/px4/menu/remote.png:/files/images/px4/menu/remote.png + + + + 64 + 64 + + + + + + + + + 100 + 75 + + + + Sensor +Calibration + + + + :/files/images/px4/menu/sensors.png:/files/images/px4/menu/sensors.png + + + + 64 + 64 + + + + + + + + Airframe +Config + + + + :/files/images/px4/menu/plane.png:/files/images/px4/menu/plane.png + + + + 64 + 64 + + + + + + + + + 100 + 75 + + + + General +Config + + + + :/files/images/px4/menu/cogwheels.png:/files/images/px4/menu/cogwheels.png + + + + 64 + 64 + + + + + + + + + 100 + 75 + + + + Advanced +Config + + + + :/files/images/px4/menu/cogwheels.png:/files/images/px4/menu/cogwheels.png + + + + 64 + 64 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + -- GitLab From baafca2ea4b6d18ea4bbf0b6885e7a55e35e4ae7 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 25 Aug 2013 23:24:25 +0200 Subject: [PATCH 326/460] Fixed image paths --- .../QGCPX4SensorCalibration.cc | 20 ++++++++-------- .../QGCPX4SensorCalibration.ui | 23 +++++++------------ 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc index f0d328eb29..e202df099e 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc @@ -32,7 +32,7 @@ QGCPX4SensorCalibration::QGCPX4SensorCalibration(QWidget *parent) : ui->magButton->setEnabled(false); ui->accelButton->setEnabled(false); - setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); setObjectName("PX4_SENSOR_CALIBRATION"); @@ -111,7 +111,7 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever if (text.startsWith("accel meas started: ")) { QString axis = text.split("meas started: ").last().right(2); qDebug() << "AXIS" << axis << "STR" << text; - setInstructionImage(QString("./files/images/px4/calibration/accel_%1.png").arg(axis)); + setInstructionImage(QString(":/files/images/px4/calibration/accel_%1.png").arg(axis)); } } @@ -128,7 +128,7 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever accelDone[i] = true; if (!accelDone[i]) { - setInstructionImage(QString("./files/images/px4/calibration/accel_%1.png").arg(accelAxes[i])); + setInstructionImage(QString(":/files/images/px4/calibration/accel_%1.png").arg(accelAxes[i])); ui->calibrationExplanationLabel->setText(tr("Axis %1 completed. Please rotate to a different axis, e.g. the one shown here.").arg(axis)); } } @@ -136,27 +136,27 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever if (text.contains("please rotate in a figure 8")) { ui->calibrationExplanationLabel->setText(tr("Rotate the system around all its axes, e.g. in a figure eight.")); - setInstructionImage("./files/images/px4/calibration/mag_calibration_figure8.png"); + setInstructionImage(":/files/images/px4/calibration/mag_calibration_figure8.png"); } if (text.contains("accel calibration done")) { accelStarted = false; // XXX use a confirmation image or something - setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); ui->calibrationExplanationLabel->setText(tr("Accelerometer calibration completed. Parameters permanently stored.")); } if (text.contains("gyro calibration done")) { gyroStarted = false; // XXX use a confirmation image or something - setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); ui->calibrationExplanationLabel->setText(tr("Gyroscope calibration completed. Parameters permanently stored.")); } if (text.contains("mag calibration done")) { magStarted = false; // XXX use a confirmation image or something - setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); ui->calibrationExplanationLabel->setText(tr("Magnetometer calibration completed. Parameters permanently stored.")); } @@ -180,7 +180,7 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever void QGCPX4SensorCalibration::gyroButtonClicked() { - setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); activeUAS->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); ui->progressBar->setValue(0); ui->calibrationExplanationLabel->setText(tr("Please do not move the system at all and wait for calibration to complete.")); @@ -188,7 +188,7 @@ void QGCPX4SensorCalibration::gyroButtonClicked() void QGCPX4SensorCalibration::magButtonClicked() { - setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); activeUAS->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); ui->progressBar->setValue(0); ui->calibrationExplanationLabel->setText(tr("Please put the system in a rest position and wait for instructions.")); @@ -196,7 +196,7 @@ void QGCPX4SensorCalibration::magButtonClicked() void QGCPX4SensorCalibration::accelButtonClicked() { - setInstructionImage("./files/images/px4/calibration/accel_z-.png"); + setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); activeUAS->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0); ui->progressBar->setValue(0); accelStarted = true; diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui index 95ca42e8cf..5e5de8479b 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui @@ -50,13 +50,6 @@ QPushButton#gyroButton, QPushButton#accelButton { - - - - Magnetometer Calibration - - - @@ -124,7 +117,14 @@ QPushButton#gyroButton, QPushButton#accelButton { - + + + + To calibrate the system, execute the three calibration steps below. + + + + @@ -134,13 +134,6 @@ QPushButton#gyroButton, QPushButton#accelButton { - - - - To calibrate the system, execute the three calibration steps below. - - - -- GitLab From 402029725dfb60f9ce29f9b370946989ae593498 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 26 Aug 2013 08:11:21 +0200 Subject: [PATCH 327/460] Added periodic check for ports to QGC toolbar to not depend on port state on power up --- src/ui/QGCToolBar.cc | 17 ++++++++++++----- src/ui/QGCToolBar.h | 4 +++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 96c0a00d55..ba164b430a 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -221,6 +221,9 @@ void QGCToolBar::createUI() loadSettings(); + connect(&portBoxTimer, SIGNAL(timeout()), this, SLOT(updateComboBox())); + portBoxTimer.start(500); + changed = false; } @@ -647,25 +650,29 @@ void QGCToolBar::removeLink(LinkInterface* link) } void QGCToolBar::updateComboBox() { - portComboBox->clear(); +// portComboBox->clear(); if (currentLink) { SerialLink *slink = qobject_cast(currentLink); QList portlist = slink->getCurrentPorts(); - foreach(QString port, portlist) { - portComboBox->addItem(port, port); + foreach (QString port, portlist) + { + if (portComboBox->findText(port) == -1) + { + portComboBox->addItem(port, port); + } } - portComboBox->setCurrentIndex(portComboBox->findData(slink->getPortName())); if (slink->getPortName().trimmed().length() > 0) { + portComboBox->setCurrentIndex(portComboBox->findData(slink->getPortName())); portComboBox->setEditText(slink->getPortName()); } else { if (portlist.length() > 0) { - portComboBox->setEditText(portlist.first()); + portComboBox->setEditText(portlist.last()); } else { diff --git a/src/ui/QGCToolBar.h b/src/ui/QGCToolBar.h index 35a2ea88ed..c6bfe1d568 100644 --- a/src/ui/QGCToolBar.h +++ b/src/ui/QGCToolBar.h @@ -31,6 +31,7 @@ This file is part of the QGROUNDCONTROL project #include #include #include +#include #include "UASInterface.h" #include "QGCMAVLinkLogPlayer.h" #include "SerialLink.h" @@ -84,13 +85,13 @@ public slots: void clearStatusString(); /** @brief Set an activity action as checked in menu */ void advancedActivityTriggered(QAction* action); + void updateComboBox(); protected: void storeSettings(); void loadSettings(); void createUI(); void resetToolbarUI(); - void updateComboBox(); UASInterface* mav; QLabel* symbolLabel; QLabel* toolBarNameLabel; @@ -108,6 +109,7 @@ protected: QGCMAVLinkLogPlayer* player; QComboBox *portComboBox; QComboBox *baudcomboBox; + QTimer portBoxTimer; bool changed; float batteryPercent; float batteryVoltage; -- GitLab From 107d7167f28b6a8364b8280a48bbfeb3c57eba4e Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 26 Aug 2013 11:53:17 +0200 Subject: [PATCH 328/460] Fixed race issues in config upload, tested to be reliable now - board startup scripts now need the other half of testing --- files/styles/style-dark.css | 7 +- src/comm/MAVLinkProtocol.cc | 4 +- src/comm/SerialLink.cc | 2 +- src/ui/QGCPX4VehicleConfig.cc | 7 +- src/ui/QGCPX4VehicleConfig.ui | 69 +------ .../px4_configuration/QGCPX4AirframeConfig.cc | 174 ++++++++++++++---- .../px4_configuration/QGCPX4AirframeConfig.h | 15 ++ 7 files changed, 174 insertions(+), 104 deletions(-) diff --git a/files/styles/style-dark.css b/files/styles/style-dark.css index a0b8d91087..0818591a8e 100644 --- a/files/styles/style-dark.css +++ b/files/styles/style-dark.css @@ -249,7 +249,12 @@ QLabel#noUas { } QMessageBox QLabel { - font-size: 12pt; + font-size: 14pt; +} + +QMessageBox { + min-width: 400px; + min-height: 300px; } QLabel#calibrationExplanationLabel { diff --git a/src/comm/MAVLinkProtocol.cc b/src/comm/MAVLinkProtocol.cc index 8684e0a668..3a24378912 100644 --- a/src/comm/MAVLinkProtocol.cc +++ b/src/comm/MAVLinkProtocol.cc @@ -250,9 +250,9 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b) if (decodeState == 0 && !decodedFirstPacket) { nonmavlinkCount++; - if (nonmavlinkCount > 500 && !warnedUserNonMavlink) + if (nonmavlinkCount > 2000 && !warnedUserNonMavlink) { - //500 bytes with no mavlink message. Are we connected to a mavlink capable device? + //2000 bytes with no mavlink message. Are we connected to a mavlink capable device? if (!checkedUserNonMavlink) { link->requestReset(); diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 1fcb664f11..3af32a6b81 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -183,7 +183,7 @@ void SerialLink::run() if (m_transmitBuffer.count() > 0) { QMutexLocker writeLocker(&m_writeMutex); int numWritten = m_port->write(m_transmitBuffer); - bool txSuccess = m_port->waitForBytesWritten(1); + bool txSuccess = m_port->waitForBytesWritten(5); if (!txSuccess || (numWritten != m_transmitBuffer.count())) { linkErrorCount++; qDebug() << "TX Error! wrote" << numWritten << ", asked for " << m_transmitBuffer.count() << "bytes"; diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 593f410ed3..cf71c3cdcf 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -1182,12 +1182,11 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float fval) // Raw value float mappedVal = rcMappedValue[rcToFunctionMapping[chan]]; - bool isMapped = (((float)UINT16_MAX) != mappedVal); + float deltaRaw = fabsf(fval - rcValue[chan]); float delta = fabsf(fval - mappedVal); if (!configEnabled && !calibrationEnabled && - (!isMapped || - (delta < 12.0f && rcValue[chan] > 800 && rcValue[chan] < 2200) ) - ) { + (deltaRaw < 12.0f && delta < 12.0f && rcValue[chan] > 800 && rcValue[chan] < 2200)) + { //ignore tiny jitter values return; } diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index a9f062e9cf..7e258f4cd4 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -798,40 +798,6 @@ - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 13 - 50 - false - - - - Load Platform Defaults - - - - - @@ -853,8 +819,8 @@ 0 0 - 98 - 28 + 492 + 828 @@ -890,8 +856,8 @@ 0 0 - 98 - 28 + 491 + 828 @@ -914,33 +880,6 @@ - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - Load Platform Defaults - - - - - diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index 82694e6b82..4f3ecd2b51 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -1,5 +1,7 @@ #include +#include #include +#include #include "QGCPX4AirframeConfig.h" #include "ui_QGCPX4AirframeConfig.h" @@ -7,10 +9,14 @@ #include "UASManager.h" #include "LinkManager.h" #include "UAS.h" +#include "QGC.h" QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : QWidget(parent), mav(NULL), + progress(NULL), + pendingParams(0), + configState(CONFIG_STATE_ABORT), selectedId(-1), ui(new Ui::QGCPX4AirframeConfig) { @@ -75,6 +81,7 @@ void QGCPX4AirframeConfig::parameterChanged(int uas, int component, QString para setAirframeID(index); ui->statusLabel->setText(tr("Onboard start script ID: #%1").arg(index)); } else { + uncheckAll(); ui->statusLabel->setText(tr("System not configured for autostart.")); } } @@ -171,12 +178,14 @@ void QGCPX4AirframeConfig::applyAndReboot() if (paramMgr->countOnboardParams() == 0 && paramMgr->countPendingParams() == 0) { - paramMgr->requestParameterListIfEmpty(); - QGC::SLEEP::msleep(100); + paramMgr->requestParameterList(); + QGC::SLEEP::msleep(300); } + QList components = paramMgr->getComponentForParam("SYS_AUTOSTART"); + // Guard against the case of an edit where we didn't receive all params yet - if (paramMgr->countPendingParams() > 0) + if (paramMgr->countPendingParams() > 0 || components.count() == 0) { QMessageBox msgBox; msgBox.setText(tr("Parameter sync with UAS not yet complete")); @@ -188,8 +197,6 @@ void QGCPX4AirframeConfig::applyAndReboot() return; } - QList components = paramMgr->getComponentForParam("SYS_AUTOSTART"); - // Guard against multiple components responding - this will never show in practice if (components.count() != 1) { QMessageBox msgBox; @@ -202,32 +209,137 @@ void QGCPX4AirframeConfig::applyAndReboot() return; } - qDebug() << "Setting comp" << components.first() << "SYS_AUTOSTART" << (qint32)selectedId; - - paramMgr->setPendingParam(components.first(),"SYS_AUTOSTART", (qint32)selectedId); - - //need to set autoconfig in order for PX4 to pick up the selected airframe params - if (ui->defaultGainsCheckBox->checkState() == Qt::Checked) - setAutoConfig(true); - - // Send pending params and then write them to persistent storage when done - paramMgr->sendPendingParameters(true); - - // Reboot - //TODO right now this relies upon the above send & persist finishing before the reboot command is received... - QMessageBox msgBox(this); - msgBox.setText(tr("Storing Parameters and Rebooting Autopilot")); - msgBox.setInformativeText(tr("Please wait a few seconds for the reboot to complete.")); - msgBox.setStandardButtons(QMessageBox::NoButton); - msgBox.setModal(false); - msgBox.show(); - QGC::SLEEP::sleep(2); - mav->executeCommand(MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); - QGC::SLEEP::msleep(200); - LinkManager::instance()->disconnectAll(); - QGC::SLEEP::sleep(8); - LinkManager::instance()->connectAll(); - msgBox.close(); + // This is really evil: 'fake' a thread by + // periodic work queue calls and clock + // through a small state machine + // ugh.. if we just had time to do this properly. + + // To the reader who can't program and wants to whine: + // this is not beautiful, but technically completely + // sound. If you want to fix it, you'd be welcome + // to rebase the link, param manager and UI classes + // on a proper threading framework - which I'd love to do + // if I just had more time.. + + configState = CONFIG_STATE_SEND; + QTimer::singleShot(200, this, SLOT(checkConfigState())); +} + +void QGCPX4AirframeConfig::checkConfigState() +{ + + if (configState == CONFIG_STATE_SEND) + { + QList components = paramMgr->getComponentForParam("SYS_AUTOSTART"); + qDebug() << "Setting comp" << components.first() << "SYS_AUTOSTART" << (qint32)selectedId; + + paramMgr->setPendingParam(components.first(),"SYS_AUTOSTART", (qint32)selectedId); + + //need to set autoconfig in order for PX4 to pick up the selected airframe params + if (ui->defaultGainsCheckBox->checkState() == Qt::Checked) + setAutoConfig(true); + + // Send pending params and then write them to persistent storage when done + paramMgr->sendPendingParameters(true); + + configState = CONFIG_STATE_WAIT_PENDING; + pendingParams = 0; + QTimer::singleShot(2000, this, SLOT(checkConfigState())); + return; + } + + if (configState == CONFIG_STATE_WAIT_PENDING) { + // Guard against the case of an edit where we didn't receive all params yet + if (paramMgr->countPendingParams() > 0) + { + if (pendingParams == 0) { + + pendingParams = paramMgr->countPendingParams(); + + if (progress) + delete progress; + + progress = new QProgressDialog("Writing parameters", "Abort Send", 0, pendingParams, this); + progress->setWindowModality(Qt::WindowModal); + progress->setMinimumDuration(2000); + } + + qDebug() << "PENDING" << paramMgr->countPendingParams() << "PROGRESS" << pendingParams - paramMgr->countPendingParams(); + progress->setValue(pendingParams - paramMgr->countPendingParams()); + + if (progress->wasCanceled()) { + configState = CONFIG_STATE_ABORT; + pendingParams = 0; + return; + } + } else { + pendingParams = 0; + configState = CONFIG_STATE_REBOOT; + } + + qDebug() << "PENDING PARAMS WAIT PENDING: " << paramMgr->countPendingParams(); + QTimer::singleShot(1000, this, SLOT(checkConfigState())); + return; + } + + if (configState == CONFIG_STATE_REBOOT) { + + // Reboot + //TODO right now this relies upon the above send & persist finishing before the reboot command is received... + + unsigned pendingMax = 20; + + qDebug() << "PENDING PARAMS REBOOT BEFORE" << pendingParams; + + if (pendingParams == 0) { + pendingParams = 1; + + if (progress) + delete progress; + + progress = new QProgressDialog("Waiting for autopilot reboot", "Abort", 0, pendingMax, this); + progress->setWindowModality(Qt::WindowModal); + qDebug() << "Waiting for reboot, pending" << pendingParams; + } + + if (pendingParams == 3) { + qDebug() << "REQUESTING REBOOT"; + mav->executeCommand(MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); + mav->executeCommand(MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); + } + + if (pendingParams == 4) { + qDebug() << "DISCONNECT AIRFRAME"; + LinkManager::instance()->disconnectAll(); + } + + if (pendingParams == 14) { + qDebug() << "CONNECT AIRFRAME"; + LinkManager::instance()->connectAll(); + } + if (pendingParams == 15) { + qDebug() << "DISCONNECT AIRFRAME"; + LinkManager::instance()->disconnectAll(); + } + if (pendingParams == 16) { + qDebug() << "CONNECT AIRFRAME"; + LinkManager::instance()->connectAll(); + } + + if (pendingParams < pendingMax) { + progress->setValue(pendingParams); + QTimer::singleShot(1000, this, SLOT(checkConfigState())); + } else { + paramMgr->requestParameterList(); + progress->setValue(pendingMax); + configState = CONFIG_STATE_ABORT; + pendingParams = 0; + return; + } + qDebug() << "PENDING PARAMS REBOOT AFTER:" << pendingParams; + pendingParams++; + return; + } } void QGCPX4AirframeConfig::setAutoConfig(bool enabled) diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.h b/src/ui/px4_configuration/QGCPX4AirframeConfig.h index 346076e184..dcbf4abc14 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.h +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.h @@ -4,6 +4,8 @@ #include #include +class QProgressDialog; + namespace Ui { class QGCPX4AirframeConfig; } @@ -67,6 +69,9 @@ public slots: */ void applyAndReboot(); +protected slots: + void checkConfigState(); + protected: /** @@ -83,9 +88,19 @@ protected: void uncheckAll(); + enum CONFIG_STATE { + CONFIG_STATE_ABORT = 0, + CONFIG_STATE_SEND, + CONFIG_STATE_WAIT_PENDING, + CONFIG_STATE_REBOOT + }; + private: UASInterface* mav; QGCUASParamManager *paramMgr; + QProgressDialog* progress; + unsigned pendingParams; + enum CONFIG_STATE configState; int selectedId; Ui::QGCPX4AirframeConfig *ui; }; -- GitLab From 94fcdaa30dd77789544dbf15369161afdd8765eb Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 26 Aug 2013 12:23:03 +0200 Subject: [PATCH 329/460] Instatiation / state fixes --- src/ui/QGCConfigView.cc | 9 ++++++--- src/ui/QGCToolBar.cc | 15 +++++++++++++-- src/ui/QGCToolBar.h | 7 +++++++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/ui/QGCConfigView.cc b/src/ui/QGCConfigView.cc index 8e647cd804..16147f3e4b 100644 --- a/src/ui/QGCConfigView.cc +++ b/src/ui/QGCConfigView.cc @@ -22,6 +22,7 @@ QGCConfigView::QGCConfigView(QWidget *parent) : ui->gridLayout->removeWidget(ui->waitingLabel); ui->waitingLabel->setVisible(false); delete ui->waitingLabel; + ui->waitingLabel = NULL; config = new QGCPX4VehicleConfig(); ui->gridLayout->addWidget(config); @@ -48,10 +49,12 @@ void QGCConfigView::activeUASChanged(UASInterface* uas) type = mav->getAutopilotType(); mav = uas; - if (NULL != uas && type != uas->getAutopilotType()) { + if (uas && type != uas->getAutopilotType()) { - ui->gridLayout->removeWidget(ui->waitingLabel); - ui->waitingLabel->setVisible(false); + if (ui->waitingLabel) { + ui->gridLayout->removeWidget(ui->waitingLabel); + ui->waitingLabel->setVisible(false); + } //remove all child widgets since they could contain stale data //for example, when we switch from one PX4 UAS to another UAS diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index ba164b430a..520ac1c9d0 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -32,6 +32,7 @@ This file is part of the QGROUNDCONTROL project QGCToolBar::QGCToolBar(QWidget *parent) : QToolBar(parent), mav(NULL), + userBaudChoice(false), changed(true), batteryPercent(0), batteryVoltage(0), @@ -180,7 +181,7 @@ void QGCToolBar::createUI() baudcomboBox->addItem("921600", 921600); baudcomboBox->setCurrentIndex(baudcomboBox->findData(57600)); addWidget(baudcomboBox); - + connect(baudcomboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(baudSelected(int))); connectButton = new QPushButton(tr("Connect"), this); @@ -251,6 +252,11 @@ void QGCToolBar::resetToolbarUI() symbolLabel->clear(); } +void QGCToolBar::baudSelected(int index) +{ + userBaudChoice = true; +} + void QGCToolBar::setPerspectiveChangeActions(const QList &actions) { if (actions.count() > 1) @@ -679,7 +685,12 @@ void QGCToolBar::updateComboBox() portComboBox->setEditText(tr("No serial port found")); } } - baudcomboBox->setCurrentIndex(baudcomboBox->findData(slink->getBaudRate())); + + if (!userBaudChoice) { + int index = baudcomboBox->findData(slink->getBaudRate()); + if (index > 0) + baudcomboBox->setCurrentIndex(index); + } } } diff --git a/src/ui/QGCToolBar.h b/src/ui/QGCToolBar.h index c6bfe1d568..0b82f91473 100644 --- a/src/ui/QGCToolBar.h +++ b/src/ui/QGCToolBar.h @@ -87,6 +87,12 @@ public slots: void advancedActivityTriggered(QAction* action); void updateComboBox(); + /** + * @brief User selected baud rate + * @param index The current index of the combo box + */ + void baudSelected(int index); + protected: void storeSettings(); void loadSettings(); @@ -110,6 +116,7 @@ protected: QComboBox *portComboBox; QComboBox *baudcomboBox; QTimer portBoxTimer; + bool userBaudChoice; bool changed; float batteryPercent; float batteryVoltage; -- GitLab From 7aa3ca2dcb8564e6ddc98661e9d3914a258eee81 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 26 Aug 2013 15:34:39 +0200 Subject: [PATCH 330/460] Fixed port to not auto-reset --- src/ui/QGCToolBar.cc | 38 +++++++++++++++++++++++++------------- src/ui/QGCToolBar.h | 7 +++++++ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 520ac1c9d0..28c586df5b 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -33,6 +33,7 @@ QGCToolBar::QGCToolBar(QWidget *parent) : QToolBar(parent), mav(NULL), userBaudChoice(false), + userPortChoice(false), changed(true), batteryPercent(0), batteryVoltage(0), @@ -182,7 +183,7 @@ void QGCToolBar::createUI() baudcomboBox->setCurrentIndex(baudcomboBox->findData(57600)); addWidget(baudcomboBox); connect(baudcomboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(baudSelected(int))); - + connect(portComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(portSelected(int))); connectButton = new QPushButton(tr("Connect"), this); connectButton->setObjectName("connectButton"); @@ -254,9 +255,16 @@ void QGCToolBar::resetToolbarUI() void QGCToolBar::baudSelected(int index) { + Q_UNUSED(index); userBaudChoice = true; } +void QGCToolBar::portSelected(int index) +{ + Q_UNUSED(index); + userPortChoice = true; +} + void QGCToolBar::setPerspectiveChangeActions(const QList &actions) { if (actions.count() > 1) @@ -656,7 +664,6 @@ void QGCToolBar::removeLink(LinkInterface* link) } void QGCToolBar::updateComboBox() { -// portComboBox->clear(); if (currentLink) { SerialLink *slink = qobject_cast(currentLink); @@ -669,26 +676,31 @@ void QGCToolBar::updateComboBox() } } - if (slink->getPortName().trimmed().length() > 0) - { - portComboBox->setCurrentIndex(portComboBox->findData(slink->getPortName())); - portComboBox->setEditText(slink->getPortName()); - } - else - { - if (portlist.length() > 0) + if (!userPortChoice) { + if (slink->getPortName().trimmed().length() > 0) { - portComboBox->setEditText(portlist.last()); + int portIndex = portComboBox->findData(slink->getPortName()); + if (portIndex >= 0) { + portComboBox->setCurrentIndex(portIndex); + portComboBox->setEditText(slink->getPortName()); + } } else { - portComboBox->setEditText(tr("No serial port found")); + if (portlist.length() > 0) + { + portComboBox->setEditText(portlist.last()); + } + else + { + portComboBox->setEditText(tr("No serial port found")); + } } } if (!userBaudChoice) { int index = baudcomboBox->findData(slink->getBaudRate()); - if (index > 0) + if (index >= 0) baudcomboBox->setCurrentIndex(index); } } diff --git a/src/ui/QGCToolBar.h b/src/ui/QGCToolBar.h index 0b82f91473..65495ec8ce 100644 --- a/src/ui/QGCToolBar.h +++ b/src/ui/QGCToolBar.h @@ -93,6 +93,12 @@ public slots: */ void baudSelected(int index); + /** + * @brief User selected port + * @param index The current index of the combo box + */ + void portSelected(int index); + protected: void storeSettings(); void loadSettings(); @@ -117,6 +123,7 @@ protected: QComboBox *baudcomboBox; QTimer portBoxTimer; bool userBaudChoice; + bool userPortChoice; bool changed; float batteryPercent; float batteryVoltage; -- GitLab From 6f8553bbdae7374dce96d7895df04e783f11ef1e Mon Sep 17 00:00:00 2001 From: Anton Babushkin Date: Mon, 26 Aug 2013 16:24:27 +0200 Subject: [PATCH 331/460] Config panel title initialization fix --- src/ui/QGCPX4VehicleConfig.cc | 2 ++ src/ui/QGCPX4VehicleConfig.ui | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index cf71c3cdcf..7286ecd155 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -220,6 +220,8 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : rcMappedNormalizedValue[i] = 0.0f; } + firmwareMenuButtonClicked(); + updateTimer.setInterval(150); connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateView())); updateTimer.start(); diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 7e258f4cd4..f23424e64e 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -33,7 +33,7 @@ - Configuration + @@ -819,8 +819,8 @@ 0 0 - 492 - 828 + 98 + 28 @@ -856,8 +856,8 @@ 0 0 - 491 - 828 + 98 + 28 -- GitLab From d55937a1c807f605ac743d850d252d30c5aefd5b Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 26 Aug 2013 17:05:57 +0200 Subject: [PATCH 332/460] Another cleanup round --- src/comm/SerialLink.cc | 9 +++++---- src/ui/QGCPX4VehicleConfig.cc | 2 ++ src/ui/QGCToolBar.cc | 12 ++++++++++-- src/ui/uas/UASListWidget.cc | 20 ++++++++++++++++++++ src/ui/uas/UASListWidget.h | 1 + 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 3af32a6b81..e30f9e3c28 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -28,8 +28,6 @@ SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, m_stopp(false), m_reqReset(false) { - qDebug() << "create SerialLink " << portname << baudRate << hardwareFlowControl - << parity << dataBits << stopBits; // Setup settings m_portName = portname.trimmed(); @@ -38,8 +36,6 @@ SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, m_portName = m_ports.first().trimmed(); } - qDebug() << "m_portName " << m_portName; - // Set unique ID and add link to the list of links m_id = getNextLinkId(); @@ -66,6 +62,11 @@ SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, m_stopBits = stopBits; loadSettings(); + + qDebug() << "create SerialLink " << portname << baudRate << hardwareFlowControl + << parity << dataBits << stopBits; + qDebug() << "m_portName " << m_portName; + LinkManager::instance()->add(this); } void SerialLink::requestReset() diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index cf71c3cdcf..5e8edb5b3d 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -223,6 +223,8 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : updateTimer.setInterval(150); connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateView())); updateTimer.start(); + + firmwareMenuButtonClicked(); } QGCPX4VehicleConfig::~QGCPX4VehicleConfig() diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 28c586df5b..c75b8554b9 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -182,8 +182,8 @@ void QGCToolBar::createUI() baudcomboBox->addItem("921600", 921600); baudcomboBox->setCurrentIndex(baudcomboBox->findData(57600)); addWidget(baudcomboBox); - connect(baudcomboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(baudSelected(int))); - connect(portComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(portSelected(int))); + connect(baudcomboBox, SIGNAL(activated(int)), this, SLOT(baudSelected(int))); + connect(portComboBox, SIGNAL(activated(int)), this, SLOT(portSelected(int))); connectButton = new QPushButton(tr("Connect"), this); connectButton->setObjectName("connectButton"); @@ -666,6 +666,10 @@ void QGCToolBar::updateComboBox() { if (currentLink) { + // Do not update if not visible + if (!portComboBox->isVisible()) + return; + SerialLink *slink = qobject_cast(currentLink); QList portlist = slink->getCurrentPorts(); foreach (QString port, portlist) @@ -715,6 +719,8 @@ void QGCToolBar::updateLinkState(bool connected) connectButton->blockSignals(true); connectButton->setChecked(true); connectButton->blockSignals(false); + portComboBox->hide(); + baudcomboBox->hide(); } else { @@ -722,6 +728,8 @@ void QGCToolBar::updateLinkState(bool connected) connectButton->blockSignals(true); connectButton->setChecked(false); connectButton->blockSignals(false); + portComboBox->show(); + baudcomboBox->show(); } } diff --git a/src/ui/uas/UASListWidget.cc b/src/ui/uas/UASListWidget.cc index a3fab70aaf..bc92aa44e0 100644 --- a/src/ui/uas/UASListWidget.cc +++ b/src/ui/uas/UASListWidget.cc @@ -64,6 +64,8 @@ UASListWidget::UASListWidget(QWidget *parent) : QWidget(parent), this->setVisible(false); + connect(LinkManager::instance(), SIGNAL(linkRemoved(LinkInterface*)), this, SLOT(removeLink(LinkInterface*))); + // Listen for when UASes are added or removed. This does not manage the UASView // widgets that are displayed within this widget. connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), @@ -96,12 +98,30 @@ void UASListWidget::changeEvent(QEvent *e) } } +// XXX This is just to prevent +// upfront crashes, will probably need further inspection +void UASListWidget::removeLink(LinkInterface* link) +{ + QGroupBox* box = linkToBoxMapping.value(link, NULL); + + if (box) { + // Just stop updating the status for now - we should + // remove the UAS probably + linkToBoxMapping.remove(link); + } +} + void UASListWidget::updateStatus() { QMapIterator i(linkToBoxMapping); while (i.hasNext()) { i.next(); LinkInterface* link = i.key(); + + // Paranoid sanity check + if (!LinkManager::instance()->getLinks().contains(link)) + continue; + if (!link) continue; diff --git a/src/ui/uas/UASListWidget.h b/src/ui/uas/UASListWidget.h index b14e1e97de..494d16fdb8 100644 --- a/src/ui/uas/UASListWidget.h +++ b/src/ui/uas/UASListWidget.h @@ -53,6 +53,7 @@ public slots: void addUAS(UASInterface* uas); void activeUAS(UASInterface* uas); void removeUAS(UASInterface* uas); + void removeLink(LinkInterface* link); protected: // Keep a mapping from UASes to their GroupBox. Useful for determining when groupboxes are empty. -- GitLab From 59743ec5212b108a69a621c067225aacdc7b2342 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 26 Aug 2013 17:07:22 +0200 Subject: [PATCH 333/460] Post-merge cleanup --- src/ui/QGCPX4VehicleConfig.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index c28751cfc3..c7b882a21f 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -226,7 +226,6 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateView())); updateTimer.start(); - firmwareMenuButtonClicked(); } QGCPX4VehicleConfig::~QGCPX4VehicleConfig() -- GitLab From 1f76bbed9ef608c3a00e3f71b722bed2700fcf8b Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 26 Aug 2013 17:39:51 +0200 Subject: [PATCH 334/460] More fixes and rigor --- files/styles/style-dark.css | 9 ++++++ .../px4_configuration/QGCPX4AirframeConfig.cc | 28 +++++++++++++++---- .../px4_configuration/QGCPX4AirframeConfig.ui | 2 +- .../QGCPX4SensorCalibration.cc | 1 + 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/files/styles/style-dark.css b/files/styles/style-dark.css index 0818591a8e..26b68253b6 100644 --- a/files/styles/style-dark.css +++ b/files/styles/style-dark.css @@ -408,6 +408,15 @@ QPushButton#viewModeGeneric, QPushButton#viewModePX4, QPushButton#viewModeAPM, Q border: 3px solid #465158; } +QPushButton#magButton, QPushButton#gyroButton, QPushButton#accelButton { + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #73D95D, stop: 1 #18A154); + border-radius: 8px; + min-height: 30px; + max-height: 50px; + min-width: 60px; + border: 3px solid #465158; +} + QWidget#containerWidget { background-color: qlineargradient(spread:pad, x1:0.527222, y1:0.961, x2:0.536946, y2:0.198864, stop:0.103448 rgba(65, 65, 65, 255), stop:1 rgba(119, 119, 119, 255)); border-radius: 16px; diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index 4f3ecd2b51..e4de511d49 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -46,20 +46,31 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : connect(ui->quadPlusPushButton, SIGNAL(clicked()), this, SLOT(quadPlusSelected())); connect(ui->quadPlusComboBox, SIGNAL(activated(int)), this, SLOT(quadPlusSelected(int))); + ui->quadPlusPushButton->setEnabled(ui->quadPlusComboBox->count() > 0); + connect(ui->hexaXPushButton, SIGNAL(clicked()), this, SLOT(hexaXSelected())); connect(ui->hexaXComboBox, SIGNAL(activated(int)), this, SLOT(hexaXSelected(int))); + ui->hexaXPushButton->setEnabled(ui->hexaXComboBox->count() > 0); + connect(ui->hexaPlusPushButton, SIGNAL(clicked()), this, SLOT(hexaPlusSelected())); connect(ui->hexaPlusComboBox, SIGNAL(activated(int)), this, SLOT(hexaPlusSelected(int))); + ui->hexaPlusPushButton->setEnabled(ui->hexaPlusComboBox->count() > 0); + connect(ui->octoXPushButton, SIGNAL(clicked()), this, SLOT(octoXSelected())); connect(ui->octoXComboBox, SIGNAL(activated(int)), this, SLOT(octoXSelected(int))); + ui->octoXPushButton->setEnabled(ui->octoXComboBox->count() > 0); + connect(ui->octoPlusPushButton, SIGNAL(clicked()), this, SLOT(octoPlusSelected())); connect(ui->octoPlusComboBox, SIGNAL(activated(int)), this, SLOT(octoPlusSelected(int))); - - connect(ui->hComboBox, SIGNAL(activated(int)), this, SLOT(hSelected(int))); + ui->octoPlusPushButton->setEnabled(ui->octoPlusComboBox->count() > 0); ui->hComboBox->addItem(tr("TBS Discovery"), 15); ui->hComboBox->addItem(tr("H Custom"), 16); + connect(ui->hPushButton, SIGNAL(clicked()), this, SLOT(hSelected())); + connect(ui->hComboBox, SIGNAL(activated(int)), this, SLOT(hSelected(int))); + ui->hPushButton->setEnabled(ui->hComboBox->count() > 0); + connect(ui->applyButton, SIGNAL(clicked()), this, SLOT(applyAndReboot())); connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); @@ -123,9 +134,6 @@ void QGCPX4AirframeConfig::setAirframeID(int id) qDebug() << "setAirframeID" << id; ui->statusLabel->setText(tr("Start script ID: #%1").arg(id)); - if (selectedId == id) - return; - selectedId = id; // XXX too much boilerplate code here - this widget is really just @@ -223,6 +231,7 @@ void QGCPX4AirframeConfig::applyAndReboot() configState = CONFIG_STATE_SEND; QTimer::singleShot(200, this, SLOT(checkConfigState())); + setEnabled(false); } void QGCPX4AirframeConfig::checkConfigState() @@ -269,6 +278,7 @@ void QGCPX4AirframeConfig::checkConfigState() if (progress->wasCanceled()) { configState = CONFIG_STATE_ABORT; + setEnabled(true); pendingParams = 0; return; } @@ -300,6 +310,13 @@ void QGCPX4AirframeConfig::checkConfigState() progress = new QProgressDialog("Waiting for autopilot reboot", "Abort", 0, pendingMax, this); progress->setWindowModality(Qt::WindowModal); qDebug() << "Waiting for reboot, pending" << pendingParams; + } else { + if (progress->wasCanceled()) { + configState = CONFIG_STATE_ABORT; + setEnabled(true); + pendingParams = 0; + return; + } } if (pendingParams == 3) { @@ -334,6 +351,7 @@ void QGCPX4AirframeConfig::checkConfigState() progress->setValue(pendingMax); configState = CONFIG_STATE_ABORT; pendingParams = 0; + setEnabled(true); return; } qDebug() << "PENDING PARAMS REBOOT AFTER:" << pendingParams; diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui index 045df39b17..245c3741ef 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui @@ -33,7 +33,7 @@ 0 - -291 + 0 762 647 diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc index e202df099e..1fbea1f62d 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc @@ -21,6 +21,7 @@ QGCPX4SensorCalibration::QGCPX4SensorCalibration(QWidget *parent) : accelAxes << "z+"; accelAxes << "z-"; + ui->setupUi(this); connect(clearAction, SIGNAL(triggered()), ui->textView, SLOT(clear())); -- GitLab From 4d5aa0df22ec9363941728ce7419fa35dea29257 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Tue, 27 Aug 2013 08:00:13 +0200 Subject: [PATCH 335/460] Fixed RC mapping check --- files/images/px4/rc/cessna_back.png | Bin 0 -> 133822 bytes files/images/px4/rc/cessna_side.png | Bin 0 -> 74727 bytes files/images/px4/rc/rc_backgrounds.graffle | 674 +++++++++++++++++++++ qgroundcontrol.qrc | 2 + src/ui/QGCPX4VehicleConfig.cc | 34 +- src/ui/QGCPX4VehicleConfig.h | 13 +- src/ui/QGCPX4VehicleConfig.ui | 17 +- 7 files changed, 716 insertions(+), 24 deletions(-) create mode 100644 files/images/px4/rc/cessna_back.png create mode 100644 files/images/px4/rc/cessna_side.png create mode 100644 files/images/px4/rc/rc_backgrounds.graffle diff --git a/files/images/px4/rc/cessna_back.png b/files/images/px4/rc/cessna_back.png new file mode 100644 index 0000000000000000000000000000000000000000..ae54c7eb0c03bff52b0c681bbcf940ac4910714c GIT binary patch literal 133822 zcmeAS@N?(olHy`uVBq!ia0y~yU|Gt*z~sll#=yXk_HK&-0|Sdnrn7T^r?ay{Kv8~L zW=<*tgN0yg=>7cLAtH92`9Vv>>=h#1+q;gg4-JmqDJ`}37@OzhrEk5&mcG29rSine zymO^A`|X$8R{2*qnzQ|3bhydP?_s0J%a&Aq^V@+fp26)}t2{lbUmW3ARC~)B`fzty zl6vrwn6JN1Ti&;PZv8y&wu^0i=GIw~p&ip!ubX>bW$NVRVpHb%c3s+h#hdxc>X&}H z6HlKN(mN>n{oLz^vRxdf-%fn@&+nV^{;KXf7dw^w59Eo;)=K{12|RNpdz-h&e)iu# zGPkqc`7HC{vKb50YNqM6bA&1`9#^;ZQ?%#oyP)-2bS=joHk&;+()70{#xqNtnEWs_ zPkNV9+QiLkCnXl0f2iMIxZUtSzuxT9FK=R-BYw|Wx-)qPf9E~zZz20S?XPeBBJ;s} zL;U)ko{9CWKl*=Ns$r^-5B#!nQfqttYAHR$;#Y#k=Q5i@a(*GD;;mGn-v+z{nu!wbzJ`m&D`Bn4^5Fj z&9|#;q2y^XuVWWqs@1Pet4bHVb%S;HJn>r-=HI>ari4wR@`n8$EB$9|GPh%|1SM@- ze8ByMi;J?Km~PV5m0s3M0_GV_IkMNy%tqDdL`&=8(}{*k{+EPu?p9j%KR({lvq^lf z?xMh@*2mWu>_53N!an#W;~)8?&2J2((}kC8FuyVT4TtwZtAl*3Tt&H7qFR@0HNJk{ z<6jygX5|;~>5oILMn~YeoA0H5o$deEHfw{o_7`RU3x+1qZ-o`ug)>UcFWD{6&bEKU zXLE{e_m6XL_ho07{3-n0d$&9HxY>rhW7`h>xUqht?w{NsChLT%u4xNTeJDG`S)nXz z8^d^6mG^c2gUAcFf^KbGy!6%2#tX`72klSTow>C0;e}QI7X4e9w<3Op_?7$CSuK** z%T#K$YPJ7r)T-C&|MlrAiQJ|1S0#4pzKMFQmb>5Yov(VMdVPGN@ZGN1jH}u6P1S?_ zPE|h&yQo_g{x%tg|o4BZ1?#Vd9E(IW_C(6{O0;q>oqxR zPVF#?z3SdBde%hr{8J6H@*R5*buU)g*R0g{!tvhkeXeD9d2-)HyR`p5Wc@lUBYK5! z?OTDb`=xHReekP!X1u7I{p+s1kDf2~c)~U@*lNT5-?A^gAKfk4ezBtAd+2#}7i)QQ zssHQDrL5zX{)=5q{cIn}P*{;8tu4&Jz`$AH5n0T@z%2~Ij105pNH8!sFnGE+hEy=V z*~@()H#}5t$G_v1DiU&z%uOZ}j-+R|cX(~L`S+h;(H@bdt5)Ylmqp(VtrcZaVq6!# z{@I)r9V#3`4!3WI*1lc$N^5=idafg@nV#D_WQ3?R)MmOe1^H_8AIvymSvlvwz3o23 zXEWY!{dTK*{a?A)bL!Vy9+z4F^X$%Nvx?vBymoI_$;+VRcEtn^38uCN?395&%eLp4 zXL2NQssQPBIM5Vyjh~0n`G9}{3s&k`UjysXXM8&)O1jSwU0a7m_j&w9!}g>JLP5~TF~`0H?S@}=6Je-7aA6gysigq zSCzl}|7Y>xXAk3D1y}LQnVIi@6H)xv{By{oHLT0bwj@Vvg((N=n!&_az5I&EgPAMf zUeDy%;r{Jg+?MT^ZJw>(KI?t;JHO(~((*a){+xGjcqGEQp3jU|c=dXidQg*7YF9x{QCQepMRIjm|eFo-2L;JdXBmN@4z}nE4ioEdpmbT%!R22dBuR` znDc?ApvMnW?;uQe;7~Adt&e_R@&Dn>^4b?GcD^f&J}bWeib?&4_kIlXXWvP#YnzJV zl?KHNT@9>DqZV#tg8Aiuz>DSs)|uO{{I)B*Qgixxp6ULA+hLzyxZ6u5Rg2Ad)jaPb za-!a_ljBDBIrHsr*FJ+ec9iE_9Zsx6O(H+&*{9@7IdWkm5-UPC@e9 zfnN#rJZ~HO3;=GmdM^ZP^6IXeo9ndnSnky%Nnro zG;VcPs6Q@JH}n0IlatTx{eJKEo!akrSFGQgob@*9t`@ST4)rWK%R}nd^jrpc3z}3M z6z&_g#y>l}xW?Vx{cLD>EURzD@hb-Pm{k@70dxgdcrl1 zC)Ud}?%RAgz|4EDzvhYZY*3uPpRvoO{`cl@N54p;6w5kdjJGwnM*KOu3!X+Na$G6% zd1xD~?msVQ-EL{(-YVKt@p_PlA4A?-)fHxy$^&+_D9*!$a!8Z&`A06pD zW_yZ#yRO03p5Amjb8*fU0Y9Pnmg8lIw;#aMsEWUOf?Ra}dbcx%v6#(__mbKTlm>vvlY0ce?}SZyRn6 zTAOuF3d!3BQjE7XO{J6{gF_5l0X0f0Jt*^;+ga`-D=TX%t{3y*Zcun^spy*I<5ylv z?n+#RT1GwVX?QzjmhpqMbFk!O!19V?$MG-c;tG$7o;`QY&-o{t^|B9rE4#(@&EkI? z5?81=$GY*AS5FpF05&LYFye>^$V#1cO2!lxuh--ow;j0B%x`yM|C#j0m0#a8hdCnx z>V^!9j>cBY++0(*hA^has06Ov%RaQrhKS9G>P$0HM|P}4XT#p$EEShyNXhQAOM~2b zYlZ6NkIH=nd+X=&_kRZG0qbg!B~0^W!O0k2JZN_{yqywtvCVip%-F_K_XXRMxk~No z{#dZD_;9-B`T6&k{)J{Ry*BeH?9;{siSRtC{B@5qEKwGFd_kR7_r?Lb{^einysBP^pQaOemz{teyt`~Cj? zI}08WTvifbU3Tti z<4Sh9iUUl+mzi=tp*WR+vAQOoZNV%rgi#SPOgDI4^{wuA*H7i||0HW&)>9r>`&2tV z^W1#XpV4Y$yt6yYul`!If$@Q7Rh8kGg9D) zGnM$;?^WpkcJkdlmTl)Jo^jN1|2*MxVcq0QVpDD{xwdT=Jg-Q%IYcMCdhud~W!;}0 ztjo;S*hfHeTSPj`i+S7qzaGA?)K_a{<=K!XxNlvPFK>+On&0B-(y~)lxrBV?_Ow29 zsqB_--wM6l#WRwjVdvf2z_v`F<s;KQ>{^q zHO;11I92k5a^LFp`*!X8c58ilo_W4T zjl<-uE{{6Z3m7iJA7_tW?IPM^N{rghu_`W?{~W{#vF^5HWtmZmS#HL%+M?R z`w8#Aw9-2!+DDg#3phM@Rv7<%M_RSJGh<*t+w{6j1s9LN3oX~$eWV#*Jf8o7h3{NW ze*W(VeC!z>edm|3%zDJY8FLq8 zHePsd(4D|H8w@Zk*TE1XE4c&6GXSx6M`NR7>feb-(*nYL`@suldEl|Fit8 z&FS}rcbE1VvA;H$9x;1CND1>tW?S~TTW+pcyyr)IoDMUa6|bxHPW~sd9a8&Wdw8vE z?kQH;)T%JG%veNdvQX67fV&re3jR%!vweK%zzWZ+uAG|>SP0b!$rLDh-kZD7^`HA5 z$^OZe-*?|Xx~bOg2UDuLk$vZ}TVLPQh|Wzi|F-;`_SfW@9{o>dKhwASBVHS0GViHt z1N(c|UDrz=FDQKTMXA>KcH4nAg#zJMop%GjaMwx)rLJBEPLRHz=idJ~cMDq)BmZ_b zCjpjhC6$bCOF5BD_-(~g1;#c9<0FlibE-9%97ytO;^Tv7iYWwPkm*#FWQFv~9T1eE! z`s+rE!W5rKGvlT=DnGgVHBH5azGAQg|WILh0=#t!CqL7FCb+7h($i zDgwRcE_tirwW4^dtm}-`&D(w1U%V9y=~DKYHS=ZV7JbvtDyB0Nd?VF!jf~&^OB6U* z?WMP~k@;75!(8r+s$JdF3L|_&cW?7&Q@zyc_#)r_@5^&my;?2)A13}yv6kw&Y;4lt z?KelsZlMPM(+Or-}Et`5~Y3jjMyrCr|mdGFaZ0 z)Bn8HnPX-)k$n$*n>Y|1$*ws5v#>dmg6$0sD*w+nNo_}qAZvFt;XP-{f>M?FoQof}>_%?mzz@#x`a zi{*cNeE!&9zvtvV*V4X0zp}mN^mdc~SGUKy%j&Sq z|G{+0ro8A*NXV)>zh4~bLS9NCQxa0|6^W?I?g^Oqp;&F9N?6yV#-^0ci8{e77dCxT zv0k)}^Zk^WOxo(>;!7)cx&a|E5lWU`mVQb^f&OoQhHVMWv zHU7kVEqK3f_q$m-3)&42OCEUn;ll*xs(aJ6zn^j7+{p*ZZ|c8oo}c^g-TQy`-`0Km z7<>Qglt2F@?i$=?U$^8)dd(t(&?zD-T92-^{o!zj~gD?ToVZC)CwSGYu>&l)^)HtlJbOf96_1*SckQ8LnT-W2oQp)BS|< zQ?bqSB0P7by?Bx`Z_{3(uJb!uczkjU+)R0viN;SkqGe?pc)Nf0y1q1$=6mS?3GO*nI9s;j@7aT*JUYs@Ug5{v`~SXI7Q7NUDbI5E z^xUYG3#M?p%~kXG&hYx*zq-%P_CJ#95?{XCn9OT`-usJ^fav>aUGoK}hPAGGHIXH@ z;@dQzhe9(KwQzQ}mHjI$=|9ZfeUZhakinI8;Q|#I&zC#uN?1+`DMzYpoH?~L&HB|{ zO>@V@YVC53*^BEZCwgq1<+EY&rMIq+XDfAnY`rDBVoJr=z-U9=^Um8Au>RjO?}S^; z>CO|GlV%2;Gnu~W_nkdY6LuJ7zImQ~GBl{>tW(p>OEW$6cXq8`IW1vPeV0!9vCTQV zSN*7avZLx`*oVH}FP8+lw=DAv?%pI;v}~o`egCkKM5nTk2fHh(Y<8YAa@LF99{xOc zx!+awE>`BBE?kqXc7L1QaV*c#^xt^K)?;Gy3v!k3Z{)K3E|!J;*|Rz3!Vbj;=@Oltb_Ie*`(M3Wus~SxzJZU%ip-7Ajy-%D z$8vDjJMUW$L$-ghIxCvKo=^4hkB2{nc{~3dISh*V({(D-Zq-U0JbiTI7Y_TRYwJpO zm&*nz-&*Tj^kz}#pJvhR91^!5urR&dyT&ZBohF)7y=GOq?o8cdp%MSH)`V zoiev5t<2-&r;uCMH}!k(x-IH-r|;(vP9+h+yW2M}`&|6Rb^3~rLZ9+{Bo;cq@wxuo z?`hWo7Qu1m6Gx~zvLw|Cg19-T9Rf-#lFH-O{~YdHmi93P|Bib*Ni9rC!*Jux@dO~L>5s+E)bBeNcd z$Gp2dGe^H#plovH`gWncDaO?k-m9{&1I66BB`-a5{j|(CuD_Bs)hpB^^KXbo@|(Nt zM!6?`E!-cp?V8HIgukKDYqNr089!Fu=BoehZMDzkX|=f$@m&rghZi+jyilE7d0zIe zv`Q!E{`V4jRc1=_r9Q6;*LQ5bAXR=Xr{nE)n-Y1?Csv>Cc*oqIXyW5>zw`8~wv%2- zE6y#wVi*yca^z;_o0U7%Z*$BpEWB%X;d=B=exXXk>ye&QmUaqGnbPmI$?mOArEcn> z!jzs!GvV1TY+7m)xxe7+kc`TcD_q#S~or%$tmHnjcW@7P`d;gEmXYc=ed*6xSxaO|;vISY3 z_S391T$xYWC6>+lr=jq*<=OJOSIhsNTao;0hn$=G_X;^Tt#`pC)7q96FP(f+w{gp> ziD&G)gPs;`7n+`%{`t?O7iVXjXtg|>@~PA4luDGvW3{AD=qW^`G-oCh%lbTGS{VESPl0W!9bv{ys^&wx2l?7EzG&a#j5r-I$iZ$xF&Ev`$uJ zdn_n>vRC#0w<(rZc60cidX#8xEIaq)z$O1_JB*I$L~mBRrQIVMq~757D)v>*|(tt@Aqn;)3d9uU&QeOra&o2lqZvvOU)>zZsM#t>5R=eLb5W^xIo{ zM%1kZQ@B0mvNrvg+ExEi|DW|O#jTeWB(^&5cWONTX@}ZS5_+DP++Z| z`c^Vm$4)(Gfl7lLo8B6AHhHBLo$T6Vb}7Nl%hib8`=#f(beo9WIJFWnZuuCs z$UuoMmH8aIeS#jHRS(gh=A+}7`VW+2Gt;u4>w3+2ARDCnZw{!zR$-@d%lp$IzjH3> z;b}>_aTnBgo$-mimZdu1;!u#w=eEq6gA?!A|EYMgL&pE$^RDjTBkNN;>r}E3z~Ro%z` zt_e7<)DyqHr!*~cuWzdcw5ta!Txd^wiwsdVIYt`{ED9 zt9Ng4t>X?X&y&eA`PnacW$oH6m$P0wcFR51`4q~Qp7&_RftO9Q1Sa_?MNa|6vR?RF zuiZI|GCGZmS0B95_K8!<;fiO}Rzr!Whj@g!R^?9&ShMSBpHaci**|o0C-}@gdw$<7 zyNSg2VqLu%{CXR}@u$+~#zsF!jvVi8?1Tx>}5mU38Q? zF|DX?Raf-6(s<+RyHh7$V)?iv<&%$nzS{NuER&=Ij;cCD#yrrwb#_@Mu>&z&{NCw)(^`K!C;q<8PU_HHfF^$wAWQ@gUauHy*P`F1%} z@Qv;HbGlbbp4wd96Lz9^Utjt=CcI<{_7ro&Gs>A6)IP)cl@2|4u^mpKoUO6kXGKHrPC1 zI7d8%)VY;%ut2~FIQ zu%g7;M>t}}&h5fKOy-@qlQlu&6mw3{iTU&VrB0oly~wMwtwZhPk`@-%cqh>)-4$(( z!dYI;YizD6eOopEj76+^aJ1Ez&9Zmv-u0epn0zO^guCj@V+ov}9tKXaNg zKZI}9t4*THZnGGf7T+#obMt+=fFtC1x1(-O*QOMc*z;buS?zz9mFoX#U0C?w+Utrb z&8Bm8UO&^@D0jZQ)cf=uwV#K)pG)dZc)}d8cutn)_ixdsrZ?LxozBcJ9b9G1?!o?H zgLA9M%UiorN@6GP%H{nrX@8mEH5Km%TD!EGy1BVr<-%juPEcZ0(Voh)+KD+1l z;Btjh^R)xMpM*MO&(57wylbuLx6tM^&EDdw>%CJBO~^DxWOC-ngTA8EY^Q{vcScOkGt-RsLBbZc#re^-S~}`2DwkI!@8y2f zShhF&R-|?FLg9G}xq06$6f~{is=ruoZaSxZ zYwvlj%kyL%T-VjGX%!0xKU@AeVE<*F{#{F7N5_4g#2F>~x_pW3zp$E>G51B+b)Dl1 zw+~vj`VoVL+NDszpzO%N?$D>}tQRbuS+Fc>=ON3;H|$04MQ*;{ws2`4&%s~ai&~@} zOluD+saZHT=*!w)imZ$HGM7)Wx#Zse`6Az{`G0TLJ2$S}{otBr)%h!oLfuwka#I#@ z=grru|MhD1`g^~B&aQ844%}@m(sS#ea`mR*EcV+hTMHL4Oo`cYMdM5SuP!rz2W$90 zoSe1uRFLYjTdQQa+= zBDkFRca}-&?|E<}#zyAOi3eQI?{OtxS9rN?@zP?xoqzr`n0)`mmuVp9)pjL&7f<6) z#e}^xHkwHsdsW1CJ)$7jVDoFu!1m5bl6tD^Z=Vtu10tqq7T*pMUm!S~54BY`(*+0(tfCiyI!`uB2w%U0XPZ)*H*OqwJ& zb7jl!FXw#e-{e32tuMS{9G`-X52iod0NJhJi!4+r_l&b&t}FZm6}b^S+Sq z*6H}EW9|p4LbTJQIee?9E}ptBxvR3$?x6g~)vSk_HiCecah{GDR!dhR5duJ8=I zEGT)>$0B&H;qIJ`6(wJM#8>S7V)^l@#l+*E_CM-d?HjUEBl6*ThD9+m6Q+ggb#lJg z@rZ4v!L8`hn(Ew%hTsS7XMZEYkB>uo!JMimx+l@xzupQl*8li zqwJsIUsWVr`(MAk%pNQhJQq(=1A6|F}rRm%4y z^ftwAT(qh$LhozUx`T5MZNJE}F6!X4E9^R~?I(_&y^dP0vMucl6ZoNVL&#}T;KbHB z>F-XS;W^_|_`YmK)dYdZJf%@T^?!YpHhi+E(=-2Z_6dpjYuORDt1m?S9HzcnVcH>K|4xiO zeA}O6Y-y|Z9oT&(GJ6szB=4Drq^m7RnPdEr@0`L_V~s1`;TNo2v+AZ*Sgq;{!N zO#RN?$vq`5CudFLT6<-pX{p-fRLA4u9RUhm({-)(WjvT2wrh)b*L`i*=Rc+97ZC41hhIiRZp&X_`_zBVw#-E*=b9~`<70B`Xx1U!k5qwoi6cCzDB3an7$ur zI~5{Ym>3ka!p|#o=82=%-$@j4W-r{QFvYHE(gszjnep~QW~$Gg$NB6Gxc|pz>i5zl zrG1Vz`cp(&PME(6_!OT}XwY>`x!c_}AawFa*2q+YM;ACGo;WMdTF=XNJ)bLFmT~tB zw#_yDP2RhO1xq$+d_EEv{KMm~Kxspt}d7g`P3#OV8!&KSN^RjGA>GW%UW5ye3t5U zvvmJTVUER%)>y0L%nc7-qU@FS=|tI-v}02zhwEEiD_CahQF=t*rd;2?y#Lcf*B9%5 zhOf_iw=3K5{ft@F0a|<>d*79=U;bb+w_9Prsl9jRWF$UZeo(_?LYYF-{D0}WOl)>3 z5#=*q{o15b)#Y#TGib5?hc$K&yEOuZyuHrMUwS<0T#ER#tJ2voYn(i#IL@^N?VP6a zex)7bJtqklJE3hV&5xQCoGLvR?sN8YXUuq|dHw9Q#M9NUg*dYpnm(5^nLk4=qzv}MWMreyy> z1})vQt1mrt4-ruV8#k^iW8?KmMH(CGxX>>;Vl|Gwo&*QTCzI!}meST^F3RBMH zMoXy$N>Nv&0w*Q*e~PqNr1Ol;i$!Cy&gbe=6=w50wyH_hHl}~&jCbkOGEAFMS+!2i zC)Y>cj-7jLLS(A!FAnQn2Ew;hrgNqpov1U(bEUraidK16_S0hDFSxAJV?LO-t!(EK zm6JbK@l5d8Bkgd%K&wlu`N46?C7C{-o|Wh@HLj3Y7SZTkZRdSPuJMA_=IyCs%bX6( zS|wh?7OX$x+8oWOlWQt{#pCue>hI7CwVMBAWz+8m!v5VE`#2NLIj0Iw-*!f)@|j`% zi;To$w#M~_<`=iV+ZD{&z2m^@r87@Y&AWFEgy1J&A+v_Of z%ILgG=Kq`I_FtLP6d=`e>)ySk=R7(t)i=goYTD>_HF=gvGtd1g-#8bxpWk#KcvW_4 z{HsuvDJqL~R1E`T#U>|sei4};@Yg~e8UrTFj~wDTzobt1YFlfJ08iY)l_na?D(7hD zo;$kJ=J`v@g!euEQ=+=^CVtw~@Y{naF8PG&n$}-U0<-5>*h;VEayhHJD%G8V%XzZQ zlm(1l$5mBSY#*g9eDv9>JNWaaZQsgx&TY+qq`Gp!*DX8Ej2IFF@%|h{RZ^dqV7scONvoo>vMrO{#jV||fS$Vw<=V?~`w0t}1koWng zvB5WNRo~D0b%6ce{XPGt#kU=ZVG1th^lELmvi0oR?YkPLyz6^pYz4=jq?ngZZ(6TUJfR|)s@WM=8u_H< z6qEl)&a3^KuS*DbmxOM4Ak|=C?#%pS)`|$d^S{klkj!WFGNNTokBgCmXH>_>6;HlKCAkVt zm=+uO{OnshjvK7612^4!w=m+rOVQ%E|F6!iZTnc!baHC-wHW!iozJ5a^OknI%-pV_ zZyqS%vHHTMU{CS?d8eEjRm`mmwd;9ZmY(`_N2s60xFDBJtJs14%yHQqhpmrSDP72D zdlMHasCc48tN8D_b!LywOKw`EBVD+Cx7y8F!JyMe#tG!OXJf3o*}tz5g#v*1(qd0Eq^ z=cYT^7rdEwRozH1OXT>g-!sy`a-KhUDEeUIGDUG4X)nvkpPD0rlYtK64K<{g}#i{J8Oyh}_dB_9*|@ zGS$4;WW&n7Ij%3?KHv4&hgV+5PD?}V*Angu*Hu4vADv~ltL@K?*P;hvRAORM-)@~a zDU&%sW&Mq+=WaK*d}3ids;?N8Cc^YEOa5r)(>8~mhOcuZdY5|UCv0AmJhjs7(Ys8K z&v$yXcJ*3vv#$#9P>pfO-1~pw9p6(Geh;4s8|}YPd1^*S?@2$o9-FiUMN7_}loYvh z()3J7ky}FF`e`aJ_V4qEd)@P3a*jZu)LqV}fk8JH7nf)1+&O2t=&jO04auJkDb<|D zZb$E4Q#y8rDP8$t*tx*h&30C|UQL$n{hShht(n6w_u}Nth+;wJ^$P`-+*-J>L*q-_ zd)>PISHg;SxEfB>eKXDJ&C?Z?$1cx1=zL9gdr`uwwgU-UX1)Wp3RmaVlz#rQ+7ht7lc%`==hB#AY1Ye=geb{RLrBSIARPLOzJ$+zed5h3mz9T-VQAZYaJ<*wXPeU_X!F<|@%LW2VwhCTz zy(q=`+wAGzpv2`@Cf+tJ{n*Gpd;8yC(X;LU9KNks(^uy6R@v~2;p+ugmP+T>gnsT> z{@(O>pKLj!#;tGejVnILX}UaO*wj4R|BIuF->;+dr%Y#9((O6lTWsM>k@{%CjK!%o z?c$$aomM&?ELPFwUs0;}aO*Fo^RI;Wolw2hq%u7vWSxrIluN8aJ{A!Zm;Y#ab-g(9 zLFjbXQ0Y~f)1I%=-fUoD?!37`&Z_qH*;5C+US55cBRw@OcxK=1i#a^A!kiQ8IL>@e zniaoSEaRj?tiliN>|0f5&&CWDg(dxzhL0G5(t9$1R6_Xa3Ec z&?#}ZL_kR@;Zm_f>XA8yo2REX&k78j;<4dw(h-r&ZznxAOf3$%z;Wu=3(3WHYxh+g zXZH!vS(3Nj@9VVK!jRJVB^yQS0(M9QKe=d|I8EWIYFGb*Ks!FakKN~EXEgmwLU&KCiR?}a-?NaO4W%a&q5o{EmiXW*x506a%y9Eyx7x2%+H_a6(sy` z-nH{;N?x1O-DmR_C7$XHDK^h#Gv{G6|9E3Vl)h`}>&bhU7Mz_EVa4*sDR!6I%PX6}XE*mWzDdkaFn?}+ZMTB(J>g@arBfFQYwY<~nw=uDJ$&ol zBgzsRw_G<&`qUJtB$V@1My24&Dq9QTjV>nx&aFK0a81g+n??yQYzod@x6NHI>Am}r zRd}ygqq_OLBgx)3Y*igsd4K7yY2VWOO6b4Ve3q3@Twk=GtrgchV`5-h0iK}^a#&S) zSo+?Tn7W^ybzu{m14{~zHfrXo$hRo*u)1Z*&7a01rPFZZ+T242-Ui!EJpJQ?TbzN> z`_Nx5zAjvcxsMsiap$BqxFoK=woH@pyU6?#SEsSAeN}uh^V8CsnOk%{%5=33-Z*MH z(J(E_*O@REIg-ChYB{#8~ZZhk}bZj5vc%P3~}CxAn24q3WSP zHKDwxa-tTm7B4;@YhR?`<#tX!x!n&C@!0|9q%M(VLZ1imtAVS~cP7 z&Q~G&-qJ26dIuNt^y``&YdE-6aLKL`&i7Ngnu7IeODZ<*{Qjr)*;M0OhNc;y?#JD# z*XvFAf39l(pj=%MlJ8xg+JA4y*3FOg{0{j&SnT)m@}voQTA2?8J^tQ!Bh2`!r+G8u zi#hy1Lpsm@bn#6S+fu!Pi#&{UJ&HWtT)iI8 zJF7k={CsNT@*gdqUhUNRFy#`f`V-3#&ljwzf*(UVRIn`K7zq0t*DSAVttIvx9qH&yQbvd$Xxh9bIR`z2Uj|L zDSI}1#hl+Sl$j>dd+JK z=arYtD_3gIZ;E1@aU%HV{LHt3%E0=a*fOit6ev0o@#$LTVL~(x7q%bc|?F0b5QtYzLnAWmCnUS zMZ*I=c*dvneRosTJ-8y5%j+T6bTtPnoi9$#+=el~dZy$vx34}wz4O5PV7rOM%USm{ z_jdR3r>5QF676$cyW?TYjYo#6EGsRz z9?am&yl`-Fjr*6?H8OLYq#Cuj{9>2LLiXc4?p-fqVqlsQ@Jfg&X#1Xj*PbopugxgV z`7U9*>UmSZk5*eLMvMN~;Hrb4ul7F^xnd&38_?Ox*D9E4>$K!R|3$lnHdTDAcA`h7 zYFbsV6PUxfq=Wxtz=Ke>pkuQ?g>y}x^<=dx=k}BSf4;JA{Qcs{l=9s>W*lXn^69AM z`Jk(u=fDAetz*meSKKzM{eLJ;*Wk7}s(x&OW^BgR$=P#F?!S7rge$wK*f7Z0CS9u6 zIj`i?{V6*WyJbGM23xC|EelKL;%QWMSx_b)?__><=~>qUYzgJ_Z{N`~m_O^fwUjBtG&k^Fp)H@!#qP7U zPi8Jqx=`cLHBneZRUy<#QtFJNJInk}od-mN6pbF-tWhfP)Drm-B5;0&E&Ju#bLvLl z9^`UN-}33%rq$ErV-24@;Af1`=UADkwZ3uPfqB!MkC_KYJ~^Nb3Tv6w_LXbrJ&LS7 zB)-!n@`0wEVVloOCq0|geOFg%em&=3(;>A)xv$TE1@qFU_RAkP>|F9Z+<)_ybsS6f z=Er7del=ndVli8CdwO>l3+w4MyiAizGNPD1u`JuCF{RQ_UwN_TyBdYzk#BFtMxP!g{z%jPh6&)aj6Qq!@2!+hW^Q(vu4&Cq-`h6%&pbBrFvjS zn8{1-bsA3tT$Qt~XhvUOG3)1>2rq5hl(_*XBZGuypRkxV$$0sZ$Gp4_d(K_i$gxp$ z(L;OPeH)Em3G7~SN4e&YQpxu0SO0#$e}3Q!|K1<$H${KB?zEPx6t8=*xPBh`sD6jz8moLkl!oCgL&cVCO*%b=C~KF zn}2xn<*)q*UI*Jv^j_jNbL~{|O$#q94-%coc>bWt{Lh^orcYnADT&Wkx&P|0$|*7B z#p079uIJAUil5FJajC)12YhYt(Xo~U1RvEj*OiR)qec6moIGM92nAB~ApXE_!5$?B@!%I;n@PMOye zXXc&V93%1LXL=-d?lcPTIWW%kBJ?{_w z{5`Aqy=_L_$F2JrxSw~_?>D$Q*&q~Dn*aZ`yl&Uc`?vG;cK&oD=jngUbJzJS8>W2t-b`L!ABNVBfd41<-F*7*;g_jd z-d>G6k~M!j@kgqM6iu6QNROjW_o-iT=+3Z6ktwE{B_VI!yto_Z2pki=H|=1ukB>4_ zukXK&w%fD08nym7$)Bs}dC&A$>Hf~|vL@?m-|8PaaHMhN-8*~tRq}e+{{N|;G4Ef` z-e*rvo_=xk*%vuY9v7JjhZ>&5<(=#Q^mfCmcM2j4wg2yxJ}~=w^4ey@VuStu2ScXH z%UCSAuzBk1+Qi3k)3mHUxyf|fd;SeE-@NphO}a-%;`wK?Tr!hB$;?T;d+O4w-M@4< z%?X}#O7G*&<4Yqx*7a~{EfLjK?VMq|e_Qd%t0f{w?^wNL@V(Xg_~IcU(nY{ZNVx{*r@^JAV2ltrH9L#zOysGJQ>X2E`nZ&*U!NoE!hdBhz1)jR z--OuYew|O|JNM=NrE^Qu+K(wd(VN(`_N{Z(dXe5>mF@*sJ|>sgRj#c3b@|(@?Dc=w zKASxM&l9;`;pHpelsx--;*E>-(i1oAGVQ9*nqD`{ult;P)>&`&9?QZ zWA(u7FO$5L#?zEQ_jH+$i~KHyBp!1+HB&Q+>9fHZ`JkZxJc6?>{&Ae?|I@{{TH{HG zL1-f1o_V?xtbW?g_J8swPFdU_T3bKDX`%m8EhXl8hcA0|>Cdt=41Rif_x3+hObuHd zrvLI!W|N)qXGilbdFD`Yl6CEIwXf;mpM zdcv_K0q6d77D_Z~Bt9&XTpp0nuDBtMe30U zjW@i`t%wU%bT4UISu-nJv^;0!(z;Ea0iL`CEVolFZpcncE=u*Dc_eB=pRTe4pH#1{ z728G2IB_q_9~nMYM|QLr_Amuo?6#?!%D;Q*x%eFy_WTjmcTM2(@}GEyQK+_mV{?$A zLaFcP)%knY?);-T-F*5*y_IiczjIgH98jF(7I1-YrEK4-h0KRl8DlRobuAAT&s`AFyLysa)aKXeivAq+dW|od^BW54TAchkSI#;4lzDwR_mVCjjVB=| z!YcM23)t)TFW^P6qpNGZ^hxjShB~sfX>#X%KCV%?!a4E9^Ocj5bM(#zPc~T3Rjf7FKk=8d&kQ9+i=)A+kKDJ;SraeQbW~SI zkmta{MioAT#J^9Q*gSt){M&Tx*KvoeSErUQ(p#S%9GWfl&@g|+mExNFjW?J4e^O_0 zSM`;us`%8-ZRa*TzLc3#9d>P|hwjpyHx{eBy%FSXn_9f*Lu+|m!}1ul%5`5Ry5G9% z;=kl*yEI>i$jfC*X7pvaIGo#W@5Lt0XX7Y;Px`2`kYApS(*iDiOLvB@^HOsb9T2%z z&u{lbfqki7jK%#uk3{ve?JBSTXk6(jci)=3z5Yl0|LUstD<_{FIXU_4xs9=0cAoCf z5~gswyxq|l=ukAlK<#243&Z1bC6@+HnRSIN`yTIe_1O8qm*Lt$9hYA@^>_RtFD$sR zO^yA#;6BET%DQRynCj9#ch2Ge8E`_=Ff`exVr%!tf7i}QmN+Y37w%m3{-D8^i1jh$s;~3T$b*~I{R*%pP{6@Vag@-zvar4-aIHVXO~>PB%mUAXNCCG zjP2(S3J4rv58kfX#k0*f^QGtOOxu*8Cq8+s0uqL@kzGV!hXIWN+QCQ%apUw?~_=sEXO_X(>KM zrPO~|wd-mLd)``inDeA#*e#xw4&2+6rBqd?U!Bp}*Wdku)$j>J`+=W6^6t0y2y<0c z9%h_dp3&p<>qWurxS~22qb<>|1UAlBeq@`~moNLg=)<26{Qo_QpFNxX;K|J^ffH`^ zZ!Gf)Y`0Sgt+xNZdHL*go5wHDdfIF&|HJb4l$>R2{4HmLt_!ypmU}(y;gCD$xqP|X z6b8Ff4yDkWc?th77G)oLvd7FB+X`)9(sB!v&v+Z;~)xXg5J>5`uN*>3{R?^fHEUaFywmy2NZ9lENo9AXAIRkF`i zF!>o$Tz7X7%bZBNr_L8Vli6fy78!b74|-|E^;%7`{*U+hOa-eWkE^#7cV+6;&Xaq5 zIB(_meed_4J!?L{?P>9nYWdDU_xB5?uq}!Eap--1+_z2BKPy*P?EI-`yG^{wzr?e^ zflJ?FdbjiTS((ZT9<9#Oiu&U1rG}c8awjG?G&PA$Ro1KsYYJrMen0up=J@)z*Uj@QU*EP+D3yFW$*PRUdSRKwhuo;G3l)Ft zX>ORpvh-1gEc*fu^_UooA5M#G3XAOiaxienPVKimbwHT^^1}Td8CnxpzVJA;FrL$N zzS8d){)c^*kx`)&)}>7BUJ&*~e#=AG#JlZNs`cit@ML{@=GsZ_p9c(P**|WrFldh{ zW2sByzS+ZnGvGzAU0`BAPqo?n6(83t=Wf-q3C`dBYoT=W_o4~_t6vEjLglY8cUw3oNoQ&{kxaVBm6;d^M(t8g0E9o zHRfCs@ITbXd&>Ix9nDqQ{Xa8S=d9EX((ybV6!lV(n|JHa^7#!xino*cPe}PEv|HXk zbeiXv;&svbWz%OExjf%+AfT={Uqkp-F1K{ilm(*8YdCCLgABM#G<}N%c|Xbh>G1PB z`O|4z40q5`!x=aB-iY@9Zphuczhy=z+v*K*?lR5IfgB!z1zh^p-yJol@B3d@_0lq~ z#;FxC2wGql>&>|G_PsyXo_#v4H@Vz%?v5V0%gzd1 zfl=FyyQEU39kra;COY!(&K6~LZxr63$bXz6&+f)E$2klFDg^}@TCYNm2p+d+QPv7~ zh@4?BQnPeJn@4-eiHRGP?|X*$--?`atG4g;{HuF!ES>s$?JVb1OVLfICd@s}t(V-f z3EVt9@@(?L3(K1<&x;Dp^FHLKC>>FwCGu;Ef5kG5K=V7ALZ1Co=X74$XcJ-lER$jC z!rh`1R#{Z+bwx|g)GJ7tW+pY=4v<`lEtIkT39>FFHx z+9hn>BC{?}%lVsaeqpKkgjxUU`k%yX+Re?_!q5=^e^YhDcdnveB7s|@`0j{2HVL1~ zd~xH{j4xBv4>lDqYM4|tBXe<%7w5cZ#koiI-hZeIHUDHK!1hn(q<562MdSCB(~h~U zIvU#;+owt`KVo0de(8YpMIj&NyR*BRB10=T32YE}e?!Yz{7WHcYO7E|YMk1#J*$Gv zPbxfUQRa7P6#KkD#(EXsT}kU@UoP(J7U!S+`=(;Y zK97_4-oF2%EIwgZ&$;R5*1NwH6|dsdTk%$wW$A^2P0n1I2OjG0;xO3Du+>NYu`*-% zlY`TY1g7#IlX3gBS2(L^W}wyMgb9<6YhIekzTZpwjNm%SCWY*>j2wHee<8a>&b*em z-grvszG5}!`%6hteXP@~zV6kJQa79xZ&jY8I$_V<2^_6+PQ4QRA=K+rcGWv_Qp~d5 zArlMw&y`r2N7bB@S@?}vYF_6h#=pU#?}}E%hrV2}R;lWm^b)>1UfVY-ZurJg5-*h< z|2HyxgPq*jTdQ8aZ*SP@XFsPW+k)klu-44;?K`d4SI#JXVY!0$$K2dVNui9TubEkY zzEiswI9X$jhR3PcV;iTgy%;=?h5MW$v)3zQNzO8({Mwn17fdeLVPmv+_xc#|d3)<- zt_Uv?WBa$}Ly}+r@?8QslbUY@$nX4Ix9G^vt||V%Si&`)ESln9#avqX$lE|LeNKEF zXYkRw3+gUk4W6!D8(Jd!*yo4vBeRc%opOf{3nsBC3b4kMHuteD5m@3R&@F%Wu=Uc6 z4OU9B?d|SonfYxFFs}S8u4nT6+}`CsXV!l<4yf(>@qOY7*}41oxi>Cm7P?h^k$+DI zQ=ocg`xKTXee(8xjT*cTiW;p9AvY9{3c3pQICeDqKRi@=*0CbX^`XiNMJINyr(YA@ z&RvXtc=6?zFJ3xKOyL~FF`Rb-BzfH^Ji#3cK-GnA3RU)oIP{7X#byHN2rIp69!+J$V<}FgNbylXpG3mW%er#5zq?S<1ZU&H<;FH=g-|PJg*3+-NE* zc5O?P_AU0creRwiR_$0j`P8P~jeR!{{c5W_D^)DGruIYk(>)nW;@?GgE?#r(NFM)+ ztS$UoPB0zXl-6q&wIib~Z=HvTCHv`VFJD@6ip_CmnZmX7V0NVUG`VKwxZ}#}KPN6J z{4!tMTmHGfj;hva&ae~mhh9gjNOyIIEV=#hQ}x=Tk!&IJA0-7IQaT{G)P|*z?bw9R zJQsgiYkl>c-@z0v*gI!MqMk{G#K)kZHEt&Q^DoXY{K4UCk@eRk-~HhdfAJ-cWCPcD z)y?F8Dz)LzEb0AHx86M1XuBjcp z#}TkdV_LlnBy=#77-NDp5I*tIzcJKxQE|bc%|Bg^Je$05La^d%%S$c^4?+y4Zz|OLP_@nB)f4wb^=#K& z=9y_-)zuqj^}GwxSl{7r(U42@%10g9^S>Xav(`wxnYjOD zkFnN<6m6zDx0wY$R?4a$+U2@`4u3X>mbc1ngrZu zJ3B?Y#%s|6cFP^Evy%%J-0Lt^kW;j@3N+f{I)%$Kago0PTagE+TOXsk6^puG;XM02 zdwwitZAv^9efgwJj@gYgsny=4UF$XFD?Wc)^K#F}tLs^2hOqpM|NV8l;o7&4kJr69 z?ku?V^yYa#*F3A<|9@n#$~u%CUc#Z@`=>sh;V`a=>Cn@ zX6N3RsVe5=&@Fi8mg;vUh8GLJcFqz18E|6dgtZ3CTjy{;v-)Wpy=sxtW!G6=JG?(G zNHzXkBy@D$>1npxmuPTUZ8&b8A-npJZ`97W(8E#;%2{r;f7rSE()9;iyY6hy@;%}#76V9o|iEkHXE6?Nnyu@gJw7#RU&P49Y1D@s{FKYDas@%ohJ@sEn`#8<*{wmbb zX(sThJ=uHb<*QO5t)C_^O?1j|)c-B`R8zBhFO&EGDQjYONUO zZ#8rJ{i8g%*mm2U?52SI0mlV?G-e&tU1}L;#Tueq>EDxK_mcbO5_R`)s~y#ZCjXUm zWV(0MP~b@+OT2QNSJ%^yXO+RXyH zvew7Mt?EkoxlLof{F0Erw7&A}Y8P|Hjz0nucfDR$9rXF`|Fh+rEeQyHm zyiW%$d0zOnG>QM4Bv2cf(DnW8iLH-aiexJvc;@qDElg+7-9B;0)Z1rXA6+OdKcn$! z+(Fqyp1x~ASMnZy^3tCoRehTw;3=!%-$UYT-t(?Z3s}gq-7DI`?vPQw|KDYtIe&O` z7DbBHyadHH&_9F0WCXoguZuQmol#|KU!b%RXn;n+6)*y}P7%Qwi^)(DyGl zCwuR7FR6PzIm+u?$g{Mbc{X_knk>sNnLT|sanhdN3E-ACx8}=|zdx1#y4Lf?d3aTP ztdNcS+}zw8P_d}XY|D}v-s{9tg#NfJK6g=3=81Fl&dgoOWilmQ79kU7-&dA4VU2cF z+A3PnyuMNF4ZBoyLaF2PUh{t`In!!qC2x4iBi&<{5nE$*O3ZWDwNIaFlWu8CsH@NE zto3LLN|8BsuE^ol{lD)&osfGw;Sl#Z|4X}<7zDiFTlxQs`~Q`e78bW_J~aOi|9r8( zcFRSMn@{R|^-nUcdB2Q7ESBG^Ts+V|khhtJmQBD}j;zpFpHzD=UT8Hn<{CA;YjoQZ8;%LyA z#Fo#Cj%;QvHf7^eaBt0Xou&# zbD4*2w(J-0e(J;QXL5Q`=ZrHO1saMzZ`kl^z4dD~x0iobq^m0`rY~I;?c+YnQ@1Jk zU&7B5V$UxZ&2p^z_EG4P^Nwtlxl5P1O8h8R(SNe^@Ym=4U$%d_Dj+QIe}`_l#*3B+ z$48qU2r}7glx$&HrSNoD(`6-}%oyvt4qV^&y_DX+vht*N z+^rh@+}($it1C+0r`LU3UU}e0@BJU~H=c<&t}vGMdw;mj{bz!!U4yGs<$?0Kzj(L* z>tdOxAZ=s0Fe|Ig?# z*ztVFvcHXiJq4DlEHjV~(` z{AONzx291e#E03xXxhAmlNVJaE!xuBBxv={>Fy1e$GOT!)shlR&k1h0H&HpM(m7$V zfJ8aR2jO*6UU_*hn1d5#g`Txp{a4|7{bCo`z+vydS2ePL z<ovUebx8f4qkn%Y_s_?&Q?sY*xVwy>)-d2x_@uK zE-<{Q%4#P+MM-tJX1#DnuuOVVB-8tnIrCLyL-oYxU%MU?pZ)K6{U6nZJ?kP^gg&tS zdT#fk58b8)0Q*BlA=gs;l^k+)QiyXVB!j}4<78)$cs!6`! z_I0LVi0YbkiI>B!o}3U+8l;rI@Z~y3kG?8_{!cmBwa z!*@L{{q~$C?D}!f98-4Plv9-oCZ{~?dZItp@cBFn+c0^0dxB`9=br~D8P#WfQ`O$g zVtVE#bLjjk)td+H*X0#f*u;PMGWkz|u(H`%QG%@bYft2G0HqwJCP*v#pflROV|7=6Ko6 z3p~cYG{nC2%*5$kk8RzbGyl1Gp!4&g{-xXrf=WL^Em<~vU@Dhk_}-CGwfW&}Z=)Ym z&1Y^%?hc*6cWKg=N%zhyk!j6*pvhk+=q~2Vxx3<4=@O-#=PtdUXq9<~<1pu&WtLx$ z%wK6y(BgP}`t!~fdyi*1cK$k!+5B}vJk1&Qb@|;wsn&cAnweMK4MOYXE=-Ewz*F<4 z^R<8K?4xqZvR3o_f4ZEzJ$1gv3h%_QY1`VjOlDiUWa?Bg|ENDpx+7iM{dO5KPcvoV zX_RUFvgx$9xl#UvGmCHXKCN7kW0uz3aPI1)gvrt3FJkuE8ibyEuKw}T`Pz)s{+)q> z1xiwKr(RhgY;*QmQtf*AIx>CBZoc6RlBEOqkhUDn)P_4ItmoT8S-)1QxU9+ydR z(n|BbbVO*&x5xZ3ic??o7%z$0v8z(@I?L-lxsMbkOPsi^W=mQl{S1l>(o?tQ9J$ZBUR+eo-1pm+s-&2^n-~&So)F)1m#@tF<2$u1eJ|w~ zEeRnOuN>75+84a^^|p6@~UNni`kCJe4)p^zARfILviyv#^^;5~Cu%pw1of$SSu*8cs$9PY7omg3V!?Ilq^4>HBP zSaXLbxGD5zo2eYHN$1)S0 z5H+*S*G^wyF=;L;PM&MuS~;CEeiCP`+|A&Zwfo$*i=IIN$BaDXPkt40UlQE3bfN85*^BE{DqQsnmJ2Vv z^xwttp7>KXDYc{zUi%k5J~`>WXsZyTk9wk#w#g+1wtsFDg}*@$8Q-vzqhQ$$E8ZHipSsMU)gw+1W1-IxiGuL zZ^=_5QLd*(-+Mkyxl$=~y1-8BdzYK)Bg;D)aZ^5LDb2mUz02~h(zR2fTuODGZHuzJ zW^9?eN@v~;fAd?Zvzz@|*4@6l#d&|iaqD>**MqA99%!oXbalEZ^i?7Fh5f2XmEgTe zOM179r3B?}O%S$s`aZE=ZM{rtF zN%-c6K95T!-Z*O+q-Z8_M*aTCzHY*)Ep0lQ{4t865~o6TY-Bm_wa$U_&*CrPx3u}W z79E|WrjuH6YN8KE(L9?4uD0s0ETm$1O#|vKIlEkGsx7#BJ)d>yJf;4Eo>T zzQLe&ReZEh{&5rNVa7Q;OpEhw8#5(2rlp6>o^|VCR>w}GXQGMkZi!U{+26|jZP}eX z^{3Z^=?TtLo~O*HfAVLi-B*P<$2re9cs)zBk>vKW3bIjdiRgEp@xyp#`nFEDKglop zm(9-Y>WsV2Tci4-#r@Tbehv<~y!`iRy4$K^mX1qx+_#}19 zx9`|k^2Cwv`(5uvi=S|cEf%@UaL86+iBg}5r_RN<_PVQ|9=qyqb;w-C_D`d4zH&ua z@zKjR_4R)*$SjMTaJsp5@|I-ZWmmN8ydQr`zjQ8YwV<&4y3G%Q@0|#3pKC7NIPd!5 zwC0qp<}7N?3yLbg?nzGlrqyM{cX}NsQ?l9D8E=9cOnR289B|QkJlEUEpR?@KgGuLv zKmYvt!s{feT&RM%(hemGSqhs$<(=Dn=<*<1n9S?f3=0oWFO&h<(Gn|9hUBw|}`R zz`l{sd5OdQ=GOfFFM?}7@J>oF`@3$n&5x&fa|6%xr#xb$xeIP%(R5t6p`>yI-%@=fB(Y`CLnW!x_s`n)7hV1zlZp;=}(qH@LK-J^*dpgfPEYnOqPT484v86i1{@(%7pw>9m6Myw2f~#)N z3}IV)aI@LBFKJRLyMHuall!wo39?;!Bv$-4FgtKUROHDyXL6nX zIvrTZDx1W6XN6JG4DHM6{uQZ0lh4)eUa<0P;_ja}ol@6@c%5X~W555iY}cfn)hi=4 z1nc$dUzI*}e`WEZWv-u4$*qU7ejby9eb6T?HQ2#ZB1ue0@g%>y()j920&pe)fw4Lkv{m)Adt~$^z zlCxA~*;VNYlKCIrXLBj+|GGB+>{OGjTLXK;ILd_2Jvl0tb4qaIpFIK_7F^jg;huuE zx8Q-QSHa!0Ur66qvEESd*ltmI?8CX?91#yMED)_*c;Wp8uJ7!R7DyL=I_oQ$a;jYR z)7tu$zLM*rHkx0PjtRX>KYEwX>7}C%Xq8{Q+{6FaV#CfoZ6A1U+1&|I z53{>pmbsUq`MocVsirc${dOIw&?sz?$@M^<{xJ8GQ>n1hK$Y|=a%&_uj zwLkAt_^MJTQD9a3d!dqBj}#{Jn+0CToL*+5IA1QAW#)&z6^H6_%R{mlcM9ZirRLYZ zj&^Db%5_|7R;6@jo~64hd*nyPul;kTZH%}k5TOG)Fkk1NbpBq|hSJL>2e$A&GyOGr zUPS^6@ zfv&sje#n(sB_5yrrr?mIzWDvSM=hByT-~s3GH2DP#qkq3KVK-nBDZii^ZRVC`)9vw zn!b0<&bQlc3k7dA^*Cf;RooZBXJp20mf8?eRw}q*!If9r?z&a_nNO-+W$^FQ<7IOU z{PvYiUU6~3=cW38JDo~p4mc^Qas4>z$g{mDcYsb-mxkQFU~c;FGS; zKPGiAljPLpkLxwuxIj94hi-dFmf`7(f8#8wKMBt+m?qrnvpL1KzW%RcvH#3fiSAE+ zwI+ysi@$8reoOVH-1VggPw_NfbxCMAoo=eVk1vk@dPSm5EPKovKDow&(q?aqFSDoY zS^ifz`KspE?Popg*O|TKe34@ivLwr1aTkv--{YUE&-(T_pE_$PxFpMdNss;R8+({$ z{{Qm4{8zRA>_dA(oBTFi&g{PTdW(1eE!BhSdtPhK+PSKGt3vQ!K^ygn39F)hvCqzW z-5kZBmGN$>)#T#9+4Ih2PBUk@CdoO3`_+AtG3S_#p09b<&hYJbHWmxc@@73Z;ndBV zc@a$EGdg~LvYGgS{p6grrte+6yl3jIbC>KnG(B_1jfj9%qKVoP42^5dr%CDeKG8_+ z*(Av^rTKQ+mD^dC8ca_)f`gVBS!~#~OMh#D>)c|2S651fSg(3pDCh00W{|sjxP0;^ zW38H(nw2ceTBflrP1$sO{?^KP#$!3n0e@DPezB0nw>@YD{Y+Em;IRjLZIeUrjNw?$3Exs4la`sJT1+{$jI%*s-v^Dkz)(X zhHso*dov%r_?_$Z_M_vCzoFm%X@6yGRPnLmvz(whnZNdX=pUu;i=DYLR0EeAaZG)` zONnpZn-#iq9JxQQo6uD`$%MUp%BAM{5lrD`+`*GnS&3re;1 z{>+&6z*hD-cWYPwB6mAO`NQHfKK;}9bb)oj47U}r_-uRxBKdmF#e zWA-azmb%Fs*C-}%^f(=83R*0%smS?&qJ#OB%c2I~I=6){{I0b1uEJ{b%cp*?Pk7>+ zUsasMT|CiSWX>hd?mgVyOi?C@2fOb$x?AxjBwm{Am!!3OUBc2El~ZT%NzRHsQNp!k z0vAtYR|He||4z>doGX1cpZ~_^Hc^YubE5PNmRlQVa(sEyI-B#HPqyu^sClRMn7#@5 zF!RGF1%t=hsry7-1=2a!o&9L=_Tb%S*G9fIEG?%!4ruau?c6E(te7L@=K_&u<+~=Y z%DwlfDIoXgs}6f^3w!p_2+f=KZWDV zMeaDh&+aNWXbhVze?8-Y>|+b}J?xVES!WwL=wx%85n|-_Ix7@=dGAIJ9h(N%=>DIq z?`}SM?7M#!+Xf3US7W}LxveMr-W_7nW!cc8*SK~^prb$kOo^o?r&=w=QnfZubaJ@S zV(e3rl@n`HW9pefIOXoW2B+j92<;(bF)U9^MRL@ZK|`bUyat5)rTgZxBs_7uQqcU%hC|H=emzs7pBy;ESSt~_c3p|$qNyCqvOS^<)+sBbCzxvkYu6UN8 zo%2`hJ@B`B*8BQ{+qt5urZI6qxo$Rk5^i=NX;?( z+$weQ!uH;fiEkR57IenTHq3o3vtZJL$@L-qKd zgbhyZo*VT;ZNl?7X7NWFR1GEx0zNyWa`X|~eWcsC*p;@7yOG^cBtT|`D{noj& z7hZkabM=!=AID2R4e^FYJ11Nas613&W+6~;DfTXh&07V3>$x-5#jj}W-+B1B{GPc@ zzV(yXX208^eD`1ox7pPU$L#l4W^z4eWWB_vRiZ4()OMgvDZz0iZ*IlvZHfyxE~Gr$ zvTX5ZyQSY3{kd`S7T+2v-pTWp+kMS!{b#=4vig7Mk;d`_MUB=3(f8X9nRmHZAKBhI zG~}gv;&EcF>JLZ0-tiExhY$a$19{jkh*! zj5T9)J|GYw!SvXdXVo3iMem9hadMqc53uz~HAp|W{`yu~sf<&WdEI5Ej@!)Muex~a zP05AxPf|msLo-tX#}~%~O+mE*Msm&v1QJ-%1P^5WR$FJ5nRL&PIif(udIO)}ibFpA zd~=U@_T9@r8mPhPmV3Ec?9B{urdvXP--Pa5eWdPJ&uIYz7VyPL5n?R&KK7NH)c-lY zWwEE4`n|PL3piW1-wm@1o4)_>N$r=@E!=b1EmyP7E^^Vy=a67>R!(qS2|6^ftwHes z#~JGe*2N!Lcq>`9Ww~G1TO+mqBG_01mNwT1PxbZdr)EcRFFPynqTRu+{Dr!y&h&HP zN%3F2cWW~H7HkpAv09LD`QV1F2D#wdD16#LY3cCUC7=uG6j(GWw)(I703L@Z{Jhmu zuH?!KtDn->+dh^n8yra4b-Q8eITpqke)Ib^#h;tRUEVj$?o}cGpdYBWmHUD@?vO1na6=UnQ)Q0$q4^fFmN{lvR^r0>>I2rp-JF znE|W(1zan`*>O?4Dbm-+184quEKhHW!Xh&hd$ut+us`r@Mi5 zR@>3bTR_RFOCiB=rD&!`G3ffeW9|!{3OZ@bsuI8UsnpOk*Rm3PzT z+VQW88m`Pt{ancU_v80X`TxJ==j-kN^Xb{9(|Xx{b1W{-v8kN&zfa!&-UI&k-bboM z-|zqb@7etSKj+UrU;D23?8fBd7WLO-%T4G1|MPt7ud4?-#MV8&Sthhqw{@t3F-tk%g9?Jh~JRjk5x9<1bv+eeO5?ep@ z=<11dy*yVa{qmdxw~uf8OEqt01<|)ot`{Dg#I9za-E-2UwEX(>$QK88RKB{h@|pGi z&(^a+R}$sP{XF6R>HgI4xSKX_68W>`K22!<&|hiu;Q+Ht$F9%ktY`24|9gM>=lWmE z>u=4mtqx-jx~6y8r0XO&&Js9$dO!)K?Hmhua=?IPnWI8ngzc}3{m)vj8qfRK!qSGz8%2ZGqi=5C|5sK$C*RA*+*79i_1`<^|H_0*{%!9o7U{W_-c;Mu>mZ|Z z%wp&M{r78*m)EfOPnMeCWbg`fSta}84c4y?vO{hbGpql5z5Z^^GvoOW=LT|k{e71I zPmO)$9AUGxzPnOt36N{63`Cg3rbuylUWQ)zWgy73<${%O(;o>gu_*gri|ud4RKMN2 z=fbX6t5#cBw91C;-o1OzfnTS>_g%^;;A+(T>s;{a!2^eK#v9xJ32$}N6k+Gjy&lrp zANYzxL1F6NGk2KeOINrBeNGT5oA%6lvA_v;gI8VJ>oUs9%4RKItb8x@SEql?qMuLH z?Qh;Gzh8US{@-JJGf?>7ulcfAK6LgqwXT-A(0~>L~-;-f>bqdE9`YQ}OoUUxCv%m1=vx$WA{d-A2H8qz_x~jy6lGs7 zFyqpLEARiDd%q%y+fP#{c+O*1qcY#SHJ{IZv$!u(v2L*jQ_#CW+mQEjY}c7bY9D{B zAa~JuLR@oTMF@YR#vj`+3;Cal&sLUbb@-cZ|NG{%Wcl9`{hi`^F&PGIN&)Zrq}fF| zt))RlPy&YzFUX0rmKnH1ohZT>HQ{aWFO$C?`51Lh#r=6CZth=kNcczUzKS#a`ah1Y z_kFlmGot39_|gv*T>rkLzNnbaB^Q2haqYVeuA7t$A4ZCw{x)wVCu2r`DB}3@x&8m2e-88iI;Zhwf|CK)Znuxg0u~#jx!zy-eR}_&)6cl$e>gQypH=^W zSw7?4j>mj;^F=mB7<5hC#1FZ5tufW*KvU4^8(PmMgO`xCF(?bLFW(USYNdazmc7`Q zAII(I$;bb^wf=7upI>5OTltEF=OXvar~VI;ZwjvPEZ>s+fak4_MXrH=TSK<^zpwfk z4h^T|p3mkvT{_{=`qvKwZFxh2=K5XyTDpO+bauGxqXZGAcjs%K8P9(IYu)=t3VYa= zd^o4UvRI%;z3%^|qBlLi?mV|UzCY~OLH@c4_t&;R5Rnz@nHA1FOBU+hPEcq4$c32; zAkICoN1&rQxT1x1|E2c*$L+pt{IgF}=aGYb;UgCIkCUHs$a;Cn^DCf$diL#h z{`T_KJQoTIXFJTbJ!j6aLVJZ$bqv4hhK4H=Zzba0IW|2O|7s#3y5HQZKG6UE%65m{ z`;N%$_v^a5;CMyZX*Z7jRG;V|?MKMNhFI}uIZgpw z)+;~k(|n_KfV+NUz~u*1_VL6rhtz*dufO)^|C_y)Q_@0bKHIIVdi0+y0YfcKi7LMtA(5M<05WIxKhhf6A9?_psuUecAo+irt=R zY)kL``&O=Tq3GDQg*zYnylw7qpOD!tZ)%jvJWx-qpJBf0KL9?EAmg-q*^$zOGllrsgHH-$z&fGC`ib{L2|a<{Z#uT3G+Ccz$-W zq@Ss3*<>?~uLt?-R;-EGx2Wb}x4Fp<@wFTV@1NG}7W}}m>ecc7L(UsB9zILHE&rI4 zXKC4Ix!?coHZHyw8XhZZ_~Dk2Z9~ZI!2TT-G8N7b4_2PH{eGmc>W#svzN+|Nm!{wH z`1gIK=EEzHAnnUwNT=(a^zvf2gXTLqH@$c==1MGGJ|M|Aw{UX(4 z_3y{y-SyMwRlnQW5Lo}&yk6Mw{f7^Gem*(DNgXBThnhJ^Ej6QKtJUY)2d zpSKf|Y|kuqkoOaee>KTlPjh-)RptTBcR!0dzF&EDb#?c&y;DFmg%Fj+?f46`CpQqRVZ`%B&XrEt~vX-&@ghz}#OU3GX|JFBm z6mPHl`>R9ts?B1Lk3C85whEQE1N#>|{r|ZBPk+QZcbz@ac{^3jQWCBQ$hHM?d%u&? zP5>oRizZQnDOOGK^OomR5hd_WeK4j4Ul9{p|mKiLg36-SvUU#%K-| z8?NQEo?l7sw+*xV_p!fv`99VqaU5Q6E9%@WKQ2|D=3o2j|LZNxK7T*g|2w~TPCldV z^r*u6opQy>3g5-|eQ2GrY~htV+pqpNXFq?Y^!2r=-FmxL-1c36w3o?Ew))LR#>Kb# zs#py7$18}x_nr2(_L1=X7y8Yn0`s-Edqabjby35@E8I_9e;Gmq66#oAi68B~!nE+m zq7&aj6JS??6kW5&(3{$M^FEp_AlQ@-a~Nm+uHrV{gc#B z`~Q31qS_YJTz;cHaLT^lci-!=7#%mBJon42b`gWF8)biGzt;UYEI+OK{a*6~5e1p| zXLO@?EnVLh$UJlIW=Mt;U%_-bZo&Dd$2WobjM@TRAq7j`_a+BNv2A|1dH&y=n_Du2 zD_=+7mzoz`BY0#om&Z}R+BrHaAD&L${rt4b>D-RsqmyR6e3`jN(rlH#{>sP)-*a+m zbeK*D|MkE3{okhx*V<3j|2sdQC%eq^&kJ|^sDFRX|F3Dhre_z!)uVU)@%u-$?|-Wc zYWI{^UGh}_Zd<{3-DLWi9e;K&I+>H;RN=buB-8(S47+Zh+%H?a z)NZ%WXWQIg9iN>hJlqy69~XSKxT_*~`@O1c7WuTw`F)GU{5<{N9t`8!{r(}N(7Yh7 zvUQ&rDo;)6{P=NG*4I@<|7*WbpS`azxbnq9_RJuebgh&Kqv?SPU;lltUofZiTGU@z z8}Wdy)OG*=X8+%Nr}BCE>HI&xtd%pq*Z=63@BhjDuTOU-yCsY8%m3C)YyO?R|L1I; zyKRDqLYMG{y;)aR%?OO1HGI=2wDI3N_#nTyutM~k;3tM zKPPow7g0Z5bmQJ!3G3PB`Dw@PtNmE#o%(L3Cvfzly6F0vr`pc1>;KmOkF4mb`M&!; zZ^c&g(?1#1K)0-xy?Y&}-H<0!eQDkP82;b({~rI}I;ZSa=F^+;Hm7stn0kJ7Cg0xH z{`mcpYci&u@@^Zye0P@r6`;c`cQ;Mzjjo>WC#F!k2cir2WeoeAmtIn#$nzHNJtn8%ab_YZbUa*Wj zr#>TeUhTJ==ZaUcI;kIh{qUG{e$S5JFN+_qh^$lo%j8x{T*z>ezxAnfiZ}Y_!!mKycAGf}@(f!7y zH~rJT^#A|Se|rB<^Z#l4<-hOwd`|oSr}%&IpSWr^*(mlqEVxo^eJQx>`!CZs#yRZ@2U3Uy1Cf zJd#&i;rH<5g|b)Cd#g%yjvj30dT?pavJVS>Jz%$&c-s)X{chQ9wy!%KU&)ykta>lJ z)%*1KwwNW4uCLj3gCmIXN8SJL{};skIo5sp|3CHr(O2GSdt`pA{>1Pp|HnP;f_s(g zHU7Up{x4VYSm2(u&&002ZrTxa_u}cYRQ(M;zqdQ~o1Way{Q6a2)nA2YXPbp2w&vX2 z#KFN|0%}6N+UV2&bYIStfa$*%U8?#k>ofTyH1UQ#$Ot8z;OAg{HT^K3 zU#8{FCDWd;&X_f4j!ycVLbvT}`ga7^{A3B(np(^2H*w$pzwh<;f0W)I`0wxj|KHzO zlz%y>`B7uRYe5?I_SKNSW$MUnHT;3Y*_x*mi>_Q;Rs@uxe zTcKs>h7C+@LEPDoVHMjckr#(GYj@5G+OxtlX+OgGB^=UE4*x ze}9cM=wET<)^M>*tx}{}=ta zx&L4I!_-YN^VBM4vwV<9lv{itb>Y7LZ=Y;mvJ~I?c&G2v=lTDgo}WKF`MJ9P--y$v z=QT_4B|Pf*m$1tCyv^px+xyqKs)yI+l=S@{$BMpQ4R;qP{`ZVAXvv>m z=EY%aA_N8ceFfwy9yAuc-}`;q{6A0BH)=9jzxq0Dj+C3?3VulZZD3O7lJM%~coYre z+gg~a`nU65kFT$Nv&CITa@zX`yce4mZnrQxuyWfHehXL2_!!Q%e{KV`9Q_ zcXxx5gFRv|YF=#TJaO=o?NZ}UQ(nnmkFyTF=HXmo^K3?F>s|ipbyl^(&-q;#Q^d

`X#l< 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 Q9)RRLUHx3vIVCg!04%G};{X5v literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/3dr_gps/gps_03.png b/files/images/px4/calibration/3dr_gps/gps_03.png new file mode 100644 index 0000000000000000000000000000000000000000..3a9f51c6e6a1e05c1f056a125dafb5c247488703 GIT binary patch literal 73246 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 z�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 literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/3dr_gps/gps_04.png b/files/images/px4/calibration/3dr_gps/gps_04.png new file mode 100644 index 0000000000000000000000000000000000000000..2e945c1d744151ba66e3d616f5f8c459a8943da5 GIT binary patch literal 59034 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 C5Tt1U literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/3dr_gps/gps_05.png b/files/images/px4/calibration/3dr_gps/gps_05.png new file mode 100644 index 0000000000000000000000000000000000000000..92f2e2fa47e46efb0c8303e5bdf4b187fb816c34 GIT binary patch literal 73697 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

;Zk|8f{F8`bIIp!zSt;Py1LB|oRv3koW)tL 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

_PkXpSjEWDuu`Ccalsz5#Wu5-#4d+8?faLu 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 z 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 J%Q~loCIFRuGg1Hm literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/3dr_gps/gps_07.png b/files/images/px4/calibration/3dr_gps/gps_07.png new file mode 100644 index 0000000000000000000000000000000000000000..021fcd497b627e85dfe2eef7e1e9a6d7407819e8 GIT binary patch literal 61146 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 literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/3dr_gps/gps_12.png b/files/images/px4/calibration/3dr_gps/gps_12.png new file mode 100644 index 0000000000000000000000000000000000000000..3ec1a7a543875db4cf2a4f95f2beb6e8c705c06e GIT binary patch literal 81113 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 Sa+%8nkhG_(pUXO@geCwS1)4Mf literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/3dr_gps/gps_13.png b/files/images/px4/calibration/3dr_gps/gps_13.png new file mode 100644 index 0000000000000000000000000000000000000000..6374b96bb636722589c343fae53238a2ae1818b5 GIT binary patch literal 82220 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 Wo!%;Pk`t7B89ZJ6T-G@yGywpj9y}}n literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/3dr_gps/gps_14.png b/files/images/px4/calibration/3dr_gps/gps_14.png new file mode 100644 index 0000000000000000000000000000000000000000..3cd81390c5d1962f1f68ae86f8cb14ee07367c47 GIT binary patch literal 86632 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

vh-V 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 z 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%0DYDF2)AR4_ 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 literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/3dr_gps/gps_16.png b/files/images/px4/calibration/3dr_gps/gps_16.png new file mode 100644 index 0000000000000000000000000000000000000000..3581f855879c600ff5ff8c37628f50c3f00fa743 GIT binary patch literal 91147 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%0AG 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 z%0Aguep>Qxqtn8G^{Nun3t10;^I}`MKdNmRe}b*Vr>LtYEqm_%jbF20yVt71UGfuO zQq}gGzpp)67kd7~qodr*%CkZC?&6_^t)4%faDCNMMUW-4 zTlbtjbj2~QZ!Ob3zbvU4_ulp+LZU2 z$@;(lole~TQ+&I1&)vLT*G@j~&8pfSqNO?g^u**FDngyVzr{2DTg4!IC+ydY|C@Av z2k;z+tp$KuJa0*BhRLb|i#s12Yj!8U%sF9gYP$6D<;%Z*`+Pp+UHA8O{QQ^CzjpZ@ zz8}c8i&y?kpW>6Z>JO%_+PmqTXWZ}qtrNEYd|tNcWz_QNf%_Tr?Jw{CcJi**(nZ(T z$7k2q&kt9=Zm^g8OU3M0hyP#RwIY{+fk9&V@6DSxf1R-XYV*%D{tw+p7xD4&iEy=o znsARFCr|ZKT~_(f(tp0))oqY4&!`!5 z=U%;X<;qUp!YEsg^13$<9yoxUa^d@zFI()+S{oZ5_BtFqtoxR@0F~*`2362-rJt8%$IksHQdYn<=p#ZeoIgOY;&H|;C3|6 z;fSds4x1k5mvcUt zXDozD+auVgQjEcs-wXV>>! zn(;DrLHy)TySDW#k@YkL*X9OVzgM;Hxwa%~^RBis{!`5d7c9ECqU-3QuA_@iJ>BHA zaDvviuyL`g@u9T@9s==xo~^EW6byCwZAX=-(^tD|D3S>_U9b)y|>?do?ZIU z?AIT!rHd9XR(|{b{dM!U`Cndd$egut?b@~V>tx?~{F)MNw!nIFNX)e0(plT8yG4!YpLMcE*IQ3|Teb?*#XHr5A7S zFIe||@0{}s_LVOUTG_sPZ;q1ZiE6tix#CmGqc<9Myo`OlWx9U+stBD|)A#>*nlE87 z8L9alayFl#BvGh**@=}_@BDL_85j;^TyehVwe*s~lebSC_kMj~A;B|`v+DHIO)49I zO4*#{s+w+1Gi;T8DwZTrhx3znD9X5H)aeqQRVv@-@hQ*S-& zTlHIm@x>*T`@he2++t&3Xb8MHeTw!}FZ1rBi+MeknV_d;Pnkzo4}L_nTA38}ZO($meYfvTj5&XN=gV1t zx2?PGdBu~vayIM3yFQNmNmbh;|F5g9D$mdNXJ=;zH9t>E&$!3R)_Hw>=u;PP$Y?|; zzJL1o@#CEV8dtUjEsWh!{p?(>#*(0wOD0bic8aT*XZzys-S>6Jn=E)f|FS)Io9}hm z+UW(?dF}u2&~LA+x)&WQcXnCDZPwk>igvCM*N^j-{V2Qt#!+9~@&ezN8y{+zgtiAaA+U%{88G6$vtJqe3c@ci6%X4MO zt2ndSu`6WPt*|O!U*PWZ!ECxPxOsFqY<-S}rRB?tS=(cGWY0Z+@}%cizx{zYf^m{bsai8zTcl!i+Vi+8kDfbj_VN@0$AcD$a^E>^BZ31S}2m zyw;Z2a9>AH?^lwt*>=`lXX}my*7$C|ZIYeabnwB6x;p!KzPoe$_3!Tf_PxKaZ_EDu z>nm*Ld8`Ww&^X^2^|rR%d7XEzh5|tg`v8J|hDI z+oPFFVwMK&tSKroN@v}C?!xlR`;K@mU6f$3B57m9-p8j!^lMJ+6Pz916sOO!D=%9A z`7O))@4waj*(5jj&pgwp!)f)#xBkXveyu#WGWPY`r>CcDiFJcch5sqdc4XD%-ODnM zWwlE$n#Cx=@$PAvx_TCKp1B`)tiP$2N(n;N8^ zZ+kg&mGnI}ucbk@FSh=wlx~$etF~?pZyra5A?F*%_n_5C8~^as&AT959@_l(&#}9_ zZ?>IYboENE{#2f~cGp0Im%T6VZk}lUCVC? zzkXN{VQg&7)qeQ7T!#6rlYf5vh*%orxq0*EHA-sdzJ1%aZTt52-wTSEvc;lW8>TH@ ztSrjax=eol?AfoY=7NV+3jT)j?k)M`cj@WXcPH6?-|sHkS@Uj7*?+TJA!}pwRtK$o z@!>-NsOYzmJ8xU@;emEu?-CcK!uxd}Hz*xo$bTQv)EGJa%hJCsXV0EpKYiLXNVVS+ z@pkRMN#|zHl=SuYH(!&xK`zC5`Mm~DlM@T3zrJ+yw$yTPn_>Uw#IqSDt3Z9??CsyK zsZF^yyLQp`$qyc9xNURUc7NL*v~me(H(J$~7Z=y>*ye%AAssJc z6Bewo@L{{8jy?E0xrtKZ+(+4JV<^Z8Rwuen*Z^>t}} z$ms_*>q4|3L(~CAGi%Po*A#uPtHr)32(u z?>W0=c2l0%o2XMyH^uF#P+a+IRopt&OV_SlQ~z0W@0H5WHQ%;NA5h4@9nrM#l*g|d zbxhzA$a!nj@9qCqX{lG|FBRRfg}a_}=L2_06RzyK@Lr46K`S*xxUQO)@U$QPD#e<< z{GTMLT|lhysB>iRQGR_)xm(^!rZ|l9crvIk>@{7N} zc`2-3)V#NHmCxm#wQJYjT`T);g&7Zf!iE_SWY@Jril`~`uHM@hT6*aEs^Sw@?a!AZw!nD+SLcX9%Pq)acymMu6otQI$!67^72v92iMtN z*?Mn!2!GPr$1`V2?)`qRy6WerrJxv|Jb7~Q{lyVFuO2*bIDY&%SNmaJ^{Tm{yjM)O z%s=+_%m2G8CSU*e{Xo_IRWCY@Ki&zt?rQ(TTL-`B8ECQWISehNAAdRX?OVk2=KBpx zEVb`!W#9je{oUGSkF9u{t2xCQ>PkKd{nHL#2XfVS&puW9>wjrp z$n|%%&vXBro~|FNBlh)l{J&4;JS7+Ra`$|BZ|iMPBnhtRAB1hZHT&y7r^Wu8mOXzH zT-nScIcK>r+v5B8m*?f==Vw<}&p!I*(3LAwnhq}TS{k&MZQ10PvFRV=I9NdE=)OKX z+Z=TDm`Y|@S=hylkf5!r9=>?-;>?z>UteDr?R7gJV)|p{x`p!vwqN~!dFQvYTH;Zm zCK35hiz3_G+p9i4YK8T73)fBvT6tw}j#>6!+1Qm&6&czZIPYDo)&Q5pce3JTuh>|q z*Ur7XuldHDu9XQTNfOeFboKOJottYtX~v7UAqEm_>_0x9^CY*-(sb9EHJA7O|5pvl zlm`<6K;wej&GYZQ06FaXp4#7Gtxk>)3nGGpgL(J+Z{Huh*rbPH`~ClmKc{DfoIda+ zFWcum(_+^H)^d=x&;!-nY&or|r(zaA*dEA`v$xlXLyhNKdm_uOvk{K(FE96h`TT9e zW}|~UI~Nx}x^J2K`puKS|9-y*h56+9f0o!CmF8f1HTPlJ(WJoq`};zd2Cek}z0358 ztowr7FRHgiOFw^`w)pb~yXP-nc>MnTyX*L4OS7=mzy5qazkh@5u?WG06W{qGn8Hth z8+;7=U#xhxaAunR`fd4-OfImq_*Q8|*UBi@9C$YAYyGb;E4OXm{`JX8VZAA8X=!OD zrlw1acE;@2i=LjSewF9k>A!DpZ~wLa|1bTsXU=5g<@s&iyqUM&9JDCF=PPKwvzgy+ zg+IgX{pscpUn$goZn$bLOYHXy>(kJ_a*B5KS9tK$&V)6A6w^dyYN~vN}qGPbgIA`o4E!R z8?s-!vFttD>ZItZB*@zAIQ8_?;>*|O`n&c=wL$O?ZxUyWGNfw%bLQUr+bf=5uR49z&ir|W^>?9g?S>8edpF4) zs+?ECTAmkT%H3S{^pxn`U8UaL-Q87RUx{Aj?R(u+yV&@3)wR=K)}^MUxq)24)Y$Ov z*Y*9cUc6ZG&-M*y5F9l1?x3(>=~7kCRqXws`RRG{u6_AZ;(vX=pMCuW#y2Zg%e)ER z^X>M=wC$zWazAv7>#Kyux1Qd*z-n*ytYu%nXF2DrVe5Hj)}vamwg+5uI%Kcr^^1P_ z^^DY2XNziQ_FoApPRpDAeyN8Hd6->yxt(flZC$-=)xycWSFL{D-QfS(O-V3zZ`Ic` zN9q;^TzL0xonGv&CG-EjNw>1Fu-NQ*4>XI=Z})3Oovge|>|q7x8;PvD-k#fjF*Rxa zrLB7I&!6aB-rZ}sm%HcXdw%Z+S*O7TEW_W=CAKY3=C4cG@24;PW!_%7m>mU<3j>2_5b&RGN0$A>i2t>@7%fbSLu1VPjS1;eCz*xo?lu~QSq%yzWe2+ zrQWvx-|;DR$cD_Y?)aR!<>oBo2f1IoTFc+xySlvm<-N6ws>LN9|K*-`K=_(!ZKi!= zItL>Ig8@r#Q^Lyrl@Ht;KUgepx+}Cn=*zF$U%qTvba92#!hpk`_uTfgzpYcBllZLs ze(iGe{CggglqPo6eVRO9L#h`vGIsB9cJ7(9);$+9LfqZme?4gCFL`@w>%_lu-=vQ8 zty;G5vRvHjzePLO+`S9BSt~9xI(b%FPHyhoytf7JTVHuHDDR3tC{*F)=JT0}f#HCx zO)S6S&Sb3{>mA>Nrd>PlcjTs}xozIOIo&Mw_1E&XkryIYhJ5++^Ybs4_h-)ZC{65u zOjm_yh@7jbGm#2a5xRKq-n_K*^skra|0~hh-#nLX^W#;i86~zQejmKjtIxd!9r3a- zZcoKRSeN6ECA6&Eo$xz)LSkscMa2hS=Ya+l9`tj8rW95M3cUGQ#qs-PGtY@XB0ubE ze}&w>eOp-ei<{EKsuQp86l|D%f4*De(qiTfpoJ(uKRlvairg<$jzRKhCe%|pfdJmfRo9i?#*X{Pb!N9;^P+1en|IlXd z^!M+d3H*3@dHJvJ_5Z(j{%PH+R{3`Bp1E;xpc3T&)_b5bgpZFeWM#;g>HGgIefj;z z?)|@a|0>B}{r>jL^VfS5S$6K7lfL-$p;hS{)GB7)v+aKwdq9?>;%_2&dd6lp2WWz5 zznqiQpO6nboF91J1xKp5UQB?6j9vKk3qHFGuGi(*`#;ZId+*=(`v2kW?d`vQ@Bd#7 zYBSjW^_lzP>1#LJqqnn~w#Vqb{`&g*t^4<%U)^lx^PcIQ!-3cOuOYeV#Wej_ic1c* z9$d`PsBZXT?yOmtTDiqRg|>r2LE5bC6YG|hOYhBpKXL2+|M&m@z2D`wcvs=$V>2_q z4#~jQ*EomWN*}h8^JeIs>BN>3wS@!o_VV`>+iW0nX?Qpo8+H4 zfBt>^-m231s!R+F4Cii6|8nNzx3#O*Pb%KWs`6AO|6IWiyN~Jh+Ecxr-;-i3Xmm(e zz?i*w>v$2rrZS6`ND-F-La-?#Oh zZi}n_{@S{1`SRD&n@T?yfBj_H{OhjVk}y-=>gsAO5iZa;z~he=Q#&Rh4Vq+aZ)Z5x zz!~>HN(|hXJg|dji`=3>{|zR8syJ5eU-`h#`GM!{4qX8b4XNI1=JAtD(q?VH-FtOS zy>#pMbIH%Yto!r0PRJG}{9gE0JA7ifFLYkm5&X;mHn z|D69Hq9Aag{C;it`l1bWdapmv`EPZ0=*Tn?|3+~>HWm}x{;vVar&W7?L-RpTB_S^h6#1$RdJc)sUfgwkV_28w3$3OENGp zG$?*_v2|Jf;rkip*KCgYs|9x4UJ0^j=FFMKj`@pE-tnt0pZjo~sjLhSo2jks+5(F= z-M(+C0#}BBx~b34&o};)f>c#qO*CZCb3DMkI~Cl@XE=0WRs42F7xaSjG!eMI~QJeE|FrX|9-dp*J1g80srs#9lmeOf9Xub&^j<(9!-?j7=s`cWrOn4Q&z zI`;FiDE`FO{nPIM`?meB{RVy(5x(}<3%8hd-qx6q7ykHymQJqt5e?qTz;G@(koz@8~?%Vx+_5rfaXi7W@d30#x>XJuaV`t`y3wT}+YV%X;YbK5Jn zysv+E|DAbEP++@tzV?HAckf=c|9jc~gW#x?d3J+YDUwe9^r59Y;F-$ONs_Ibp zpZDVAWc9C)%cS>}%5a(7c(L|w=GuMXo8RBhuCRU~aP#Gh7aovu&gY%kfiHRwcv<$m z2!j>?4*F882W$OV|3Bofx7hsf_G0(`D0W8KmIZTL_Vn5{Toyio}kF)t+dHM3?S+izk$w`z5 zockvHZ`<#R?T#hO`}+F69Ok!Q5uowm)DR?Ex3w`XF=+&5eAZI_#`r>kqLd?WX~K~Lym zgEhWP=2`t;8Fxr9>a*p>ZoS3EeZCJ=n@wK;Zk(*rj}&ev{KCBa8TVNCv}G{zvw-%W!WRK z44SbRUIZ*Q*dgh3=U{S`_y@IhYb07rA*q<5A$w`i%IazL$G8+JFi*hMxXp<-M|k@0jKZC2<-!@n_d-Bux?noiA|T#P{>D zx3{54-9=i9O5ln<@Y%Vw7Q3Z;XsGM zUhW^vjQV#}l#fG4-WV7RD%uj)EW7-2_SVC^q2Et4K5z^%Ij|O%tQnjqdZ@g+&3Ce$ zfj_xPJa4KnB=s=x%t@434H=$YwQrGFgS+5|LvJA?(xBl^&!s`-x$W9(I3DEoJUHwP zH_q0WC;6%YkM@X@pSr`BKz?DkAai$j!~cMb4Em=! zAQ_!um(zE>2mUs}%Eh*qWz}Z*#?yj_*$M%5P=fk1bMXT&yOKkXO@$~ag z%fkj?s;rMb{xF7wputPz#!dfn#vcrf`hS$5Ns7VZxXIZWxyf5)H*S=ApdDgzpdaq; zNlT!0#1+19m+yKHv>m50*i8xida|4MbxV%f?g^k!I`srp_A-311+D2WD0gq!-S9r( zB7^|X*K)Bmtu!MlNT+q$e1yOZZ8NF4K0nz$psdYUje==}|OlCPHSIM~JT z&+R`~z}7Wc52D{c?>+u_XNu8J-oJamiu4y&i_g#rF<}UWjKwf8e6ZM6-gxrxW($X8 z$(ze6RWpl=KW8rkEk9&n$UF8$&!BR~16HZ(65odfeImRSFzR24-!EYpmpsGtCh2`M@+6I$*`Xpm+F-p21CyipF`o6 z3WbMFu6HYQ!C}P1dUrR&k}L(*gbhZM?6&be`dFbi)2D7T zbS)ACgTxF_gS5=!7_*PYx<3aBV7YqkSJ#=awE)OD{KfP{iPhU)-sLsi%k87X6qm3A z+yhsf>0{@oHu?Sr6OgqHafW-j4>+;w8^lOjnk5?h8mA$zgmeL`$&&yzNYmDo?Fg)X z!sM1(xeCs9rWnj*gE0A7g!I;up=;Obv#03435!XaO_IBmhHFleon8IncDb zB@sT8x}-FWwZY{8_YPNR^~^Bq#;sewRKSVCKDac2gJDGmLrey=ImnQO73zAbT0+UA?Bw;sB^-KfYg=b&14!*`w4zb4J; zUn`7=>gl!ovbirt1+l03Wh}#8 zg$JyE6d}WD3*({2b}o5aKT8OvD-W8=xtuVdD?T!0e|kFNRp< z2doJvJ#J0dvgnq{`pj8|kYXsog6D9=)~io)ugFbjbO>kCVQgTV7Frv5;rKQ9($5Gf zkh3LvAQ{t*d4amm2c`^_L|47JHk;s+Kyg_faLKxWMVnFU?O z%fN7VH$z)j7wB$uSd(7?v5VtCgWv}yiKXBba~{wIu%HQh1_paC6`}9B?N1CC*!n=a zr$C#lYAx{gMpCjVgYyAncZOrBk$tz=Ad&ln^YU&6H^mb|3=)%l-twJmD{V@Y&<3rj zeJhyKD?>Skhft?mi>E3)KB+O+aDPfRdwtWSf$jma>gDm**y$* z6x3fPzV$o5N#*J1pF2yeYJ-CmxtF@D%C-w0EofG*=*XO9c-SB;tKE9lJ5weGXVDZ+h8=fytx|m72lwmR%UmF%j-4~;2|b=H z$sl2+R>4?t)EUz7J+O4fJyrufmOTu6RG_Br5V*UW;aF=I8$;X{JxKE2(ULi9V~*MG z0P8ywrzD0l^l%C9Vc7EqS~eJ@&9DFWQ+%6qn;%1u2%|p3dRXn8oFs8<)!V5ppj|o# zI#?r^80@e#UwC35rC~awL6Oe~rVq2*vx06HfR^w_%7L8TeCUfFgZYD*stk48F!RR+ z{bl8hI~axcF#OS3{A%+H?Nz>?XDyRV76vUHXZV{`CEgJI;f+v(=SGaRAPfz8po&p< z#sgLZ&7xIytK|Yr--O!DpKr{Q914oo&7j#_hK9Z+K`X0&*3_*l+YwZ~hmj%K@c?(i zC8Uf#7gVH49P@fx;C^+lJwrlH1t(*J=Qe06FHxN8b@z1IX6~(rMKA8|t;K570F5<>cnpCcVD**Qew?Qvsuv6vKlx(EiJTgYY!u_jV&Q zLyxTR9)^N2KgcLZK?2CDf*+V1k|EQD3=WeLC04&I`IYvz!1w9&j<@Nxo`wHsWo8^VRU*j1AcWADA4TL#y-|8Y@Fy zt$SP0D$4l4Y|k17hALS9Js!0kUm(pC$ME9(t|j`2_10h?J}4}C&-8&wONwEEy`*K9 z^re?yd?Cp!e{r>VLpaE`|3#DJR!M!S(+V|D^j?11{HR(EsN4H|#xlvgK3mOeldyaDnQsa>fc#kP%f-BML+h8-&SzzsYz& z804~#m5`~^hKjjvhuvO;%+!QgTKN9)`pMJc1yw3aOYMpFhuP*Iu=65+8#N=r+wgir|`(R}s>#+m!%s)~%{eU}#Vm{J_+( zJtgEVTXbOVtm`IcXJpPotOOMT)qrbrK{;afy}v#_@0mUr{7PjwuzQ-S?Y8*>{l|;> zs$dHrcEUlQSW;ZvvCSUhV_$LCNRjl;F}T z#RXY6R@d0sgCcW@gN9MB*PC0;XMot%RvizUY7h)11HoET+7NCeLzQsI4E0&W=o%gMFFU4oRKJ@ zz4frH=j%0G4EBo`F)~~@1*yg$OI8Yu!8s8;l1zAiAA>wiA!3Tf=!V@yZ_6`3#GA(EP$G+$_cphWXXGoYJw`x~(A+A1cgJV*a_<<#${lz>{P=j6IxjW$!OC%G+ zfeC9?OMQA5p)S$35!|^~(*YHL^FYqGzLVg};G?8g!N_p<8)QF8!U3PlJ-NBLe~aH1 zxL;bnhO5ETL@T5%e1HLzg(iWs=KQPgikS`^0qsKW339tS{oL9WW@oc!rS*U# zz2vaT*%^rvVfWwlt@@h4U@#H1(f{#>fNi(fvO&318oZz8DI)`egSO9mrUU(8`ANae zx7u#GNrEe)1&Yhc86W5{#W5V%kqU1Nn;ib4$1q0}bkCXICd`@`smJ!tp6P%~a+5g2 z12xM~^TfsAYVtYs;DqEg91H>BLr^Ik$Sc+Ga$irs;`&vP&c_jj=|G~9+{zlP4~ zkYN#Hh6Qb$aSRQ&A#KwGF3DBm46{JtUjgk=`hdoAu9xjN)WvY1zrvH5;XwB^@F?y9 z7Xy^hDTs&TFxw#?*mspPE-=-SVql1y25F$~o9ean9jKLf>tWZb-^L6KITg>i86Jp3 zI@JfvA%2d$yW4u}?`j4Hc2I=YO$^>TSvTSC&+~}x^~ZEjYp|gl+%SL^gAUH1!w2@C zgp7pwgSzyfDlKOX8-p(>JN(fAHB%2BSRPb5%N#V01nxMlJN`wFp+xV55CcPv&f=`p z!-ytv<}5={A%39N=W-9E?DKnTC(E#a6XdGN3d-)e&Q^2xd4kH!hTjHzxf$+)QjkyA zoK;(S)6F2UbikJ9aKzfX_LEnwKU8&M6@x=I<1_{agN2}>j`@n(j_5B(76CJ zK)W5bIU8{^ykHRC!_eUQ6_Sp3v?WTc-c~CF8n9w0X=xB=Fn~6c4v4~Y2*X^?O)Lxy z8L?Lnqfh)&j%)k3%3s6YVO6= z^Il*c9UVRY$>*OtZ#_(3wQm*|!v$8RI0lAWkfw1%Bd8GqZ86pgFfhb&fxJ|bgX*Vi z((DWj4SW)98(;01&&u!u)XHTjdB1Sh6*KS}c~FckFkM#8m{0)9hcA5nc(bIlCToE6 z;TDJQdJH^#pl#28k$b*opbd2yJuhP!B-Vh6$pZ&qgG`8lr2tUUg(QQnRsJ)W8LE!3 z=rb@hPYy1fH67GhZ(!p&9O1kCvUzs9^s2BpMuuMwpj+%7ATqorY+E101$$7gkXQ$) zUcp_yySt?qRf{vQfp+dUT*Rmo8$7{-r+g=s84?^ojhzG&NFnQ^ao8Zt_j1owKJz2T zvKR~uY?9d+4!nTmcLT>6_gEVqCW0}Glga9aF zj;SkyS_uvPGnYwj&Rw%j*({8?q49C5AOpjW!;p@(-DE_&;Ke=GhDJ~!#ZZ0%Jh1dY z8B`o*fXb!^dXV;aO+t3|YvJhc@6thjZENacV_>+G4XMBRjgT8F%nTAu3f>G14cVz7 zwMJ!!trTaU)dOXbWtqn!cwnft6*VrC7uWb;VDb&~Lpe?}gR5l_o{n~lHIf9KRlO|eClv zFJ>?_m}zu9+E%!woZ*I{C@(`njM!K9rB5HbdS$NJ#>kM-tbUcpT#ac%^}HpF2R=%< zew}(eykGqA!-CjpPmiBIecHa4o#BT0%h-m$mk)9?9M6^&q{LkdZ+l#4V6chy%KY@?yaL0U zi7fgICAXbH&DS!O=QbXiy{{h|=~OU&JJ%%6uq$6SOPZlUcE;JXe6!hSGiz(2|LHu2SrGA%6n3}4QJjhp9LCB8sbr-E_8{A&xhF*5vc z+*Qta3lzg&ZkK}W+ZPOWgfN3l2a7&~z{jb#+ODsU|9`xKp}}2qspsFd^E*0b|2i+o zAakNqkb%KJ#{EeC*=|H^Ez-!7cCTh_V4nPdm0@0#%hY3%?sK1=wdCK^!pq>H=__UG zXa04*G=qhL|1E}w^^&efmOndMU=efw?%lt6CJYzsFYRV{t9+1~q2{dBs*-b_A*b)% z$T3^~wL8?W?eN3-ZY&Ic74~vp@Dtm^aA14Hk;&6HtjuL-sGI4x{Jqrijhzfzn%4(2 zFx<};$&zMR5Wej4%imYCN(1GOEAHjKASJYi;lTH(_FHTWFM8*ER#^IF#*J9FBU@K8 zY-wlJXZWyK3=||*`DU~C-UQkCF*k(2nlXb@l$YUvS&vgLGee2rxypjl(yur6?p{;> zjQN5R$V4-6G?(;!(R276`GJYy_7;wbx14s;9B5Svp;WD zbF!ov9uzFQ{BrlP!W<=rx8DzOFf=gl?#nv4yJnAvW^ebR9l0tU3=Oj0n!ZxUrG*(S z_;!^rG?+=cZv9aEwZc$_?|N!v-Iep)47-G6p z=TjK^8oJmR7WA$IWsx_o=PEaVL&j)N1n+|t9v_$(a=!)CUyyM*;_7mw#;$&5@xPaU z{`~oT^XAQTWu}JbGtZ{wOTE0iU2!jWL5NNTW5c#+P_*9Y1VyXKy8hEE_PH`25DdJ? zz#!8N4&vykL9=XrMsgpRIPn21L*H3Yc4$bSe2?`78z=xI)`A>j)BP^CAN5xOkQ5f;Bdc3=~3|KBnz2!@87+vGnZo6 zrS;rq$F5yf;queJo_A)ja%d7~crm*)WaZMy$N9IRC5?g&gGa@ zZ@!u1_xkbeU(Xd8WD^c@Gkm$Kbj6I}0<-0FN3YBn`RReBmzggJg6dq5aN^~cU;buo z-L<0s@rAwI7c_!VvhI()n`Cl%Mlyt>yS zzM8RQ8py1CbFQtt3^I+2H1cY{vAA`DCnwJ< zGE_M=i8CaW%Yh0ZYqh=H7xKmSFfi=i3i8&Q3pr-hmtWkgmEKj(Smo-<%y6JC29z7N z={&cISQ{q(wNUb^w>{$vL6A%TR)GqboX#(L3?L(ZgG0t<^1E1uMgIaA84e`sDm@DQ z{OI4mfBmOVdw0h%{0j^e*=~2AS>YfzLqP@q!flKV?!F^Y7O~91ILmPpwv|zW?-5X{m``*Q0F{uP`k*4$2K5kGU}X@^$BDaH#HG z6!qiZ)$^b{R9;@bUz*pU{^dQ^1)i?V3=Y+6A9HWzEiLlSWp?0yd5`shCMf2=MPHGB zbUbi>i|%uq4?<=Qbtf(P(>C8c|Fuw3aQ_T0hJB|P846&%a}+ z;TGj(VEDTk6!&YV2F-dhhyCkEwLKBM4eLLM2rw+T52~UTgo0czr{BZCu;98_pe}!& zoIa=-0ZNQtBp9ke$=bXxZVlUk{h-E%!x8Z;>1UsRdT-@r_&vE;&LnQlHXi*j<_FTC zko=GVuCYYxIy*oWIH=BYnZwh5*uIw|p*(H#&Dr3p;QqD!`pgHyLDj^Am98OMc~2kj zo^mN7m-)cECv(_WUwyU6PVaE{RfZpKphD!&(BR?PmC+!5zoIurE#a>Z0!| zN^XK#(hS>tzw0ra2aRVn|U^mzy?y>E+*c#-&Et&Q3m=i+T$K!<$2pQW{h* zFR5hIy0n`iryJD0+5JHv)cn1IlAe;%v(Ghqz2^;CQvAT%an~@k-I`TH%q#~Z#Gi1avlf6`J{u~3

r%Y)c%60Asy5zd~o4f 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

S`cE&}z6K<($aWwy;O-EE1kA9qPzXPkMtB4%0Db?Fbg)~~*qla-wO*f3fi6xAM0 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 I>zopr0M+6Lg#Z8m literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/3dr_gps/gps_19.png b/files/images/px4/calibration/3dr_gps/gps_19.png new file mode 100644 index 0000000000000000000000000000000000000000..0e19c227af9732905c9678dc185d91888b1be828 GIT binary patch literal 80885 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 literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/3dr_gps/gps_24.png b/files/images/px4/calibration/3dr_gps/gps_24.png new file mode 100644 index 0000000000000000000000000000000000000000..215b0b40426b5ff12accfd8025448a570aede4aa GIT binary patch literal 56471 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ⅈ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 literal 0 HcmV?d00001 diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index d9bd57f2f6..8be41b43a6 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -182,6 +182,22 @@ files/images/px4/menu/cogwheels.png files/images/px4/rc/cessna_back.png files/images/px4/rc/cessna_side.png + files/images/px4/calibration/3dr_gps/gps_15.png + files/images/px4/calibration/3dr_gps/gps_14.png + files/images/px4/calibration/3dr_gps/gps_13.png + files/images/px4/calibration/3dr_gps/gps_12.png + files/images/px4/calibration/3dr_gps/gps_19.png + files/images/px4/calibration/3dr_gps/gps_18.png + files/images/px4/calibration/3dr_gps/gps_17.png + files/images/px4/calibration/3dr_gps/gps_16.png + files/images/px4/calibration/3dr_gps/gps_07.png + files/images/px4/calibration/3dr_gps/gps_06.png + files/images/px4/calibration/3dr_gps/gps_05.png + files/images/px4/calibration/3dr_gps/gps_04.png + files/images/px4/calibration/3dr_gps/gps_03.png + files/images/px4/calibration/3dr_gps/gps_02.png + files/images/px4/calibration/3dr_gps/gps_01.png + files/images/px4/calibration/3dr_gps/gps_24.png files/styles/Vera.ttf diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc index e9c1fb72c0..e5eb3501fb 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc @@ -226,12 +226,12 @@ void QGCPX4SensorCalibration::setInstructionImage(const QString &path) void QGCPX4SensorCalibration::setAutopilotImage(int index) { - setAutopilotImage(QString(":/files/images/px4/calibration/pixhawk_%1.png").arg(index)); + setAutopilotImage(QString(":/files/images/px4/calibration/pixhawk_%1.png").arg(index, 2, 10, QChar('0'))); } void QGCPX4SensorCalibration::setGpsImage(int index) { - setGpsImage(QString(":/files/images/px4/calibration/gps_%1.png").arg(index)); + setGpsImage(QString(":/files/images/px4/calibration/3dr_gps/gps_%1.png").arg(index, 2, 10, QChar('0'))); } void QGCPX4SensorCalibration::setAutopilotOrientation(int index) -- GitLab From 2f9ccfd9a9016810abf7234f231fd788940dc64f Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sun, 1 Sep 2013 12:18:29 -0700 Subject: [PATCH 357/460] Custom plist file to set version number for Mac OSX --- Custom-Info.plist | 24 ++++++++++++++++++++++++ qgroundcontrol.pro | 4 +++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 Custom-Info.plist diff --git a/Custom-Info.plist b/Custom-Info.plist new file mode 100644 index 0000000000..ee8648c0b4 --- /dev/null +++ b/Custom-Info.plist @@ -0,0 +1,24 @@ + + + + + NSPrincipalClass + NSApplication + CFBundleIconFile + macx.icns + CFBundlePackageType + APPL + CFBundleVersion + 227 + CFBundleShortVersionString + 2.0.0 + CFBundleSignature + ???? + CFBundleExecutable + @EXECUTABLE@ + CFBundleIdentifier + org.qgroundcontrol.qgroundcontrol + NOTE + Open source ground control app provided by PX4 dev team + + diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index f61628c5d1..884185df6f 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -79,7 +79,9 @@ win32 { } } - +macx { + QMAKE_INFO_PLIST = Custom-Info.plist +} ################################################################# # EXTERNAL LIBRARY CONFIGURATION -- GitLab From 4194c297710d70f2cc40aa683db9f32aa94ed4fb Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sun, 1 Sep 2013 14:05:36 -0700 Subject: [PATCH 358/460] add win32 target version info --- qgroundcontrol.pro | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 884185df6f..3f2d56cf3a 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -62,6 +62,12 @@ MAVLINKPATH = $$BASEDIR/libs/mavlink/include/mavlink/v1.0 DEFINES += MAVLINK_NO_DATA win32 { + VERSION = 2.0.0.227 + QMAKE_TARGET_COMPANY = qgroundcontrol.org + QMAKE_TARGET_PRODUCT = qgroundcontrol + QMAKE_TARGET_DESCRIPTION = "Open source ground control app provided by PX4 dev team" + QMAKE_TARGET_COPYRIGHT = "Copyright (C) 2013 PX4 Development Team. All rights reserved." + QMAKE_INCDIR_QT = $$(QTDIR)/include QMAKE_LIBDIR_QT = $$(QTDIR)/lib QMAKE_UIC = "$$(QTDIR)/bin/uic.exe" -- GitLab From 9de036303074f90e6d11954088f7c95319212342 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sun, 1 Sep 2013 14:08:36 -0700 Subject: [PATCH 359/460] Use QGroundControl team instead of PX4 --- Custom-Info.plist | 2 +- qgroundcontrol.pro | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Custom-Info.plist b/Custom-Info.plist index ee8648c0b4..89cae30f60 100644 --- a/Custom-Info.plist +++ b/Custom-Info.plist @@ -19,6 +19,6 @@ CFBundleIdentifier org.qgroundcontrol.qgroundcontrol NOTE - Open source ground control app provided by PX4 dev team + Open source ground control app provided by QGroundControl dev team diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 3f2d56cf3a..2788a190bf 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -65,8 +65,8 @@ win32 { VERSION = 2.0.0.227 QMAKE_TARGET_COMPANY = qgroundcontrol.org QMAKE_TARGET_PRODUCT = qgroundcontrol - QMAKE_TARGET_DESCRIPTION = "Open source ground control app provided by PX4 dev team" - QMAKE_TARGET_COPYRIGHT = "Copyright (C) 2013 PX4 Development Team. All rights reserved." + QMAKE_TARGET_DESCRIPTION = "Open source ground control app provided by QGroundControl dev team" + QMAKE_TARGET_COPYRIGHT = "Copyright (C) 2013 QGroundControl Development Team. All rights reserved." QMAKE_INCDIR_QT = $$(QTDIR)/include QMAKE_LIBDIR_QT = $$(QTDIR)/lib -- GitLab From 08ed1b26bf3bdf9044626d591d73840e0635886b Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sun, 1 Sep 2013 14:28:12 -0700 Subject: [PATCH 360/460] clean references and update version number --- src/QGCCore.cc | 4 ++-- src/comm/SerialLink.cc | 4 ++-- src/configuration.h | 7 ++++--- src/ui/configuration/terminalconsole.cpp | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/QGCCore.cc b/src/QGCCore.cc index 4740f37059..04fe7e7b8c 100644 --- a/src/QGCCore.cc +++ b/src/QGCCore.cc @@ -77,8 +77,8 @@ QGCCore::QGCCore(bool firstStart, int &argc, char* argv[]) : QApplication(argc, // Set application name this->setApplicationName(QGC_APPLICATION_NAME); this->setApplicationVersion(QGC_APPLICATION_VERSION); - this->setOrganizationName(QLatin1String("diydrones")); - this->setOrganizationDomain("com.diydrones"); + this->setOrganizationName(QGC::ORG_NAME); + this->setOrganizationDomain(QGC::ORG_DOMAIN); // Set settings format QSettings::setDefaultFormat(QSettings::IniFormat); diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index e30f9e3c28..61af2ac043 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -106,7 +106,7 @@ QList SerialLink::getCurrentPorts() void SerialLink::loadSettings() { // Load defaults from settings - QSettings settings(QGC::COMPANYNAME, QGC::APPNAME); + QSettings settings(QGC::ORG_NAME, QGC::APPNAME); settings.sync(); if (settings.contains("SERIALLINK_COMM_PORT")) { @@ -122,7 +122,7 @@ void SerialLink::loadSettings() void SerialLink::writeSettings() { // Store settings - QSettings settings(QGC::COMPANYNAME, QGC::APPNAME); + QSettings settings(QGC::ORG_NAME, QGC::APPNAME); settings.setValue("SERIALLINK_COMM_PORT", getPortName()); settings.setValue("SERIALLINK_COMM_BAUD", getBaudRateType()); settings.setValue("SERIALLINK_COMM_PARITY", getParityType()); diff --git a/src/configuration.h b/src/configuration.h index d2397ccc75..2f04348123 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -11,14 +11,15 @@ #define WITH_TEXT_TO_SPEECH 1 #define QGC_APPLICATION_NAME "QGroundControl" -#define QGC_APPLICATION_VERSION "v. 1.1.2 (beta)" +#define QGC_APPLICATION_VERSION "v. 2.0.0 (beta)" namespace QGC { const QString APPNAME = "QGROUNDCONTROL"; -const QString COMPANYNAME = "QGROUNDCONTROL"; -const int APPLICATIONVERSION = 110; // 1.1.0 +const QString ORG_NAME = "QGROUNDCONTROL.ORG"; //can be customized by forks to e.g. mycompany.com to maintain separate Settings for customized apps +const QString ORG_DOMAIN = "org.qgroundcontrol";//can be customized by forks +const int APPLICATIONVERSION = 200; // 2.0.0 } #endif // QGC_CONFIGURATION_H diff --git a/src/ui/configuration/terminalconsole.cpp b/src/ui/configuration/terminalconsole.cpp index 919c646671..66ef546911 100644 --- a/src/ui/configuration/terminalconsole.cpp +++ b/src/ui/configuration/terminalconsole.cpp @@ -265,7 +265,7 @@ void TerminalConsole::setLink(int index) void TerminalConsole::loadSettings() { // Load defaults from settings - QSettings settings(QGC::COMPANYNAME, QGC::APPNAME); + QSettings settings(QGC::ORG_NAME, QGC::APPNAME); settings.sync(); if (settings.contains("TERMINALCONSOLE_COMM_PORT")) { @@ -287,7 +287,7 @@ void TerminalConsole::loadSettings() void TerminalConsole::writeSettings() { // Store settings - QSettings settings(QGC::COMPANYNAME, QGC::APPNAME); + QSettings settings(QGC::ORG_NAME, QGC::APPNAME); settings.setValue("TERMINALCONSOLE_COMM_PORT", m_settings.name); settings.setValue("TERMINALCONSOLE_COMM_BAUD", m_settings.baudRate); settings.setValue("TERMINALCONSOLE_COMM_PARITY", m_settings.parity); -- GitLab From c6d28ad1ec2a623054e3a091a2e5ddab853841b1 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 2 Sep 2013 08:20:38 +0200 Subject: [PATCH 361/460] Fixed indices on explanation images --- .../images/px4/calibration/3dr_gps/gps_00.png | Bin 0 -> 77187 bytes .../images/px4/calibration/3dr_gps/gps_01.png | Bin 77187 -> 58288 bytes .../images/px4/calibration/3dr_gps/gps_02.png | Bin 58288 -> 73246 bytes .../images/px4/calibration/3dr_gps/gps_03.png | Bin 73246 -> 59034 bytes .../images/px4/calibration/3dr_gps/gps_04.png | Bin 59034 -> 73697 bytes .../images/px4/calibration/3dr_gps/gps_05.png | Bin 73697 -> 72523 bytes .../images/px4/calibration/3dr_gps/gps_06.png | Bin 72523 -> 61146 bytes .../images/px4/calibration/3dr_gps/gps_07.png | Bin 61146 -> 0 bytes qgroundcontrol.qrc | 2 +- 9 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 files/images/px4/calibration/3dr_gps/gps_00.png delete mode 100644 files/images/px4/calibration/3dr_gps/gps_07.png diff --git a/files/images/px4/calibration/3dr_gps/gps_00.png b/files/images/px4/calibration/3dr_gps/gps_00.png new file mode 100644 index 0000000000000000000000000000000000000000..483c45ca09b5590ade075a30b3481c2d98ebb945 GIT binary patch literal 77187 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 Mp00i_>zopr06_~lK>z>% literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/3dr_gps/gps_01.png b/files/images/px4/calibration/3dr_gps/gps_01.png index 483c45ca09b5590ade075a30b3481c2d98ebb945..2bb8670270bb1d9d23e826b87c6640210aee1c50 100644 GIT binary patch literal 58288 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 Q9)RRLUHx3vIVCg!04%G};{X5v literal 77187 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 Mp00i_>zopr06_~lK>z>% diff --git a/files/images/px4/calibration/3dr_gps/gps_02.png b/files/images/px4/calibration/3dr_gps/gps_02.png index 2bb8670270bb1d9d23e826b87c6640210aee1c50..3a9f51c6e6a1e05c1f056a125dafb5c247488703 100644 GIT binary patch literal 73246 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 z�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 literal 58288 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 Q9)RRLUHx3vIVCg!04%G};{X5v diff --git a/files/images/px4/calibration/3dr_gps/gps_03.png b/files/images/px4/calibration/3dr_gps/gps_03.png index 3a9f51c6e6a1e05c1f056a125dafb5c247488703..2e945c1d744151ba66e3d616f5f8c459a8943da5 100644 GIT binary patch literal 59034 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 C5Tt1U literal 73246 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 z�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 diff --git a/files/images/px4/calibration/3dr_gps/gps_04.png b/files/images/px4/calibration/3dr_gps/gps_04.png index 2e945c1d744151ba66e3d616f5f8c459a8943da5..92f2e2fa47e46efb0c8303e5bdf4b187fb816c34 100644 GIT binary patch literal 73697 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

;Zk|8f{F8`bIIp!zSt;Py1LB|oRv3koW)tL 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 C5Tt1U diff --git a/files/images/px4/calibration/3dr_gps/gps_05.png b/files/images/px4/calibration/3dr_gps/gps_05.png index 92f2e2fa47e46efb0c8303e5bdf4b187fb816c34..f4c909906ed59c37f07c1767dc7694f01113dee0 100644 GIT binary patch literal 72523 zcmeAS@N?(olHy`uVBq!ia0y~yV69+aVEMzr#=yW}8T-PQfq{Xg*vT`5gM)*kh9jke zfq{Xuz$3Dl0S4wKsTnaaC@^@sIEGZ*dUJPUk#zXH7Z2?<`r0OBbS|;EFzd=S)->}F z_PQo-rk%}qIfQo}o1DL4W<;>~y0wMt*l+AjOg9hk^R8oJdvPXObywM(1m8$gbGetV*dr%lZd1EohV zFD~DH$)wlBx4r&lxqJNcnGabQ7`pr(urj2@sCPw5L214FSpNY}w<7jvIn;&zt*yi|PO-b3@Rc66l8 zTJ}}v^rG8upUwZT$2M{M;{pZ-23N%oObnMdNj`VE8~pmEo&B!fU}dFQk<+eTHj(Aq zD<~M>eu0~TL8RdTH$%+wa~F?iy50>0`DMWdmNu3UBmuuU{^0I6JU>N}5Z~(o8Loi;X=Wurk

_PkXpSjEWDuu`Ccalsz5#Wu5-#4d+8?faLu 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 z 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 J%Q~loCIFRuGg1Hm literal 73697 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

;Zk|8f{F8`bIIp!zSt;Py1LB|oRv3koW)tL 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 literal 72523 zcmeAS@N?(olHy`uVBq!ia0y~yV69+aVEMzr#=yW}8T-PQfq{Xg*vT`5gM)*kh9jke zfq{Xuz$3Dl0S4wKsTnaaC@^@sIEGZ*dUJPUk#zXH7Z2?<`r0OBbS|;EFzd=S)->}F z_PQo-rk%}qIfQo}o1DL4W<;>~y0wMt*l+AjOg9hk^R8oJdvPXObywM(1m8$gbGetV*dr%lZd1EohV zFD~DH$)wlBx4r&lxqJNcnGabQ7`pr(urj2@sCPw5L214FSpNY}w<7jvIn;&zt*yi|PO-b3@Rc66l8 zTJ}}v^rG8upUwZT$2M{M;{pZ-23N%oObnMdNj`VE8~pmEo&B!fU}dFQk<+eTHj(Aq zD<~M>eu0~TL8RdTH$%+wa~F?iy50>0`DMWdmNu3UBmuuU{^0I6JU>N}5Z~(o8Loi;X=Wurk

_PkXpSjEWDuu`Ccalsz5#Wu5-#4d+8?faLu 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 z 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 J%Q~loCIFRuGg1Hm diff --git a/files/images/px4/calibration/3dr_gps/gps_07.png b/files/images/px4/calibration/3dr_gps/gps_07.png deleted file mode 100644 index 021fcd497b627e85dfe2eef7e1e9a6d7407819e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61146 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 diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 8be41b43a6..f6e42aa5e5 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -190,7 +190,6 @@ files/images/px4/calibration/3dr_gps/gps_18.png files/images/px4/calibration/3dr_gps/gps_17.png files/images/px4/calibration/3dr_gps/gps_16.png - files/images/px4/calibration/3dr_gps/gps_07.png files/images/px4/calibration/3dr_gps/gps_06.png files/images/px4/calibration/3dr_gps/gps_05.png files/images/px4/calibration/3dr_gps/gps_04.png @@ -198,6 +197,7 @@ files/images/px4/calibration/3dr_gps/gps_02.png files/images/px4/calibration/3dr_gps/gps_01.png files/images/px4/calibration/3dr_gps/gps_24.png + files/images/px4/calibration/3dr_gps/gps_00.png files/styles/Vera.ttf -- GitLab From 81524eeb43e4ae71245fded1a581a7a14d2e597e Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 2 Sep 2013 09:01:06 +0200 Subject: [PATCH 362/460] Added DSM binding support, improved mag and board rotation UI support --- src/ui/QGCPX4VehicleConfig.cc | 23 +++ src/ui/QGCPX4VehicleConfig.h | 2 + src/ui/QGCPX4VehicleConfig.ui | 134 +++++++++++------- .../QGCPX4SensorCalibration.cc | 20 ++- .../QGCPX4SensorCalibration.ui | 6 + 5 files changed, 128 insertions(+), 57 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 9ab20d3241..04bd330d03 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -154,7 +154,11 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : ui->graphicsView->hide(); ui->rcCalibrationButton->setCheckable(true); + ui->rcCalibrationButton->setEnabled(false); connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool))); + ui->spektrumPairButton->setCheckable(true); + ui->spektrumPairButton->setEnabled(false); + connect(ui->spektrumPairButton, SIGNAL(clicked(bool)), this, SLOT(toggleSpektrumPairing(bool))); //TODO connect buttons here to save/clear actions? UASInterface* tmpMav = UASManager::instance()->getActiveUAS(); @@ -329,6 +333,22 @@ void QGCPX4VehicleConfig::toggleCalibrationRC(bool enabled) } } +void QGCPX4VehicleConfig::toggleSpektrumPairing(bool enabled) +{ + if (enabled) + { + mav->getParamManager()->setPendingParam(0, "RC_DSM_BIND", (int)1); + // Do not save this parameter, just set in RAM + mav->getParamManager()->sendPendingParameters(); + } + else + { + mav->getParamManager()->setPendingParam(0, "RC_DSM_BIND", (int)0); + // Do not save this parameter, just set in RAM + mav->getParamManager()->sendPendingParameters(); + } +} + void QGCPX4VehicleConfig::setTrimPositions() { int rollMap = rcMapping[0]; @@ -1140,6 +1160,9 @@ void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active) ui->airframeMenuButton->setEnabled(true); ui->sensorMenuButton->setEnabled(true); ui->rcMenuButton->setEnabled(true); + + ui->rcCalibrationButton->setEnabled(true); + ui->spektrumPairButton->setEnabled(true); } void QGCPX4VehicleConfig::resetCalibrationRC() diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index 62d11c0143..55778bc3a8 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -60,6 +60,8 @@ public slots: void stopCalibrationRC(); /** Start/stop the RC calibration routine */ void toggleCalibrationRC(bool enabled); + /** Start/stop the Spektrum pair routine */ + void toggleSpektrumPairing(bool enabled); /** Set trim positions */ void setTrimPositions(); /** Detect which channels need to be inverted */ diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 858e409363..db6fbd9f21 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -7,7 +7,7 @@ 0 0 1256 - 985 + 1009 @@ -50,9 +50,25 @@ - - - + + + + + + 50 + 200 + + + + + 50 + 200 + + + + + + 250 @@ -67,6 +83,28 @@ + + + + + 1 + 0 + + + + + 50 + 200 + + + + + 50 + 200 + + + + @@ -135,30 +173,8 @@ - - - - - 1 - 0 - - - - - 50 - 200 - - - - - 50 - 200 - - - - - - + + 250 @@ -173,28 +189,36 @@ - - - - - 50 - 200 - - - - - 50 - 200 - - - - - - - Start Calibration - - + + + + + Start Calibration + + + + + + + Spektrum RC Pairing + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + @@ -829,8 +853,8 @@ 0 0 - 98 - 28 + 16 + 16 @@ -866,8 +890,8 @@ 0 0 - 98 - 28 + 16 + 16 @@ -917,8 +941,8 @@ 0 0 - 98 - 28 + 16 + 16 diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc index e5eb3501fb..6ba8f4c4e2 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc @@ -67,6 +67,18 @@ QGCPX4SensorCalibration::QGCPX4SensorCalibration(QWidget *parent) : ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_270_YAW_135"), 23); ui->autopilotComboBox->addItem(tr("ROTATION_PITCH_90"), 24); ui->autopilotComboBox->addItem(tr("ROTATION_PITCH_270"), 25); + ui->autopilotComboBox->addItem(tr("ROTATION_PITCH_180_YAW_90"), 26); + ui->autopilotComboBox->addItem(tr("ROTATION_PITCH_180_YAW_270"), 27); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_90_PITCH_90"), 28); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_180_PITCH_90"), 29); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_270_PITCH_90"), 30); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_90_PITCH_180"), 31); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_270_PITCH_180"), 32); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_90_PITCH_270"), 33); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_180_PITCH_270"), 34); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_270_PITCH_270"), 35); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_90_PITCH_180_YAW_90"), 36); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_90_YAW_270"), 37); ui->magComboBox->addItem(tr("Default Orientation"), 0); ui->magComboBox->addItem(tr("ROTATION_YAW_45"), 1); @@ -381,8 +393,10 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever accelStarted = false; // XXX use a confirmation image or something setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); - if (activeUAS) + if (activeUAS) { activeUAS->requestParameter(0, "SENS_ACC_XOFF"); + activeUAS->requestParameter(0, "SENS_BOARD_ROT"); + } } if (text.contains("gyro calibration done")) { @@ -398,8 +412,10 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever magStarted = false; // XXX use a confirmation image or something setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); - if (activeUAS) + if (activeUAS) { activeUAS->requestParameter(0, "SENS_MAG_XOFF"); + activeUAS->requestParameter(0, "SENS_EXT_MAG_ROT"); + } } if (text.contains("accel calibration started")) { diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui index 0533f386bb..411796a590 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui @@ -179,6 +179,12 @@ QPushButton#gyroButton, QPushButton#accelButton { + + + 150 + 150 + + -- GitLab From 33dde65ddf841a392df5424395977f44b06420db Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 2 Sep 2013 21:59:16 +0200 Subject: [PATCH 363/460] Improved sensor calibration UI --- .../QGCPX4SensorCalibration.ui | 138 ++++++++++-------- 1 file changed, 76 insertions(+), 62 deletions(-) diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui index 411796a590..e954372126 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui @@ -6,8 +6,8 @@ 0 0 - 657 - 598 + 659 + 603 @@ -36,74 +36,37 @@ QPushButton#gyroButton, QPushButton#accelButton { border: 2px solid #465158; } - + - - - Autopilot and GPS / Compass Orientation - - - - - - - - - - - - - - 24 - - + - - + + - Qt::Vertical + Qt::Horizontal - 498 - 5 + 40 + 20 - - + + - Qt::Horizontal + Qt::Vertical - 40 - 20 + 498 + 5 - - - - - - - - - - - - - - - - true - - - - + @@ -170,26 +133,77 @@ QPushButton#gyroButton, QPushButton#accelButton { - - + + + + 24 + + + + + + + Autopilot Orientation + + + + + + + 0 + 250 + + + + + + + + + + + + + + + - - - - - 150 - 150 - - + + + + + + Magnetometer Orientation + + + + + + + 150 + 120 + + + + + + + + + + + + + -- GitLab From a5fb558a8cd16b046dd6cac5870d49895e2ddcee Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Tue, 3 Sep 2013 08:19:18 +0200 Subject: [PATCH 364/460] Allow higher error count --- src/comm/SerialLink.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 61af2ac043..6ae7105f59 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -174,7 +174,7 @@ void SerialLink::run() } } - if (isConnected() && (linkErrorCount > 100)) { + if (isConnected() && (linkErrorCount > 1000)) { qDebug() << "linkErrorCount too high: disconnecting!"; linkErrorCount = 0; emit communicationUpdate(getName(), tr("Disconnecting on too many link errors")); -- GitLab From a0f71c30aed8ff399edfbe77f8038337e5fba8d8 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Wed, 4 Sep 2013 13:36:19 +0200 Subject: [PATCH 365/460] Added QUpgrade submodule --- .gitignore | 1 - .gitmodules | 3 +++ qupgrade | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .gitmodules create mode 160000 qupgrade diff --git a/.gitignore b/.gitignore index 6a777bb495..5c9f0e4f34 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,5 @@ thirdParty/qserialport-build-desktop/ thirdParty/qserialport/bin/ thirdParty/qserialport/lib/ GeneratedFiles/ -/qupgrade/ *.autosave diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..3f0d4baa87 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "qupgrade"] + path = qupgrade + url = https://github.com/LorenzMeier/qupgrade.git diff --git a/qupgrade b/qupgrade new file mode 160000 index 0000000000..faa4f1a757 --- /dev/null +++ b/qupgrade @@ -0,0 +1 @@ +Subproject commit faa4f1a757b372ac1534d76cf996501b296557a7 -- GitLab From 88921e7db798316ad0881d436ae798ece6c0ad9c Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Wed, 4 Sep 2013 13:15:31 +0200 Subject: [PATCH 366/460] Linux compile fix --- src/QGC.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/QGC.h b/src/QGC.h index bf36900d33..e49b2a4ce7 100644 --- a/src/QGC.h +++ b/src/QGC.h @@ -49,7 +49,7 @@ inline bool isinf(T value) { return (value == std::numeric_limits::infinity() || (-1*value) == std::numeric_limits::infinity()) && std::numeric_limits::has_infinity; } -#else +#elif defined __APPLE__ #include #ifndef isnan #define isnan(x) std::isnan(x) -- GitLab From cb3618b824b06e16109a32ccab08115bd5f44889 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Wed, 4 Sep 2013 15:56:05 +0200 Subject: [PATCH 367/460] Fix math calls --- README | 1 - src/uas/senseSoarMAV.cpp | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README b/README index 1952d7d2bd..7f00e42398 100644 --- a/README +++ b/README @@ -1,4 +1,3 @@ -maah QGroundControl Open Source Micro Air Vehicle Ground Control Station Project: diff --git a/src/uas/senseSoarMAV.cpp b/src/uas/senseSoarMAV.cpp index fc1ad32031..fee4838629 100644 --- a/src/uas/senseSoarMAV.cpp +++ b/src/uas/senseSoarMAV.cpp @@ -1,4 +1,5 @@ #include "senseSoarMAV.h" +#include #include senseSoarMAV::senseSoarMAV(MAVLinkProtocol* mavlink, int id) @@ -207,8 +208,8 @@ void senseSoarMAV::receiveMessage(LinkInterface *link, mavlink_message_t message void senseSoarMAV::quat2euler(const double *quat, double &roll, double &pitch, double &yaw) { - roll = std::atan2(2*(quat[0]*quat[1] + quat[2]*quat[3]),quat[0]*quat[0] - quat[1]*quat[1] - quat[2]*quat[2] + quat[3]*quat[3]); - pitch = std::asin(qMax(-1.0,qMin(1.0,2*(quat[0]*quat[2] - quat[1]*quat[3])))); - yaw = std::atan2(2*(quat[1]*quat[2] + quat[0]*quat[3]),quat[0]*quat[0] + quat[1]*quat[1] - quat[2]*quat[2] - quat[3]*quat[3]); + roll = atan2(2*(quat[0]*quat[1] + quat[2]*quat[3]),quat[0]*quat[0] - quat[1]*quat[1] - quat[2]*quat[2] + quat[3]*quat[3]); + pitch = asin(qMax(-1.0,qMin(1.0,2*(quat[0]*quat[2] - quat[1]*quat[3])))); + yaw = atan2(2*(quat[1]*quat[2] + quat[0]*quat[3]),quat[0]*quat[0] + quat[1]*quat[1] - quat[2]*quat[2] - quat[3]*quat[3]); return; } -- GitLab From 46b5453cbd187480405675338dc8f985ec0423b7 Mon Sep 17 00:00:00 2001 From: akistanov Date: Thu, 5 Sep 2013 18:06:32 +0400 Subject: [PATCH 368/460] fix windows build --- src/comm/XbeeLink.h | 4 ++-- src/ui/MainWindow.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/comm/XbeeLink.h b/src/comm/XbeeLink.h index 52ff65706e..4159cf9593 100644 --- a/src/comm/XbeeLink.h +++ b/src/comm/XbeeLink.h @@ -20,9 +20,9 @@ public: ~XbeeLink(); public: // virtual functions from XbeeLinkInterface - QString getPortName(); + QString getPortName() const; void requestReset() { } - int getBaudRate(); + int getBaudRate() const; public slots: // virtual functions from XbeeLinkInterface bool setPortName(QString portName); diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 23893f5269..354c73b4b1 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -719,7 +719,7 @@ void MainWindow::buildCommonWidgets() #endif #if (defined _MSC_VER) /*| (defined Q_OS_MAC) mac os doesn't support gearth right now */ - if (!gEarthWidget) + if (!earthWidget) { earthWidget = new QGCGoogleEarthView(this); addToCentralStackedWidget(earthWidget,VIEW_GOOGLEEARTH, tr("Google Earth")); -- GitLab From 8548528599f46680997b8162ce21a210b4a6ac08 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Fri, 6 Sep 2013 08:55:40 +0200 Subject: [PATCH 369/460] Fixed toolbar fun when disconnected --- src/ui/QGCToolBar.cc | 119 ++++++++++++++++++++++++------------------- src/ui/QGCToolBar.h | 4 ++ 2 files changed, 71 insertions(+), 52 deletions(-) diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index c75b8554b9..7ed5c55485 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -77,8 +77,7 @@ void QGCToolBar::heartbeatTimeout(bool timeout, unsigned int ms) } toolBarTimeoutLabel->setText(tr("CONNECTION LOST: %1 s").arg((ms / 1000.0f), 2, 'f', 1, ' ')); toolBarTimeoutAction->setVisible(true); - - toolBarMessageLabel->hide(); + toolBarMessageAction->setVisible(false); } else { @@ -86,8 +85,7 @@ void QGCToolBar::heartbeatTimeout(bool timeout, unsigned int ms) if (toolBarTimeoutAction->isVisible()) { toolBarTimeoutAction->setVisible(false); - - toolBarMessageLabel->show(); + toolBarMessageAction->setVisible(true); } } } @@ -124,11 +122,11 @@ void QGCToolBar::createUI() toolBarModeLabel->setAlignment(Qt::AlignCenter); addWidget(toolBarModeLabel); - toolBarStateLabel = new QLabel(this); - toolBarStateLabel->setToolTip(tr("Vehicle state")); - toolBarStateLabel->setObjectName("toolBarStateLabel"); - toolBarStateLabel->setAlignment(Qt::AlignCenter); - addWidget(toolBarStateLabel); +// toolBarStateLabel = new QLabel(this); +// toolBarStateLabel->setToolTip(tr("Vehicle state")); +// toolBarStateLabel->setObjectName("toolBarStateLabel"); +// toolBarStateLabel->setAlignment(Qt::AlignCenter); +// addWidget(toolBarStateLabel); toolBarBatteryBar = new QProgressBar(this); toolBarBatteryBar->setMinimum(0); @@ -150,12 +148,12 @@ void QGCToolBar::createUI() toolBarWpLabel->setToolTip(tr("Current waypoint")); toolBarWpLabel->setObjectName("toolBarWpLabel"); toolBarWpLabel->setAlignment(Qt::AlignCenter); - addWidget(toolBarWpLabel); + toolBarWpAction = addWidget(toolBarWpLabel); toolBarMessageLabel = new QLabel(this); toolBarMessageLabel->setToolTip(tr("Most recent system message")); toolBarMessageLabel->setObjectName("toolBarMessageLabel"); - addWidget(toolBarMessageLabel); + toolBarMessageAction = addWidget(toolBarMessageLabel); QWidget* spacer = new QWidget(); spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -165,7 +163,7 @@ void QGCToolBar::createUI() portComboBox->setToolTip(tr("Choose the COM port to use")); portComboBox->setEnabled(true); portComboBox->setMinimumWidth(100); - addWidget(portComboBox); + toolBarPortAction = addWidget(portComboBox); baudcomboBox = new QComboBox(this); baudcomboBox->setToolTip(tr("Choose what baud rate to use")); @@ -181,7 +179,7 @@ void QGCToolBar::createUI() baudcomboBox->addItem("460800", 460800); baudcomboBox->addItem("921600", 921600); baudcomboBox->setCurrentIndex(baudcomboBox->findData(57600)); - addWidget(baudcomboBox); + toolBarBaudAction = addWidget(baudcomboBox); connect(baudcomboBox, SIGNAL(activated(int)), this, SLOT(baudSelected(int))); connect(portComboBox, SIGNAL(activated(int)), this, SLOT(portSelected(int))); @@ -206,8 +204,8 @@ void QGCToolBar::createUI() // Update label if required if (LinkManager::instance()->getSerialLinks().count() < 1) { connectButton->setText(tr("New Serial Link")); - baudcomboBox->hide(); - portComboBox->hide(); + toolBarPortAction->setVisible(false); + toolBarBaudAction->setVisible(false); } else { QList links = LinkManager::instance()->getSerialLinks(); @@ -241,7 +239,7 @@ void QGCToolBar::resetToolbarUI() //toolBarTimeoutLabel->show(); toolBarSafetyLabel->setText("----"); toolBarModeLabel->setText("------"); - toolBarStateLabel->setText("------"); +// toolBarStateLabel->setText("------"); toolBarBatteryBar->setValue(0); toolBarBatteryBar->setDisabled(true); toolBarBatteryVoltageLabel->setText("xx.x V"); @@ -401,11 +399,14 @@ void QGCToolBar::setActiveUAS(UASInterface* active) // Update all values once systemName = mav->getUASName(); systemArmed = mav->isArmed(); - toolBarNameLabel->setText(mav->getUASName()); + toolBarNameLabel->setText(mav->getUASName().replace("MAV", "")); toolBarNameLabel->setStyleSheet(QString("QLabel {color: %1;}").arg(mav->getColor().name())); symbolLabel->setStyleSheet(QString("QWidget {background-color: %1;}").arg(mav->getColor().name())); - toolBarModeLabel->setText(mav->getShortMode()); - toolBarStateLabel->setText(mav->getShortState()); + QString shortMode = mav->getShortMode(); + shortMode = shortMode.replace("D|", ""); + shortMode = shortMode.replace("A|", ""); + toolBarModeLabel->setText(shortMode); +// toolBarStateLabel->setText(mav->getShortState()); toolBarTimeoutAction->setVisible(false); toolBarMessageLabel->clear(); lastSystemMessageTimeMs = 0; @@ -430,37 +431,47 @@ void QGCToolBar::updateArmingState(bool armed) void QGCToolBar::updateView() { if (!changed) return; - toolBarWpLabel->setText(tr("WP%1").arg(wpId)); - toolBarBatteryBar->setValue(batteryPercent); - if (batteryPercent < 30 && toolBarBatteryBar->value() >= 30) { - if (MainWindow::instance()->getStyle() == MainWindow::QGC_MAINWINDOW_STYLE_LIGHT) - { - toolBarBatteryBar->setStyleSheet("QProgressBar {color: #FFF} QProgressBar::chunk { background-color: #008000}"); - } - else - { - toolBarBatteryBar->setStyleSheet("QProgressBar {color: #000} QProgressBar QProgressBar::chunk { background-color: #0F0}"); - } - } else if (batteryPercent >= 30 && toolBarBatteryBar->value() < 30){ - if (MainWindow::instance()->getStyle() == MainWindow::QGC_MAINWINDOW_STYLE_LIGHT) - { - toolBarBatteryBar->setStyleSheet("QProgressBar {color: #FFF} QProgressBar::chunk { background-color: #808000}"); - } - else - { - toolBarBatteryBar->setStyleSheet("QProgressBar {color: #000} QProgressBar QProgressBar::chunk { background-color: #FF0}"); + if (toolBarWpLabel->isVisible()) + toolBarWpLabel->setText(tr("WP%1").arg(wpId)); + + if (toolBarBatteryBar->isVisible()) { + toolBarBatteryBar->setValue(batteryPercent); + + if (batteryPercent < 30 && toolBarBatteryBar->value() >= 30) { + if (MainWindow::instance()->getStyle() == MainWindow::QGC_MAINWINDOW_STYLE_LIGHT) + { + toolBarBatteryBar->setStyleSheet("QProgressBar {color: #FFF} QProgressBar::chunk { background-color: #008000}"); + } + else + { + toolBarBatteryBar->setStyleSheet("QProgressBar {color: #000} QProgressBar QProgressBar::chunk { background-color: #0F0}"); + } + } else if (batteryPercent >= 30 && toolBarBatteryBar->value() < 30){ + if (MainWindow::instance()->getStyle() == MainWindow::QGC_MAINWINDOW_STYLE_LIGHT) + { + toolBarBatteryBar->setStyleSheet("QProgressBar {color: #FFF} QProgressBar::chunk { background-color: #808000}"); + } + else + { + toolBarBatteryBar->setStyleSheet("QProgressBar {color: #000} QProgressBar QProgressBar::chunk { background-color: #FF0}"); + } } + + toolBarBatteryVoltageLabel->setText(tr("%1 V").arg(batteryVoltage, 4, 'f', 1, ' ')); } - toolBarBatteryVoltageLabel->setText(tr("%1 V").arg(batteryVoltage, 4, 'f', 1, ' ')); - toolBarStateLabel->setText(QString("%1").arg(state)); + +// toolBarStateLabel->setText(QString("%1").arg(state)); toolBarModeLabel->setText(QString("%1").arg(mode)); toolBarNameLabel->setText(systemName); // expire after 15 seconds - if (QGC::groundTimeMilliseconds() - lastSystemMessageTimeMs < 15000) { - toolBarMessageLabel->setText(QString("%1").arg(lastSystemMessage)); - } else { - toolBarMessageLabel->clear(); + + if (toolBarMessageLabel->isVisible()) { + if (QGC::groundTimeMilliseconds() - lastSystemMessageTimeMs < 15000) { + toolBarMessageLabel->setText(QString("%1").arg(lastSystemMessage)); + } else { + toolBarMessageLabel->clear(); + } } // Display the system armed state with a red-on-yellow background if armed or green text if safe. @@ -627,8 +638,8 @@ void QGCToolBar::addLink(LinkInterface* link) if (serial && !currentLink) { - baudcomboBox->show(); - portComboBox->show(); + toolBarPortAction->setVisible(true); + toolBarBaudAction->setVisible(true); currentLink = link; connect(currentLink, SIGNAL(connected(bool)), this, SLOT(updateLinkState(bool))); @@ -664,7 +675,7 @@ void QGCToolBar::removeLink(LinkInterface* link) } void QGCToolBar::updateComboBox() { - if (currentLink) + if (currentLink && !currentLink->isConnected()) { // Do not update if not visible if (!portComboBox->isVisible()) @@ -713,14 +724,16 @@ void QGCToolBar::updateComboBox() void QGCToolBar::updateLinkState(bool connected) { Q_UNUSED(connected); - if (currentLink && currentLink->isConnected()) + if (currentLink && currentLink->isConnected() && portComboBox->isVisible()) { connectButton->setText(tr("Disconnect")); connectButton->blockSignals(true); connectButton->setChecked(true); connectButton->blockSignals(false); - portComboBox->hide(); - baudcomboBox->hide(); + toolBarPortAction->setVisible(false); + toolBarBaudAction->setVisible(false); + toolBarMessageAction->setVisible(true); + toolBarWpAction->setVisible(true); } else { @@ -728,8 +741,10 @@ void QGCToolBar::updateLinkState(bool connected) connectButton->blockSignals(true); connectButton->setChecked(false); connectButton->blockSignals(false); - portComboBox->show(); - baudcomboBox->show(); + toolBarPortAction->setVisible(true); + toolBarBaudAction->setVisible(true); + toolBarMessageAction->setVisible(false); + toolBarWpAction->setVisible(false); } } diff --git a/src/ui/QGCToolBar.h b/src/ui/QGCToolBar.h index 65495ec8ce..e31d1731f5 100644 --- a/src/ui/QGCToolBar.h +++ b/src/ui/QGCToolBar.h @@ -109,6 +109,10 @@ protected: QLabel* toolBarNameLabel; QLabel* toolBarTimeoutLabel; QAction* toolBarTimeoutAction; ///< Needed to set label (in)visible. + QAction* toolBarMessageAction; + QAction* toolBarPortAction; + QAction* toolBarBaudAction; + QAction* toolBarWpAction; QLabel* toolBarSafetyLabel; QLabel* toolBarModeLabel; QLabel* toolBarStateLabel; -- GitLab From 5322c774892be0ad37d1038d418d5fdd8187618c Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Fri, 6 Sep 2013 08:59:42 +0200 Subject: [PATCH 370/460] Final toolbar tweaks --- src/ui/QGCToolBar.cc | 6 ++++-- src/ui/QGCToolBar.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 7ed5c55485..99e1425d9a 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -78,6 +78,7 @@ void QGCToolBar::heartbeatTimeout(bool timeout, unsigned int ms) toolBarTimeoutLabel->setText(tr("CONNECTION LOST: %1 s").arg((ms / 1000.0f), 2, 'f', 1, ' ')); toolBarTimeoutAction->setVisible(true); toolBarMessageAction->setVisible(false); + toolBarBatteryBarAction->setVisible(false); } else { @@ -86,6 +87,7 @@ void QGCToolBar::heartbeatTimeout(bool timeout, unsigned int ms) { toolBarTimeoutAction->setVisible(false); toolBarMessageAction->setVisible(true); + toolBarBatteryBarAction->setVisible(true); } } } @@ -136,13 +138,13 @@ void QGCToolBar::createUI() toolBarBatteryBar->setToolTip(tr("Battery charge level")); toolBarBatteryBar->setObjectName("toolBarBatteryBar"); toolBarBatteryBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding); - addWidget(toolBarBatteryBar); + toolBarBatteryBarAction = addWidget(toolBarBatteryBar); toolBarBatteryVoltageLabel = new QLabel(this); toolBarBatteryVoltageLabel->setToolTip(tr("Battery voltage")); toolBarBatteryVoltageLabel->setObjectName("toolBarBatteryVoltageLabel"); toolBarBatteryVoltageLabel->setAlignment(Qt::AlignCenter); - addWidget(toolBarBatteryVoltageLabel); + toolBarBatteryVoltageAction = addWidget(toolBarBatteryVoltageLabel); toolBarWpLabel = new QLabel(this); toolBarWpLabel->setToolTip(tr("Current waypoint")); diff --git a/src/ui/QGCToolBar.h b/src/ui/QGCToolBar.h index e31d1731f5..e161bcc9d8 100644 --- a/src/ui/QGCToolBar.h +++ b/src/ui/QGCToolBar.h @@ -113,6 +113,8 @@ protected: QAction* toolBarPortAction; QAction* toolBarBaudAction; QAction* toolBarWpAction; + QAction* toolBarBatteryBarAction; + QAction* toolBarBatteryVoltageAction; QLabel* toolBarSafetyLabel; QLabel* toolBarModeLabel; QLabel* toolBarStateLabel; -- GitLab From af3ace3b71e538bf97cad6f69e3a3c8e95c6a504 Mon Sep 17 00:00:00 2001 From: Jean Cyr Date: Sat, 7 Sep 2013 14:43:13 -0400 Subject: [PATCH 371/460] Don't flood log with debug info --- src/uas/UAS.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 75da0e1d2e..2408409dbe 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -2611,7 +2611,7 @@ void UAS::requestParameter(int component, const QString& parameter) read.target_component = component; mavlink_msg_param_request_read_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &read); sendMessage(msg); - qDebug() << __FILE__ << __LINE__ << "REQUESTING PARAM RETRANSMISSION FROM COMPONENT" << component << "FOR PARAM NAME" << parameter; + //qDebug() << __FILE__ << __LINE__ << "REQUESTING PARAM RETRANSMISSION FROM COMPONENT" << component << "FOR PARAM NAME" << parameter; } /** -- GitLab From e87936ccb0e2a00ad7f444683dab037973cb03c5 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 8 Sep 2013 18:21:50 +0200 Subject: [PATCH 372/460] Added DSM-X support --- src/ui/QGCPX4VehicleConfig.cc | 16 +++++++++++++++- src/ui/QGCPX4VehicleConfig.ui | 29 +++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 04bd330d03..0176aa6598 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -335,9 +335,23 @@ void QGCPX4VehicleConfig::toggleCalibrationRC(bool enabled) void QGCPX4VehicleConfig::toggleSpektrumPairing(bool enabled) { + if (!ui->dsm2RadioButton->isChecked() && !ui->dsmxRadioButton) { + // Reject + QMessageBox warnMsgBox; + warnMsgBox.setText(tr("Please select a Spektrum Protocol Version")); + warnMsgBox.setInformativeText(tr("Please select either DSM2 or DSM-X\ndirectly below the pair button,\nbased on the receiver type.")); + warnMsgBox.setStandardButtons(QMessageBox::Ok); + warnMsgBox.setDefaultButton(QMessageBox::Ok); + (void)warnMsgBox.exec(); + } + if (enabled) { - mav->getParamManager()->setPendingParam(0, "RC_DSM_BIND", (int)1); + int mode = 1; // DSM2 + if (ui->dsmxRadioButton->isChecked()) + mode = 2; // DSMX + + mav->getParamManager()->setPendingParam(0, "RC_DSM_BIND", mode); // Do not save this parameter, just set in RAM mav->getParamManager()->sendPendingParameters(); } diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index db6fbd9f21..26210d1c87 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -205,6 +205,23 @@ + + + + DSM2 Mode + + + true + + + + + + + DSMX Mode + + + @@ -853,8 +870,8 @@ 0 0 - 16 - 16 + 98 + 28 @@ -890,8 +907,8 @@ 0 0 - 16 - 16 + 98 + 28 @@ -941,8 +958,8 @@ 0 0 - 16 - 16 + 98 + 28 -- GitLab From dac4d313dc8835398a81d404f6b74232d204a59c Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 8 Sep 2013 20:43:52 +0200 Subject: [PATCH 373/460] Added HILSTAR --- src/ui/px4_configuration/QGCPX4AirframeConfig.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index f550417240..28a7b85b4a 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -27,6 +27,7 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : ui->planeComboBox->addItem(tr("Multiplex Easystar 1/2"), 100); ui->planeComboBox->addItem(tr("Hobbyking Bixler 1/2"), 101); + ui->planeComboBox->addItem(tr("HilStar (SIMULATION)"), 1000); connect(ui->planePushButton, SIGNAL(clicked()), this, SLOT(planeSelected())); connect(ui->planeComboBox, SIGNAL(activated(int)), this, SLOT(planeSelected(int))); -- GitLab From 8216b137c7522afc37ca92c678ca8d6b876d221d Mon Sep 17 00:00:00 2001 From: Jean Cyr Date: Sun, 8 Sep 2013 23:04:54 -0400 Subject: [PATCH 374/460] Fix Spektrum pair buton such that it works every time. - MAV resets the RC_DSM_BIND param back to 0 automatically but QGC doesn't know about this and thinks the parameter hasn't changed when the pair button is hit a second time. Since it thinks the param has not change, it doesn't transmit the update. - This implements method to allow to optionally force QGC to send the update. By default it does not - Also added copy statements to include the two missing DLLs (QtDeclarative and QtScript) automatically as part of Windows build. --- qupgrade.pro | 4 ++++ src/uas/QGCUASParamManager.cc | 8 ++++---- src/uas/QGCUASParamManager.h | 4 ++-- src/uas/UASParameterCommsMgr.cc | 24 +++++++++++++----------- src/uas/UASParameterCommsMgr.h | 4 ++-- src/uas/UASParameterDataModel.cc | 18 ++++++++++-------- src/uas/UASParameterDataModel.h | 2 +- src/ui/QGCPX4VehicleConfig.cc | 23 +++++++---------------- 8 files changed, 43 insertions(+), 44 deletions(-) diff --git a/qupgrade.pro b/qupgrade.pro index 728a67558e..296785ff82 100644 --- a/qupgrade.pro +++ b/qupgrade.pro @@ -223,6 +223,8 @@ win32-msvc2008|win32-msvc2010 { QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtWebKitd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXmld4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXmlPatternsd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) + QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtDeclaratived4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) + QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtScriptd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) } CONFIG(release, debug|release) { @@ -242,6 +244,8 @@ win32-msvc2008|win32-msvc2010 { QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtWebKit4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXml4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXmlPatterns4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n)) + QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtDeclarative4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) + QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtScript4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(del /F "$$TARGETDIR_WIN\\release\\qupgrade.exp"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(del /F "$$TARGETDIR_WIN\\release\\qupgrade.lib"$$escape_expand(\\n)) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index c4d81c7761..5a3442b5ab 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -124,21 +124,21 @@ void QGCUASParamManager::setParameter(int compId, QString paramName, QVariant va paramDataModel.updatePendingParamWithValue(compId,paramName,value); } -void QGCUASParamManager::sendPendingParameters(bool persistAfterSend) +void QGCUASParamManager::sendPendingParameters(bool persistAfterSend, bool forceSend) { - paramCommsMgr->sendPendingParameters(persistAfterSend); + paramCommsMgr->sendPendingParameters(persistAfterSend, forceSend); } -void QGCUASParamManager::setPendingParam(int compId, const QString& paramName, const QVariant& value) +void QGCUASParamManager::setPendingParam(int compId, const QString& paramName, const QVariant& value, bool forceSend) { if ((0 == compId) || (-1 == compId)) { //attempt to get an actual component ID compId = paramDataModel.getDefaultComponentId(); } - paramDataModel.updatePendingParamWithValue(compId,paramName,value); + paramDataModel.updatePendingParamWithValue(compId,paramName,value, forceSend); } diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 84efadfeed..4fd05aa341 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -90,7 +90,7 @@ public slots: /** @brief Send all pending parameters to the MAV, for storage in transient (RAM) memory * @param persistAfterSend If true, all parameters will be written to persistent storage as well */ - virtual void sendPendingParameters(bool persistAfterSend = false); + virtual void sendPendingParameters(bool persistAfterSend = false, bool forceSend = false); /** @brief Request list of parameters from MAV */ @@ -100,7 +100,7 @@ public slots: virtual void requestParameterListIfEmpty(); /** @brief queue a pending parameter for sending to the MAV */ - virtual void setPendingParam(int componentId, const QString& key, const QVariant& value); + virtual void setPendingParam(int componentId, const QString& key, const QVariant& value, bool forceSend = false); /** @brief remove all params from the pending list */ virtual void clearAllPendingParams(); diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 8110651a8b..cbc0bb2082 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -307,7 +307,7 @@ void UASParameterCommsMgr::requestRcCalibrationParamsUpdate() * @param parameterName name of the parameter, as delivered by the system * @param value value of the parameter */ -void UASParameterCommsMgr::setParameter(int compId, QString paramName, QVariant value) +void UASParameterCommsMgr::setParameter(int compId, QString paramName, QVariant value, bool forceSend) { if (paramName.isEmpty()) { return; @@ -328,14 +328,16 @@ void UASParameterCommsMgr::setParameter(int compId, QString paramName, QVariant return; } - QVariant onboardVal; - paramDataModel->getOnboardParamValue(compId,paramName,onboardVal); - if (onboardVal == value) { - setParameterStatusMsg(tr("REJ. %1 already %2").arg(paramName).arg(dblValue), - ParamCommsStatusLevel_Warning - ); - return; - } + if (!forceSend) { + QVariant onboardVal; + paramDataModel->getOnboardParamValue(compId,paramName,onboardVal); + if (onboardVal == value) { + setParameterStatusMsg(tr("REJ. %1 already %2").arg(paramName).arg(dblValue), + ParamCommsStatusLevel_Warning + ); + return; + } + } emitPendingParameterCommit(compId, paramName, value); @@ -501,7 +503,7 @@ void UASParameterCommsMgr::writeParamsToPersistentStorage() } -void UASParameterCommsMgr::sendPendingParameters(bool copyToPersistent) +void UASParameterCommsMgr::sendPendingParameters(bool copyToPersistent, bool forceSend) { persistParamsAfterSend |= copyToPersistent; @@ -517,7 +519,7 @@ void UASParameterCommsMgr::sendPendingParameters(bool copyToPersistent) setParameterStatusMsg(tr("%1 pending params for component %2").arg(paramList->count()).arg(compId)); for (j = paramList->begin(); j != paramList->end(); ++j) { - setParameter(compId, j.key(), j.value()); + setParameter(compId, j.key(), j.value(), forceSend); parametersSent++; } } diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 0f240c5e17..ef31376154 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -71,13 +71,13 @@ signals: public slots: /** @brief Iterate through all components, through all pending parameters and send them to UAS */ - virtual void sendPendingParameters(bool copyToPersistent = false); + virtual void sendPendingParameters(bool copyToPersistent = false, bool forceSend = false); /** @brief Write the current onboard parameters from transient RAM into persistent storage, e.g. EEPROM or harddisk */ virtual void writeParamsToPersistentStorage(); /** @brief Write one parameter to the MAV */ - virtual void setParameter(int component, QString parameterName, QVariant value); + virtual void setParameter(int component, QString parameterName, QVariant value, bool forceSend = false); /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 80b7f70a7c..b4f916dd64 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -46,19 +46,21 @@ int UASParameterDataModel::countOnboardParams() } -bool UASParameterDataModel::updatePendingParamWithValue(int compId, const QString& key, const QVariant& value) +bool UASParameterDataModel::updatePendingParamWithValue(int compId, const QString& key, const QVariant& value, bool forceSend) { bool pending = true; //ensure we have this component in our onboard and pending lists already addComponent(compId); - QMap* existParams = getOnboardParamsForComponent(compId); - if (existParams->contains(key)) { - QVariant existValue = existParams->value(key); - if (existValue == value) { - pending = false; - } - } + if (!forceSend) { + QMap* existParams = getOnboardParamsForComponent(compId); + if (existParams->contains(key)) { + QVariant existValue = existParams->value(key); + if (existValue == value) { + pending = false; + } + } + } if (pending) { setPendingParam(compId,key,value); diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 501f488e85..c0b5b76379 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -53,7 +53,7 @@ public: /** @brief add this parameter to pending list iff it has changed from onboard value * @return true if the parameter is now pending */ - virtual bool updatePendingParamWithValue(int componentId, const QString &key, const QVariant &value); + virtual bool updatePendingParamWithValue(int componentId, const QString &key, const QVariant &value, bool forceSend = false); virtual void handleParamUpdate(int componentId, const QString& key, const QVariant& value); virtual bool getOnboardParamValue(int componentId, const QString& key, QVariant& value) const; diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 0176aa6598..c06fdd54ee 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -156,7 +156,7 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : ui->rcCalibrationButton->setCheckable(true); ui->rcCalibrationButton->setEnabled(false); connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool))); - ui->spektrumPairButton->setCheckable(true); + ui->spektrumPairButton->setCheckable(false); ui->spektrumPairButton->setEnabled(false); connect(ui->spektrumPairButton, SIGNAL(clicked(bool)), this, SLOT(toggleSpektrumPairing(bool))); @@ -345,22 +345,13 @@ void QGCPX4VehicleConfig::toggleSpektrumPairing(bool enabled) (void)warnMsgBox.exec(); } - if (enabled) - { - int mode = 1; // DSM2 - if (ui->dsmxRadioButton->isChecked()) - mode = 2; // DSMX + int mode = 1; // DSM2 + if (ui->dsmxRadioButton->isChecked()) + mode = 2; // DSMX - mav->getParamManager()->setPendingParam(0, "RC_DSM_BIND", mode); - // Do not save this parameter, just set in RAM - mav->getParamManager()->sendPendingParameters(); - } - else - { - mav->getParamManager()->setPendingParam(0, "RC_DSM_BIND", (int)0); - // Do not save this parameter, just set in RAM - mav->getParamManager()->sendPendingParameters(); - } + mav->getParamManager()->setPendingParam(0, "RC_DSM_BIND", mode, true); + // Do not save this parameter, just set in RAM + mav->getParamManager()->sendPendingParameters(false, true); } void QGCPX4VehicleConfig::setTrimPositions() -- GitLab From 51be66c66da277ac9324298a36d7c4d0da7a6703 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Tue, 10 Sep 2013 12:27:10 +0200 Subject: [PATCH 375/460] Make sure to only use available space when disconnected --- src/ui/QGCToolBar.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 99e1425d9a..b71ea8f95a 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -226,6 +226,9 @@ void QGCToolBar::createUI() connect(&portBoxTimer, SIGNAL(timeout()), this, SLOT(updateComboBox())); portBoxTimer.start(500); + toolBarMessageAction->setVisible(false); + toolBarBatteryBarAction->setVisible(false); + changed = false; } @@ -251,6 +254,8 @@ void QGCToolBar::resetToolbarUI() lastSystemMessageTimeMs = 0; symbolLabel->setStyleSheet(""); symbolLabel->clear(); + toolBarMessageAction->setVisible(false); + toolBarBatteryBarAction->setVisible(false); } void QGCToolBar::baudSelected(int index) @@ -433,10 +438,10 @@ void QGCToolBar::updateArmingState(bool armed) void QGCToolBar::updateView() { if (!changed) return; - if (toolBarWpLabel->isVisible()) + if (toolBarWpAction->isVisible()) toolBarWpLabel->setText(tr("WP%1").arg(wpId)); - if (toolBarBatteryBar->isVisible()) { + if (toolBarBatteryBarAction->isVisible()) { toolBarBatteryBar->setValue(batteryPercent); if (batteryPercent < 30 && toolBarBatteryBar->value() >= 30) { @@ -468,7 +473,7 @@ void QGCToolBar::updateView() toolBarNameLabel->setText(systemName); // expire after 15 seconds - if (toolBarMessageLabel->isVisible()) { + if (toolBarMessageAction->isVisible()) { if (QGC::groundTimeMilliseconds() - lastSystemMessageTimeMs < 15000) { toolBarMessageLabel->setText(QString("%1").arg(lastSystemMessage)); } else { -- GitLab From 74f9e1c14c634b07219fbe201f09fe9a7ef65371 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 10 Sep 2013 07:33:26 -0700 Subject: [PATCH 376/460] update master docs (first visible on github) to explain how to grab QGC2 etc --- README | 186 ------------------------------------------------------ README.md | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 186 deletions(-) delete mode 100644 README create mode 100644 README.md diff --git a/README b/README deleted file mode 100644 index 1952d7d2bd..0000000000 --- a/README +++ /dev/null @@ -1,186 +0,0 @@ -maah -QGroundControl Open Source Micro Air Vehicle Ground Control Station - -Project: -http://qgroundcontrol.org - -Files: -http://github.com/mavlink/qgroundcontrol - -Credits: -http://qgroundcontrol.org/credits - - -Documentation -============= -For generating documentation, refer to README in the doc directory. - -Notes: -===== -Please make sure to delete your build folder before re-building. Independent of which -build system you use (this is not related to Qt or your OS) the dependency checking and -cleaning is based on the current project revision. So if you change the project and not -doing a clean build before you do, incremental building can leave you with stale -object files. - -For the current config branch 'qupgrade' has to be installed (subject to change): - -cd qgroundcontrol -git clone https://github.com/LorenzMeier/qupgrade.git - - -Mac OS X -======== - -To build on Mac OS X (10.6 or later): - -Install SDL ------------ -1) Download SDL from: - -2) From the SDL disk image, copy the `sdl.framework` bundle to `/Library/Frameworks` directory (if you are not an admin copy to `~/Library/Framewroks`) - -Install QT ------------ -1) Download Qt 4.8+ - -2) Double click the package installer - -Build QGroundControl (use clang compiler - not gcc) -------------------------------------- -1) From the terminal go to the `groundcontrol` directory - -2) Run `qmake qgroundcontrol.pro -r -spec unsupported/macx-clang CONFIG+=x86_64` - -3) Run `make -j4` - - -Linux -===== - - -To build on Linux: - -sudo apt-get install phonon libqt4-dev \ - libphonon-dev libphonon4 phonon-backend-gstreamer \ - qtcreator libsdl1.2-dev libflite1 flite1-dev build-essential \ - libopenscenegraph-dev - -cd directory - -git clone https://github.com/mavlink/qgroundcontrol.git - -go to libs/thirdParty -> libxbee - -Create Library -> Readme file in folder - -Ubuntu Application Menu -> Development -> Qt Creator - -QtCreator Menu File -> Open File or Project.. - -Open directory/qgroundcontrol/qgroundcontrol.pro - -Hit the green play button to compile and launch it - -Done. - - -Windows -======= - -GNU GCC / MINGW IS UNTESTED, COULD WORK -VISUAL STUDIO 2008 / 2010 EXPRESS EDITION IS FREE! - -Steps for Visual Studio 2008 / 2010: - -Windows XP/7: - -1) Download and install the Qt libraries for Windows from https://qt.nokia.com/downloads/ (the Visual Studio 2008 or 2010 version as appropriate) - -2) Download and install Visual Studio 2008 or 2010 Express Edition (free) from https://www.microsoft.com/visualstudio. If using Visual Studio 2010, make sure you are running at least SP1. There is a linking error you'll encounter otherwise that will prevent compilation. - -3) Go to the QGroundControl folder and then to thirdParty/libxbee and build it following the instructions in win32.README - -4) Open the Qt Command Prompt program (should be in the Start Menu), navigate to the source folder of QGroundControl and create the Visual Studio project by typing: - -`qmake -tp vc qgroundcontrol.pro` - -5) Now start Visual Studio and load the qgroundcontrol.vcproj if using Visual Studio 2008 or qgroundcontrol.vcxproj if using Visual Studio 2010 - -6) Compile and edit in Visual Studio. If you need to add new files, add them to qgroundcontrol.pro and re-run `qmake -tp vc qgroundcontrol.pro - - -Repository Layout -================= - -qgroundcontrol: - demo-log.txt - license.txt - qgcunittest.pro - For the unit tests. - qgcunittest.pro.user - qgcvideo.pro - qgroundcontrol.pri - Used by qgroundcontrol.pro - qgroundcontrol.pro - Project opened in QT to run qgc. - qgroundcontrol.pro.user - qgroundcontrol.qrc - Holds many images. - qgroundcontrol.rc - line of code to point toward the images - qserialport.pri - generated by qmake. - testlog.txt - testlog2.txt - user_config.pri.dist - Custom message specs to be added here. -data: - Maps from yahoo and kinect and earth. -deploy: - Install and uninstall for win32. - Create a debian packet. - Create .DMG file for publishing for mac. - Audio test on mac. -doc: - Doxyfile is in this directory and information for creating html documentation for qgc. -files: - Has the audio for the vehicle and data output. - ardupilotmega: - widgets and tool tips for pilot heading for the fixed wing. - tooltips for quadrotor - flightgear: - Aircraft: - Different types of planes and one jeep. - Protocol: - The protocol for the fixed_wings and quadrotor and quadhil.holds info about the fixed wing yaw, roll etc. Quadrotor. Agian holds info about yaw, roll etc. - Pixhawk: - Widgets for hexarotor. Widgets and tooltips for quadrotor. - vehicles: - different vehicles. Seems to hold the different kinds of aircrafts as well as files for audio and the hexarotor and quadrotor. - widgets: - Has a lot of widgets defined for buttons and sliders. - -images: - For the UI. Has a bunch of different images such as images for applications or actions or buttons. -lib: - SDL is located in this direcotry. - Msinttypes: - Defines intteger types for microsoft visual studio. - sdl: - Information about the library and to run the library on different platforms. -mavlink: - The files for the library mavlink. -qgcunittest: - Has the unittests for qgc -settings: - Parameter lists for alpha, bravo and charlie. - Data for stereo, waypoints and radio calibrartion. -src: - Code for QGCCore, audio output, configuration, waypoints, main and log compressor. - apps - Code for mavlink generation and for a video application. - comm - Code for linking to simulation, mavlink, udp, xbee, opal, flight gear and interface. - Has other libraries. Qwt is in directory named lib. The other libraries are in libs. - lib - qwt library - libs - eigen, opmapcontrol, qestserialport, qtconcurrent, utils. - input - joystick and freenect code. - plugins - Qt project for PIXHAWK plugins. - uas - Ardu pilot, UAS, mavlink factory, uas manager, interface, waypoint manager and slugs. - ui - Has code for data plots, waypoint lists and window congfiguration. All of the ui code. -thirdParty: - Library called lxbee. - Library called QSerialPort. - diff --git a/README.md b/README.md new file mode 100644 index 0000000000..412be38c17 --- /dev/null +++ b/README.md @@ -0,0 +1,179 @@ +# QGroundControl +## Open Source Micro Air Vehicle Ground Control Station + + +* Project: + + +* Files: + + +* Credits: + + + +## Documentation +For generating documentation, refer to /doc/README. + +## Notes +Please make sure to delete your build folder before re-building. Independent of which +build system you use (this is not related to Qt or your OS) the dependency checking and +cleaning is based on the current project revision. So if you change the project and don't remove the build folder before your next build, incremental building can leave you with stale object files. + +## QGC2.0 Tech Preview +Developers: In order to build the tech preview branch you need to: + + git clone https://github.com/mavlink/qgroundcontrol -b config qgc2 + git submodule init + git submodule update + +This procedure: + +* Clones the config branch (which contains QGC2) from github into your qgc2 directory +* initializes all the submodules required for QGC, such as qupdate, the firmware installer +* gets the latest code for all submodules + + +# Build on Mac OSX + +To build on Mac OSX (10.6 or later): +- - - +### Install SDL + +1. Download SDL from: +2. From the SDL disk image, copy the `sdl.framework` bundle to `/Library/Frameworks` directory (if you are not an admin copy to `~/Library/Frameworks`) + +### Install QT +- - - +1. Download Qt 4.8+ from +2. Double click the package installer and follow instructions: + +### Build QGroundControl +- - - + (use clang compiler - not gcc) + +1. From the terminal go to the `groundcontrol` directory +2. Run `qmake qgroundcontrol.pro -r -spec unsupported/macx-clang CONFIG+=x86_64` +3. Run `make -j4` + + +# Build on Linux + + +To build on Linux: +- - - + sudo apt-get install phonon libqt4-dev libphonon-dev libphonon4 phonon-backend-gstreamer qtcreator libsdl1.2-dev libflite1 flite1-dev build-essential libopenscenegraph-dev + cd directory + git clone https://github.com/mavlink/qgroundcontrol.git + +* go to `libs/thirdParty -> libxbee` +* Create Library -> Readme file in folder +* Ubuntu Application Menu -> Development -> Qt Creator +* QtCreator Menu File -> Open File or Project.. +* Open `directory/qgroundcontrol/qgroundcontrol.pro` +* Hit the green play button to compile and launch it + + +# Build on Windows +- - - + +__GNU GCC / MINGW IS UNTESTED, COULD WORK WITH +VISUAL STUDIO 2008 / 2010 EXPRESS EDITION (FREE!)__ + +Steps for Visual Studio 2008 / 2010: + +Windows XP/7: + +1. Download and install the Qt libraries for Windows from https://qt.nokia.com/downloads/ (the Visual Studio 2008 or 2010 version as appropriate) + +2. Download and install Visual Studio 2008 or 2010 Express Edition (free) from https://www.microsoft.com/visualstudio. If using Visual Studio 2010, make sure you are running at least SP1. There is a linking error you'll encounter otherwise that will prevent compilation. + +3. Go to the QGroundControl folder and then to thirdParty/libxbee and build it following the instructions in win32.README + +4. Open the Qt Command Prompt program (should be in the Start Menu), navigate to the source folder of QGroundControl and create the Visual Studio project by typing `qmake -tp vc qgroundcontrol.pro` + +5. Now start Visual Studio and load the qgroundcontrol.vcproj if using Visual Studio 2008 or qgroundcontrol.vcxproj if using Visual Studio 2010 + +6. Compile and edit in Visual Studio. If you need to add new files, add them to qgroundcontrol.pro and re-run `qmake -tp vc qgroundcontrol.pro` + + +## Repository Layout + qgroundcontrol: + demo-log.txt + license.txt + qgcunittest.pro - For the unit tests. + qgcunittest.pro.user + qgcvideo.pro + qgroundcontrol.pri - Used by qgroundcontrol.pro + qgroundcontrol.pro - Project opened in QT to run qgc. + qgroundcontrol.pro.user + qgroundcontrol.qrc - Holds many images. + qgroundcontrol.rc - line of code to point toward the images + qserialport.pri - generated by qmake. + testlog.txt - sample log file + testlog2.txt - sample log file + user_config.pri.dist - Custom message specs to be added here. + data: + Maps from yahoo and kinect and earth. + deploy: + Install and uninstall for win32. + Create a debian packet. + Create .DMG file for publishing for mac. + Audio test on mac. + doc: + Doxyfile is in this directory and information for creating html documentation for qgc. + files: + Has the audio for the vehicle and data output. + ardupilotmega: + widgets and tool tips for pilot heading for the fixed wing. + tooltips for quadrotor + flightgear: + Aircraft: + Different types of planes and one jeep. + Protocol: + The protocol for the fixed_wings and quadrotor and quadhil.holds info about the fixed wing yaw, roll etc. + Quadrotor: + Again holds info about yaw, roll etc. + Pixhawk: + Widgets for hexarotor. Widgets and tooltips for quadrotor. + vehicles: + different vehicles. Seems to hold the different kinds of aircrafts as well as files for audio and the hexarotor and quadrotor. + widgets: + Has a lot of widgets defined for buttons and sliders. + + images: + For the UI. Has a bunch of different images such as images for applications or actions or buttons. + lib: + SDL is located in this direcotry. + Msinttypes: + Defines intteger types for microsoft visual studio. + sdl: + Information about the library and to run the library on different platforms. + mavlink: + The files for the library mavlink. + qgcunittest: + Has the unittests for qgc + settings: + Parameter lists for alpha, bravo and charlie. Data for stereo, waypoints and radio calibration. + src: + Code for QGCCore, audio output, configuration, waypoints, main and log compressor. + apps + Code for mavlink generation and for a video application. + comm + Code for linking to simulation, mavlink, udp, xbee, opal, flight gear and interface. + Has other libraries. Qwt is in directory named lib. The other libraries are in libs. + lib + qwt library + libs + eigen, opmapcontrol, qestserialport, qtconcurrent, utils. + input + joystick and freenect code. + plugins + Qt project for PIXHAWK plugins. + uas + Ardu pilot, UAS, mavlink factory, uas manager, interface, waypoint manager and slugs. + ui + Has code for data plots, waypoint lists and window congfiguration. All of the ui code. +thirdParty: + Library called lxbee. + Library called QSerialPort. -- GitLab From 863c9f704d7644d13f8841b7b6b043cedd7b4730 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Tue, 10 Sep 2013 23:55:44 +0200 Subject: [PATCH 377/460] Updated MAVLink version --- .../v1.0/ardupilotmega/ardupilotmega.h | 11 +- .../v1.0/ardupilotmega/mavlink_msg_ahrs.h | 18 +- .../mavlink_msg_airspeed_autocal.h | 419 ++++++++++++++++++ .../v1.0/ardupilotmega/mavlink_msg_ap_adc.h | 18 +- .../v1.0/ardupilotmega/mavlink_msg_data16.h | 18 +- .../v1.0/ardupilotmega/mavlink_msg_data32.h | 18 +- .../v1.0/ardupilotmega/mavlink_msg_data64.h | 18 +- .../v1.0/ardupilotmega/mavlink_msg_data96.h | 18 +- .../mavlink_msg_digicam_configure.h | 18 +- .../mavlink_msg_digicam_control.h | 18 +- .../mavlink_msg_fence_fetch_point.h | 18 +- .../ardupilotmega/mavlink_msg_fence_point.h | 18 +- .../ardupilotmega/mavlink_msg_fence_status.h | 18 +- .../v1.0/ardupilotmega/mavlink_msg_hwstatus.h | 18 +- .../ardupilotmega/mavlink_msg_limits_status.h | 18 +- .../v1.0/ardupilotmega/mavlink_msg_meminfo.h | 18 +- .../mavlink_msg_mount_configure.h | 18 +- .../ardupilotmega/mavlink_msg_mount_control.h | 18 +- .../ardupilotmega/mavlink_msg_mount_status.h | 18 +- .../v1.0/ardupilotmega/mavlink_msg_radio.h | 18 +- .../ardupilotmega/mavlink_msg_rangefinder.h | 18 +- .../mavlink_msg_sensor_offsets.h | 18 +- .../mavlink_msg_set_mag_offsets.h | 18 +- .../v1.0/ardupilotmega/mavlink_msg_simstate.h | 72 +-- .../v1.0/ardupilotmega/mavlink_msg_wind.h | 18 +- .../mavlink/v1.0/ardupilotmega/testsuite.h | 70 ++- .../mavlink/v1.0/ardupilotmega/version.h | 2 +- .../include/mavlink/v1.0/autoquad/autoquad.h | 28 +- .../autoquad/mavlink_msg_aq_telemetry_f.h | 18 +- .../include/mavlink/v1.0/autoquad/version.h | 2 +- .../include/mavlink/v1.0/common/common.h | 4 +- .../v1.0/common/mavlink_msg_6dof_setpoint.h | 276 ------------ .../v1.0/common/mavlink_msg_8dof_setpoint.h | 320 ------------- .../v1.0/common/mavlink_msg_attitude.h | 18 +- .../common/mavlink_msg_attitude_quaternion.h | 18 +- .../v1.0/common/mavlink_msg_auth_key.h | 18 +- .../v1.0/common/mavlink_msg_battery_status.h | 18 +- .../mavlink_msg_change_operator_control.h | 18 +- .../mavlink_msg_change_operator_control_ack.h | 18 +- .../v1.0/common/mavlink_msg_command_ack.h | 18 +- .../v1.0/common/mavlink_msg_command_long.h | 18 +- .../v1.0/common/mavlink_msg_data_stream.h | 18 +- .../mavlink/v1.0/common/mavlink_msg_debug.h | 18 +- .../v1.0/common/mavlink_msg_debug_vect.h | 18 +- .../mavlink_msg_file_transfer_dir_list.h | 18 +- .../common/mavlink_msg_file_transfer_res.h | 18 +- .../common/mavlink_msg_file_transfer_start.h | 18 +- .../common/mavlink_msg_global_position_int.h | 28 +- ...mavlink_msg_global_position_setpoint_int.h | 18 +- ...link_msg_global_vision_position_estimate.h | 18 +- .../common/mavlink_msg_gps_global_origin.h | 18 +- .../v1.0/common/mavlink_msg_gps_raw_int.h | 58 ++- .../v1.0/common/mavlink_msg_gps_status.h | 18 +- .../v1.0/common/mavlink_msg_heartbeat.h | 18 +- .../v1.0/common/mavlink_msg_highres_imu.h | 18 +- .../v1.0/common/mavlink_msg_hil_controls.h | 18 +- .../mavlink/v1.0/common/mavlink_msg_hil_gps.h | 18 +- .../common/mavlink_msg_hil_optical_flow.h | 18 +- .../common/mavlink_msg_hil_rc_inputs_raw.h | 18 +- .../v1.0/common/mavlink_msg_hil_sensor.h | 18 +- .../v1.0/common/mavlink_msg_hil_state.h | 18 +- .../common/mavlink_msg_hil_state_quaternion.h | 18 +- .../common/mavlink_msg_local_position_ned.h | 18 +- ..._local_position_ned_system_global_offset.h | 18 +- .../mavlink_msg_local_position_setpoint.h | 18 +- .../v1.0/common/mavlink_msg_manual_control.h | 18 +- .../v1.0/common/mavlink_msg_manual_setpoint.h | 18 +- .../v1.0/common/mavlink_msg_memory_vect.h | 18 +- .../v1.0/common/mavlink_msg_mission_ack.h | 18 +- .../common/mavlink_msg_mission_clear_all.h | 18 +- .../v1.0/common/mavlink_msg_mission_count.h | 18 +- .../v1.0/common/mavlink_msg_mission_current.h | 18 +- .../v1.0/common/mavlink_msg_mission_item.h | 18 +- .../common/mavlink_msg_mission_item_reached.h | 18 +- .../v1.0/common/mavlink_msg_mission_request.h | 18 +- .../common/mavlink_msg_mission_request_list.h | 18 +- ...mavlink_msg_mission_request_partial_list.h | 18 +- .../common/mavlink_msg_mission_set_current.h | 18 +- .../mavlink_msg_mission_write_partial_list.h | 18 +- .../common/mavlink_msg_named_value_float.h | 18 +- .../v1.0/common/mavlink_msg_named_value_int.h | 18 +- .../mavlink_msg_nav_controller_output.h | 18 +- .../common/mavlink_msg_omnidirectional_flow.h | 18 +- .../v1.0/common/mavlink_msg_optical_flow.h | 38 +- .../common/mavlink_msg_param_request_list.h | 18 +- .../common/mavlink_msg_param_request_read.h | 18 +- .../v1.0/common/mavlink_msg_param_set.h | 18 +- .../v1.0/common/mavlink_msg_param_value.h | 18 +- .../mavlink/v1.0/common/mavlink_msg_ping.h | 18 +- .../v1.0/common/mavlink_msg_radio_status.h | 18 +- .../mavlink/v1.0/common/mavlink_msg_raw_imu.h | 18 +- .../v1.0/common/mavlink_msg_raw_pressure.h | 18 +- .../common/mavlink_msg_rc_channels_override.h | 98 ++-- .../v1.0/common/mavlink_msg_rc_channels_raw.h | 98 ++-- .../common/mavlink_msg_rc_channels_scaled.h | 98 ++-- .../common/mavlink_msg_request_data_stream.h | 18 +- ...msg_roll_pitch_yaw_rates_thrust_setpoint.h | 18 +- ...msg_roll_pitch_yaw_speed_thrust_setpoint.h | 18 +- ...vlink_msg_roll_pitch_yaw_thrust_setpoint.h | 18 +- .../common/mavlink_msg_safety_allowed_area.h | 18 +- .../mavlink_msg_safety_set_allowed_area.h | 18 +- .../v1.0/common/mavlink_msg_scaled_imu.h | 18 +- .../v1.0/common/mavlink_msg_scaled_pressure.h | 18 +- .../common/mavlink_msg_servo_output_raw.h | 18 +- ...ink_msg_set_global_position_setpoint_int.h | 18 +- .../mavlink_msg_set_gps_global_origin.h | 18 +- .../mavlink_msg_set_local_position_setpoint.h | 18 +- .../v1.0/common/mavlink_msg_set_mode.h | 18 +- .../mavlink_msg_set_quad_motors_setpoint.h | 18 +- ...set_quad_swarm_led_roll_pitch_yaw_thrust.h | 58 ++- ...msg_set_quad_swarm_roll_pitch_yaw_thrust.h | 58 ++- ...link_msg_set_roll_pitch_yaw_speed_thrust.h | 18 +- .../mavlink_msg_set_roll_pitch_yaw_thrust.h | 18 +- .../v1.0/common/mavlink_msg_setpoint_6dof.h | 18 +- .../v1.0/common/mavlink_msg_setpoint_8dof.h | 18 +- .../v1.0/common/mavlink_msg_sim_state.h | 18 +- .../common/mavlink_msg_state_correction.h | 18 +- .../v1.0/common/mavlink_msg_statustext.h | 18 +- .../v1.0/common/mavlink_msg_sys_status.h | 18 +- .../v1.0/common/mavlink_msg_system_time.h | 18 +- .../mavlink/v1.0/common/mavlink_msg_vfr_hud.h | 18 +- .../mavlink_msg_vicon_position_estimate.h | 18 +- .../mavlink_msg_vision_position_estimate.h | 18 +- .../mavlink_msg_vision_speed_estimate.h | 18 +- .../include/mavlink/v1.0/common/version.h | 2 +- .../mavlink/v1.0/matrixpilot/matrixpilot.h | 4 +- .../v1.0/matrixpilot/mavlink_msg_airspeeds.h | 18 +- .../v1.0/matrixpilot/mavlink_msg_altitudes.h | 18 +- ...avlink_msg_flexifunction_buffer_function.h | 18 +- ...nk_msg_flexifunction_buffer_function_ack.h | 18 +- .../mavlink_msg_flexifunction_command.h | 18 +- .../mavlink_msg_flexifunction_command_ack.h | 18 +- .../mavlink_msg_flexifunction_directory.h | 18 +- .../mavlink_msg_flexifunction_directory_ack.h | 18 +- .../mavlink_msg_flexifunction_read_req.h | 18 +- .../mavlink_msg_flexifunction_set.h | 18 +- .../mavlink_msg_serial_udb_extra_f13.h | 18 +- .../mavlink_msg_serial_udb_extra_f14.h | 18 +- .../mavlink_msg_serial_udb_extra_f15.h | 18 +- .../mavlink_msg_serial_udb_extra_f16.h | 18 +- .../mavlink_msg_serial_udb_extra_f2_a.h | 18 +- .../mavlink_msg_serial_udb_extra_f2_b.h | 18 +- .../mavlink_msg_serial_udb_extra_f4.h | 18 +- .../mavlink_msg_serial_udb_extra_f5.h | 18 +- .../mavlink_msg_serial_udb_extra_f6.h | 18 +- .../mavlink_msg_serial_udb_extra_f7.h | 18 +- .../mavlink_msg_serial_udb_extra_f8.h | 18 +- .../mavlink/v1.0/matrixpilot/version.h | 2 +- .../include/mavlink/v1.0/mavlink_helpers.h | 10 +- .../pixhawk/mavlink_msg_attitude_control.h | 18 +- .../v1.0/pixhawk/mavlink_msg_brief_feature.h | 18 +- .../mavlink_msg_data_transmission_handshake.h | 18 +- .../pixhawk/mavlink_msg_encapsulated_data.h | 18 +- .../pixhawk/mavlink_msg_image_available.h | 18 +- .../mavlink_msg_image_trigger_control.h | 18 +- .../pixhawk/mavlink_msg_image_triggered.h | 18 +- .../mavlink/v1.0/pixhawk/mavlink_msg_marker.h | 18 +- .../pixhawk/mavlink_msg_pattern_detected.h | 18 +- .../pixhawk/mavlink_msg_point_of_interest.h | 18 +- ...mavlink_msg_point_of_interest_connection.h | 18 +- .../mavlink_msg_position_control_setpoint.h | 18 +- .../v1.0/pixhawk/mavlink_msg_raw_aux.h | 18 +- .../pixhawk/mavlink_msg_set_cam_shutter.h | 18 +- .../mavlink_msg_set_position_control_offset.h | 18 +- .../pixhawk/mavlink_msg_watchdog_command.h | 18 +- .../pixhawk/mavlink_msg_watchdog_heartbeat.h | 18 +- .../mavlink_msg_watchdog_process_info.h | 18 +- .../mavlink_msg_watchdog_process_status.h | 18 +- .../include/mavlink/v1.0/pixhawk/pixhawk.h | 4 +- .../include/mavlink/v1.0/pixhawk/version.h | 2 +- libs/mavlink/include/mavlink/v1.0/protocol.h | 2 +- .../sensesoar/mavlink_msg_cmd_airspeed_ack.h | 18 +- .../sensesoar/mavlink_msg_cmd_airspeed_chng.h | 18 +- .../v1.0/sensesoar/mavlink_msg_filt_rot_vel.h | 18 +- .../v1.0/sensesoar/mavlink_msg_llc_out.h | 18 +- .../v1.0/sensesoar/mavlink_msg_obs_air_temp.h | 18 +- .../sensesoar/mavlink_msg_obs_air_velocity.h | 18 +- .../v1.0/sensesoar/mavlink_msg_obs_attitude.h | 18 +- .../v1.0/sensesoar/mavlink_msg_obs_bias.h | 18 +- .../v1.0/sensesoar/mavlink_msg_obs_position.h | 18 +- .../v1.0/sensesoar/mavlink_msg_obs_qff.h | 18 +- .../v1.0/sensesoar/mavlink_msg_obs_velocity.h | 18 +- .../v1.0/sensesoar/mavlink_msg_obs_wind.h | 18 +- .../v1.0/sensesoar/mavlink_msg_pm_elec.h | 18 +- .../v1.0/sensesoar/mavlink_msg_sys_stat.h | 18 +- .../include/mavlink/v1.0/sensesoar/version.h | 2 +- 186 files changed, 3469 insertions(+), 1177 deletions(-) create mode 100644 libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_airspeed_autocal.h delete mode 100644 libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_6dof_setpoint.h delete mode 100644 libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_8dof_setpoint.h diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/ardupilotmega.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/ardupilotmega.h index eec9a89c50..3aad8e6785 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/ardupilotmega.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/ardupilotmega.h @@ -12,15 +12,15 @@ extern "C" { // MESSAGE LENGTHS AND CRCS #ifndef MAVLINK_MESSAGE_LENGTHS -#define MAVLINK_MESSAGE_LENGTHS {9, 31, 12, 0, 14, 28, 3, 32, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 20, 2, 25, 23, 30, 101, 22, 26, 16, 14, 28, 32, 28, 28, 22, 22, 21, 6, 6, 37, 4, 4, 2, 2, 4, 2, 2, 3, 13, 12, 19, 17, 15, 15, 27, 25, 18, 18, 20, 20, 9, 34, 26, 46, 36, 0, 6, 4, 0, 11, 18, 0, 0, 0, 20, 0, 33, 3, 0, 0, 20, 22, 0, 0, 0, 0, 0, 0, 0, 28, 56, 42, 33, 0, 0, 0, 0, 0, 0, 0, 26, 32, 32, 20, 32, 62, 54, 64, 84, 9, 254, 249, 9, 36, 26, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 33, 25, 42, 8, 4, 12, 15, 13, 6, 15, 14, 0, 12, 3, 8, 28, 44, 3, 9, 22, 12, 18, 34, 66, 98, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 30, 18, 18, 51, 9, 0} +#define MAVLINK_MESSAGE_LENGTHS {9, 31, 12, 0, 14, 28, 3, 32, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 20, 2, 25, 23, 30, 101, 22, 26, 16, 14, 28, 32, 28, 28, 22, 22, 21, 6, 6, 37, 4, 4, 2, 2, 4, 2, 2, 3, 13, 12, 19, 17, 15, 15, 27, 25, 18, 18, 20, 20, 9, 34, 26, 46, 36, 0, 6, 4, 0, 11, 18, 0, 0, 0, 20, 0, 33, 3, 0, 0, 20, 22, 0, 0, 0, 0, 0, 0, 0, 28, 56, 42, 33, 0, 0, 0, 0, 0, 0, 0, 26, 32, 32, 20, 32, 62, 54, 64, 84, 9, 254, 249, 9, 36, 26, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 33, 25, 42, 8, 4, 12, 15, 13, 6, 15, 14, 0, 12, 3, 8, 28, 44, 3, 9, 22, 12, 18, 34, 66, 98, 8, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 30, 18, 18, 51, 9, 0} #endif #ifndef MAVLINK_MESSAGE_CRCS -#define MAVLINK_MESSAGE_CRCS {50, 124, 137, 0, 237, 217, 104, 119, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 214, 159, 220, 168, 24, 23, 170, 144, 67, 115, 39, 246, 185, 104, 237, 244, 222, 212, 9, 254, 230, 28, 28, 132, 221, 232, 11, 153, 41, 39, 214, 223, 141, 33, 15, 3, 100, 24, 239, 238, 30, 240, 183, 130, 130, 0, 148, 21, 0, 243, 124, 0, 0, 0, 20, 0, 152, 143, 0, 0, 127, 106, 0, 0, 0, 0, 0, 0, 0, 231, 183, 63, 54, 0, 0, 0, 0, 0, 0, 0, 175, 102, 158, 208, 56, 93, 211, 108, 32, 185, 235, 93, 124, 124, 119, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 241, 15, 134, 219, 208, 188, 84, 22, 19, 21, 134, 0, 78, 68, 189, 127, 111, 21, 21, 144, 1, 234, 73, 181, 22, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 49, 170, 44, 83, 46, 0} +#define MAVLINK_MESSAGE_CRCS {50, 124, 137, 0, 237, 217, 104, 119, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 214, 159, 220, 168, 24, 23, 170, 144, 67, 115, 39, 246, 185, 104, 237, 244, 222, 212, 9, 254, 230, 28, 28, 132, 221, 232, 11, 153, 41, 39, 214, 223, 141, 33, 15, 3, 100, 24, 239, 238, 30, 240, 183, 130, 130, 0, 148, 21, 0, 243, 124, 0, 0, 0, 20, 0, 152, 143, 0, 0, 127, 106, 0, 0, 0, 0, 0, 0, 0, 231, 183, 63, 54, 0, 0, 0, 0, 0, 0, 0, 175, 102, 158, 208, 56, 93, 211, 108, 32, 185, 235, 93, 124, 124, 119, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 241, 15, 134, 219, 208, 188, 84, 22, 19, 21, 134, 0, 78, 68, 189, 127, 154, 21, 21, 144, 1, 234, 73, 181, 22, 83, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 49, 170, 44, 83, 46, 0} #endif #ifndef MAVLINK_MESSAGE_INFO -#define MAVLINK_MESSAGE_INFO {MAVLINK_MESSAGE_INFO_HEARTBEAT, MAVLINK_MESSAGE_INFO_SYS_STATUS, MAVLINK_MESSAGE_INFO_SYSTEM_TIME, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_PING, MAVLINK_MESSAGE_INFO_CHANGE_OPERATOR_CONTROL, MAVLINK_MESSAGE_INFO_CHANGE_OPERATOR_CONTROL_ACK, MAVLINK_MESSAGE_INFO_AUTH_KEY, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_SET_MODE, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_PARAM_REQUEST_READ, MAVLINK_MESSAGE_INFO_PARAM_REQUEST_LIST, MAVLINK_MESSAGE_INFO_PARAM_VALUE, MAVLINK_MESSAGE_INFO_PARAM_SET, MAVLINK_MESSAGE_INFO_GPS_RAW_INT, MAVLINK_MESSAGE_INFO_GPS_STATUS, MAVLINK_MESSAGE_INFO_SCALED_IMU, MAVLINK_MESSAGE_INFO_RAW_IMU, MAVLINK_MESSAGE_INFO_RAW_PRESSURE, MAVLINK_MESSAGE_INFO_SCALED_PRESSURE, MAVLINK_MESSAGE_INFO_ATTITUDE, MAVLINK_MESSAGE_INFO_ATTITUDE_QUATERNION, MAVLINK_MESSAGE_INFO_LOCAL_POSITION_NED, MAVLINK_MESSAGE_INFO_GLOBAL_POSITION_INT, MAVLINK_MESSAGE_INFO_RC_CHANNELS_SCALED, MAVLINK_MESSAGE_INFO_RC_CHANNELS_RAW, MAVLINK_MESSAGE_INFO_SERVO_OUTPUT_RAW, MAVLINK_MESSAGE_INFO_MISSION_REQUEST_PARTIAL_LIST, MAVLINK_MESSAGE_INFO_MISSION_WRITE_PARTIAL_LIST, MAVLINK_MESSAGE_INFO_MISSION_ITEM, MAVLINK_MESSAGE_INFO_MISSION_REQUEST, MAVLINK_MESSAGE_INFO_MISSION_SET_CURRENT, MAVLINK_MESSAGE_INFO_MISSION_CURRENT, MAVLINK_MESSAGE_INFO_MISSION_REQUEST_LIST, MAVLINK_MESSAGE_INFO_MISSION_COUNT, MAVLINK_MESSAGE_INFO_MISSION_CLEAR_ALL, MAVLINK_MESSAGE_INFO_MISSION_ITEM_REACHED, MAVLINK_MESSAGE_INFO_MISSION_ACK, MAVLINK_MESSAGE_INFO_SET_GPS_GLOBAL_ORIGIN, MAVLINK_MESSAGE_INFO_GPS_GLOBAL_ORIGIN, MAVLINK_MESSAGE_INFO_SET_LOCAL_POSITION_SETPOINT, MAVLINK_MESSAGE_INFO_LOCAL_POSITION_SETPOINT, MAVLINK_MESSAGE_INFO_GLOBAL_POSITION_SETPOINT_INT, MAVLINK_MESSAGE_INFO_SET_GLOBAL_POSITION_SETPOINT_INT, MAVLINK_MESSAGE_INFO_SAFETY_SET_ALLOWED_AREA, MAVLINK_MESSAGE_INFO_SAFETY_ALLOWED_AREA, MAVLINK_MESSAGE_INFO_SET_ROLL_PITCH_YAW_THRUST, MAVLINK_MESSAGE_INFO_SET_ROLL_PITCH_YAW_SPEED_THRUST, MAVLINK_MESSAGE_INFO_ROLL_PITCH_YAW_THRUST_SETPOINT, MAVLINK_MESSAGE_INFO_ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT, MAVLINK_MESSAGE_INFO_SET_QUAD_MOTORS_SETPOINT, MAVLINK_MESSAGE_INFO_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST, MAVLINK_MESSAGE_INFO_NAV_CONTROLLER_OUTPUT, MAVLINK_MESSAGE_INFO_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST, MAVLINK_MESSAGE_INFO_STATE_CORRECTION, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_REQUEST_DATA_STREAM, MAVLINK_MESSAGE_INFO_DATA_STREAM, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_MANUAL_CONTROL, MAVLINK_MESSAGE_INFO_RC_CHANNELS_OVERRIDE, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_VFR_HUD, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_COMMAND_LONG, MAVLINK_MESSAGE_INFO_COMMAND_ACK, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_ROLL_PITCH_YAW_RATES_THRUST_SETPOINT, MAVLINK_MESSAGE_INFO_MANUAL_SETPOINT, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET, MAVLINK_MESSAGE_INFO_HIL_STATE, MAVLINK_MESSAGE_INFO_HIL_CONTROLS, MAVLINK_MESSAGE_INFO_HIL_RC_INPUTS_RAW, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_OPTICAL_FLOW, MAVLINK_MESSAGE_INFO_GLOBAL_VISION_POSITION_ESTIMATE, MAVLINK_MESSAGE_INFO_VISION_POSITION_ESTIMATE, MAVLINK_MESSAGE_INFO_VISION_SPEED_ESTIMATE, MAVLINK_MESSAGE_INFO_VICON_POSITION_ESTIMATE, MAVLINK_MESSAGE_INFO_HIGHRES_IMU, MAVLINK_MESSAGE_INFO_OMNIDIRECTIONAL_FLOW, MAVLINK_MESSAGE_INFO_HIL_SENSOR, MAVLINK_MESSAGE_INFO_SIM_STATE, MAVLINK_MESSAGE_INFO_RADIO_STATUS, MAVLINK_MESSAGE_INFO_FILE_TRANSFER_START, MAVLINK_MESSAGE_INFO_FILE_TRANSFER_DIR_LIST, MAVLINK_MESSAGE_INFO_FILE_TRANSFER_RES, MAVLINK_MESSAGE_INFO_HIL_GPS, MAVLINK_MESSAGE_INFO_HIL_OPTICAL_FLOW, MAVLINK_MESSAGE_INFO_HIL_STATE_QUATERNION, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_BATTERY_STATUS, MAVLINK_MESSAGE_INFO_SETPOINT_8DOF, MAVLINK_MESSAGE_INFO_SETPOINT_6DOF, MAVLINK_MESSAGE_INFO_SENSOR_OFFSETS, MAVLINK_MESSAGE_INFO_SET_MAG_OFFSETS, MAVLINK_MESSAGE_INFO_MEMINFO, MAVLINK_MESSAGE_INFO_AP_ADC, MAVLINK_MESSAGE_INFO_DIGICAM_CONFIGURE, MAVLINK_MESSAGE_INFO_DIGICAM_CONTROL, MAVLINK_MESSAGE_INFO_MOUNT_CONFIGURE, MAVLINK_MESSAGE_INFO_MOUNT_CONTROL, MAVLINK_MESSAGE_INFO_MOUNT_STATUS, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_FENCE_POINT, MAVLINK_MESSAGE_INFO_FENCE_FETCH_POINT, MAVLINK_MESSAGE_INFO_FENCE_STATUS, MAVLINK_MESSAGE_INFO_AHRS, MAVLINK_MESSAGE_INFO_SIMSTATE, MAVLINK_MESSAGE_INFO_HWSTATUS, MAVLINK_MESSAGE_INFO_RADIO, MAVLINK_MESSAGE_INFO_LIMITS_STATUS, MAVLINK_MESSAGE_INFO_WIND, MAVLINK_MESSAGE_INFO_DATA16, MAVLINK_MESSAGE_INFO_DATA32, MAVLINK_MESSAGE_INFO_DATA64, MAVLINK_MESSAGE_INFO_DATA96, MAVLINK_MESSAGE_INFO_RANGEFINDER, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_MEMORY_VECT, MAVLINK_MESSAGE_INFO_DEBUG_VECT, MAVLINK_MESSAGE_INFO_NAMED_VALUE_FLOAT, MAVLINK_MESSAGE_INFO_NAMED_VALUE_INT, MAVLINK_MESSAGE_INFO_STATUSTEXT, MAVLINK_MESSAGE_INFO_DEBUG, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}} +#define MAVLINK_MESSAGE_INFO {MAVLINK_MESSAGE_INFO_HEARTBEAT, MAVLINK_MESSAGE_INFO_SYS_STATUS, MAVLINK_MESSAGE_INFO_SYSTEM_TIME, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_PING, MAVLINK_MESSAGE_INFO_CHANGE_OPERATOR_CONTROL, MAVLINK_MESSAGE_INFO_CHANGE_OPERATOR_CONTROL_ACK, MAVLINK_MESSAGE_INFO_AUTH_KEY, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_SET_MODE, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_PARAM_REQUEST_READ, MAVLINK_MESSAGE_INFO_PARAM_REQUEST_LIST, MAVLINK_MESSAGE_INFO_PARAM_VALUE, MAVLINK_MESSAGE_INFO_PARAM_SET, MAVLINK_MESSAGE_INFO_GPS_RAW_INT, MAVLINK_MESSAGE_INFO_GPS_STATUS, MAVLINK_MESSAGE_INFO_SCALED_IMU, MAVLINK_MESSAGE_INFO_RAW_IMU, MAVLINK_MESSAGE_INFO_RAW_PRESSURE, MAVLINK_MESSAGE_INFO_SCALED_PRESSURE, MAVLINK_MESSAGE_INFO_ATTITUDE, MAVLINK_MESSAGE_INFO_ATTITUDE_QUATERNION, MAVLINK_MESSAGE_INFO_LOCAL_POSITION_NED, MAVLINK_MESSAGE_INFO_GLOBAL_POSITION_INT, MAVLINK_MESSAGE_INFO_RC_CHANNELS_SCALED, MAVLINK_MESSAGE_INFO_RC_CHANNELS_RAW, MAVLINK_MESSAGE_INFO_SERVO_OUTPUT_RAW, MAVLINK_MESSAGE_INFO_MISSION_REQUEST_PARTIAL_LIST, MAVLINK_MESSAGE_INFO_MISSION_WRITE_PARTIAL_LIST, MAVLINK_MESSAGE_INFO_MISSION_ITEM, MAVLINK_MESSAGE_INFO_MISSION_REQUEST, MAVLINK_MESSAGE_INFO_MISSION_SET_CURRENT, MAVLINK_MESSAGE_INFO_MISSION_CURRENT, MAVLINK_MESSAGE_INFO_MISSION_REQUEST_LIST, MAVLINK_MESSAGE_INFO_MISSION_COUNT, MAVLINK_MESSAGE_INFO_MISSION_CLEAR_ALL, MAVLINK_MESSAGE_INFO_MISSION_ITEM_REACHED, MAVLINK_MESSAGE_INFO_MISSION_ACK, MAVLINK_MESSAGE_INFO_SET_GPS_GLOBAL_ORIGIN, MAVLINK_MESSAGE_INFO_GPS_GLOBAL_ORIGIN, MAVLINK_MESSAGE_INFO_SET_LOCAL_POSITION_SETPOINT, MAVLINK_MESSAGE_INFO_LOCAL_POSITION_SETPOINT, MAVLINK_MESSAGE_INFO_GLOBAL_POSITION_SETPOINT_INT, MAVLINK_MESSAGE_INFO_SET_GLOBAL_POSITION_SETPOINT_INT, MAVLINK_MESSAGE_INFO_SAFETY_SET_ALLOWED_AREA, MAVLINK_MESSAGE_INFO_SAFETY_ALLOWED_AREA, MAVLINK_MESSAGE_INFO_SET_ROLL_PITCH_YAW_THRUST, MAVLINK_MESSAGE_INFO_SET_ROLL_PITCH_YAW_SPEED_THRUST, MAVLINK_MESSAGE_INFO_ROLL_PITCH_YAW_THRUST_SETPOINT, MAVLINK_MESSAGE_INFO_ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT, MAVLINK_MESSAGE_INFO_SET_QUAD_MOTORS_SETPOINT, MAVLINK_MESSAGE_INFO_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST, MAVLINK_MESSAGE_INFO_NAV_CONTROLLER_OUTPUT, MAVLINK_MESSAGE_INFO_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST, MAVLINK_MESSAGE_INFO_STATE_CORRECTION, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_REQUEST_DATA_STREAM, MAVLINK_MESSAGE_INFO_DATA_STREAM, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_MANUAL_CONTROL, MAVLINK_MESSAGE_INFO_RC_CHANNELS_OVERRIDE, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_VFR_HUD, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_COMMAND_LONG, MAVLINK_MESSAGE_INFO_COMMAND_ACK, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_ROLL_PITCH_YAW_RATES_THRUST_SETPOINT, MAVLINK_MESSAGE_INFO_MANUAL_SETPOINT, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET, MAVLINK_MESSAGE_INFO_HIL_STATE, MAVLINK_MESSAGE_INFO_HIL_CONTROLS, MAVLINK_MESSAGE_INFO_HIL_RC_INPUTS_RAW, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_OPTICAL_FLOW, MAVLINK_MESSAGE_INFO_GLOBAL_VISION_POSITION_ESTIMATE, MAVLINK_MESSAGE_INFO_VISION_POSITION_ESTIMATE, MAVLINK_MESSAGE_INFO_VISION_SPEED_ESTIMATE, MAVLINK_MESSAGE_INFO_VICON_POSITION_ESTIMATE, MAVLINK_MESSAGE_INFO_HIGHRES_IMU, MAVLINK_MESSAGE_INFO_OMNIDIRECTIONAL_FLOW, MAVLINK_MESSAGE_INFO_HIL_SENSOR, MAVLINK_MESSAGE_INFO_SIM_STATE, MAVLINK_MESSAGE_INFO_RADIO_STATUS, MAVLINK_MESSAGE_INFO_FILE_TRANSFER_START, MAVLINK_MESSAGE_INFO_FILE_TRANSFER_DIR_LIST, MAVLINK_MESSAGE_INFO_FILE_TRANSFER_RES, MAVLINK_MESSAGE_INFO_HIL_GPS, MAVLINK_MESSAGE_INFO_HIL_OPTICAL_FLOW, MAVLINK_MESSAGE_INFO_HIL_STATE_QUATERNION, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_BATTERY_STATUS, MAVLINK_MESSAGE_INFO_SETPOINT_8DOF, MAVLINK_MESSAGE_INFO_SETPOINT_6DOF, MAVLINK_MESSAGE_INFO_SENSOR_OFFSETS, MAVLINK_MESSAGE_INFO_SET_MAG_OFFSETS, MAVLINK_MESSAGE_INFO_MEMINFO, MAVLINK_MESSAGE_INFO_AP_ADC, MAVLINK_MESSAGE_INFO_DIGICAM_CONFIGURE, MAVLINK_MESSAGE_INFO_DIGICAM_CONTROL, MAVLINK_MESSAGE_INFO_MOUNT_CONFIGURE, MAVLINK_MESSAGE_INFO_MOUNT_CONTROL, MAVLINK_MESSAGE_INFO_MOUNT_STATUS, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_FENCE_POINT, MAVLINK_MESSAGE_INFO_FENCE_FETCH_POINT, MAVLINK_MESSAGE_INFO_FENCE_STATUS, MAVLINK_MESSAGE_INFO_AHRS, MAVLINK_MESSAGE_INFO_SIMSTATE, MAVLINK_MESSAGE_INFO_HWSTATUS, MAVLINK_MESSAGE_INFO_RADIO, MAVLINK_MESSAGE_INFO_LIMITS_STATUS, MAVLINK_MESSAGE_INFO_WIND, MAVLINK_MESSAGE_INFO_DATA16, MAVLINK_MESSAGE_INFO_DATA32, MAVLINK_MESSAGE_INFO_DATA64, MAVLINK_MESSAGE_INFO_DATA96, MAVLINK_MESSAGE_INFO_RANGEFINDER, MAVLINK_MESSAGE_INFO_AIRSPEED_AUTOCAL, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, MAVLINK_MESSAGE_INFO_MEMORY_VECT, MAVLINK_MESSAGE_INFO_DEBUG_VECT, MAVLINK_MESSAGE_INFO_NAMED_VALUE_FLOAT, MAVLINK_MESSAGE_INFO_NAMED_VALUE_INT, MAVLINK_MESSAGE_INFO_STATUSTEXT, MAVLINK_MESSAGE_INFO_DEBUG, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}} #endif #include "../protocol.h" @@ -74,6 +74,7 @@ enum MAV_CMD MAV_CMD_DO_SET_SERVO=183, /* Set a servo to a desired PWM value. |Servo number| PWM (microseconds, 1000 to 2000 typical)| Empty| Empty| Empty| Empty| Empty| */ MAV_CMD_DO_REPEAT_SERVO=184, /* Cycle a between its nominal setting and a desired PWM for a desired number of cycles with a desired period. |Servo number| PWM (microseconds, 1000 to 2000 typical)| Cycle count| Cycle time (seconds)| Empty| Empty| Empty| */ MAV_CMD_DO_CONTROL_VIDEO=200, /* Control onboard camera system. |Camera ID (-1 for all)| Transmission: 0: disabled, 1: enabled compressed, 2: enabled raw| Transmission mode: 0: video stream, >0: single images every n seconds (decimal)| Recording: 0: disabled, 1: enabled compressed, 2: enabled raw| Empty| Empty| Empty| */ + MAV_CMD_DO_SET_ROI=201, /* Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. |Region of intereset mode. (see MAV_ROI enum)| MISSION index/ target ID. (see MAV_ROI enum)| ROI index (allows a vehicle to manage multiple ROI's)| Empty| x the location of the fixed ROI (see MAV_FRAME)| y| z| */ MAV_CMD_DO_DIGICAM_CONFIGURE=202, /* Mission command to configure an on-board camera controller system. |Modes: P, TV, AV, M, Etc| Shutter speed: Divisor number for one second| Aperture: F stop number| ISO number e.g. 80, 100, 200, Etc| Exposure type enumerator| Command Identity| Main engine cut-off time before camera trigger in seconds/10 (0 means no cut-off)| */ MAV_CMD_DO_DIGICAM_CONTROL=203, /* Mission command to control an on-board camera controller system. |Session control e.g. show/hide lens| Zoom's absolute position| Zooming step value to offset zoom from the current position| Focus Locking, Unlocking or Re-locking| Shooting Command| Command Identity| Empty| */ MAV_CMD_DO_MOUNT_CONFIGURE=204, /* Mission command to configure a camera or antenna mount |Mount operation mode (see MAV_MOUNT_MODE enum)| stabilize roll? (1 = yes, 0 = no)| stabilize pitch? (1 = yes, 0 = no)| stabilize yaw? (1 = yes, 0 = no)| Empty| Empty| Empty| */ @@ -86,7 +87,8 @@ enum MAV_CMD MAV_CMD_OVERRIDE_GOTO=252, /* Hold / continue the current action |MAV_GOTO_DO_HOLD: hold MAV_GOTO_DO_CONTINUE: continue with next item in mission plan| MAV_GOTO_HOLD_AT_CURRENT_POSITION: Hold at current position MAV_GOTO_HOLD_AT_SPECIFIED_POSITION: hold at specified position| MAV_FRAME coordinate frame of hold point| Desired yaw angle in degrees| Latitude / X position| Longitude / Y position| Altitude / Z position| */ MAV_CMD_MISSION_START=300, /* start running a mission |first_item: the first mission item to run| last_item: the last mission item to run (after this item is run, the mission ends)| */ MAV_CMD_COMPONENT_ARM_DISARM=400, /* Arms / Disarms a component |1 to arm, 0 to disarm| */ - MAV_CMD_ENUM_END=401, /* | */ + MAV_CMD_START_RX_PAIR=500, /* Starts receiver pairing |0:Spektrum| 0:Spektrum DSM2, 1:Spektrum DSMX| */ + MAV_CMD_ENUM_END=501, /* | */ }; #endif @@ -179,6 +181,7 @@ enum LIMIT_MODULE #include "./mavlink_msg_data64.h" #include "./mavlink_msg_data96.h" #include "./mavlink_msg_rangefinder.h" +#include "./mavlink_msg_airspeed_autocal.h" #ifdef __cplusplus } diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_ahrs.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_ahrs.h index d9d2ccb041..c3ead11401 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_ahrs.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_ahrs.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_ahrs_pack(uint8_t system_id, uint8_t componen * @brief Pack a ahrs message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param omegaIx X gyro drift estimate rad/s * @param omegaIy Y gyro drift estimate rad/s @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_ahrs_pack_chan(uint8_t system_id, uint8_t com } /** - * @brief Encode a ahrs struct into a message + * @brief Encode a ahrs struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_ahrs_encode(uint8_t system_id, uint8_t compon return mavlink_msg_ahrs_pack(system_id, component_id, msg, ahrs->omegaIx, ahrs->omegaIy, ahrs->omegaIz, ahrs->accel_weight, ahrs->renorm_val, ahrs->error_rp, ahrs->error_yaw); } +/** + * @brief Encode a ahrs struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param ahrs C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_ahrs_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_ahrs_t* ahrs) +{ + return mavlink_msg_ahrs_pack_chan(system_id, component_id, chan, msg, ahrs->omegaIx, ahrs->omegaIy, ahrs->omegaIz, ahrs->accel_weight, ahrs->renorm_val, ahrs->error_rp, ahrs->error_yaw); +} + /** * @brief Send a ahrs message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_airspeed_autocal.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_airspeed_autocal.h new file mode 100644 index 0000000000..d046f2ad09 --- /dev/null +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_airspeed_autocal.h @@ -0,0 +1,419 @@ +// MESSAGE AIRSPEED_AUTOCAL PACKING + +#define MAVLINK_MSG_ID_AIRSPEED_AUTOCAL 174 + +typedef struct __mavlink_airspeed_autocal_t +{ + float vx; ///< GPS velocity north m/s + float vy; ///< GPS velocity east m/s + float vz; ///< GPS velocity down m/s + float diff_pressure; ///< Differential pressure pascals + float EAS2TAS; ///< Estimated to true airspeed ratio + float ratio; ///< Airspeed ratio + float state_x; ///< EKF state x + float state_y; ///< EKF state y + float state_z; ///< EKF state z + float Pax; ///< EKF Pax + float Pby; ///< EKF Pby + float Pcz; ///< EKF Pcz +} mavlink_airspeed_autocal_t; + +#define MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN 48 +#define MAVLINK_MSG_ID_174_LEN 48 + +#define MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_CRC 167 +#define MAVLINK_MSG_ID_174_CRC 167 + + + +#define MAVLINK_MESSAGE_INFO_AIRSPEED_AUTOCAL { \ + "AIRSPEED_AUTOCAL", \ + 12, \ + { { "vx", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_airspeed_autocal_t, vx) }, \ + { "vy", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_airspeed_autocal_t, vy) }, \ + { "vz", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_airspeed_autocal_t, vz) }, \ + { "diff_pressure", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_airspeed_autocal_t, diff_pressure) }, \ + { "EAS2TAS", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_airspeed_autocal_t, EAS2TAS) }, \ + { "ratio", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_airspeed_autocal_t, ratio) }, \ + { "state_x", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_airspeed_autocal_t, state_x) }, \ + { "state_y", NULL, MAVLINK_TYPE_FLOAT, 0, 28, offsetof(mavlink_airspeed_autocal_t, state_y) }, \ + { "state_z", NULL, MAVLINK_TYPE_FLOAT, 0, 32, offsetof(mavlink_airspeed_autocal_t, state_z) }, \ + { "Pax", NULL, MAVLINK_TYPE_FLOAT, 0, 36, offsetof(mavlink_airspeed_autocal_t, Pax) }, \ + { "Pby", NULL, MAVLINK_TYPE_FLOAT, 0, 40, offsetof(mavlink_airspeed_autocal_t, Pby) }, \ + { "Pcz", NULL, MAVLINK_TYPE_FLOAT, 0, 44, offsetof(mavlink_airspeed_autocal_t, Pcz) }, \ + } \ +} + + +/** + * @brief Pack a airspeed_autocal message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param vx GPS velocity north m/s + * @param vy GPS velocity east m/s + * @param vz GPS velocity down m/s + * @param diff_pressure Differential pressure pascals + * @param EAS2TAS Estimated to true airspeed ratio + * @param ratio Airspeed ratio + * @param state_x EKF state x + * @param state_y EKF state y + * @param state_z EKF state z + * @param Pax EKF Pax + * @param Pby EKF Pby + * @param Pcz EKF Pcz + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_airspeed_autocal_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, + float vx, float vy, float vz, float diff_pressure, float EAS2TAS, float ratio, float state_x, float state_y, float state_z, float Pax, float Pby, float Pcz) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN]; + _mav_put_float(buf, 0, vx); + _mav_put_float(buf, 4, vy); + _mav_put_float(buf, 8, vz); + _mav_put_float(buf, 12, diff_pressure); + _mav_put_float(buf, 16, EAS2TAS); + _mav_put_float(buf, 20, ratio); + _mav_put_float(buf, 24, state_x); + _mav_put_float(buf, 28, state_y); + _mav_put_float(buf, 32, state_z); + _mav_put_float(buf, 36, Pax); + _mav_put_float(buf, 40, Pby); + _mav_put_float(buf, 44, Pcz); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN); +#else + mavlink_airspeed_autocal_t packet; + packet.vx = vx; + packet.vy = vy; + packet.vz = vz; + packet.diff_pressure = diff_pressure; + packet.EAS2TAS = EAS2TAS; + packet.ratio = ratio; + packet.state_x = state_x; + packet.state_y = state_y; + packet.state_z = state_z; + packet.Pax = Pax; + packet.Pby = Pby; + packet.Pcz = Pcz; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN); +#endif + + msg->msgid = MAVLINK_MSG_ID_AIRSPEED_AUTOCAL; +#if MAVLINK_CRC_EXTRA + return mavlink_finalize_message(msg, system_id, component_id, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_CRC); +#else + return mavlink_finalize_message(msg, system_id, component_id, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN); +#endif +} + +/** + * @brief Pack a airspeed_autocal message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param vx GPS velocity north m/s + * @param vy GPS velocity east m/s + * @param vz GPS velocity down m/s + * @param diff_pressure Differential pressure pascals + * @param EAS2TAS Estimated to true airspeed ratio + * @param ratio Airspeed ratio + * @param state_x EKF state x + * @param state_y EKF state y + * @param state_z EKF state z + * @param Pax EKF Pax + * @param Pby EKF Pby + * @param Pcz EKF Pcz + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_airspeed_autocal_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t* msg, + float vx,float vy,float vz,float diff_pressure,float EAS2TAS,float ratio,float state_x,float state_y,float state_z,float Pax,float Pby,float Pcz) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN]; + _mav_put_float(buf, 0, vx); + _mav_put_float(buf, 4, vy); + _mav_put_float(buf, 8, vz); + _mav_put_float(buf, 12, diff_pressure); + _mav_put_float(buf, 16, EAS2TAS); + _mav_put_float(buf, 20, ratio); + _mav_put_float(buf, 24, state_x); + _mav_put_float(buf, 28, state_y); + _mav_put_float(buf, 32, state_z); + _mav_put_float(buf, 36, Pax); + _mav_put_float(buf, 40, Pby); + _mav_put_float(buf, 44, Pcz); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN); +#else + mavlink_airspeed_autocal_t packet; + packet.vx = vx; + packet.vy = vy; + packet.vz = vz; + packet.diff_pressure = diff_pressure; + packet.EAS2TAS = EAS2TAS; + packet.ratio = ratio; + packet.state_x = state_x; + packet.state_y = state_y; + packet.state_z = state_z; + packet.Pax = Pax; + packet.Pby = Pby; + packet.Pcz = Pcz; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN); +#endif + + msg->msgid = MAVLINK_MSG_ID_AIRSPEED_AUTOCAL; +#if MAVLINK_CRC_EXTRA + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_CRC); +#else + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN); +#endif +} + +/** + * @brief Encode a airspeed_autocal struct + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param airspeed_autocal C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_airspeed_autocal_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, const mavlink_airspeed_autocal_t* airspeed_autocal) +{ + return mavlink_msg_airspeed_autocal_pack(system_id, component_id, msg, airspeed_autocal->vx, airspeed_autocal->vy, airspeed_autocal->vz, airspeed_autocal->diff_pressure, airspeed_autocal->EAS2TAS, airspeed_autocal->ratio, airspeed_autocal->state_x, airspeed_autocal->state_y, airspeed_autocal->state_z, airspeed_autocal->Pax, airspeed_autocal->Pby, airspeed_autocal->Pcz); +} + +/** + * @brief Encode a airspeed_autocal struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param airspeed_autocal C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_airspeed_autocal_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_airspeed_autocal_t* airspeed_autocal) +{ + return mavlink_msg_airspeed_autocal_pack_chan(system_id, component_id, chan, msg, airspeed_autocal->vx, airspeed_autocal->vy, airspeed_autocal->vz, airspeed_autocal->diff_pressure, airspeed_autocal->EAS2TAS, airspeed_autocal->ratio, airspeed_autocal->state_x, airspeed_autocal->state_y, airspeed_autocal->state_z, airspeed_autocal->Pax, airspeed_autocal->Pby, airspeed_autocal->Pcz); +} + +/** + * @brief Send a airspeed_autocal message + * @param chan MAVLink channel to send the message + * + * @param vx GPS velocity north m/s + * @param vy GPS velocity east m/s + * @param vz GPS velocity down m/s + * @param diff_pressure Differential pressure pascals + * @param EAS2TAS Estimated to true airspeed ratio + * @param ratio Airspeed ratio + * @param state_x EKF state x + * @param state_y EKF state y + * @param state_z EKF state z + * @param Pax EKF Pax + * @param Pby EKF Pby + * @param Pcz EKF Pcz + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_airspeed_autocal_send(mavlink_channel_t chan, float vx, float vy, float vz, float diff_pressure, float EAS2TAS, float ratio, float state_x, float state_y, float state_z, float Pax, float Pby, float Pcz) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN]; + _mav_put_float(buf, 0, vx); + _mav_put_float(buf, 4, vy); + _mav_put_float(buf, 8, vz); + _mav_put_float(buf, 12, diff_pressure); + _mav_put_float(buf, 16, EAS2TAS); + _mav_put_float(buf, 20, ratio); + _mav_put_float(buf, 24, state_x); + _mav_put_float(buf, 28, state_y); + _mav_put_float(buf, 32, state_z); + _mav_put_float(buf, 36, Pax); + _mav_put_float(buf, 40, Pby); + _mav_put_float(buf, 44, Pcz); + +#if MAVLINK_CRC_EXTRA + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL, buf, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_CRC); +#else + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL, buf, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN); +#endif +#else + mavlink_airspeed_autocal_t packet; + packet.vx = vx; + packet.vy = vy; + packet.vz = vz; + packet.diff_pressure = diff_pressure; + packet.EAS2TAS = EAS2TAS; + packet.ratio = ratio; + packet.state_x = state_x; + packet.state_y = state_y; + packet.state_z = state_z; + packet.Pax = Pax; + packet.Pby = Pby; + packet.Pcz = Pcz; + +#if MAVLINK_CRC_EXTRA + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL, (const char *)&packet, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_CRC); +#else + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL, (const char *)&packet, MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN); +#endif +#endif +} + +#endif + +// MESSAGE AIRSPEED_AUTOCAL UNPACKING + + +/** + * @brief Get field vx from airspeed_autocal message + * + * @return GPS velocity north m/s + */ +static inline float mavlink_msg_airspeed_autocal_get_vx(const mavlink_message_t* msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field vy from airspeed_autocal message + * + * @return GPS velocity east m/s + */ +static inline float mavlink_msg_airspeed_autocal_get_vy(const mavlink_message_t* msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field vz from airspeed_autocal message + * + * @return GPS velocity down m/s + */ +static inline float mavlink_msg_airspeed_autocal_get_vz(const mavlink_message_t* msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field diff_pressure from airspeed_autocal message + * + * @return Differential pressure pascals + */ +static inline float mavlink_msg_airspeed_autocal_get_diff_pressure(const mavlink_message_t* msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field EAS2TAS from airspeed_autocal message + * + * @return Estimated to true airspeed ratio + */ +static inline float mavlink_msg_airspeed_autocal_get_EAS2TAS(const mavlink_message_t* msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field ratio from airspeed_autocal message + * + * @return Airspeed ratio + */ +static inline float mavlink_msg_airspeed_autocal_get_ratio(const mavlink_message_t* msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Get field state_x from airspeed_autocal message + * + * @return EKF state x + */ +static inline float mavlink_msg_airspeed_autocal_get_state_x(const mavlink_message_t* msg) +{ + return _MAV_RETURN_float(msg, 24); +} + +/** + * @brief Get field state_y from airspeed_autocal message + * + * @return EKF state y + */ +static inline float mavlink_msg_airspeed_autocal_get_state_y(const mavlink_message_t* msg) +{ + return _MAV_RETURN_float(msg, 28); +} + +/** + * @brief Get field state_z from airspeed_autocal message + * + * @return EKF state z + */ +static inline float mavlink_msg_airspeed_autocal_get_state_z(const mavlink_message_t* msg) +{ + return _MAV_RETURN_float(msg, 32); +} + +/** + * @brief Get field Pax from airspeed_autocal message + * + * @return EKF Pax + */ +static inline float mavlink_msg_airspeed_autocal_get_Pax(const mavlink_message_t* msg) +{ + return _MAV_RETURN_float(msg, 36); +} + +/** + * @brief Get field Pby from airspeed_autocal message + * + * @return EKF Pby + */ +static inline float mavlink_msg_airspeed_autocal_get_Pby(const mavlink_message_t* msg) +{ + return _MAV_RETURN_float(msg, 40); +} + +/** + * @brief Get field Pcz from airspeed_autocal message + * + * @return EKF Pcz + */ +static inline float mavlink_msg_airspeed_autocal_get_Pcz(const mavlink_message_t* msg) +{ + return _MAV_RETURN_float(msg, 44); +} + +/** + * @brief Decode a airspeed_autocal message into a struct + * + * @param msg The message to decode + * @param airspeed_autocal C-struct to decode the message contents into + */ +static inline void mavlink_msg_airspeed_autocal_decode(const mavlink_message_t* msg, mavlink_airspeed_autocal_t* airspeed_autocal) +{ +#if MAVLINK_NEED_BYTE_SWAP + airspeed_autocal->vx = mavlink_msg_airspeed_autocal_get_vx(msg); + airspeed_autocal->vy = mavlink_msg_airspeed_autocal_get_vy(msg); + airspeed_autocal->vz = mavlink_msg_airspeed_autocal_get_vz(msg); + airspeed_autocal->diff_pressure = mavlink_msg_airspeed_autocal_get_diff_pressure(msg); + airspeed_autocal->EAS2TAS = mavlink_msg_airspeed_autocal_get_EAS2TAS(msg); + airspeed_autocal->ratio = mavlink_msg_airspeed_autocal_get_ratio(msg); + airspeed_autocal->state_x = mavlink_msg_airspeed_autocal_get_state_x(msg); + airspeed_autocal->state_y = mavlink_msg_airspeed_autocal_get_state_y(msg); + airspeed_autocal->state_z = mavlink_msg_airspeed_autocal_get_state_z(msg); + airspeed_autocal->Pax = mavlink_msg_airspeed_autocal_get_Pax(msg); + airspeed_autocal->Pby = mavlink_msg_airspeed_autocal_get_Pby(msg); + airspeed_autocal->Pcz = mavlink_msg_airspeed_autocal_get_Pcz(msg); +#else + memcpy(airspeed_autocal, _MAV_PAYLOAD(msg), MAVLINK_MSG_ID_AIRSPEED_AUTOCAL_LEN); +#endif +} diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_ap_adc.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_ap_adc.h index c6c7624513..821ce73e47 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_ap_adc.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_ap_adc.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_ap_adc_pack(uint8_t system_id, uint8_t compon * @brief Pack a ap_adc message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param adc1 ADC output 1 * @param adc2 ADC output 2 @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_ap_adc_pack_chan(uint8_t system_id, uint8_t c } /** - * @brief Encode a ap_adc struct into a message + * @brief Encode a ap_adc struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_ap_adc_encode(uint8_t system_id, uint8_t comp return mavlink_msg_ap_adc_pack(system_id, component_id, msg, ap_adc->adc1, ap_adc->adc2, ap_adc->adc3, ap_adc->adc4, ap_adc->adc5, ap_adc->adc6); } +/** + * @brief Encode a ap_adc struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param ap_adc C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_ap_adc_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_ap_adc_t* ap_adc) +{ + return mavlink_msg_ap_adc_pack_chan(system_id, component_id, chan, msg, ap_adc->adc1, ap_adc->adc2, ap_adc->adc3, ap_adc->adc4, ap_adc->adc5, ap_adc->adc6); +} + /** * @brief Send a ap_adc message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data16.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data16.h index c753585267..9200eefa0d 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data16.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data16.h @@ -67,7 +67,7 @@ static inline uint16_t mavlink_msg_data16_pack(uint8_t system_id, uint8_t compon * @brief Pack a data16 message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param type data type * @param len data length @@ -101,7 +101,7 @@ static inline uint16_t mavlink_msg_data16_pack_chan(uint8_t system_id, uint8_t c } /** - * @brief Encode a data16 struct into a message + * @brief Encode a data16 struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -113,6 +113,20 @@ static inline uint16_t mavlink_msg_data16_encode(uint8_t system_id, uint8_t comp return mavlink_msg_data16_pack(system_id, component_id, msg, data16->type, data16->len, data16->data); } +/** + * @brief Encode a data16 struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param data16 C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_data16_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_data16_t* data16) +{ + return mavlink_msg_data16_pack_chan(system_id, component_id, chan, msg, data16->type, data16->len, data16->data); +} + /** * @brief Send a data16 message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data32.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data32.h index 46c804a3c2..3afedb7874 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data32.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data32.h @@ -67,7 +67,7 @@ static inline uint16_t mavlink_msg_data32_pack(uint8_t system_id, uint8_t compon * @brief Pack a data32 message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param type data type * @param len data length @@ -101,7 +101,7 @@ static inline uint16_t mavlink_msg_data32_pack_chan(uint8_t system_id, uint8_t c } /** - * @brief Encode a data32 struct into a message + * @brief Encode a data32 struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -113,6 +113,20 @@ static inline uint16_t mavlink_msg_data32_encode(uint8_t system_id, uint8_t comp return mavlink_msg_data32_pack(system_id, component_id, msg, data32->type, data32->len, data32->data); } +/** + * @brief Encode a data32 struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param data32 C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_data32_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_data32_t* data32) +{ + return mavlink_msg_data32_pack_chan(system_id, component_id, chan, msg, data32->type, data32->len, data32->data); +} + /** * @brief Send a data32 message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data64.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data64.h index 843084dffa..6931ada167 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data64.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data64.h @@ -67,7 +67,7 @@ static inline uint16_t mavlink_msg_data64_pack(uint8_t system_id, uint8_t compon * @brief Pack a data64 message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param type data type * @param len data length @@ -101,7 +101,7 @@ static inline uint16_t mavlink_msg_data64_pack_chan(uint8_t system_id, uint8_t c } /** - * @brief Encode a data64 struct into a message + * @brief Encode a data64 struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -113,6 +113,20 @@ static inline uint16_t mavlink_msg_data64_encode(uint8_t system_id, uint8_t comp return mavlink_msg_data64_pack(system_id, component_id, msg, data64->type, data64->len, data64->data); } +/** + * @brief Encode a data64 struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param data64 C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_data64_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_data64_t* data64) +{ + return mavlink_msg_data64_pack_chan(system_id, component_id, chan, msg, data64->type, data64->len, data64->data); +} + /** * @brief Send a data64 message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data96.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data96.h index 095628865c..cffc7d7e7f 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data96.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_data96.h @@ -67,7 +67,7 @@ static inline uint16_t mavlink_msg_data96_pack(uint8_t system_id, uint8_t compon * @brief Pack a data96 message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param type data type * @param len data length @@ -101,7 +101,7 @@ static inline uint16_t mavlink_msg_data96_pack_chan(uint8_t system_id, uint8_t c } /** - * @brief Encode a data96 struct into a message + * @brief Encode a data96 struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -113,6 +113,20 @@ static inline uint16_t mavlink_msg_data96_encode(uint8_t system_id, uint8_t comp return mavlink_msg_data96_pack(system_id, component_id, msg, data96->type, data96->len, data96->data); } +/** + * @brief Encode a data96 struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param data96 C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_data96_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_data96_t* data96) +{ + return mavlink_msg_data96_pack_chan(system_id, component_id, chan, msg, data96->type, data96->len, data96->data); +} + /** * @brief Send a data96 message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_digicam_configure.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_digicam_configure.h index bcc706a887..c6518c4199 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_digicam_configure.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_digicam_configure.h @@ -109,7 +109,7 @@ static inline uint16_t mavlink_msg_digicam_configure_pack(uint8_t system_id, uin * @brief Pack a digicam_configure message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -169,7 +169,7 @@ static inline uint16_t mavlink_msg_digicam_configure_pack_chan(uint8_t system_id } /** - * @brief Encode a digicam_configure struct into a message + * @brief Encode a digicam_configure struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -181,6 +181,20 @@ static inline uint16_t mavlink_msg_digicam_configure_encode(uint8_t system_id, u return mavlink_msg_digicam_configure_pack(system_id, component_id, msg, digicam_configure->target_system, digicam_configure->target_component, digicam_configure->mode, digicam_configure->shutter_speed, digicam_configure->aperture, digicam_configure->iso, digicam_configure->exposure_type, digicam_configure->command_id, digicam_configure->engine_cut_off, digicam_configure->extra_param, digicam_configure->extra_value); } +/** + * @brief Encode a digicam_configure struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param digicam_configure C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_digicam_configure_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_digicam_configure_t* digicam_configure) +{ + return mavlink_msg_digicam_configure_pack_chan(system_id, component_id, chan, msg, digicam_configure->target_system, digicam_configure->target_component, digicam_configure->mode, digicam_configure->shutter_speed, digicam_configure->aperture, digicam_configure->iso, digicam_configure->exposure_type, digicam_configure->command_id, digicam_configure->engine_cut_off, digicam_configure->extra_param, digicam_configure->extra_value); +} + /** * @brief Send a digicam_configure message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_digicam_control.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_digicam_control.h index 7fa8cdfef8..bfa5414a39 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_digicam_control.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_digicam_control.h @@ -104,7 +104,7 @@ static inline uint16_t mavlink_msg_digicam_control_pack(uint8_t system_id, uint8 * @brief Pack a digicam_control message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -161,7 +161,7 @@ static inline uint16_t mavlink_msg_digicam_control_pack_chan(uint8_t system_id, } /** - * @brief Encode a digicam_control struct into a message + * @brief Encode a digicam_control struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -173,6 +173,20 @@ static inline uint16_t mavlink_msg_digicam_control_encode(uint8_t system_id, uin return mavlink_msg_digicam_control_pack(system_id, component_id, msg, digicam_control->target_system, digicam_control->target_component, digicam_control->session, digicam_control->zoom_pos, digicam_control->zoom_step, digicam_control->focus_lock, digicam_control->shot, digicam_control->command_id, digicam_control->extra_param, digicam_control->extra_value); } +/** + * @brief Encode a digicam_control struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param digicam_control C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_digicam_control_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_digicam_control_t* digicam_control) +{ + return mavlink_msg_digicam_control_pack_chan(system_id, component_id, chan, msg, digicam_control->target_system, digicam_control->target_component, digicam_control->session, digicam_control->zoom_pos, digicam_control->zoom_step, digicam_control->focus_lock, digicam_control->shot, digicam_control->command_id, digicam_control->extra_param, digicam_control->extra_value); +} + /** * @brief Send a digicam_control message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_fence_fetch_point.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_fence_fetch_point.h index 2cd4fc798c..fe3677d53d 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_fence_fetch_point.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_fence_fetch_point.h @@ -69,7 +69,7 @@ static inline uint16_t mavlink_msg_fence_fetch_point_pack(uint8_t system_id, uin * @brief Pack a fence_fetch_point message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -105,7 +105,7 @@ static inline uint16_t mavlink_msg_fence_fetch_point_pack_chan(uint8_t system_id } /** - * @brief Encode a fence_fetch_point struct into a message + * @brief Encode a fence_fetch_point struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -117,6 +117,20 @@ static inline uint16_t mavlink_msg_fence_fetch_point_encode(uint8_t system_id, u return mavlink_msg_fence_fetch_point_pack(system_id, component_id, msg, fence_fetch_point->target_system, fence_fetch_point->target_component, fence_fetch_point->idx); } +/** + * @brief Encode a fence_fetch_point struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param fence_fetch_point C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_fence_fetch_point_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_fence_fetch_point_t* fence_fetch_point) +{ + return mavlink_msg_fence_fetch_point_pack_chan(system_id, component_id, chan, msg, fence_fetch_point->target_system, fence_fetch_point->target_component, fence_fetch_point->idx); +} + /** * @brief Send a fence_fetch_point message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_fence_point.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_fence_point.h index b3c4706ee0..febda6cdc5 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_fence_point.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_fence_point.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_fence_point_pack(uint8_t system_id, uint8_t c * @brief Pack a fence_point message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_fence_point_pack_chan(uint8_t system_id, uint } /** - * @brief Encode a fence_point struct into a message + * @brief Encode a fence_point struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_fence_point_encode(uint8_t system_id, uint8_t return mavlink_msg_fence_point_pack(system_id, component_id, msg, fence_point->target_system, fence_point->target_component, fence_point->idx, fence_point->count, fence_point->lat, fence_point->lng); } +/** + * @brief Encode a fence_point struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param fence_point C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_fence_point_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_fence_point_t* fence_point) +{ + return mavlink_msg_fence_point_pack_chan(system_id, component_id, chan, msg, fence_point->target_system, fence_point->target_component, fence_point->idx, fence_point->count, fence_point->lat, fence_point->lng); +} + /** * @brief Send a fence_point message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_fence_status.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_fence_status.h index 32f2bc03a8..6120904061 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_fence_status.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_fence_status.h @@ -74,7 +74,7 @@ static inline uint16_t mavlink_msg_fence_status_pack(uint8_t system_id, uint8_t * @brief Pack a fence_status message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param breach_status 0 if currently inside fence, 1 if outside * @param breach_count number of fence breaches @@ -113,7 +113,7 @@ static inline uint16_t mavlink_msg_fence_status_pack_chan(uint8_t system_id, uin } /** - * @brief Encode a fence_status struct into a message + * @brief Encode a fence_status struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -125,6 +125,20 @@ static inline uint16_t mavlink_msg_fence_status_encode(uint8_t system_id, uint8_ return mavlink_msg_fence_status_pack(system_id, component_id, msg, fence_status->breach_status, fence_status->breach_count, fence_status->breach_type, fence_status->breach_time); } +/** + * @brief Encode a fence_status struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param fence_status C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_fence_status_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_fence_status_t* fence_status) +{ + return mavlink_msg_fence_status_pack_chan(system_id, component_id, chan, msg, fence_status->breach_status, fence_status->breach_count, fence_status->breach_type, fence_status->breach_time); +} + /** * @brief Send a fence_status message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_hwstatus.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_hwstatus.h index 73870ec0fb..2f5dea513a 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_hwstatus.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_hwstatus.h @@ -64,7 +64,7 @@ static inline uint16_t mavlink_msg_hwstatus_pack(uint8_t system_id, uint8_t comp * @brief Pack a hwstatus message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param Vcc board voltage (mV) * @param I2Cerr I2C error count @@ -97,7 +97,7 @@ static inline uint16_t mavlink_msg_hwstatus_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a hwstatus struct into a message + * @brief Encode a hwstatus struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -109,6 +109,20 @@ static inline uint16_t mavlink_msg_hwstatus_encode(uint8_t system_id, uint8_t co return mavlink_msg_hwstatus_pack(system_id, component_id, msg, hwstatus->Vcc, hwstatus->I2Cerr); } +/** + * @brief Encode a hwstatus struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param hwstatus C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_hwstatus_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_hwstatus_t* hwstatus) +{ + return mavlink_msg_hwstatus_pack_chan(system_id, component_id, chan, msg, hwstatus->Vcc, hwstatus->I2Cerr); +} + /** * @brief Send a hwstatus message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_limits_status.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_limits_status.h index f7b04fba71..34743fd021 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_limits_status.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_limits_status.h @@ -99,7 +99,7 @@ static inline uint16_t mavlink_msg_limits_status_pack(uint8_t system_id, uint8_t * @brief Pack a limits_status message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param limits_state state of AP_Limits, (see enum LimitState, LIMITS_STATE) * @param last_trigger time of last breach in milliseconds since boot @@ -153,7 +153,7 @@ static inline uint16_t mavlink_msg_limits_status_pack_chan(uint8_t system_id, ui } /** - * @brief Encode a limits_status struct into a message + * @brief Encode a limits_status struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -165,6 +165,20 @@ static inline uint16_t mavlink_msg_limits_status_encode(uint8_t system_id, uint8 return mavlink_msg_limits_status_pack(system_id, component_id, msg, limits_status->limits_state, limits_status->last_trigger, limits_status->last_action, limits_status->last_recovery, limits_status->last_clear, limits_status->breach_count, limits_status->mods_enabled, limits_status->mods_required, limits_status->mods_triggered); } +/** + * @brief Encode a limits_status struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param limits_status C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_limits_status_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_limits_status_t* limits_status) +{ + return mavlink_msg_limits_status_pack_chan(system_id, component_id, chan, msg, limits_status->limits_state, limits_status->last_trigger, limits_status->last_action, limits_status->last_recovery, limits_status->last_clear, limits_status->breach_count, limits_status->mods_enabled, limits_status->mods_required, limits_status->mods_triggered); +} + /** * @brief Send a limits_status message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_meminfo.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_meminfo.h index 437029eed7..55f772bbc5 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_meminfo.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_meminfo.h @@ -64,7 +64,7 @@ static inline uint16_t mavlink_msg_meminfo_pack(uint8_t system_id, uint8_t compo * @brief Pack a meminfo message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param brkval heap top * @param freemem free memory @@ -97,7 +97,7 @@ static inline uint16_t mavlink_msg_meminfo_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a meminfo struct into a message + * @brief Encode a meminfo struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -109,6 +109,20 @@ static inline uint16_t mavlink_msg_meminfo_encode(uint8_t system_id, uint8_t com return mavlink_msg_meminfo_pack(system_id, component_id, msg, meminfo->brkval, meminfo->freemem); } +/** + * @brief Encode a meminfo struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param meminfo C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_meminfo_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_meminfo_t* meminfo) +{ + return mavlink_msg_meminfo_pack_chan(system_id, component_id, chan, msg, meminfo->brkval, meminfo->freemem); +} + /** * @brief Send a meminfo message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_mount_configure.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_mount_configure.h index 450153c6fe..de717dfa4d 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_mount_configure.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_mount_configure.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_mount_configure_pack(uint8_t system_id, uint8 * @brief Pack a mount_configure message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_mount_configure_pack_chan(uint8_t system_id, } /** - * @brief Encode a mount_configure struct into a message + * @brief Encode a mount_configure struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_mount_configure_encode(uint8_t system_id, uin return mavlink_msg_mount_configure_pack(system_id, component_id, msg, mount_configure->target_system, mount_configure->target_component, mount_configure->mount_mode, mount_configure->stab_roll, mount_configure->stab_pitch, mount_configure->stab_yaw); } +/** + * @brief Encode a mount_configure struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mount_configure C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mount_configure_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mount_configure_t* mount_configure) +{ + return mavlink_msg_mount_configure_pack_chan(system_id, component_id, chan, msg, mount_configure->target_system, mount_configure->target_component, mount_configure->mount_mode, mount_configure->stab_roll, mount_configure->stab_pitch, mount_configure->stab_yaw); +} + /** * @brief Send a mount_configure message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_mount_control.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_mount_control.h index 5b83d7e970..44416353ed 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_mount_control.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_mount_control.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_mount_control_pack(uint8_t system_id, uint8_t * @brief Pack a mount_control message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_mount_control_pack_chan(uint8_t system_id, ui } /** - * @brief Encode a mount_control struct into a message + * @brief Encode a mount_control struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_mount_control_encode(uint8_t system_id, uint8 return mavlink_msg_mount_control_pack(system_id, component_id, msg, mount_control->target_system, mount_control->target_component, mount_control->input_a, mount_control->input_b, mount_control->input_c, mount_control->save_position); } +/** + * @brief Encode a mount_control struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mount_control C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mount_control_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mount_control_t* mount_control) +{ + return mavlink_msg_mount_control_pack_chan(system_id, component_id, chan, msg, mount_control->target_system, mount_control->target_component, mount_control->input_a, mount_control->input_b, mount_control->input_c, mount_control->save_position); +} + /** * @brief Send a mount_control message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_mount_status.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_mount_status.h index c031db42b4..4905905dc5 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_mount_status.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_mount_status.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_mount_status_pack(uint8_t system_id, uint8_t * @brief Pack a mount_status message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -121,7 +121,7 @@ static inline uint16_t mavlink_msg_mount_status_pack_chan(uint8_t system_id, uin } /** - * @brief Encode a mount_status struct into a message + * @brief Encode a mount_status struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -133,6 +133,20 @@ static inline uint16_t mavlink_msg_mount_status_encode(uint8_t system_id, uint8_ return mavlink_msg_mount_status_pack(system_id, component_id, msg, mount_status->target_system, mount_status->target_component, mount_status->pointing_a, mount_status->pointing_b, mount_status->pointing_c); } +/** + * @brief Encode a mount_status struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mount_status C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mount_status_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mount_status_t* mount_status) +{ + return mavlink_msg_mount_status_pack_chan(system_id, component_id, chan, msg, mount_status->target_system, mount_status->target_component, mount_status->pointing_a, mount_status->pointing_b, mount_status->pointing_c); +} + /** * @brief Send a mount_status message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_radio.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_radio.h index e13776993e..8e9740e828 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_radio.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_radio.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_radio_pack(uint8_t system_id, uint8_t compone * @brief Pack a radio message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param rssi local signal strength * @param remrssi remote signal strength @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_radio_pack_chan(uint8_t system_id, uint8_t co } /** - * @brief Encode a radio struct into a message + * @brief Encode a radio struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_radio_encode(uint8_t system_id, uint8_t compo return mavlink_msg_radio_pack(system_id, component_id, msg, radio->rssi, radio->remrssi, radio->txbuf, radio->noise, radio->remnoise, radio->rxerrors, radio->fixed); } +/** + * @brief Encode a radio struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param radio C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_radio_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_radio_t* radio) +{ + return mavlink_msg_radio_pack_chan(system_id, component_id, chan, msg, radio->rssi, radio->remrssi, radio->txbuf, radio->noise, radio->remnoise, radio->rxerrors, radio->fixed); +} + /** * @brief Send a radio message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_rangefinder.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_rangefinder.h index d88abe36a4..c476447a87 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_rangefinder.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_rangefinder.h @@ -64,7 +64,7 @@ static inline uint16_t mavlink_msg_rangefinder_pack(uint8_t system_id, uint8_t c * @brief Pack a rangefinder message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param distance distance in meters * @param voltage raw voltage if available, zero otherwise @@ -97,7 +97,7 @@ static inline uint16_t mavlink_msg_rangefinder_pack_chan(uint8_t system_id, uint } /** - * @brief Encode a rangefinder struct into a message + * @brief Encode a rangefinder struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -109,6 +109,20 @@ static inline uint16_t mavlink_msg_rangefinder_encode(uint8_t system_id, uint8_t return mavlink_msg_rangefinder_pack(system_id, component_id, msg, rangefinder->distance, rangefinder->voltage); } +/** + * @brief Encode a rangefinder struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param rangefinder C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_rangefinder_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_rangefinder_t* rangefinder) +{ + return mavlink_msg_rangefinder_pack_chan(system_id, component_id, chan, msg, rangefinder->distance, rangefinder->voltage); +} + /** * @brief Send a rangefinder message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_sensor_offsets.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_sensor_offsets.h index d121e48e66..31b7d989de 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_sensor_offsets.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_sensor_offsets.h @@ -114,7 +114,7 @@ static inline uint16_t mavlink_msg_sensor_offsets_pack(uint8_t system_id, uint8_ * @brief Pack a sensor_offsets message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param mag_ofs_x magnetometer X offset * @param mag_ofs_y magnetometer Y offset @@ -177,7 +177,7 @@ static inline uint16_t mavlink_msg_sensor_offsets_pack_chan(uint8_t system_id, u } /** - * @brief Encode a sensor_offsets struct into a message + * @brief Encode a sensor_offsets struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -189,6 +189,20 @@ static inline uint16_t mavlink_msg_sensor_offsets_encode(uint8_t system_id, uint return mavlink_msg_sensor_offsets_pack(system_id, component_id, msg, sensor_offsets->mag_ofs_x, sensor_offsets->mag_ofs_y, sensor_offsets->mag_ofs_z, sensor_offsets->mag_declination, sensor_offsets->raw_press, sensor_offsets->raw_temp, sensor_offsets->gyro_cal_x, sensor_offsets->gyro_cal_y, sensor_offsets->gyro_cal_z, sensor_offsets->accel_cal_x, sensor_offsets->accel_cal_y, sensor_offsets->accel_cal_z); } +/** + * @brief Encode a sensor_offsets struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param sensor_offsets C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_sensor_offsets_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_sensor_offsets_t* sensor_offsets) +{ + return mavlink_msg_sensor_offsets_pack_chan(system_id, component_id, chan, msg, sensor_offsets->mag_ofs_x, sensor_offsets->mag_ofs_y, sensor_offsets->mag_ofs_z, sensor_offsets->mag_declination, sensor_offsets->raw_press, sensor_offsets->raw_temp, sensor_offsets->gyro_cal_x, sensor_offsets->gyro_cal_y, sensor_offsets->gyro_cal_z, sensor_offsets->accel_cal_x, sensor_offsets->accel_cal_y, sensor_offsets->accel_cal_z); +} + /** * @brief Send a sensor_offsets message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_set_mag_offsets.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_set_mag_offsets.h index a59e906494..b2c629c39a 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_set_mag_offsets.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_set_mag_offsets.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_set_mag_offsets_pack(uint8_t system_id, uint8 * @brief Pack a set_mag_offsets message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -121,7 +121,7 @@ static inline uint16_t mavlink_msg_set_mag_offsets_pack_chan(uint8_t system_id, } /** - * @brief Encode a set_mag_offsets struct into a message + * @brief Encode a set_mag_offsets struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -133,6 +133,20 @@ static inline uint16_t mavlink_msg_set_mag_offsets_encode(uint8_t system_id, uin return mavlink_msg_set_mag_offsets_pack(system_id, component_id, msg, set_mag_offsets->target_system, set_mag_offsets->target_component, set_mag_offsets->mag_ofs_x, set_mag_offsets->mag_ofs_y, set_mag_offsets->mag_ofs_z); } +/** + * @brief Encode a set_mag_offsets struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param set_mag_offsets C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_mag_offsets_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_set_mag_offsets_t* set_mag_offsets) +{ + return mavlink_msg_set_mag_offsets_pack_chan(system_id, component_id, chan, msg, set_mag_offsets->target_system, set_mag_offsets->target_component, set_mag_offsets->mag_ofs_x, set_mag_offsets->mag_ofs_y, set_mag_offsets->mag_ofs_z); +} + /** * @brief Send a set_mag_offsets message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_simstate.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_simstate.h index 7373c8bffe..8ef44f76d5 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_simstate.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_simstate.h @@ -13,15 +13,15 @@ typedef struct __mavlink_simstate_t float xgyro; ///< Angular speed around X axis rad/s float ygyro; ///< Angular speed around Y axis rad/s float zgyro; ///< Angular speed around Z axis rad/s - float lat; ///< Latitude in degrees - float lng; ///< Longitude in degrees + int32_t lat; ///< Latitude in degrees * 1E7 + int32_t lng; ///< Longitude in degrees * 1E7 } mavlink_simstate_t; #define MAVLINK_MSG_ID_SIMSTATE_LEN 44 #define MAVLINK_MSG_ID_164_LEN 44 -#define MAVLINK_MSG_ID_SIMSTATE_CRC 111 -#define MAVLINK_MSG_ID_164_CRC 111 +#define MAVLINK_MSG_ID_SIMSTATE_CRC 154 +#define MAVLINK_MSG_ID_164_CRC 154 @@ -37,8 +37,8 @@ typedef struct __mavlink_simstate_t { "xgyro", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_simstate_t, xgyro) }, \ { "ygyro", NULL, MAVLINK_TYPE_FLOAT, 0, 28, offsetof(mavlink_simstate_t, ygyro) }, \ { "zgyro", NULL, MAVLINK_TYPE_FLOAT, 0, 32, offsetof(mavlink_simstate_t, zgyro) }, \ - { "lat", NULL, MAVLINK_TYPE_FLOAT, 0, 36, offsetof(mavlink_simstate_t, lat) }, \ - { "lng", NULL, MAVLINK_TYPE_FLOAT, 0, 40, offsetof(mavlink_simstate_t, lng) }, \ + { "lat", NULL, MAVLINK_TYPE_INT32_T, 0, 36, offsetof(mavlink_simstate_t, lat) }, \ + { "lng", NULL, MAVLINK_TYPE_INT32_T, 0, 40, offsetof(mavlink_simstate_t, lng) }, \ } \ } @@ -58,12 +58,12 @@ typedef struct __mavlink_simstate_t * @param xgyro Angular speed around X axis rad/s * @param ygyro Angular speed around Y axis rad/s * @param zgyro Angular speed around Z axis rad/s - * @param lat Latitude in degrees - * @param lng Longitude in degrees + * @param lat Latitude in degrees * 1E7 + * @param lng Longitude in degrees * 1E7 * @return length of the message in bytes (excluding serial stream start sign) */ static inline uint16_t mavlink_msg_simstate_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, - float roll, float pitch, float yaw, float xacc, float yacc, float zacc, float xgyro, float ygyro, float zgyro, float lat, float lng) + float roll, float pitch, float yaw, float xacc, float yacc, float zacc, float xgyro, float ygyro, float zgyro, int32_t lat, int32_t lng) { #if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS char buf[MAVLINK_MSG_ID_SIMSTATE_LEN]; @@ -76,8 +76,8 @@ static inline uint16_t mavlink_msg_simstate_pack(uint8_t system_id, uint8_t comp _mav_put_float(buf, 24, xgyro); _mav_put_float(buf, 28, ygyro); _mav_put_float(buf, 32, zgyro); - _mav_put_float(buf, 36, lat); - _mav_put_float(buf, 40, lng); + _mav_put_int32_t(buf, 36, lat); + _mav_put_int32_t(buf, 40, lng); memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, MAVLINK_MSG_ID_SIMSTATE_LEN); #else @@ -109,7 +109,7 @@ static inline uint16_t mavlink_msg_simstate_pack(uint8_t system_id, uint8_t comp * @brief Pack a simstate message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param roll Roll angle (rad) * @param pitch Pitch angle (rad) @@ -120,13 +120,13 @@ static inline uint16_t mavlink_msg_simstate_pack(uint8_t system_id, uint8_t comp * @param xgyro Angular speed around X axis rad/s * @param ygyro Angular speed around Y axis rad/s * @param zgyro Angular speed around Z axis rad/s - * @param lat Latitude in degrees - * @param lng Longitude in degrees + * @param lat Latitude in degrees * 1E7 + * @param lng Longitude in degrees * 1E7 * @return length of the message in bytes (excluding serial stream start sign) */ static inline uint16_t mavlink_msg_simstate_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, - float roll,float pitch,float yaw,float xacc,float yacc,float zacc,float xgyro,float ygyro,float zgyro,float lat,float lng) + float roll,float pitch,float yaw,float xacc,float yacc,float zacc,float xgyro,float ygyro,float zgyro,int32_t lat,int32_t lng) { #if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS char buf[MAVLINK_MSG_ID_SIMSTATE_LEN]; @@ -139,8 +139,8 @@ static inline uint16_t mavlink_msg_simstate_pack_chan(uint8_t system_id, uint8_t _mav_put_float(buf, 24, xgyro); _mav_put_float(buf, 28, ygyro); _mav_put_float(buf, 32, zgyro); - _mav_put_float(buf, 36, lat); - _mav_put_float(buf, 40, lng); + _mav_put_int32_t(buf, 36, lat); + _mav_put_int32_t(buf, 40, lng); memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, MAVLINK_MSG_ID_SIMSTATE_LEN); #else @@ -169,7 +169,7 @@ static inline uint16_t mavlink_msg_simstate_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a simstate struct into a message + * @brief Encode a simstate struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -181,6 +181,20 @@ static inline uint16_t mavlink_msg_simstate_encode(uint8_t system_id, uint8_t co return mavlink_msg_simstate_pack(system_id, component_id, msg, simstate->roll, simstate->pitch, simstate->yaw, simstate->xacc, simstate->yacc, simstate->zacc, simstate->xgyro, simstate->ygyro, simstate->zgyro, simstate->lat, simstate->lng); } +/** + * @brief Encode a simstate struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param simstate C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_simstate_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_simstate_t* simstate) +{ + return mavlink_msg_simstate_pack_chan(system_id, component_id, chan, msg, simstate->roll, simstate->pitch, simstate->yaw, simstate->xacc, simstate->yacc, simstate->zacc, simstate->xgyro, simstate->ygyro, simstate->zgyro, simstate->lat, simstate->lng); +} + /** * @brief Send a simstate message * @param chan MAVLink channel to send the message @@ -194,12 +208,12 @@ static inline uint16_t mavlink_msg_simstate_encode(uint8_t system_id, uint8_t co * @param xgyro Angular speed around X axis rad/s * @param ygyro Angular speed around Y axis rad/s * @param zgyro Angular speed around Z axis rad/s - * @param lat Latitude in degrees - * @param lng Longitude in degrees + * @param lat Latitude in degrees * 1E7 + * @param lng Longitude in degrees * 1E7 */ #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS -static inline void mavlink_msg_simstate_send(mavlink_channel_t chan, float roll, float pitch, float yaw, float xacc, float yacc, float zacc, float xgyro, float ygyro, float zgyro, float lat, float lng) +static inline void mavlink_msg_simstate_send(mavlink_channel_t chan, float roll, float pitch, float yaw, float xacc, float yacc, float zacc, float xgyro, float ygyro, float zgyro, int32_t lat, int32_t lng) { #if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS char buf[MAVLINK_MSG_ID_SIMSTATE_LEN]; @@ -212,8 +226,8 @@ static inline void mavlink_msg_simstate_send(mavlink_channel_t chan, float roll, _mav_put_float(buf, 24, xgyro); _mav_put_float(buf, 28, ygyro); _mav_put_float(buf, 32, zgyro); - _mav_put_float(buf, 36, lat); - _mav_put_float(buf, 40, lng); + _mav_put_int32_t(buf, 36, lat); + _mav_put_int32_t(buf, 40, lng); #if MAVLINK_CRC_EXTRA _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SIMSTATE, buf, MAVLINK_MSG_ID_SIMSTATE_LEN, MAVLINK_MSG_ID_SIMSTATE_CRC); @@ -340,21 +354,21 @@ static inline float mavlink_msg_simstate_get_zgyro(const mavlink_message_t* msg) /** * @brief Get field lat from simstate message * - * @return Latitude in degrees + * @return Latitude in degrees * 1E7 */ -static inline float mavlink_msg_simstate_get_lat(const mavlink_message_t* msg) +static inline int32_t mavlink_msg_simstate_get_lat(const mavlink_message_t* msg) { - return _MAV_RETURN_float(msg, 36); + return _MAV_RETURN_int32_t(msg, 36); } /** * @brief Get field lng from simstate message * - * @return Longitude in degrees + * @return Longitude in degrees * 1E7 */ -static inline float mavlink_msg_simstate_get_lng(const mavlink_message_t* msg) +static inline int32_t mavlink_msg_simstate_get_lng(const mavlink_message_t* msg) { - return _MAV_RETURN_float(msg, 40); + return _MAV_RETURN_int32_t(msg, 40); } /** diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_wind.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_wind.h index ebdd2949d9..7608a7bd10 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_wind.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/mavlink_msg_wind.h @@ -69,7 +69,7 @@ static inline uint16_t mavlink_msg_wind_pack(uint8_t system_id, uint8_t componen * @brief Pack a wind message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param direction wind direction that wind is coming from (degrees) * @param speed wind speed in ground plane (m/s) @@ -105,7 +105,7 @@ static inline uint16_t mavlink_msg_wind_pack_chan(uint8_t system_id, uint8_t com } /** - * @brief Encode a wind struct into a message + * @brief Encode a wind struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -117,6 +117,20 @@ static inline uint16_t mavlink_msg_wind_encode(uint8_t system_id, uint8_t compon return mavlink_msg_wind_pack(system_id, component_id, msg, wind->direction, wind->speed, wind->speed_z); } +/** + * @brief Encode a wind struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param wind C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_wind_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_wind_t* wind) +{ + return mavlink_msg_wind_pack_chan(system_id, component_id, chan, msg, wind->direction, wind->speed, wind->speed_z); +} + /** * @brief Send a wind message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/testsuite.h b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/testsuite.h index 07bf19ee07..2c9cfef3dc 100644 --- a/libs/mavlink/include/mavlink/v1.0/ardupilotmega/testsuite.h +++ b/libs/mavlink/include/mavlink/v1.0/ardupilotmega/testsuite.h @@ -738,8 +738,8 @@ static void mavlink_test_simstate(uint8_t system_id, uint8_t component_id, mavli 185.0, 213.0, 241.0, - 269.0, - 297.0, + 963499336, + 963499544, }; mavlink_simstate_t packet1, packet2; memset(&packet1, 0, sizeof(packet1)); @@ -1225,6 +1225,71 @@ static void mavlink_test_rangefinder(uint8_t system_id, uint8_t component_id, ma MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); } +static void mavlink_test_airspeed_autocal(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_airspeed_autocal_t packet_in = { + 17.0, + 45.0, + 73.0, + 101.0, + 129.0, + 157.0, + 185.0, + 213.0, + 241.0, + 269.0, + 297.0, + 325.0, + }; + mavlink_airspeed_autocal_t packet1, packet2; + memset(&packet1, 0, sizeof(packet1)); + packet1.vx = packet_in.vx; + packet1.vy = packet_in.vy; + packet1.vz = packet_in.vz; + packet1.diff_pressure = packet_in.diff_pressure; + packet1.EAS2TAS = packet_in.EAS2TAS; + packet1.ratio = packet_in.ratio; + packet1.state_x = packet_in.state_x; + packet1.state_y = packet_in.state_y; + packet1.state_z = packet_in.state_z; + packet1.Pax = packet_in.Pax; + packet1.Pby = packet_in.Pby; + packet1.Pcz = packet_in.Pcz; + + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_airspeed_autocal_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_airspeed_autocal_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_airspeed_autocal_pack(system_id, component_id, &msg , packet1.vx , packet1.vy , packet1.vz , packet1.diff_pressure , packet1.EAS2TAS , packet1.ratio , packet1.state_x , packet1.state_y , packet1.state_z , packet1.Pax , packet1.Pby , packet1.Pcz ); + mavlink_msg_airspeed_autocal_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_airspeed_autocal_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg , packet1.vx , packet1.vy , packet1.vz , packet1.diff_pressure , packet1.EAS2TAS , packet1.ratio , packet1.state_x , packet1.state_y , packet1.state_z , packet1.Pax , packet1.Pby , packet1.Pcz ); + mavlink_msg_airspeed_autocal_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i=0; i0: single images every n seconds (decimal)| Recording: 0: disabled, 1: enabled compressed, 2: enabled raw| Empty| Empty| Empty| */ + MAV_CMD_DO_SET_ROI=201, /* Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. |Region of intereset mode. (see MAV_ROI enum)| MISSION index/ target ID. (see MAV_ROI enum)| ROI index (allows a vehicle to manage multiple ROI's)| Empty| x the location of the fixed ROI (see MAV_FRAME)| y| z| */ MAV_CMD_DO_LAST=240, /* NOP - This command is only used to mark the upper limit of the DO commands in the enumeration |Empty| Empty| Empty| Empty| Empty| Empty| Empty| */ MAV_CMD_PREFLIGHT_CALIBRATION=241, /* Trigger calibration. This command will be only accepted if in pre-flight mode. |Gyro calibration: 0: no, 1: yes| Magnetometer calibration: 0: no, 1: yes| Ground pressure: 0: no, 1: yes| Radio calibration: 0: no, 1: yes| Accelerometer calibration: 0: no, 1: yes| Empty| Empty| */ MAV_CMD_PREFLIGHT_SET_SENSOR_OFFSETS=242, /* Set sensor offsets. This command will be only accepted if in pre-flight mode. |Sensor to adjust the offsets for: 0: gyros, 1: accelerometer, 2: magnetometer, 3: barometer, 4: optical flow| X axis offset (or generic dimension 1), in the sensor's raw units| Y axis offset (or generic dimension 2), in the sensor's raw units| Z axis offset (or generic dimension 3), in the sensor's raw units| Generic dimension 4, in the sensor's raw units| Generic dimension 5, in the sensor's raw units| Generic dimension 6, in the sensor's raw units| */ @@ -71,7 +96,8 @@ enum MAV_CMD MAV_CMD_OVERRIDE_GOTO=252, /* Hold / continue the current action |MAV_GOTO_DO_HOLD: hold MAV_GOTO_DO_CONTINUE: continue with next item in mission plan| MAV_GOTO_HOLD_AT_CURRENT_POSITION: Hold at current position MAV_GOTO_HOLD_AT_SPECIFIED_POSITION: hold at specified position| MAV_FRAME coordinate frame of hold point| Desired yaw angle in degrees| Latitude / X position| Longitude / Y position| Altitude / Z position| */ MAV_CMD_MISSION_START=300, /* start running a mission |first_item: the first mission item to run| last_item: the last mission item to run (after this item is run, the mission ends)| */ MAV_CMD_COMPONENT_ARM_DISARM=400, /* Arms / Disarms a component |1 to arm, 0 to disarm| */ - MAV_CMD_ENUM_END=401, /* | */ + MAV_CMD_START_RX_PAIR=500, /* Starts receiver pairing |0:Spektrum| 0:Spektrum DSM2, 1:Spektrum DSMX| */ + MAV_CMD_ENUM_END=501, /* | */ }; #endif diff --git a/libs/mavlink/include/mavlink/v1.0/autoquad/mavlink_msg_aq_telemetry_f.h b/libs/mavlink/include/mavlink/v1.0/autoquad/mavlink_msg_aq_telemetry_f.h index dabccdf733..ed7c86bcb8 100644 --- a/libs/mavlink/include/mavlink/v1.0/autoquad/mavlink_msg_aq_telemetry_f.h +++ b/libs/mavlink/include/mavlink/v1.0/autoquad/mavlink_msg_aq_telemetry_f.h @@ -159,7 +159,7 @@ static inline uint16_t mavlink_msg_aq_telemetry_f_pack(uint8_t system_id, uint8_ * @brief Pack a aq_telemetry_f message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param Index Index of message * @param value1 value1 @@ -249,7 +249,7 @@ static inline uint16_t mavlink_msg_aq_telemetry_f_pack_chan(uint8_t system_id, u } /** - * @brief Encode a aq_telemetry_f struct into a message + * @brief Encode a aq_telemetry_f struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -261,6 +261,20 @@ static inline uint16_t mavlink_msg_aq_telemetry_f_encode(uint8_t system_id, uint return mavlink_msg_aq_telemetry_f_pack(system_id, component_id, msg, aq_telemetry_f->Index, aq_telemetry_f->value1, aq_telemetry_f->value2, aq_telemetry_f->value3, aq_telemetry_f->value4, aq_telemetry_f->value5, aq_telemetry_f->value6, aq_telemetry_f->value7, aq_telemetry_f->value8, aq_telemetry_f->value9, aq_telemetry_f->value10, aq_telemetry_f->value11, aq_telemetry_f->value12, aq_telemetry_f->value13, aq_telemetry_f->value14, aq_telemetry_f->value15, aq_telemetry_f->value16, aq_telemetry_f->value17, aq_telemetry_f->value18, aq_telemetry_f->value19, aq_telemetry_f->value20); } +/** + * @brief Encode a aq_telemetry_f struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param aq_telemetry_f C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_aq_telemetry_f_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_aq_telemetry_f_t* aq_telemetry_f) +{ + return mavlink_msg_aq_telemetry_f_pack_chan(system_id, component_id, chan, msg, aq_telemetry_f->Index, aq_telemetry_f->value1, aq_telemetry_f->value2, aq_telemetry_f->value3, aq_telemetry_f->value4, aq_telemetry_f->value5, aq_telemetry_f->value6, aq_telemetry_f->value7, aq_telemetry_f->value8, aq_telemetry_f->value9, aq_telemetry_f->value10, aq_telemetry_f->value11, aq_telemetry_f->value12, aq_telemetry_f->value13, aq_telemetry_f->value14, aq_telemetry_f->value15, aq_telemetry_f->value16, aq_telemetry_f->value17, aq_telemetry_f->value18, aq_telemetry_f->value19, aq_telemetry_f->value20); +} + /** * @brief Send a aq_telemetry_f message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/autoquad/version.h b/libs/mavlink/include/mavlink/v1.0/autoquad/version.h index a26ce2e909..d8ba74f03c 100644 --- a/libs/mavlink/include/mavlink/v1.0/autoquad/version.h +++ b/libs/mavlink/include/mavlink/v1.0/autoquad/version.h @@ -5,7 +5,7 @@ #ifndef MAVLINK_VERSION_H #define MAVLINK_VERSION_H -#define MAVLINK_BUILD_DATE "Thu Jul 4 13:11:37 2013" +#define MAVLINK_BUILD_DATE "Tue Sep 10 23:49:36 2013" #define MAVLINK_WIRE_PROTOCOL_VERSION "1.0" #define MAVLINK_MAX_DIALECT_PAYLOAD_SIZE 254 diff --git a/libs/mavlink/include/mavlink/v1.0/common/common.h b/libs/mavlink/include/mavlink/v1.0/common/common.h index e2ab66ed1c..9d3db33265 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/common.h +++ b/libs/mavlink/include/mavlink/v1.0/common/common.h @@ -260,6 +260,7 @@ enum MAV_CMD MAV_CMD_DO_SET_SERVO=183, /* Set a servo to a desired PWM value. |Servo number| PWM (microseconds, 1000 to 2000 typical)| Empty| Empty| Empty| Empty| Empty| */ MAV_CMD_DO_REPEAT_SERVO=184, /* Cycle a between its nominal setting and a desired PWM for a desired number of cycles with a desired period. |Servo number| PWM (microseconds, 1000 to 2000 typical)| Cycle count| Cycle time (seconds)| Empty| Empty| Empty| */ MAV_CMD_DO_CONTROL_VIDEO=200, /* Control onboard camera system. |Camera ID (-1 for all)| Transmission: 0: disabled, 1: enabled compressed, 2: enabled raw| Transmission mode: 0: video stream, >0: single images every n seconds (decimal)| Recording: 0: disabled, 1: enabled compressed, 2: enabled raw| Empty| Empty| Empty| */ + MAV_CMD_DO_SET_ROI=201, /* Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. |Region of intereset mode. (see MAV_ROI enum)| MISSION index/ target ID. (see MAV_ROI enum)| ROI index (allows a vehicle to manage multiple ROI's)| Empty| x the location of the fixed ROI (see MAV_FRAME)| y| z| */ MAV_CMD_DO_LAST=240, /* NOP - This command is only used to mark the upper limit of the DO commands in the enumeration |Empty| Empty| Empty| Empty| Empty| Empty| Empty| */ MAV_CMD_PREFLIGHT_CALIBRATION=241, /* Trigger calibration. This command will be only accepted if in pre-flight mode. |Gyro calibration: 0: no, 1: yes| Magnetometer calibration: 0: no, 1: yes| Ground pressure: 0: no, 1: yes| Radio calibration: 0: no, 1: yes| Accelerometer calibration: 0: no, 1: yes| Empty| Empty| */ MAV_CMD_PREFLIGHT_SET_SENSOR_OFFSETS=242, /* Set sensor offsets. This command will be only accepted if in pre-flight mode. |Sensor to adjust the offsets for: 0: gyros, 1: accelerometer, 2: magnetometer, 3: barometer, 4: optical flow| X axis offset (or generic dimension 1), in the sensor's raw units| Y axis offset (or generic dimension 2), in the sensor's raw units| Z axis offset (or generic dimension 3), in the sensor's raw units| Generic dimension 4, in the sensor's raw units| Generic dimension 5, in the sensor's raw units| Generic dimension 6, in the sensor's raw units| */ @@ -268,7 +269,8 @@ enum MAV_CMD MAV_CMD_OVERRIDE_GOTO=252, /* Hold / continue the current action |MAV_GOTO_DO_HOLD: hold MAV_GOTO_DO_CONTINUE: continue with next item in mission plan| MAV_GOTO_HOLD_AT_CURRENT_POSITION: Hold at current position MAV_GOTO_HOLD_AT_SPECIFIED_POSITION: hold at specified position| MAV_FRAME coordinate frame of hold point| Desired yaw angle in degrees| Latitude / X position| Longitude / Y position| Altitude / Z position| */ MAV_CMD_MISSION_START=300, /* start running a mission |first_item: the first mission item to run| last_item: the last mission item to run (after this item is run, the mission ends)| */ MAV_CMD_COMPONENT_ARM_DISARM=400, /* Arms / Disarms a component |1 to arm, 0 to disarm| */ - MAV_CMD_ENUM_END=401, /* | */ + MAV_CMD_START_RX_PAIR=500, /* Starts receiver pairing |0:Spektrum| 0:Spektrum DSM2, 1:Spektrum DSMX| */ + MAV_CMD_ENUM_END=501, /* | */ }; #endif diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_6dof_setpoint.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_6dof_setpoint.h deleted file mode 100644 index 0c4ab8c7df..0000000000 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_6dof_setpoint.h +++ /dev/null @@ -1,276 +0,0 @@ -// MESSAGE 6DOF_SETPOINT PACKING - -#define MAVLINK_MSG_ID_6DOF_SETPOINT 149 - -typedef struct __mavlink_6dof_setpoint_t -{ - float trans_x; ///< Translational Component in x - float trans_y; ///< Translational Component in y - float trans_z; ///< Translational Component in z - float rot_x; ///< Rotational Component in x - float rot_y; ///< Rotational Component in y - float rot_z; ///< Rotational Component in z - uint8_t target_system; ///< System ID -} mavlink_6dof_setpoint_t; - -#define MAVLINK_MSG_ID_6DOF_SETPOINT_LEN 25 -#define MAVLINK_MSG_ID_149_LEN 25 - - - -#define MAVLINK_MESSAGE_INFO_6DOF_SETPOINT { \ - "6DOF_SETPOINT", \ - 7, \ - { { "trans_x", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_6dof_setpoint_t, trans_x) }, \ - { "trans_y", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_6dof_setpoint_t, trans_y) }, \ - { "trans_z", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_6dof_setpoint_t, trans_z) }, \ - { "rot_x", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_6dof_setpoint_t, rot_x) }, \ - { "rot_y", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_6dof_setpoint_t, rot_y) }, \ - { "rot_z", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_6dof_setpoint_t, rot_z) }, \ - { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 24, offsetof(mavlink_6dof_setpoint_t, target_system) }, \ - } \ -} - - -/** - * @brief Pack a 6dof_setpoint message - * @param system_id ID of this system - * @param component_id ID of this component (e.g. 200 for IMU) - * @param msg The MAVLink message to compress the data into - * - * @param target_system System ID - * @param trans_x Translational Component in x - * @param trans_y Translational Component in y - * @param trans_z Translational Component in z - * @param rot_x Rotational Component in x - * @param rot_y Rotational Component in y - * @param rot_z Rotational Component in z - * @return length of the message in bytes (excluding serial stream start sign) - */ -static inline uint16_t mavlink_msg_6dof_setpoint_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, - uint8_t target_system, float trans_x, float trans_y, float trans_z, float rot_x, float rot_y, float rot_z) -{ -#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS - char buf[25]; - _mav_put_float(buf, 0, trans_x); - _mav_put_float(buf, 4, trans_y); - _mav_put_float(buf, 8, trans_z); - _mav_put_float(buf, 12, rot_x); - _mav_put_float(buf, 16, rot_y); - _mav_put_float(buf, 20, rot_z); - _mav_put_uint8_t(buf, 24, target_system); - - memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 25); -#else - mavlink_6dof_setpoint_t packet; - packet.trans_x = trans_x; - packet.trans_y = trans_y; - packet.trans_z = trans_z; - packet.rot_x = rot_x; - packet.rot_y = rot_y; - packet.rot_z = rot_z; - packet.target_system = target_system; - - memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 25); -#endif - - msg->msgid = MAVLINK_MSG_ID_6DOF_SETPOINT; - return mavlink_finalize_message(msg, system_id, component_id, 25, 144); -} - -/** - * @brief Pack a 6dof_setpoint message on a channel - * @param system_id ID of this system - * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over - * @param msg The MAVLink message to compress the data into - * @param target_system System ID - * @param trans_x Translational Component in x - * @param trans_y Translational Component in y - * @param trans_z Translational Component in z - * @param rot_x Rotational Component in x - * @param rot_y Rotational Component in y - * @param rot_z Rotational Component in z - * @return length of the message in bytes (excluding serial stream start sign) - */ -static inline uint16_t mavlink_msg_6dof_setpoint_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, - mavlink_message_t* msg, - uint8_t target_system,float trans_x,float trans_y,float trans_z,float rot_x,float rot_y,float rot_z) -{ -#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS - char buf[25]; - _mav_put_float(buf, 0, trans_x); - _mav_put_float(buf, 4, trans_y); - _mav_put_float(buf, 8, trans_z); - _mav_put_float(buf, 12, rot_x); - _mav_put_float(buf, 16, rot_y); - _mav_put_float(buf, 20, rot_z); - _mav_put_uint8_t(buf, 24, target_system); - - memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 25); -#else - mavlink_6dof_setpoint_t packet; - packet.trans_x = trans_x; - packet.trans_y = trans_y; - packet.trans_z = trans_z; - packet.rot_x = rot_x; - packet.rot_y = rot_y; - packet.rot_z = rot_z; - packet.target_system = target_system; - - memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 25); -#endif - - msg->msgid = MAVLINK_MSG_ID_6DOF_SETPOINT; - return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 25, 144); -} - -/** - * @brief Encode a 6dof_setpoint struct into a message - * - * @param system_id ID of this system - * @param component_id ID of this component (e.g. 200 for IMU) - * @param msg The MAVLink message to compress the data into - * @param 6dof_setpoint C-struct to read the message contents from - */ -static inline uint16_t mavlink_msg_6dof_setpoint_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, const mavlink_6dof_setpoint_t* 6dof_setpoint) -{ - return mavlink_msg_6dof_setpoint_pack(system_id, component_id, msg, 6dof_setpoint->target_system, 6dof_setpoint->trans_x, 6dof_setpoint->trans_y, 6dof_setpoint->trans_z, 6dof_setpoint->rot_x, 6dof_setpoint->rot_y, 6dof_setpoint->rot_z); -} - -/** - * @brief Send a 6dof_setpoint message - * @param chan MAVLink channel to send the message - * - * @param target_system System ID - * @param trans_x Translational Component in x - * @param trans_y Translational Component in y - * @param trans_z Translational Component in z - * @param rot_x Rotational Component in x - * @param rot_y Rotational Component in y - * @param rot_z Rotational Component in z - */ -#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS - -static inline void mavlink_msg_6dof_setpoint_send(mavlink_channel_t chan, uint8_t target_system, float trans_x, float trans_y, float trans_z, float rot_x, float rot_y, float rot_z) -{ -#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS - char buf[25]; - _mav_put_float(buf, 0, trans_x); - _mav_put_float(buf, 4, trans_y); - _mav_put_float(buf, 8, trans_z); - _mav_put_float(buf, 12, rot_x); - _mav_put_float(buf, 16, rot_y); - _mav_put_float(buf, 20, rot_z); - _mav_put_uint8_t(buf, 24, target_system); - - _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_6DOF_SETPOINT, buf, 25, 144); -#else - mavlink_6dof_setpoint_t packet; - packet.trans_x = trans_x; - packet.trans_y = trans_y; - packet.trans_z = trans_z; - packet.rot_x = rot_x; - packet.rot_y = rot_y; - packet.rot_z = rot_z; - packet.target_system = target_system; - - _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_6DOF_SETPOINT, (const char *)&packet, 25, 144); -#endif -} - -#endif - -// MESSAGE 6DOF_SETPOINT UNPACKING - - -/** - * @brief Get field target_system from 6dof_setpoint message - * - * @return System ID - */ -static inline uint8_t mavlink_msg_6dof_setpoint_get_target_system(const mavlink_message_t* msg) -{ - return _MAV_RETURN_uint8_t(msg, 24); -} - -/** - * @brief Get field trans_x from 6dof_setpoint message - * - * @return Translational Component in x - */ -static inline float mavlink_msg_6dof_setpoint_get_trans_x(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 0); -} - -/** - * @brief Get field trans_y from 6dof_setpoint message - * - * @return Translational Component in y - */ -static inline float mavlink_msg_6dof_setpoint_get_trans_y(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 4); -} - -/** - * @brief Get field trans_z from 6dof_setpoint message - * - * @return Translational Component in z - */ -static inline float mavlink_msg_6dof_setpoint_get_trans_z(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 8); -} - -/** - * @brief Get field rot_x from 6dof_setpoint message - * - * @return Rotational Component in x - */ -static inline float mavlink_msg_6dof_setpoint_get_rot_x(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 12); -} - -/** - * @brief Get field rot_y from 6dof_setpoint message - * - * @return Rotational Component in y - */ -static inline float mavlink_msg_6dof_setpoint_get_rot_y(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 16); -} - -/** - * @brief Get field rot_z from 6dof_setpoint message - * - * @return Rotational Component in z - */ -static inline float mavlink_msg_6dof_setpoint_get_rot_z(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 20); -} - -/** - * @brief Decode a 6dof_setpoint message into a struct - * - * @param msg The message to decode - * @param 6dof_setpoint C-struct to decode the message contents into - */ -static inline void mavlink_msg_6dof_setpoint_decode(const mavlink_message_t* msg, mavlink_6dof_setpoint_t* 6dof_setpoint) -{ -#if MAVLINK_NEED_BYTE_SWAP - 6dof_setpoint->trans_x = mavlink_msg_6dof_setpoint_get_trans_x(msg); - 6dof_setpoint->trans_y = mavlink_msg_6dof_setpoint_get_trans_y(msg); - 6dof_setpoint->trans_z = mavlink_msg_6dof_setpoint_get_trans_z(msg); - 6dof_setpoint->rot_x = mavlink_msg_6dof_setpoint_get_rot_x(msg); - 6dof_setpoint->rot_y = mavlink_msg_6dof_setpoint_get_rot_y(msg); - 6dof_setpoint->rot_z = mavlink_msg_6dof_setpoint_get_rot_z(msg); - 6dof_setpoint->target_system = mavlink_msg_6dof_setpoint_get_target_system(msg); -#else - memcpy(6dof_setpoint, _MAV_PAYLOAD(msg), 25); -#endif -} diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_8dof_setpoint.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_8dof_setpoint.h deleted file mode 100644 index 521d2fb668..0000000000 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_8dof_setpoint.h +++ /dev/null @@ -1,320 +0,0 @@ -// MESSAGE 8DOF_SETPOINT PACKING - -#define MAVLINK_MSG_ID_8DOF_SETPOINT 148 - -typedef struct __mavlink_8dof_setpoint_t -{ - float val1; ///< Value 1 - float val2; ///< Value 2 - float val3; ///< Value 3 - float val4; ///< Value 4 - float val5; ///< Value 5 - float val6; ///< Value 6 - float val7; ///< Value 7 - float val8; ///< Value 8 - uint8_t target_system; ///< System ID -} mavlink_8dof_setpoint_t; - -#define MAVLINK_MSG_ID_8DOF_SETPOINT_LEN 33 -#define MAVLINK_MSG_ID_148_LEN 33 - - - -#define MAVLINK_MESSAGE_INFO_8DOF_SETPOINT { \ - "8DOF_SETPOINT", \ - 9, \ - { { "val1", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_8dof_setpoint_t, val1) }, \ - { "val2", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_8dof_setpoint_t, val2) }, \ - { "val3", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_8dof_setpoint_t, val3) }, \ - { "val4", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_8dof_setpoint_t, val4) }, \ - { "val5", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_8dof_setpoint_t, val5) }, \ - { "val6", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_8dof_setpoint_t, val6) }, \ - { "val7", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_8dof_setpoint_t, val7) }, \ - { "val8", NULL, MAVLINK_TYPE_FLOAT, 0, 28, offsetof(mavlink_8dof_setpoint_t, val8) }, \ - { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 32, offsetof(mavlink_8dof_setpoint_t, target_system) }, \ - } \ -} - - -/** - * @brief Pack a 8dof_setpoint message - * @param system_id ID of this system - * @param component_id ID of this component (e.g. 200 for IMU) - * @param msg The MAVLink message to compress the data into - * - * @param target_system System ID - * @param val1 Value 1 - * @param val2 Value 2 - * @param val3 Value 3 - * @param val4 Value 4 - * @param val5 Value 5 - * @param val6 Value 6 - * @param val7 Value 7 - * @param val8 Value 8 - * @return length of the message in bytes (excluding serial stream start sign) - */ -static inline uint16_t mavlink_msg_8dof_setpoint_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, - uint8_t target_system, float val1, float val2, float val3, float val4, float val5, float val6, float val7, float val8) -{ -#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS - char buf[33]; - _mav_put_float(buf, 0, val1); - _mav_put_float(buf, 4, val2); - _mav_put_float(buf, 8, val3); - _mav_put_float(buf, 12, val4); - _mav_put_float(buf, 16, val5); - _mav_put_float(buf, 20, val6); - _mav_put_float(buf, 24, val7); - _mav_put_float(buf, 28, val8); - _mav_put_uint8_t(buf, 32, target_system); - - memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 33); -#else - mavlink_8dof_setpoint_t packet; - packet.val1 = val1; - packet.val2 = val2; - packet.val3 = val3; - packet.val4 = val4; - packet.val5 = val5; - packet.val6 = val6; - packet.val7 = val7; - packet.val8 = val8; - packet.target_system = target_system; - - memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 33); -#endif - - msg->msgid = MAVLINK_MSG_ID_8DOF_SETPOINT; - return mavlink_finalize_message(msg, system_id, component_id, 33, 42); -} - -/** - * @brief Pack a 8dof_setpoint message on a channel - * @param system_id ID of this system - * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over - * @param msg The MAVLink message to compress the data into - * @param target_system System ID - * @param val1 Value 1 - * @param val2 Value 2 - * @param val3 Value 3 - * @param val4 Value 4 - * @param val5 Value 5 - * @param val6 Value 6 - * @param val7 Value 7 - * @param val8 Value 8 - * @return length of the message in bytes (excluding serial stream start sign) - */ -static inline uint16_t mavlink_msg_8dof_setpoint_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, - mavlink_message_t* msg, - uint8_t target_system,float val1,float val2,float val3,float val4,float val5,float val6,float val7,float val8) -{ -#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS - char buf[33]; - _mav_put_float(buf, 0, val1); - _mav_put_float(buf, 4, val2); - _mav_put_float(buf, 8, val3); - _mav_put_float(buf, 12, val4); - _mav_put_float(buf, 16, val5); - _mav_put_float(buf, 20, val6); - _mav_put_float(buf, 24, val7); - _mav_put_float(buf, 28, val8); - _mav_put_uint8_t(buf, 32, target_system); - - memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 33); -#else - mavlink_8dof_setpoint_t packet; - packet.val1 = val1; - packet.val2 = val2; - packet.val3 = val3; - packet.val4 = val4; - packet.val5 = val5; - packet.val6 = val6; - packet.val7 = val7; - packet.val8 = val8; - packet.target_system = target_system; - - memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 33); -#endif - - msg->msgid = MAVLINK_MSG_ID_8DOF_SETPOINT; - return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 33, 42); -} - -/** - * @brief Encode a 8dof_setpoint struct into a message - * - * @param system_id ID of this system - * @param component_id ID of this component (e.g. 200 for IMU) - * @param msg The MAVLink message to compress the data into - * @param 8dof_setpoint C-struct to read the message contents from - */ -static inline uint16_t mavlink_msg_8dof_setpoint_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, const mavlink_8dof_setpoint_t* 8dof_setpoint) -{ - return mavlink_msg_8dof_setpoint_pack(system_id, component_id, msg, 8dof_setpoint->target_system, 8dof_setpoint->val1, 8dof_setpoint->val2, 8dof_setpoint->val3, 8dof_setpoint->val4, 8dof_setpoint->val5, 8dof_setpoint->val6, 8dof_setpoint->val7, 8dof_setpoint->val8); -} - -/** - * @brief Send a 8dof_setpoint message - * @param chan MAVLink channel to send the message - * - * @param target_system System ID - * @param val1 Value 1 - * @param val2 Value 2 - * @param val3 Value 3 - * @param val4 Value 4 - * @param val5 Value 5 - * @param val6 Value 6 - * @param val7 Value 7 - * @param val8 Value 8 - */ -#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS - -static inline void mavlink_msg_8dof_setpoint_send(mavlink_channel_t chan, uint8_t target_system, float val1, float val2, float val3, float val4, float val5, float val6, float val7, float val8) -{ -#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS - char buf[33]; - _mav_put_float(buf, 0, val1); - _mav_put_float(buf, 4, val2); - _mav_put_float(buf, 8, val3); - _mav_put_float(buf, 12, val4); - _mav_put_float(buf, 16, val5); - _mav_put_float(buf, 20, val6); - _mav_put_float(buf, 24, val7); - _mav_put_float(buf, 28, val8); - _mav_put_uint8_t(buf, 32, target_system); - - _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_8DOF_SETPOINT, buf, 33, 42); -#else - mavlink_8dof_setpoint_t packet; - packet.val1 = val1; - packet.val2 = val2; - packet.val3 = val3; - packet.val4 = val4; - packet.val5 = val5; - packet.val6 = val6; - packet.val7 = val7; - packet.val8 = val8; - packet.target_system = target_system; - - _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_8DOF_SETPOINT, (const char *)&packet, 33, 42); -#endif -} - -#endif - -// MESSAGE 8DOF_SETPOINT UNPACKING - - -/** - * @brief Get field target_system from 8dof_setpoint message - * - * @return System ID - */ -static inline uint8_t mavlink_msg_8dof_setpoint_get_target_system(const mavlink_message_t* msg) -{ - return _MAV_RETURN_uint8_t(msg, 32); -} - -/** - * @brief Get field val1 from 8dof_setpoint message - * - * @return Value 1 - */ -static inline float mavlink_msg_8dof_setpoint_get_val1(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 0); -} - -/** - * @brief Get field val2 from 8dof_setpoint message - * - * @return Value 2 - */ -static inline float mavlink_msg_8dof_setpoint_get_val2(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 4); -} - -/** - * @brief Get field val3 from 8dof_setpoint message - * - * @return Value 3 - */ -static inline float mavlink_msg_8dof_setpoint_get_val3(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 8); -} - -/** - * @brief Get field val4 from 8dof_setpoint message - * - * @return Value 4 - */ -static inline float mavlink_msg_8dof_setpoint_get_val4(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 12); -} - -/** - * @brief Get field val5 from 8dof_setpoint message - * - * @return Value 5 - */ -static inline float mavlink_msg_8dof_setpoint_get_val5(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 16); -} - -/** - * @brief Get field val6 from 8dof_setpoint message - * - * @return Value 6 - */ -static inline float mavlink_msg_8dof_setpoint_get_val6(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 20); -} - -/** - * @brief Get field val7 from 8dof_setpoint message - * - * @return Value 7 - */ -static inline float mavlink_msg_8dof_setpoint_get_val7(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 24); -} - -/** - * @brief Get field val8 from 8dof_setpoint message - * - * @return Value 8 - */ -static inline float mavlink_msg_8dof_setpoint_get_val8(const mavlink_message_t* msg) -{ - return _MAV_RETURN_float(msg, 28); -} - -/** - * @brief Decode a 8dof_setpoint message into a struct - * - * @param msg The message to decode - * @param 8dof_setpoint C-struct to decode the message contents into - */ -static inline void mavlink_msg_8dof_setpoint_decode(const mavlink_message_t* msg, mavlink_8dof_setpoint_t* 8dof_setpoint) -{ -#if MAVLINK_NEED_BYTE_SWAP - 8dof_setpoint->val1 = mavlink_msg_8dof_setpoint_get_val1(msg); - 8dof_setpoint->val2 = mavlink_msg_8dof_setpoint_get_val2(msg); - 8dof_setpoint->val3 = mavlink_msg_8dof_setpoint_get_val3(msg); - 8dof_setpoint->val4 = mavlink_msg_8dof_setpoint_get_val4(msg); - 8dof_setpoint->val5 = mavlink_msg_8dof_setpoint_get_val5(msg); - 8dof_setpoint->val6 = mavlink_msg_8dof_setpoint_get_val6(msg); - 8dof_setpoint->val7 = mavlink_msg_8dof_setpoint_get_val7(msg); - 8dof_setpoint->val8 = mavlink_msg_8dof_setpoint_get_val8(msg); - 8dof_setpoint->target_system = mavlink_msg_8dof_setpoint_get_target_system(msg); -#else - memcpy(8dof_setpoint, _MAV_PAYLOAD(msg), 33); -#endif -} diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_attitude.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_attitude.h index 0ba416ee14..8ddf5bf099 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_attitude.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_attitude.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_attitude_pack(uint8_t system_id, uint8_t comp * @brief Pack a attitude message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param roll Roll angle (rad, -pi..+pi) @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_attitude_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a attitude struct into a message + * @brief Encode a attitude struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_attitude_encode(uint8_t system_id, uint8_t co return mavlink_msg_attitude_pack(system_id, component_id, msg, attitude->time_boot_ms, attitude->roll, attitude->pitch, attitude->yaw, attitude->rollspeed, attitude->pitchspeed, attitude->yawspeed); } +/** + * @brief Encode a attitude struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param attitude C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_attitude_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_attitude_t* attitude) +{ + return mavlink_msg_attitude_pack_chan(system_id, component_id, chan, msg, attitude->time_boot_ms, attitude->roll, attitude->pitch, attitude->yaw, attitude->rollspeed, attitude->pitchspeed, attitude->yawspeed); +} + /** * @brief Send a attitude message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_attitude_quaternion.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_attitude_quaternion.h index 611803f2b7..9f8d587598 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_attitude_quaternion.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_attitude_quaternion.h @@ -94,7 +94,7 @@ static inline uint16_t mavlink_msg_attitude_quaternion_pack(uint8_t system_id, u * @brief Pack a attitude_quaternion message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param q1 Quaternion component 1 @@ -145,7 +145,7 @@ static inline uint16_t mavlink_msg_attitude_quaternion_pack_chan(uint8_t system_ } /** - * @brief Encode a attitude_quaternion struct into a message + * @brief Encode a attitude_quaternion struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -157,6 +157,20 @@ static inline uint16_t mavlink_msg_attitude_quaternion_encode(uint8_t system_id, return mavlink_msg_attitude_quaternion_pack(system_id, component_id, msg, attitude_quaternion->time_boot_ms, attitude_quaternion->q1, attitude_quaternion->q2, attitude_quaternion->q3, attitude_quaternion->q4, attitude_quaternion->rollspeed, attitude_quaternion->pitchspeed, attitude_quaternion->yawspeed); } +/** + * @brief Encode a attitude_quaternion struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param attitude_quaternion C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_attitude_quaternion_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_attitude_quaternion_t* attitude_quaternion) +{ + return mavlink_msg_attitude_quaternion_pack_chan(system_id, component_id, chan, msg, attitude_quaternion->time_boot_ms, attitude_quaternion->q1, attitude_quaternion->q2, attitude_quaternion->q3, attitude_quaternion->q4, attitude_quaternion->rollspeed, attitude_quaternion->pitchspeed, attitude_quaternion->yawspeed); +} + /** * @brief Send a attitude_quaternion message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_auth_key.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_auth_key.h index 030b564c97..5703a59871 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_auth_key.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_auth_key.h @@ -59,7 +59,7 @@ static inline uint16_t mavlink_msg_auth_key_pack(uint8_t system_id, uint8_t comp * @brief Pack a auth_key message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param key key * @return length of the message in bytes (excluding serial stream start sign) @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_auth_key_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a auth_key struct into a message + * @brief Encode a auth_key struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -101,6 +101,20 @@ static inline uint16_t mavlink_msg_auth_key_encode(uint8_t system_id, uint8_t co return mavlink_msg_auth_key_pack(system_id, component_id, msg, auth_key->key); } +/** + * @brief Encode a auth_key struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param auth_key C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_auth_key_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_auth_key_t* auth_key) +{ + return mavlink_msg_auth_key_pack_chan(system_id, component_id, chan, msg, auth_key->key); +} + /** * @brief Send a auth_key message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_battery_status.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_battery_status.h index 83c8159841..c945aebaea 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_battery_status.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_battery_status.h @@ -99,7 +99,7 @@ static inline uint16_t mavlink_msg_battery_status_pack(uint8_t system_id, uint8_ * @brief Pack a battery_status message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param accu_id Accupack ID * @param voltage_cell_1 Battery voltage of cell 1, in millivolts (1 = 1 millivolt) @@ -153,7 +153,7 @@ static inline uint16_t mavlink_msg_battery_status_pack_chan(uint8_t system_id, u } /** - * @brief Encode a battery_status struct into a message + * @brief Encode a battery_status struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -165,6 +165,20 @@ static inline uint16_t mavlink_msg_battery_status_encode(uint8_t system_id, uint return mavlink_msg_battery_status_pack(system_id, component_id, msg, battery_status->accu_id, battery_status->voltage_cell_1, battery_status->voltage_cell_2, battery_status->voltage_cell_3, battery_status->voltage_cell_4, battery_status->voltage_cell_5, battery_status->voltage_cell_6, battery_status->current_battery, battery_status->battery_remaining); } +/** + * @brief Encode a battery_status struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param battery_status C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_battery_status_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_battery_status_t* battery_status) +{ + return mavlink_msg_battery_status_pack_chan(system_id, component_id, chan, msg, battery_status->accu_id, battery_status->voltage_cell_1, battery_status->voltage_cell_2, battery_status->voltage_cell_3, battery_status->voltage_cell_4, battery_status->voltage_cell_5, battery_status->voltage_cell_6, battery_status->current_battery, battery_status->battery_remaining); +} + /** * @brief Send a battery_status message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_change_operator_control.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_change_operator_control.h index c7195dfcaa..0b6de930d2 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_change_operator_control.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_change_operator_control.h @@ -72,7 +72,7 @@ static inline uint16_t mavlink_msg_change_operator_control_pack(uint8_t system_i * @brief Pack a change_operator_control message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System the GCS requests control for * @param control_request 0: request control of this MAV, 1: Release control of this MAV @@ -109,7 +109,7 @@ static inline uint16_t mavlink_msg_change_operator_control_pack_chan(uint8_t sys } /** - * @brief Encode a change_operator_control struct into a message + * @brief Encode a change_operator_control struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -121,6 +121,20 @@ static inline uint16_t mavlink_msg_change_operator_control_encode(uint8_t system return mavlink_msg_change_operator_control_pack(system_id, component_id, msg, change_operator_control->target_system, change_operator_control->control_request, change_operator_control->version, change_operator_control->passkey); } +/** + * @brief Encode a change_operator_control struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param change_operator_control C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_change_operator_control_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_change_operator_control_t* change_operator_control) +{ + return mavlink_msg_change_operator_control_pack_chan(system_id, component_id, chan, msg, change_operator_control->target_system, change_operator_control->control_request, change_operator_control->version, change_operator_control->passkey); +} + /** * @brief Send a change_operator_control message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_change_operator_control_ack.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_change_operator_control_ack.h index 5cf98e77fe..c6f6a28e4b 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_change_operator_control_ack.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_change_operator_control_ack.h @@ -69,7 +69,7 @@ static inline uint16_t mavlink_msg_change_operator_control_ack_pack(uint8_t syst * @brief Pack a change_operator_control_ack message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param gcs_system_id ID of the GCS this message * @param control_request 0: request control of this MAV, 1: Release control of this MAV @@ -105,7 +105,7 @@ static inline uint16_t mavlink_msg_change_operator_control_ack_pack_chan(uint8_t } /** - * @brief Encode a change_operator_control_ack struct into a message + * @brief Encode a change_operator_control_ack struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -117,6 +117,20 @@ static inline uint16_t mavlink_msg_change_operator_control_ack_encode(uint8_t sy return mavlink_msg_change_operator_control_ack_pack(system_id, component_id, msg, change_operator_control_ack->gcs_system_id, change_operator_control_ack->control_request, change_operator_control_ack->ack); } +/** + * @brief Encode a change_operator_control_ack struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param change_operator_control_ack C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_change_operator_control_ack_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_change_operator_control_ack_t* change_operator_control_ack) +{ + return mavlink_msg_change_operator_control_ack_pack_chan(system_id, component_id, chan, msg, change_operator_control_ack->gcs_system_id, change_operator_control_ack->control_request, change_operator_control_ack->ack); +} + /** * @brief Send a change_operator_control_ack message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_command_ack.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_command_ack.h index 82c2835de0..dca2fe6819 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_command_ack.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_command_ack.h @@ -64,7 +64,7 @@ static inline uint16_t mavlink_msg_command_ack_pack(uint8_t system_id, uint8_t c * @brief Pack a command_ack message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param command Command ID, as defined by MAV_CMD enum. * @param result See MAV_RESULT enum @@ -97,7 +97,7 @@ static inline uint16_t mavlink_msg_command_ack_pack_chan(uint8_t system_id, uint } /** - * @brief Encode a command_ack struct into a message + * @brief Encode a command_ack struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -109,6 +109,20 @@ static inline uint16_t mavlink_msg_command_ack_encode(uint8_t system_id, uint8_t return mavlink_msg_command_ack_pack(system_id, component_id, msg, command_ack->command, command_ack->result); } +/** + * @brief Encode a command_ack struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param command_ack C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_command_ack_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_command_ack_t* command_ack) +{ + return mavlink_msg_command_ack_pack_chan(system_id, component_id, chan, msg, command_ack->command, command_ack->result); +} + /** * @brief Send a command_ack message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_command_long.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_command_long.h index 5c44c62844..8f705c0dd2 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_command_long.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_command_long.h @@ -109,7 +109,7 @@ static inline uint16_t mavlink_msg_command_long_pack(uint8_t system_id, uint8_t * @brief Pack a command_long message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System which should execute the command * @param target_component Component which should execute the command, 0 for all components @@ -169,7 +169,7 @@ static inline uint16_t mavlink_msg_command_long_pack_chan(uint8_t system_id, uin } /** - * @brief Encode a command_long struct into a message + * @brief Encode a command_long struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -181,6 +181,20 @@ static inline uint16_t mavlink_msg_command_long_encode(uint8_t system_id, uint8_ return mavlink_msg_command_long_pack(system_id, component_id, msg, command_long->target_system, command_long->target_component, command_long->command, command_long->confirmation, command_long->param1, command_long->param2, command_long->param3, command_long->param4, command_long->param5, command_long->param6, command_long->param7); } +/** + * @brief Encode a command_long struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param command_long C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_command_long_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_command_long_t* command_long) +{ + return mavlink_msg_command_long_pack_chan(system_id, component_id, chan, msg, command_long->target_system, command_long->target_component, command_long->command, command_long->confirmation, command_long->param1, command_long->param2, command_long->param3, command_long->param4, command_long->param5, command_long->param6, command_long->param7); +} + /** * @brief Send a command_long message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_data_stream.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_data_stream.h index 782ea9f26b..dc0768e128 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_data_stream.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_data_stream.h @@ -69,7 +69,7 @@ static inline uint16_t mavlink_msg_data_stream_pack(uint8_t system_id, uint8_t c * @brief Pack a data_stream message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param stream_id The ID of the requested data stream * @param message_rate The requested interval between two messages of this type @@ -105,7 +105,7 @@ static inline uint16_t mavlink_msg_data_stream_pack_chan(uint8_t system_id, uint } /** - * @brief Encode a data_stream struct into a message + * @brief Encode a data_stream struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -117,6 +117,20 @@ static inline uint16_t mavlink_msg_data_stream_encode(uint8_t system_id, uint8_t return mavlink_msg_data_stream_pack(system_id, component_id, msg, data_stream->stream_id, data_stream->message_rate, data_stream->on_off); } +/** + * @brief Encode a data_stream struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param data_stream C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_data_stream_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_data_stream_t* data_stream) +{ + return mavlink_msg_data_stream_pack_chan(system_id, component_id, chan, msg, data_stream->stream_id, data_stream->message_rate, data_stream->on_off); +} + /** * @brief Send a data_stream message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_debug.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_debug.h index a111619185..9a6ed87eeb 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_debug.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_debug.h @@ -69,7 +69,7 @@ static inline uint16_t mavlink_msg_debug_pack(uint8_t system_id, uint8_t compone * @brief Pack a debug message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param ind index of debug variable @@ -105,7 +105,7 @@ static inline uint16_t mavlink_msg_debug_pack_chan(uint8_t system_id, uint8_t co } /** - * @brief Encode a debug struct into a message + * @brief Encode a debug struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -117,6 +117,20 @@ static inline uint16_t mavlink_msg_debug_encode(uint8_t system_id, uint8_t compo return mavlink_msg_debug_pack(system_id, component_id, msg, debug->time_boot_ms, debug->ind, debug->value); } +/** + * @brief Encode a debug struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param debug C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_debug_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_debug_t* debug) +{ + return mavlink_msg_debug_pack_chan(system_id, component_id, chan, msg, debug->time_boot_ms, debug->ind, debug->value); +} + /** * @brief Send a debug message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_debug_vect.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_debug_vect.h index 5ee4e323ac..6cfc75212e 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_debug_vect.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_debug_vect.h @@ -77,7 +77,7 @@ static inline uint16_t mavlink_msg_debug_vect_pack(uint8_t system_id, uint8_t co * @brief Pack a debug_vect message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param name Name * @param time_usec Timestamp @@ -117,7 +117,7 @@ static inline uint16_t mavlink_msg_debug_vect_pack_chan(uint8_t system_id, uint8 } /** - * @brief Encode a debug_vect struct into a message + * @brief Encode a debug_vect struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -129,6 +129,20 @@ static inline uint16_t mavlink_msg_debug_vect_encode(uint8_t system_id, uint8_t return mavlink_msg_debug_vect_pack(system_id, component_id, msg, debug_vect->name, debug_vect->time_usec, debug_vect->x, debug_vect->y, debug_vect->z); } +/** + * @brief Encode a debug_vect struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param debug_vect C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_debug_vect_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_debug_vect_t* debug_vect) +{ + return mavlink_msg_debug_vect_pack_chan(system_id, component_id, chan, msg, debug_vect->name, debug_vect->time_usec, debug_vect->x, debug_vect->y, debug_vect->z); +} + /** * @brief Send a debug_vect message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_file_transfer_dir_list.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_file_transfer_dir_list.h index c026419a20..4f31698d50 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_file_transfer_dir_list.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_file_transfer_dir_list.h @@ -67,7 +67,7 @@ static inline uint16_t mavlink_msg_file_transfer_dir_list_pack(uint8_t system_id * @brief Pack a file_transfer_dir_list message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param transfer_uid Unique transfer ID * @param dir_path Directory path to list @@ -101,7 +101,7 @@ static inline uint16_t mavlink_msg_file_transfer_dir_list_pack_chan(uint8_t syst } /** - * @brief Encode a file_transfer_dir_list struct into a message + * @brief Encode a file_transfer_dir_list struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -113,6 +113,20 @@ static inline uint16_t mavlink_msg_file_transfer_dir_list_encode(uint8_t system_ return mavlink_msg_file_transfer_dir_list_pack(system_id, component_id, msg, file_transfer_dir_list->transfer_uid, file_transfer_dir_list->dir_path, file_transfer_dir_list->flags); } +/** + * @brief Encode a file_transfer_dir_list struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param file_transfer_dir_list C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_file_transfer_dir_list_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_file_transfer_dir_list_t* file_transfer_dir_list) +{ + return mavlink_msg_file_transfer_dir_list_pack_chan(system_id, component_id, chan, msg, file_transfer_dir_list->transfer_uid, file_transfer_dir_list->dir_path, file_transfer_dir_list->flags); +} + /** * @brief Send a file_transfer_dir_list message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_file_transfer_res.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_file_transfer_res.h index 86d407d66b..fc6247faca 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_file_transfer_res.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_file_transfer_res.h @@ -64,7 +64,7 @@ static inline uint16_t mavlink_msg_file_transfer_res_pack(uint8_t system_id, uin * @brief Pack a file_transfer_res message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param transfer_uid Unique transfer ID * @param result 0: OK, 1: not permitted, 2: bad path / file name, 3: no space left on device @@ -97,7 +97,7 @@ static inline uint16_t mavlink_msg_file_transfer_res_pack_chan(uint8_t system_id } /** - * @brief Encode a file_transfer_res struct into a message + * @brief Encode a file_transfer_res struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -109,6 +109,20 @@ static inline uint16_t mavlink_msg_file_transfer_res_encode(uint8_t system_id, u return mavlink_msg_file_transfer_res_pack(system_id, component_id, msg, file_transfer_res->transfer_uid, file_transfer_res->result); } +/** + * @brief Encode a file_transfer_res struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param file_transfer_res C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_file_transfer_res_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_file_transfer_res_t* file_transfer_res) +{ + return mavlink_msg_file_transfer_res_pack_chan(system_id, component_id, chan, msg, file_transfer_res->transfer_uid, file_transfer_res->result); +} + /** * @brief Send a file_transfer_res message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_file_transfer_start.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_file_transfer_start.h index 24bf25413f..05be77339b 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_file_transfer_start.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_file_transfer_start.h @@ -77,7 +77,7 @@ static inline uint16_t mavlink_msg_file_transfer_start_pack(uint8_t system_id, u * @brief Pack a file_transfer_start message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param transfer_uid Unique transfer ID * @param dest_path Destination path @@ -117,7 +117,7 @@ static inline uint16_t mavlink_msg_file_transfer_start_pack_chan(uint8_t system_ } /** - * @brief Encode a file_transfer_start struct into a message + * @brief Encode a file_transfer_start struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -129,6 +129,20 @@ static inline uint16_t mavlink_msg_file_transfer_start_encode(uint8_t system_id, return mavlink_msg_file_transfer_start_pack(system_id, component_id, msg, file_transfer_start->transfer_uid, file_transfer_start->dest_path, file_transfer_start->direction, file_transfer_start->file_size, file_transfer_start->flags); } +/** + * @brief Encode a file_transfer_start struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param file_transfer_start C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_file_transfer_start_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_file_transfer_start_t* file_transfer_start) +{ + return mavlink_msg_file_transfer_start_pack_chan(system_id, component_id, chan, msg, file_transfer_start->transfer_uid, file_transfer_start->dest_path, file_transfer_start->direction, file_transfer_start->file_size, file_transfer_start->flags); +} + /** * @brief Send a file_transfer_start message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_global_position_int.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_global_position_int.h index 11ab97ee47..7ed3d2a636 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_global_position_int.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_global_position_int.h @@ -12,7 +12,7 @@ typedef struct __mavlink_global_position_int_t int16_t vx; ///< Ground X Speed (Latitude), expressed as m/s * 100 int16_t vy; ///< Ground Y Speed (Longitude), expressed as m/s * 100 int16_t vz; ///< Ground Z Speed (Altitude), expressed as m/s * 100 - uint16_t hdg; ///< Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + uint16_t hdg; ///< Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX } mavlink_global_position_int_t; #define MAVLINK_MSG_ID_GLOBAL_POSITION_INT_LEN 28 @@ -53,7 +53,7 @@ typedef struct __mavlink_global_position_int_t * @param vx Ground X Speed (Latitude), expressed as m/s * 100 * @param vy Ground Y Speed (Longitude), expressed as m/s * 100 * @param vz Ground Z Speed (Altitude), expressed as m/s * 100 - * @param hdg Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + * @param hdg Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX * @return length of the message in bytes (excluding serial stream start sign) */ static inline uint16_t mavlink_msg_global_position_int_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, @@ -99,7 +99,7 @@ static inline uint16_t mavlink_msg_global_position_int_pack(uint8_t system_id, u * @brief Pack a global_position_int message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param lat Latitude, expressed as * 1E7 @@ -109,7 +109,7 @@ static inline uint16_t mavlink_msg_global_position_int_pack(uint8_t system_id, u * @param vx Ground X Speed (Latitude), expressed as m/s * 100 * @param vy Ground Y Speed (Longitude), expressed as m/s * 100 * @param vz Ground Z Speed (Altitude), expressed as m/s * 100 - * @param hdg Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + * @param hdg Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX * @return length of the message in bytes (excluding serial stream start sign) */ static inline uint16_t mavlink_msg_global_position_int_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, @@ -153,7 +153,7 @@ static inline uint16_t mavlink_msg_global_position_int_pack_chan(uint8_t system_ } /** - * @brief Encode a global_position_int struct into a message + * @brief Encode a global_position_int struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -165,6 +165,20 @@ static inline uint16_t mavlink_msg_global_position_int_encode(uint8_t system_id, return mavlink_msg_global_position_int_pack(system_id, component_id, msg, global_position_int->time_boot_ms, global_position_int->lat, global_position_int->lon, global_position_int->alt, global_position_int->relative_alt, global_position_int->vx, global_position_int->vy, global_position_int->vz, global_position_int->hdg); } +/** + * @brief Encode a global_position_int struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param global_position_int C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_global_position_int_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_global_position_int_t* global_position_int) +{ + return mavlink_msg_global_position_int_pack_chan(system_id, component_id, chan, msg, global_position_int->time_boot_ms, global_position_int->lat, global_position_int->lon, global_position_int->alt, global_position_int->relative_alt, global_position_int->vx, global_position_int->vy, global_position_int->vz, global_position_int->hdg); +} + /** * @brief Send a global_position_int message * @param chan MAVLink channel to send the message @@ -177,7 +191,7 @@ static inline uint16_t mavlink_msg_global_position_int_encode(uint8_t system_id, * @param vx Ground X Speed (Latitude), expressed as m/s * 100 * @param vy Ground Y Speed (Longitude), expressed as m/s * 100 * @param vz Ground Z Speed (Altitude), expressed as m/s * 100 - * @param hdg Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + * @param hdg Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX */ #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS @@ -308,7 +322,7 @@ static inline int16_t mavlink_msg_global_position_int_get_vz(const mavlink_messa /** * @brief Get field hdg from global_position_int message * - * @return Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + * @return Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX */ static inline uint16_t mavlink_msg_global_position_int_get_hdg(const mavlink_message_t* msg) { diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_global_position_setpoint_int.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_global_position_setpoint_int.h index 8153628aa8..1a1c97199e 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_global_position_setpoint_int.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_global_position_setpoint_int.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_global_position_setpoint_int_pack(uint8_t sys * @brief Pack a global_position_setpoint_int message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_GLOBAL or MAV_FRAME_GLOBAL_RELATIVE_ALT * @param latitude Latitude (WGS84), in degrees * 1E7 @@ -121,7 +121,7 @@ static inline uint16_t mavlink_msg_global_position_setpoint_int_pack_chan(uint8_ } /** - * @brief Encode a global_position_setpoint_int struct into a message + * @brief Encode a global_position_setpoint_int struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -133,6 +133,20 @@ static inline uint16_t mavlink_msg_global_position_setpoint_int_encode(uint8_t s return mavlink_msg_global_position_setpoint_int_pack(system_id, component_id, msg, global_position_setpoint_int->coordinate_frame, global_position_setpoint_int->latitude, global_position_setpoint_int->longitude, global_position_setpoint_int->altitude, global_position_setpoint_int->yaw); } +/** + * @brief Encode a global_position_setpoint_int struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param global_position_setpoint_int C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_global_position_setpoint_int_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_global_position_setpoint_int_t* global_position_setpoint_int) +{ + return mavlink_msg_global_position_setpoint_int_pack_chan(system_id, component_id, chan, msg, global_position_setpoint_int->coordinate_frame, global_position_setpoint_int->latitude, global_position_setpoint_int->longitude, global_position_setpoint_int->altitude, global_position_setpoint_int->yaw); +} + /** * @brief Send a global_position_setpoint_int message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_global_vision_position_estimate.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_global_vision_position_estimate.h index b388fa24ad..f7be74c917 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_global_vision_position_estimate.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_global_vision_position_estimate.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_global_vision_position_estimate_pack(uint8_t * @brief Pack a global_vision_position_estimate message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param usec Timestamp (microseconds, synced to UNIX time or since system boot) * @param x Global X position @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_global_vision_position_estimate_pack_chan(uin } /** - * @brief Encode a global_vision_position_estimate struct into a message + * @brief Encode a global_vision_position_estimate struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_global_vision_position_estimate_encode(uint8_ return mavlink_msg_global_vision_position_estimate_pack(system_id, component_id, msg, global_vision_position_estimate->usec, global_vision_position_estimate->x, global_vision_position_estimate->y, global_vision_position_estimate->z, global_vision_position_estimate->roll, global_vision_position_estimate->pitch, global_vision_position_estimate->yaw); } +/** + * @brief Encode a global_vision_position_estimate struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param global_vision_position_estimate C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_global_vision_position_estimate_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_global_vision_position_estimate_t* global_vision_position_estimate) +{ + return mavlink_msg_global_vision_position_estimate_pack_chan(system_id, component_id, chan, msg, global_vision_position_estimate->usec, global_vision_position_estimate->x, global_vision_position_estimate->y, global_vision_position_estimate->z, global_vision_position_estimate->roll, global_vision_position_estimate->pitch, global_vision_position_estimate->yaw); +} + /** * @brief Send a global_vision_position_estimate message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_gps_global_origin.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_gps_global_origin.h index bd09cb7534..016e9cb0e6 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_gps_global_origin.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_gps_global_origin.h @@ -69,7 +69,7 @@ static inline uint16_t mavlink_msg_gps_global_origin_pack(uint8_t system_id, uin * @brief Pack a gps_global_origin message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param latitude Latitude (WGS84), in degrees * 1E7 * @param longitude Longitude (WGS84), in degrees * 1E7 @@ -105,7 +105,7 @@ static inline uint16_t mavlink_msg_gps_global_origin_pack_chan(uint8_t system_id } /** - * @brief Encode a gps_global_origin struct into a message + * @brief Encode a gps_global_origin struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -117,6 +117,20 @@ static inline uint16_t mavlink_msg_gps_global_origin_encode(uint8_t system_id, u return mavlink_msg_gps_global_origin_pack(system_id, component_id, msg, gps_global_origin->latitude, gps_global_origin->longitude, gps_global_origin->altitude); } +/** + * @brief Encode a gps_global_origin struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param gps_global_origin C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_gps_global_origin_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_gps_global_origin_t* gps_global_origin) +{ + return mavlink_msg_gps_global_origin_pack_chan(system_id, component_id, chan, msg, gps_global_origin->latitude, gps_global_origin->longitude, gps_global_origin->altitude); +} + /** * @brief Send a gps_global_origin message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_gps_raw_int.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_gps_raw_int.h index 2136b65eef..3054d4fdab 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_gps_raw_int.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_gps_raw_int.h @@ -8,10 +8,10 @@ typedef struct __mavlink_gps_raw_int_t int32_t lat; ///< Latitude (WGS84), in degrees * 1E7 int32_t lon; ///< Longitude (WGS84), in degrees * 1E7 int32_t alt; ///< Altitude (WGS84), in meters * 1000 (positive for up) - uint16_t eph; ///< GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 - uint16_t epv; ///< GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 - uint16_t vel; ///< GPS ground speed (m/s * 100). If unknown, set to: 65535 - uint16_t cog; ///< Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + uint16_t eph; ///< GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: UINT16_MAX + uint16_t epv; ///< GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: UINT16_MAX + uint16_t vel; ///< GPS ground speed (m/s * 100). If unknown, set to: UINT16_MAX + uint16_t cog; ///< Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX uint8_t fix_type; ///< 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix. uint8_t satellites_visible; ///< Number of satellites visible. If unknown, set to 255 } mavlink_gps_raw_int_t; @@ -52,10 +52,10 @@ typedef struct __mavlink_gps_raw_int_t * @param lat Latitude (WGS84), in degrees * 1E7 * @param lon Longitude (WGS84), in degrees * 1E7 * @param alt Altitude (WGS84), in meters * 1000 (positive for up) - * @param eph GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 - * @param epv GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 - * @param vel GPS ground speed (m/s * 100). If unknown, set to: 65535 - * @param cog Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + * @param eph GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: UINT16_MAX + * @param epv GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: UINT16_MAX + * @param vel GPS ground speed (m/s * 100). If unknown, set to: UINT16_MAX + * @param cog Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX * @param satellites_visible Number of satellites visible. If unknown, set to 255 * @return length of the message in bytes (excluding serial stream start sign) */ @@ -104,17 +104,17 @@ static inline uint16_t mavlink_msg_gps_raw_int_pack(uint8_t system_id, uint8_t c * @brief Pack a gps_raw_int message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) * @param fix_type 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix. * @param lat Latitude (WGS84), in degrees * 1E7 * @param lon Longitude (WGS84), in degrees * 1E7 * @param alt Altitude (WGS84), in meters * 1000 (positive for up) - * @param eph GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 - * @param epv GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 - * @param vel GPS ground speed (m/s * 100). If unknown, set to: 65535 - * @param cog Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + * @param eph GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: UINT16_MAX + * @param epv GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: UINT16_MAX + * @param vel GPS ground speed (m/s * 100). If unknown, set to: UINT16_MAX + * @param cog Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX * @param satellites_visible Number of satellites visible. If unknown, set to 255 * @return length of the message in bytes (excluding serial stream start sign) */ @@ -161,7 +161,7 @@ static inline uint16_t mavlink_msg_gps_raw_int_pack_chan(uint8_t system_id, uint } /** - * @brief Encode a gps_raw_int struct into a message + * @brief Encode a gps_raw_int struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -173,6 +173,20 @@ static inline uint16_t mavlink_msg_gps_raw_int_encode(uint8_t system_id, uint8_t return mavlink_msg_gps_raw_int_pack(system_id, component_id, msg, gps_raw_int->time_usec, gps_raw_int->fix_type, gps_raw_int->lat, gps_raw_int->lon, gps_raw_int->alt, gps_raw_int->eph, gps_raw_int->epv, gps_raw_int->vel, gps_raw_int->cog, gps_raw_int->satellites_visible); } +/** + * @brief Encode a gps_raw_int struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param gps_raw_int C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_gps_raw_int_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_gps_raw_int_t* gps_raw_int) +{ + return mavlink_msg_gps_raw_int_pack_chan(system_id, component_id, chan, msg, gps_raw_int->time_usec, gps_raw_int->fix_type, gps_raw_int->lat, gps_raw_int->lon, gps_raw_int->alt, gps_raw_int->eph, gps_raw_int->epv, gps_raw_int->vel, gps_raw_int->cog, gps_raw_int->satellites_visible); +} + /** * @brief Send a gps_raw_int message * @param chan MAVLink channel to send the message @@ -182,10 +196,10 @@ static inline uint16_t mavlink_msg_gps_raw_int_encode(uint8_t system_id, uint8_t * @param lat Latitude (WGS84), in degrees * 1E7 * @param lon Longitude (WGS84), in degrees * 1E7 * @param alt Altitude (WGS84), in meters * 1000 (positive for up) - * @param eph GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 - * @param epv GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 - * @param vel GPS ground speed (m/s * 100). If unknown, set to: 65535 - * @param cog Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + * @param eph GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: UINT16_MAX + * @param epv GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: UINT16_MAX + * @param vel GPS ground speed (m/s * 100). If unknown, set to: UINT16_MAX + * @param cog Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX * @param satellites_visible Number of satellites visible. If unknown, set to 255 */ #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS @@ -289,7 +303,7 @@ static inline int32_t mavlink_msg_gps_raw_int_get_alt(const mavlink_message_t* m /** * @brief Get field eph from gps_raw_int message * - * @return GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + * @return GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: UINT16_MAX */ static inline uint16_t mavlink_msg_gps_raw_int_get_eph(const mavlink_message_t* msg) { @@ -299,7 +313,7 @@ static inline uint16_t mavlink_msg_gps_raw_int_get_eph(const mavlink_message_t* /** * @brief Get field epv from gps_raw_int message * - * @return GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + * @return GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: UINT16_MAX */ static inline uint16_t mavlink_msg_gps_raw_int_get_epv(const mavlink_message_t* msg) { @@ -309,7 +323,7 @@ static inline uint16_t mavlink_msg_gps_raw_int_get_epv(const mavlink_message_t* /** * @brief Get field vel from gps_raw_int message * - * @return GPS ground speed (m/s * 100). If unknown, set to: 65535 + * @return GPS ground speed (m/s * 100). If unknown, set to: UINT16_MAX */ static inline uint16_t mavlink_msg_gps_raw_int_get_vel(const mavlink_message_t* msg) { @@ -319,7 +333,7 @@ static inline uint16_t mavlink_msg_gps_raw_int_get_vel(const mavlink_message_t* /** * @brief Get field cog from gps_raw_int message * - * @return Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + * @return Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX */ static inline uint16_t mavlink_msg_gps_raw_int_get_cog(const mavlink_message_t* msg) { diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_gps_status.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_gps_status.h index cd6dde700f..28d6b57d19 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_gps_status.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_gps_status.h @@ -86,7 +86,7 @@ static inline uint16_t mavlink_msg_gps_status_pack(uint8_t system_id, uint8_t co * @brief Pack a gps_status message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param satellites_visible Number of satellites visible * @param satellite_prn Global satellite ID @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_gps_status_pack_chan(uint8_t system_id, uint8 } /** - * @brief Encode a gps_status struct into a message + * @brief Encode a gps_status struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_gps_status_encode(uint8_t system_id, uint8_t return mavlink_msg_gps_status_pack(system_id, component_id, msg, gps_status->satellites_visible, gps_status->satellite_prn, gps_status->satellite_used, gps_status->satellite_elevation, gps_status->satellite_azimuth, gps_status->satellite_snr); } +/** + * @brief Encode a gps_status struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param gps_status C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_gps_status_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_gps_status_t* gps_status) +{ + return mavlink_msg_gps_status_pack_chan(system_id, component_id, chan, msg, gps_status->satellites_visible, gps_status->satellite_prn, gps_status->satellite_used, gps_status->satellite_elevation, gps_status->satellite_azimuth, gps_status->satellite_snr); +} + /** * @brief Send a gps_status message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_heartbeat.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_heartbeat.h index b2f0b65d06..826138fad1 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_heartbeat.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_heartbeat.h @@ -83,7 +83,7 @@ static inline uint16_t mavlink_msg_heartbeat_pack(uint8_t system_id, uint8_t com * @brief Pack a heartbeat message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param type Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM) * @param autopilot Autopilot type / class. defined in MAV_AUTOPILOT ENUM @@ -127,7 +127,7 @@ static inline uint16_t mavlink_msg_heartbeat_pack_chan(uint8_t system_id, uint8_ } /** - * @brief Encode a heartbeat struct into a message + * @brief Encode a heartbeat struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -139,6 +139,20 @@ static inline uint16_t mavlink_msg_heartbeat_encode(uint8_t system_id, uint8_t c return mavlink_msg_heartbeat_pack(system_id, component_id, msg, heartbeat->type, heartbeat->autopilot, heartbeat->base_mode, heartbeat->custom_mode, heartbeat->system_status); } +/** + * @brief Encode a heartbeat struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param heartbeat C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_heartbeat_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_heartbeat_t* heartbeat) +{ + return mavlink_msg_heartbeat_pack_chan(system_id, component_id, chan, msg, heartbeat->type, heartbeat->autopilot, heartbeat->base_mode, heartbeat->custom_mode, heartbeat->system_status); +} + /** * @brief Send a heartbeat message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_highres_imu.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_highres_imu.h index 6e7492ea65..0dcd95ed32 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_highres_imu.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_highres_imu.h @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_highres_imu_pack(uint8_t system_id, uint8_t c * @brief Pack a highres_imu message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (microseconds, synced to UNIX time or since system boot) * @param xacc X acceleration (m/s^2) @@ -201,7 +201,7 @@ static inline uint16_t mavlink_msg_highres_imu_pack_chan(uint8_t system_id, uint } /** - * @brief Encode a highres_imu struct into a message + * @brief Encode a highres_imu struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -213,6 +213,20 @@ static inline uint16_t mavlink_msg_highres_imu_encode(uint8_t system_id, uint8_t return mavlink_msg_highres_imu_pack(system_id, component_id, msg, highres_imu->time_usec, highres_imu->xacc, highres_imu->yacc, highres_imu->zacc, highres_imu->xgyro, highres_imu->ygyro, highres_imu->zgyro, highres_imu->xmag, highres_imu->ymag, highres_imu->zmag, highres_imu->abs_pressure, highres_imu->diff_pressure, highres_imu->pressure_alt, highres_imu->temperature, highres_imu->fields_updated); } +/** + * @brief Encode a highres_imu struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param highres_imu C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_highres_imu_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_highres_imu_t* highres_imu) +{ + return mavlink_msg_highres_imu_pack_chan(system_id, component_id, chan, msg, highres_imu->time_usec, highres_imu->xacc, highres_imu->yacc, highres_imu->zacc, highres_imu->xgyro, highres_imu->ygyro, highres_imu->zgyro, highres_imu->xmag, highres_imu->ymag, highres_imu->zmag, highres_imu->abs_pressure, highres_imu->diff_pressure, highres_imu->pressure_alt, highres_imu->temperature, highres_imu->fields_updated); +} + /** * @brief Send a highres_imu message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_controls.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_controls.h index 3319d3fd2d..aed5108d05 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_controls.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_controls.h @@ -109,7 +109,7 @@ static inline uint16_t mavlink_msg_hil_controls_pack(uint8_t system_id, uint8_t * @brief Pack a hil_controls message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) * @param roll_ailerons Control output -1 .. 1 @@ -169,7 +169,7 @@ static inline uint16_t mavlink_msg_hil_controls_pack_chan(uint8_t system_id, uin } /** - * @brief Encode a hil_controls struct into a message + * @brief Encode a hil_controls struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -181,6 +181,20 @@ static inline uint16_t mavlink_msg_hil_controls_encode(uint8_t system_id, uint8_ return mavlink_msg_hil_controls_pack(system_id, component_id, msg, hil_controls->time_usec, hil_controls->roll_ailerons, hil_controls->pitch_elevator, hil_controls->yaw_rudder, hil_controls->throttle, hil_controls->aux1, hil_controls->aux2, hil_controls->aux3, hil_controls->aux4, hil_controls->mode, hil_controls->nav_mode); } +/** + * @brief Encode a hil_controls struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param hil_controls C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_hil_controls_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_hil_controls_t* hil_controls) +{ + return mavlink_msg_hil_controls_pack_chan(system_id, component_id, chan, msg, hil_controls->time_usec, hil_controls->roll_ailerons, hil_controls->pitch_elevator, hil_controls->yaw_rudder, hil_controls->throttle, hil_controls->aux1, hil_controls->aux2, hil_controls->aux3, hil_controls->aux4, hil_controls->mode, hil_controls->nav_mode); +} + /** * @brief Send a hil_controls message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_gps.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_gps.h index 75ab6835dd..36a551872b 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_gps.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_gps.h @@ -119,7 +119,7 @@ static inline uint16_t mavlink_msg_hil_gps_pack(uint8_t system_id, uint8_t compo * @brief Pack a hil_gps message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) * @param fix_type 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix. @@ -185,7 +185,7 @@ static inline uint16_t mavlink_msg_hil_gps_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a hil_gps struct into a message + * @brief Encode a hil_gps struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -197,6 +197,20 @@ static inline uint16_t mavlink_msg_hil_gps_encode(uint8_t system_id, uint8_t com return mavlink_msg_hil_gps_pack(system_id, component_id, msg, hil_gps->time_usec, hil_gps->fix_type, hil_gps->lat, hil_gps->lon, hil_gps->alt, hil_gps->eph, hil_gps->epv, hil_gps->vel, hil_gps->vn, hil_gps->ve, hil_gps->vd, hil_gps->cog, hil_gps->satellites_visible); } +/** + * @brief Encode a hil_gps struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param hil_gps C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_hil_gps_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_hil_gps_t* hil_gps) +{ + return mavlink_msg_hil_gps_pack_chan(system_id, component_id, chan, msg, hil_gps->time_usec, hil_gps->fix_type, hil_gps->lat, hil_gps->lon, hil_gps->alt, hil_gps->eph, hil_gps->epv, hil_gps->vel, hil_gps->vn, hil_gps->ve, hil_gps->vd, hil_gps->cog, hil_gps->satellites_visible); +} + /** * @brief Send a hil_gps message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_optical_flow.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_optical_flow.h index 13e13d47cb..acb1392e14 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_optical_flow.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_optical_flow.h @@ -94,7 +94,7 @@ static inline uint16_t mavlink_msg_hil_optical_flow_pack(uint8_t system_id, uint * @brief Pack a hil_optical_flow message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (UNIX) * @param sensor_id Sensor ID @@ -145,7 +145,7 @@ static inline uint16_t mavlink_msg_hil_optical_flow_pack_chan(uint8_t system_id, } /** - * @brief Encode a hil_optical_flow struct into a message + * @brief Encode a hil_optical_flow struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -157,6 +157,20 @@ static inline uint16_t mavlink_msg_hil_optical_flow_encode(uint8_t system_id, ui return mavlink_msg_hil_optical_flow_pack(system_id, component_id, msg, hil_optical_flow->time_usec, hil_optical_flow->sensor_id, hil_optical_flow->flow_x, hil_optical_flow->flow_y, hil_optical_flow->flow_comp_m_x, hil_optical_flow->flow_comp_m_y, hil_optical_flow->quality, hil_optical_flow->ground_distance); } +/** + * @brief Encode a hil_optical_flow struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param hil_optical_flow C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_hil_optical_flow_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_hil_optical_flow_t* hil_optical_flow) +{ + return mavlink_msg_hil_optical_flow_pack_chan(system_id, component_id, chan, msg, hil_optical_flow->time_usec, hil_optical_flow->sensor_id, hil_optical_flow->flow_x, hil_optical_flow->flow_y, hil_optical_flow->flow_comp_m_x, hil_optical_flow->flow_comp_m_y, hil_optical_flow->quality, hil_optical_flow->ground_distance); +} + /** * @brief Send a hil_optical_flow message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_rc_inputs_raw.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_rc_inputs_raw.h index f2435dde87..a42bde50b2 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_rc_inputs_raw.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_rc_inputs_raw.h @@ -124,7 +124,7 @@ static inline uint16_t mavlink_msg_hil_rc_inputs_raw_pack(uint8_t system_id, uin * @brief Pack a hil_rc_inputs_raw message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) * @param chan1_raw RC channel 1 value, in microseconds @@ -193,7 +193,7 @@ static inline uint16_t mavlink_msg_hil_rc_inputs_raw_pack_chan(uint8_t system_id } /** - * @brief Encode a hil_rc_inputs_raw struct into a message + * @brief Encode a hil_rc_inputs_raw struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -205,6 +205,20 @@ static inline uint16_t mavlink_msg_hil_rc_inputs_raw_encode(uint8_t system_id, u return mavlink_msg_hil_rc_inputs_raw_pack(system_id, component_id, msg, hil_rc_inputs_raw->time_usec, hil_rc_inputs_raw->chan1_raw, hil_rc_inputs_raw->chan2_raw, hil_rc_inputs_raw->chan3_raw, hil_rc_inputs_raw->chan4_raw, hil_rc_inputs_raw->chan5_raw, hil_rc_inputs_raw->chan6_raw, hil_rc_inputs_raw->chan7_raw, hil_rc_inputs_raw->chan8_raw, hil_rc_inputs_raw->chan9_raw, hil_rc_inputs_raw->chan10_raw, hil_rc_inputs_raw->chan11_raw, hil_rc_inputs_raw->chan12_raw, hil_rc_inputs_raw->rssi); } +/** + * @brief Encode a hil_rc_inputs_raw struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param hil_rc_inputs_raw C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_hil_rc_inputs_raw_t* hil_rc_inputs_raw) +{ + return mavlink_msg_hil_rc_inputs_raw_pack_chan(system_id, component_id, chan, msg, hil_rc_inputs_raw->time_usec, hil_rc_inputs_raw->chan1_raw, hil_rc_inputs_raw->chan2_raw, hil_rc_inputs_raw->chan3_raw, hil_rc_inputs_raw->chan4_raw, hil_rc_inputs_raw->chan5_raw, hil_rc_inputs_raw->chan6_raw, hil_rc_inputs_raw->chan7_raw, hil_rc_inputs_raw->chan8_raw, hil_rc_inputs_raw->chan9_raw, hil_rc_inputs_raw->chan10_raw, hil_rc_inputs_raw->chan11_raw, hil_rc_inputs_raw->chan12_raw, hil_rc_inputs_raw->rssi); +} + /** * @brief Send a hil_rc_inputs_raw message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_sensor.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_sensor.h index 422e55adc8..6c2667473d 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_sensor.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_sensor.h @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_hil_sensor_pack(uint8_t system_id, uint8_t co * @brief Pack a hil_sensor message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (microseconds, synced to UNIX time or since system boot) * @param xacc X acceleration (m/s^2) @@ -201,7 +201,7 @@ static inline uint16_t mavlink_msg_hil_sensor_pack_chan(uint8_t system_id, uint8 } /** - * @brief Encode a hil_sensor struct into a message + * @brief Encode a hil_sensor struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -213,6 +213,20 @@ static inline uint16_t mavlink_msg_hil_sensor_encode(uint8_t system_id, uint8_t return mavlink_msg_hil_sensor_pack(system_id, component_id, msg, hil_sensor->time_usec, hil_sensor->xacc, hil_sensor->yacc, hil_sensor->zacc, hil_sensor->xgyro, hil_sensor->ygyro, hil_sensor->zgyro, hil_sensor->xmag, hil_sensor->ymag, hil_sensor->zmag, hil_sensor->abs_pressure, hil_sensor->diff_pressure, hil_sensor->pressure_alt, hil_sensor->temperature, hil_sensor->fields_updated); } +/** + * @brief Encode a hil_sensor struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param hil_sensor C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_hil_sensor_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_hil_sensor_t* hil_sensor) +{ + return mavlink_msg_hil_sensor_pack_chan(system_id, component_id, chan, msg, hil_sensor->time_usec, hil_sensor->xacc, hil_sensor->yacc, hil_sensor->zacc, hil_sensor->xgyro, hil_sensor->ygyro, hil_sensor->zgyro, hil_sensor->xmag, hil_sensor->ymag, hil_sensor->zmag, hil_sensor->abs_pressure, hil_sensor->diff_pressure, hil_sensor->pressure_alt, hil_sensor->temperature, hil_sensor->fields_updated); +} + /** * @brief Send a hil_sensor message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_state.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_state.h index 1d3f286649..bcc8577670 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_state.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_state.h @@ -134,7 +134,7 @@ static inline uint16_t mavlink_msg_hil_state_pack(uint8_t system_id, uint8_t com * @brief Pack a hil_state message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) * @param roll Roll angle (rad) @@ -209,7 +209,7 @@ static inline uint16_t mavlink_msg_hil_state_pack_chan(uint8_t system_id, uint8_ } /** - * @brief Encode a hil_state struct into a message + * @brief Encode a hil_state struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -221,6 +221,20 @@ static inline uint16_t mavlink_msg_hil_state_encode(uint8_t system_id, uint8_t c return mavlink_msg_hil_state_pack(system_id, component_id, msg, hil_state->time_usec, hil_state->roll, hil_state->pitch, hil_state->yaw, hil_state->rollspeed, hil_state->pitchspeed, hil_state->yawspeed, hil_state->lat, hil_state->lon, hil_state->alt, hil_state->vx, hil_state->vy, hil_state->vz, hil_state->xacc, hil_state->yacc, hil_state->zacc); } +/** + * @brief Encode a hil_state struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param hil_state C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_hil_state_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_hil_state_t* hil_state) +{ + return mavlink_msg_hil_state_pack_chan(system_id, component_id, chan, msg, hil_state->time_usec, hil_state->roll, hil_state->pitch, hil_state->yaw, hil_state->rollspeed, hil_state->pitchspeed, hil_state->yawspeed, hil_state->lat, hil_state->lon, hil_state->alt, hil_state->vx, hil_state->vy, hil_state->vz, hil_state->xacc, hil_state->yacc, hil_state->zacc); +} + /** * @brief Send a hil_state message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_state_quaternion.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_state_quaternion.h index 0474e64a2b..732176193e 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_state_quaternion.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_hil_state_quaternion.h @@ -132,7 +132,7 @@ static inline uint16_t mavlink_msg_hil_state_quaternion_pack(uint8_t system_id, * @brief Pack a hil_state_quaternion message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) * @param attitude_quaternion Vehicle attitude expressed as normalized quaternion @@ -205,7 +205,7 @@ static inline uint16_t mavlink_msg_hil_state_quaternion_pack_chan(uint8_t system } /** - * @brief Encode a hil_state_quaternion struct into a message + * @brief Encode a hil_state_quaternion struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -217,6 +217,20 @@ static inline uint16_t mavlink_msg_hil_state_quaternion_encode(uint8_t system_id return mavlink_msg_hil_state_quaternion_pack(system_id, component_id, msg, hil_state_quaternion->time_usec, hil_state_quaternion->attitude_quaternion, hil_state_quaternion->rollspeed, hil_state_quaternion->pitchspeed, hil_state_quaternion->yawspeed, hil_state_quaternion->lat, hil_state_quaternion->lon, hil_state_quaternion->alt, hil_state_quaternion->vx, hil_state_quaternion->vy, hil_state_quaternion->vz, hil_state_quaternion->ind_airspeed, hil_state_quaternion->true_airspeed, hil_state_quaternion->xacc, hil_state_quaternion->yacc, hil_state_quaternion->zacc); } +/** + * @brief Encode a hil_state_quaternion struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param hil_state_quaternion C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_hil_state_quaternion_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_hil_state_quaternion_t* hil_state_quaternion) +{ + return mavlink_msg_hil_state_quaternion_pack_chan(system_id, component_id, chan, msg, hil_state_quaternion->time_usec, hil_state_quaternion->attitude_quaternion, hil_state_quaternion->rollspeed, hil_state_quaternion->pitchspeed, hil_state_quaternion->yawspeed, hil_state_quaternion->lat, hil_state_quaternion->lon, hil_state_quaternion->alt, hil_state_quaternion->vx, hil_state_quaternion->vy, hil_state_quaternion->vz, hil_state_quaternion->ind_airspeed, hil_state_quaternion->true_airspeed, hil_state_quaternion->xacc, hil_state_quaternion->yacc, hil_state_quaternion->zacc); +} + /** * @brief Send a hil_state_quaternion message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_local_position_ned.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_local_position_ned.h index 56723f3d7d..a0b72c0e1e 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_local_position_ned.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_local_position_ned.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_local_position_ned_pack(uint8_t system_id, ui * @brief Pack a local_position_ned message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param x X Position @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_local_position_ned_pack_chan(uint8_t system_i } /** - * @brief Encode a local_position_ned struct into a message + * @brief Encode a local_position_ned struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_local_position_ned_encode(uint8_t system_id, return mavlink_msg_local_position_ned_pack(system_id, component_id, msg, local_position_ned->time_boot_ms, local_position_ned->x, local_position_ned->y, local_position_ned->z, local_position_ned->vx, local_position_ned->vy, local_position_ned->vz); } +/** + * @brief Encode a local_position_ned struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param local_position_ned C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_local_position_ned_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_local_position_ned_t* local_position_ned) +{ + return mavlink_msg_local_position_ned_pack_chan(system_id, component_id, chan, msg, local_position_ned->time_boot_ms, local_position_ned->x, local_position_ned->y, local_position_ned->z, local_position_ned->vx, local_position_ned->vy, local_position_ned->vz); +} + /** * @brief Send a local_position_ned message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_local_position_ned_system_global_offset.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_local_position_ned_system_global_offset.h index c206a2906b..8c46862027 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_local_position_ned_system_global_offset.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_local_position_ned_system_global_offset.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_local_position_ned_system_global_offset_pack( * @brief Pack a local_position_ned_system_global_offset message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param x X Position @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_local_position_ned_system_global_offset_pack_ } /** - * @brief Encode a local_position_ned_system_global_offset struct into a message + * @brief Encode a local_position_ned_system_global_offset struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_local_position_ned_system_global_offset_encod return mavlink_msg_local_position_ned_system_global_offset_pack(system_id, component_id, msg, local_position_ned_system_global_offset->time_boot_ms, local_position_ned_system_global_offset->x, local_position_ned_system_global_offset->y, local_position_ned_system_global_offset->z, local_position_ned_system_global_offset->roll, local_position_ned_system_global_offset->pitch, local_position_ned_system_global_offset->yaw); } +/** + * @brief Encode a local_position_ned_system_global_offset struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param local_position_ned_system_global_offset C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_local_position_ned_system_global_offset_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_local_position_ned_system_global_offset_t* local_position_ned_system_global_offset) +{ + return mavlink_msg_local_position_ned_system_global_offset_pack_chan(system_id, component_id, chan, msg, local_position_ned_system_global_offset->time_boot_ms, local_position_ned_system_global_offset->x, local_position_ned_system_global_offset->y, local_position_ned_system_global_offset->z, local_position_ned_system_global_offset->roll, local_position_ned_system_global_offset->pitch, local_position_ned_system_global_offset->yaw); +} + /** * @brief Send a local_position_ned_system_global_offset message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_local_position_setpoint.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_local_position_setpoint.h index 96f35fe625..1794815f8e 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_local_position_setpoint.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_local_position_setpoint.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_local_position_setpoint_pack(uint8_t system_i * @brief Pack a local_position_setpoint message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_LOCAL_NED or MAV_FRAME_LOCAL_ENU * @param x x position @@ -121,7 +121,7 @@ static inline uint16_t mavlink_msg_local_position_setpoint_pack_chan(uint8_t sys } /** - * @brief Encode a local_position_setpoint struct into a message + * @brief Encode a local_position_setpoint struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -133,6 +133,20 @@ static inline uint16_t mavlink_msg_local_position_setpoint_encode(uint8_t system return mavlink_msg_local_position_setpoint_pack(system_id, component_id, msg, local_position_setpoint->coordinate_frame, local_position_setpoint->x, local_position_setpoint->y, local_position_setpoint->z, local_position_setpoint->yaw); } +/** + * @brief Encode a local_position_setpoint struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param local_position_setpoint C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_local_position_setpoint_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_local_position_setpoint_t* local_position_setpoint) +{ + return mavlink_msg_local_position_setpoint_pack_chan(system_id, component_id, chan, msg, local_position_setpoint->coordinate_frame, local_position_setpoint->x, local_position_setpoint->y, local_position_setpoint->z, local_position_setpoint->yaw); +} + /** * @brief Send a local_position_setpoint message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_manual_control.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_manual_control.h index c9e4a4f8a5..6b6e9e148a 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_manual_control.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_manual_control.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_manual_control_pack(uint8_t system_id, uint8_ * @brief Pack a manual_control message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target The system to be controlled. * @param x X-axis, normalized to the range [-1000,1000]. A value of INT16_MAX indicates that this axis is invalid. Generally corresponds to forward(1000)-backward(-1000) movement on a joystick and the pitch of a vehicle. @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_manual_control_pack_chan(uint8_t system_id, u } /** - * @brief Encode a manual_control struct into a message + * @brief Encode a manual_control struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_manual_control_encode(uint8_t system_id, uint return mavlink_msg_manual_control_pack(system_id, component_id, msg, manual_control->target, manual_control->x, manual_control->y, manual_control->z, manual_control->r, manual_control->buttons); } +/** + * @brief Encode a manual_control struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param manual_control C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_manual_control_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_manual_control_t* manual_control) +{ + return mavlink_msg_manual_control_pack_chan(system_id, component_id, chan, msg, manual_control->target, manual_control->x, manual_control->y, manual_control->z, manual_control->r, manual_control->buttons); +} + /** * @brief Send a manual_control message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_manual_setpoint.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_manual_setpoint.h index d59e212921..a694947c12 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_manual_setpoint.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_manual_setpoint.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_manual_setpoint_pack(uint8_t system_id, uint8 * @brief Pack a manual_setpoint message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp in milliseconds since system boot * @param roll Desired roll rate in radians per second @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_manual_setpoint_pack_chan(uint8_t system_id, } /** - * @brief Encode a manual_setpoint struct into a message + * @brief Encode a manual_setpoint struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_manual_setpoint_encode(uint8_t system_id, uin return mavlink_msg_manual_setpoint_pack(system_id, component_id, msg, manual_setpoint->time_boot_ms, manual_setpoint->roll, manual_setpoint->pitch, manual_setpoint->yaw, manual_setpoint->thrust, manual_setpoint->mode_switch, manual_setpoint->manual_override_switch); } +/** + * @brief Encode a manual_setpoint struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param manual_setpoint C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_manual_setpoint_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_manual_setpoint_t* manual_setpoint) +{ + return mavlink_msg_manual_setpoint_pack_chan(system_id, component_id, chan, msg, manual_setpoint->time_boot_ms, manual_setpoint->roll, manual_setpoint->pitch, manual_setpoint->yaw, manual_setpoint->thrust, manual_setpoint->mode_switch, manual_setpoint->manual_override_switch); +} + /** * @brief Send a manual_setpoint message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_memory_vect.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_memory_vect.h index f8ae21b05c..5f79329c25 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_memory_vect.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_memory_vect.h @@ -72,7 +72,7 @@ static inline uint16_t mavlink_msg_memory_vect_pack(uint8_t system_id, uint8_t c * @brief Pack a memory_vect message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param address Starting address of the debug variables * @param ver Version code of the type variable. 0=unknown, type ignored and assumed int16_t. 1=as below @@ -109,7 +109,7 @@ static inline uint16_t mavlink_msg_memory_vect_pack_chan(uint8_t system_id, uint } /** - * @brief Encode a memory_vect struct into a message + * @brief Encode a memory_vect struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -121,6 +121,20 @@ static inline uint16_t mavlink_msg_memory_vect_encode(uint8_t system_id, uint8_t return mavlink_msg_memory_vect_pack(system_id, component_id, msg, memory_vect->address, memory_vect->ver, memory_vect->type, memory_vect->value); } +/** + * @brief Encode a memory_vect struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param memory_vect C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_memory_vect_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_memory_vect_t* memory_vect) +{ + return mavlink_msg_memory_vect_pack_chan(system_id, component_id, chan, msg, memory_vect->address, memory_vect->ver, memory_vect->type, memory_vect->value); +} + /** * @brief Send a memory_vect message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_ack.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_ack.h index 32825647f9..7421d8394a 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_ack.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_ack.h @@ -69,7 +69,7 @@ static inline uint16_t mavlink_msg_mission_ack_pack(uint8_t system_id, uint8_t c * @brief Pack a mission_ack message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -105,7 +105,7 @@ static inline uint16_t mavlink_msg_mission_ack_pack_chan(uint8_t system_id, uint } /** - * @brief Encode a mission_ack struct into a message + * @brief Encode a mission_ack struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -117,6 +117,20 @@ static inline uint16_t mavlink_msg_mission_ack_encode(uint8_t system_id, uint8_t return mavlink_msg_mission_ack_pack(system_id, component_id, msg, mission_ack->target_system, mission_ack->target_component, mission_ack->type); } +/** + * @brief Encode a mission_ack struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mission_ack C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_ack_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mission_ack_t* mission_ack) +{ + return mavlink_msg_mission_ack_pack_chan(system_id, component_id, chan, msg, mission_ack->target_system, mission_ack->target_component, mission_ack->type); +} + /** * @brief Send a mission_ack message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_clear_all.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_clear_all.h index 06d2ac2e79..8f441c8e5c 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_clear_all.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_clear_all.h @@ -64,7 +64,7 @@ static inline uint16_t mavlink_msg_mission_clear_all_pack(uint8_t system_id, uin * @brief Pack a mission_clear_all message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -97,7 +97,7 @@ static inline uint16_t mavlink_msg_mission_clear_all_pack_chan(uint8_t system_id } /** - * @brief Encode a mission_clear_all struct into a message + * @brief Encode a mission_clear_all struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -109,6 +109,20 @@ static inline uint16_t mavlink_msg_mission_clear_all_encode(uint8_t system_id, u return mavlink_msg_mission_clear_all_pack(system_id, component_id, msg, mission_clear_all->target_system, mission_clear_all->target_component); } +/** + * @brief Encode a mission_clear_all struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mission_clear_all C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_clear_all_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mission_clear_all_t* mission_clear_all) +{ + return mavlink_msg_mission_clear_all_pack_chan(system_id, component_id, chan, msg, mission_clear_all->target_system, mission_clear_all->target_component); +} + /** * @brief Send a mission_clear_all message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_count.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_count.h index b28cec6f6d..eac7793067 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_count.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_count.h @@ -69,7 +69,7 @@ static inline uint16_t mavlink_msg_mission_count_pack(uint8_t system_id, uint8_t * @brief Pack a mission_count message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -105,7 +105,7 @@ static inline uint16_t mavlink_msg_mission_count_pack_chan(uint8_t system_id, ui } /** - * @brief Encode a mission_count struct into a message + * @brief Encode a mission_count struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -117,6 +117,20 @@ static inline uint16_t mavlink_msg_mission_count_encode(uint8_t system_id, uint8 return mavlink_msg_mission_count_pack(system_id, component_id, msg, mission_count->target_system, mission_count->target_component, mission_count->count); } +/** + * @brief Encode a mission_count struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mission_count C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_count_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mission_count_t* mission_count) +{ + return mavlink_msg_mission_count_pack_chan(system_id, component_id, chan, msg, mission_count->target_system, mission_count->target_component, mission_count->count); +} + /** * @brief Send a mission_count message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_current.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_current.h index 5bf0899bea..dbcdbd3f9c 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_current.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_current.h @@ -59,7 +59,7 @@ static inline uint16_t mavlink_msg_mission_current_pack(uint8_t system_id, uint8 * @brief Pack a mission_current message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param seq Sequence * @return length of the message in bytes (excluding serial stream start sign) @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_mission_current_pack_chan(uint8_t system_id, } /** - * @brief Encode a mission_current struct into a message + * @brief Encode a mission_current struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -101,6 +101,20 @@ static inline uint16_t mavlink_msg_mission_current_encode(uint8_t system_id, uin return mavlink_msg_mission_current_pack(system_id, component_id, msg, mission_current->seq); } +/** + * @brief Encode a mission_current struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mission_current C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_current_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mission_current_t* mission_current) +{ + return mavlink_msg_mission_current_pack_chan(system_id, component_id, chan, msg, mission_current->seq); +} + /** * @brief Send a mission_current message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_item.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_item.h index ed9d6e4af7..634f80c379 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_item.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_item.h @@ -124,7 +124,7 @@ static inline uint16_t mavlink_msg_mission_item_pack(uint8_t system_id, uint8_t * @brief Pack a mission_item message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -193,7 +193,7 @@ static inline uint16_t mavlink_msg_mission_item_pack_chan(uint8_t system_id, uin } /** - * @brief Encode a mission_item struct into a message + * @brief Encode a mission_item struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -205,6 +205,20 @@ static inline uint16_t mavlink_msg_mission_item_encode(uint8_t system_id, uint8_ return mavlink_msg_mission_item_pack(system_id, component_id, msg, mission_item->target_system, mission_item->target_component, mission_item->seq, mission_item->frame, mission_item->command, mission_item->current, mission_item->autocontinue, mission_item->param1, mission_item->param2, mission_item->param3, mission_item->param4, mission_item->x, mission_item->y, mission_item->z); } +/** + * @brief Encode a mission_item struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mission_item C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_item_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mission_item_t* mission_item) +{ + return mavlink_msg_mission_item_pack_chan(system_id, component_id, chan, msg, mission_item->target_system, mission_item->target_component, mission_item->seq, mission_item->frame, mission_item->command, mission_item->current, mission_item->autocontinue, mission_item->param1, mission_item->param2, mission_item->param3, mission_item->param4, mission_item->x, mission_item->y, mission_item->z); +} + /** * @brief Send a mission_item message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_item_reached.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_item_reached.h index 3f8a51a134..f3744fde6c 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_item_reached.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_item_reached.h @@ -59,7 +59,7 @@ static inline uint16_t mavlink_msg_mission_item_reached_pack(uint8_t system_id, * @brief Pack a mission_item_reached message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param seq Sequence * @return length of the message in bytes (excluding serial stream start sign) @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_mission_item_reached_pack_chan(uint8_t system } /** - * @brief Encode a mission_item_reached struct into a message + * @brief Encode a mission_item_reached struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -101,6 +101,20 @@ static inline uint16_t mavlink_msg_mission_item_reached_encode(uint8_t system_id return mavlink_msg_mission_item_reached_pack(system_id, component_id, msg, mission_item_reached->seq); } +/** + * @brief Encode a mission_item_reached struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mission_item_reached C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_item_reached_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mission_item_reached_t* mission_item_reached) +{ + return mavlink_msg_mission_item_reached_pack_chan(system_id, component_id, chan, msg, mission_item_reached->seq); +} + /** * @brief Send a mission_item_reached message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_request.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_request.h index 0ced17614e..ac84e35540 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_request.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_request.h @@ -69,7 +69,7 @@ static inline uint16_t mavlink_msg_mission_request_pack(uint8_t system_id, uint8 * @brief Pack a mission_request message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -105,7 +105,7 @@ static inline uint16_t mavlink_msg_mission_request_pack_chan(uint8_t system_id, } /** - * @brief Encode a mission_request struct into a message + * @brief Encode a mission_request struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -117,6 +117,20 @@ static inline uint16_t mavlink_msg_mission_request_encode(uint8_t system_id, uin return mavlink_msg_mission_request_pack(system_id, component_id, msg, mission_request->target_system, mission_request->target_component, mission_request->seq); } +/** + * @brief Encode a mission_request struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mission_request C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_request_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mission_request_t* mission_request) +{ + return mavlink_msg_mission_request_pack_chan(system_id, component_id, chan, msg, mission_request->target_system, mission_request->target_component, mission_request->seq); +} + /** * @brief Send a mission_request message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_request_list.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_request_list.h index 391df7f4da..d999babdbd 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_request_list.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_request_list.h @@ -64,7 +64,7 @@ static inline uint16_t mavlink_msg_mission_request_list_pack(uint8_t system_id, * @brief Pack a mission_request_list message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -97,7 +97,7 @@ static inline uint16_t mavlink_msg_mission_request_list_pack_chan(uint8_t system } /** - * @brief Encode a mission_request_list struct into a message + * @brief Encode a mission_request_list struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -109,6 +109,20 @@ static inline uint16_t mavlink_msg_mission_request_list_encode(uint8_t system_id return mavlink_msg_mission_request_list_pack(system_id, component_id, msg, mission_request_list->target_system, mission_request_list->target_component); } +/** + * @brief Encode a mission_request_list struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mission_request_list C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_request_list_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mission_request_list_t* mission_request_list) +{ + return mavlink_msg_mission_request_list_pack_chan(system_id, component_id, chan, msg, mission_request_list->target_system, mission_request_list->target_component); +} + /** * @brief Send a mission_request_list message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_request_partial_list.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_request_partial_list.h index d5a1c69397..35c7e12856 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_request_partial_list.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_request_partial_list.h @@ -74,7 +74,7 @@ static inline uint16_t mavlink_msg_mission_request_partial_list_pack(uint8_t sys * @brief Pack a mission_request_partial_list message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -113,7 +113,7 @@ static inline uint16_t mavlink_msg_mission_request_partial_list_pack_chan(uint8_ } /** - * @brief Encode a mission_request_partial_list struct into a message + * @brief Encode a mission_request_partial_list struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -125,6 +125,20 @@ static inline uint16_t mavlink_msg_mission_request_partial_list_encode(uint8_t s return mavlink_msg_mission_request_partial_list_pack(system_id, component_id, msg, mission_request_partial_list->target_system, mission_request_partial_list->target_component, mission_request_partial_list->start_index, mission_request_partial_list->end_index); } +/** + * @brief Encode a mission_request_partial_list struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mission_request_partial_list C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_request_partial_list_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mission_request_partial_list_t* mission_request_partial_list) +{ + return mavlink_msg_mission_request_partial_list_pack_chan(system_id, component_id, chan, msg, mission_request_partial_list->target_system, mission_request_partial_list->target_component, mission_request_partial_list->start_index, mission_request_partial_list->end_index); +} + /** * @brief Send a mission_request_partial_list message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_set_current.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_set_current.h index 2e145aa3e9..63b37cf8c8 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_set_current.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_set_current.h @@ -69,7 +69,7 @@ static inline uint16_t mavlink_msg_mission_set_current_pack(uint8_t system_id, u * @brief Pack a mission_set_current message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -105,7 +105,7 @@ static inline uint16_t mavlink_msg_mission_set_current_pack_chan(uint8_t system_ } /** - * @brief Encode a mission_set_current struct into a message + * @brief Encode a mission_set_current struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -117,6 +117,20 @@ static inline uint16_t mavlink_msg_mission_set_current_encode(uint8_t system_id, return mavlink_msg_mission_set_current_pack(system_id, component_id, msg, mission_set_current->target_system, mission_set_current->target_component, mission_set_current->seq); } +/** + * @brief Encode a mission_set_current struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mission_set_current C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_set_current_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mission_set_current_t* mission_set_current) +{ + return mavlink_msg_mission_set_current_pack_chan(system_id, component_id, chan, msg, mission_set_current->target_system, mission_set_current->target_component, mission_set_current->seq); +} + /** * @brief Send a mission_set_current message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_write_partial_list.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_write_partial_list.h index 6342f60383..7de38bd7b5 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_write_partial_list.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_mission_write_partial_list.h @@ -74,7 +74,7 @@ static inline uint16_t mavlink_msg_mission_write_partial_list_pack(uint8_t syste * @brief Pack a mission_write_partial_list message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -113,7 +113,7 @@ static inline uint16_t mavlink_msg_mission_write_partial_list_pack_chan(uint8_t } /** - * @brief Encode a mission_write_partial_list struct into a message + * @brief Encode a mission_write_partial_list struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -125,6 +125,20 @@ static inline uint16_t mavlink_msg_mission_write_partial_list_encode(uint8_t sys return mavlink_msg_mission_write_partial_list_pack(system_id, component_id, msg, mission_write_partial_list->target_system, mission_write_partial_list->target_component, mission_write_partial_list->start_index, mission_write_partial_list->end_index); } +/** + * @brief Encode a mission_write_partial_list struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param mission_write_partial_list C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_write_partial_list_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_mission_write_partial_list_t* mission_write_partial_list) +{ + return mavlink_msg_mission_write_partial_list_pack_chan(system_id, component_id, chan, msg, mission_write_partial_list->target_system, mission_write_partial_list->target_component, mission_write_partial_list->start_index, mission_write_partial_list->end_index); +} + /** * @brief Send a mission_write_partial_list message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_named_value_float.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_named_value_float.h index a9d28a3d05..fbf4f75c95 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_named_value_float.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_named_value_float.h @@ -67,7 +67,7 @@ static inline uint16_t mavlink_msg_named_value_float_pack(uint8_t system_id, uin * @brief Pack a named_value_float message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param name Name of the debug variable @@ -101,7 +101,7 @@ static inline uint16_t mavlink_msg_named_value_float_pack_chan(uint8_t system_id } /** - * @brief Encode a named_value_float struct into a message + * @brief Encode a named_value_float struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -113,6 +113,20 @@ static inline uint16_t mavlink_msg_named_value_float_encode(uint8_t system_id, u return mavlink_msg_named_value_float_pack(system_id, component_id, msg, named_value_float->time_boot_ms, named_value_float->name, named_value_float->value); } +/** + * @brief Encode a named_value_float struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param named_value_float C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_named_value_float_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_named_value_float_t* named_value_float) +{ + return mavlink_msg_named_value_float_pack_chan(system_id, component_id, chan, msg, named_value_float->time_boot_ms, named_value_float->name, named_value_float->value); +} + /** * @brief Send a named_value_float message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_named_value_int.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_named_value_int.h index ea53ea888d..052f247935 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_named_value_int.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_named_value_int.h @@ -67,7 +67,7 @@ static inline uint16_t mavlink_msg_named_value_int_pack(uint8_t system_id, uint8 * @brief Pack a named_value_int message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param name Name of the debug variable @@ -101,7 +101,7 @@ static inline uint16_t mavlink_msg_named_value_int_pack_chan(uint8_t system_id, } /** - * @brief Encode a named_value_int struct into a message + * @brief Encode a named_value_int struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -113,6 +113,20 @@ static inline uint16_t mavlink_msg_named_value_int_encode(uint8_t system_id, uin return mavlink_msg_named_value_int_pack(system_id, component_id, msg, named_value_int->time_boot_ms, named_value_int->name, named_value_int->value); } +/** + * @brief Encode a named_value_int struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param named_value_int C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_named_value_int_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_named_value_int_t* named_value_int) +{ + return mavlink_msg_named_value_int_pack_chan(system_id, component_id, chan, msg, named_value_int->time_boot_ms, named_value_int->name, named_value_int->value); +} + /** * @brief Send a named_value_int message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_nav_controller_output.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_nav_controller_output.h index e9fa0f5220..e95c144de7 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_nav_controller_output.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_nav_controller_output.h @@ -94,7 +94,7 @@ static inline uint16_t mavlink_msg_nav_controller_output_pack(uint8_t system_id, * @brief Pack a nav_controller_output message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param nav_roll Current desired roll in degrees * @param nav_pitch Current desired pitch in degrees @@ -145,7 +145,7 @@ static inline uint16_t mavlink_msg_nav_controller_output_pack_chan(uint8_t syste } /** - * @brief Encode a nav_controller_output struct into a message + * @brief Encode a nav_controller_output struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -157,6 +157,20 @@ static inline uint16_t mavlink_msg_nav_controller_output_encode(uint8_t system_i return mavlink_msg_nav_controller_output_pack(system_id, component_id, msg, nav_controller_output->nav_roll, nav_controller_output->nav_pitch, nav_controller_output->nav_bearing, nav_controller_output->target_bearing, nav_controller_output->wp_dist, nav_controller_output->alt_error, nav_controller_output->aspd_error, nav_controller_output->xtrack_error); } +/** + * @brief Encode a nav_controller_output struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param nav_controller_output C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_nav_controller_output_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_nav_controller_output_t* nav_controller_output) +{ + return mavlink_msg_nav_controller_output_pack_chan(system_id, component_id, chan, msg, nav_controller_output->nav_roll, nav_controller_output->nav_pitch, nav_controller_output->nav_bearing, nav_controller_output->target_bearing, nav_controller_output->wp_dist, nav_controller_output->alt_error, nav_controller_output->aspd_error, nav_controller_output->xtrack_error); +} + /** * @brief Send a nav_controller_output message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_omnidirectional_flow.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_omnidirectional_flow.h index c0e765a444..4debb6e663 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_omnidirectional_flow.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_omnidirectional_flow.h @@ -83,7 +83,7 @@ static inline uint16_t mavlink_msg_omnidirectional_flow_pack(uint8_t system_id, * @brief Pack a omnidirectional_flow message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (microseconds, synced to UNIX time or since system boot) * @param sensor_id Sensor ID @@ -126,7 +126,7 @@ static inline uint16_t mavlink_msg_omnidirectional_flow_pack_chan(uint8_t system } /** - * @brief Encode a omnidirectional_flow struct into a message + * @brief Encode a omnidirectional_flow struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -138,6 +138,20 @@ static inline uint16_t mavlink_msg_omnidirectional_flow_encode(uint8_t system_id return mavlink_msg_omnidirectional_flow_pack(system_id, component_id, msg, omnidirectional_flow->time_usec, omnidirectional_flow->sensor_id, omnidirectional_flow->left, omnidirectional_flow->right, omnidirectional_flow->quality, omnidirectional_flow->front_distance_m); } +/** + * @brief Encode a omnidirectional_flow struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param omnidirectional_flow C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_omnidirectional_flow_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_omnidirectional_flow_t* omnidirectional_flow) +{ + return mavlink_msg_omnidirectional_flow_pack_chan(system_id, component_id, chan, msg, omnidirectional_flow->time_usec, omnidirectional_flow->sensor_id, omnidirectional_flow->left, omnidirectional_flow->right, omnidirectional_flow->quality, omnidirectional_flow->front_distance_m); +} + /** * @brief Send a omnidirectional_flow message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_optical_flow.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_optical_flow.h index e01dc5e79c..cf6db9147e 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_optical_flow.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_optical_flow.h @@ -8,8 +8,8 @@ typedef struct __mavlink_optical_flow_t float flow_comp_m_x; ///< Flow in meters in x-sensor direction, angular-speed compensated float flow_comp_m_y; ///< Flow in meters in y-sensor direction, angular-speed compensated float ground_distance; ///< Ground distance in meters. Positive value: distance known. Negative value: Unknown distance - int16_t flow_x; ///< Flow in pixels in x-sensor direction - int16_t flow_y; ///< Flow in pixels in y-sensor direction + int16_t flow_x; ///< Flow in pixels * 10 in x-sensor direction (dezi-pixels) + int16_t flow_y; ///< Flow in pixels * 10 in y-sensor direction (dezi-pixels) uint8_t sensor_id; ///< Sensor ID uint8_t quality; ///< Optical flow quality / confidence. 0: bad, 255: maximum quality } mavlink_optical_flow_t; @@ -45,8 +45,8 @@ typedef struct __mavlink_optical_flow_t * * @param time_usec Timestamp (UNIX) * @param sensor_id Sensor ID - * @param flow_x Flow in pixels in x-sensor direction - * @param flow_y Flow in pixels in y-sensor direction + * @param flow_x Flow in pixels * 10 in x-sensor direction (dezi-pixels) + * @param flow_y Flow in pixels * 10 in y-sensor direction (dezi-pixels) * @param flow_comp_m_x Flow in meters in x-sensor direction, angular-speed compensated * @param flow_comp_m_y Flow in meters in y-sensor direction, angular-speed compensated * @param quality Optical flow quality / confidence. 0: bad, 255: maximum quality @@ -94,12 +94,12 @@ static inline uint16_t mavlink_msg_optical_flow_pack(uint8_t system_id, uint8_t * @brief Pack a optical_flow message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (UNIX) * @param sensor_id Sensor ID - * @param flow_x Flow in pixels in x-sensor direction - * @param flow_y Flow in pixels in y-sensor direction + * @param flow_x Flow in pixels * 10 in x-sensor direction (dezi-pixels) + * @param flow_y Flow in pixels * 10 in y-sensor direction (dezi-pixels) * @param flow_comp_m_x Flow in meters in x-sensor direction, angular-speed compensated * @param flow_comp_m_y Flow in meters in y-sensor direction, angular-speed compensated * @param quality Optical flow quality / confidence. 0: bad, 255: maximum quality @@ -145,7 +145,7 @@ static inline uint16_t mavlink_msg_optical_flow_pack_chan(uint8_t system_id, uin } /** - * @brief Encode a optical_flow struct into a message + * @brief Encode a optical_flow struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -157,14 +157,28 @@ static inline uint16_t mavlink_msg_optical_flow_encode(uint8_t system_id, uint8_ return mavlink_msg_optical_flow_pack(system_id, component_id, msg, optical_flow->time_usec, optical_flow->sensor_id, optical_flow->flow_x, optical_flow->flow_y, optical_flow->flow_comp_m_x, optical_flow->flow_comp_m_y, optical_flow->quality, optical_flow->ground_distance); } +/** + * @brief Encode a optical_flow struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param optical_flow C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_optical_flow_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_optical_flow_t* optical_flow) +{ + return mavlink_msg_optical_flow_pack_chan(system_id, component_id, chan, msg, optical_flow->time_usec, optical_flow->sensor_id, optical_flow->flow_x, optical_flow->flow_y, optical_flow->flow_comp_m_x, optical_flow->flow_comp_m_y, optical_flow->quality, optical_flow->ground_distance); +} + /** * @brief Send a optical_flow message * @param chan MAVLink channel to send the message * * @param time_usec Timestamp (UNIX) * @param sensor_id Sensor ID - * @param flow_x Flow in pixels in x-sensor direction - * @param flow_y Flow in pixels in y-sensor direction + * @param flow_x Flow in pixels * 10 in x-sensor direction (dezi-pixels) + * @param flow_y Flow in pixels * 10 in y-sensor direction (dezi-pixels) * @param flow_comp_m_x Flow in meters in x-sensor direction, angular-speed compensated * @param flow_comp_m_y Flow in meters in y-sensor direction, angular-speed compensated * @param quality Optical flow quality / confidence. 0: bad, 255: maximum quality @@ -237,7 +251,7 @@ static inline uint8_t mavlink_msg_optical_flow_get_sensor_id(const mavlink_messa /** * @brief Get field flow_x from optical_flow message * - * @return Flow in pixels in x-sensor direction + * @return Flow in pixels * 10 in x-sensor direction (dezi-pixels) */ static inline int16_t mavlink_msg_optical_flow_get_flow_x(const mavlink_message_t* msg) { @@ -247,7 +261,7 @@ static inline int16_t mavlink_msg_optical_flow_get_flow_x(const mavlink_message_ /** * @brief Get field flow_y from optical_flow message * - * @return Flow in pixels in y-sensor direction + * @return Flow in pixels * 10 in y-sensor direction (dezi-pixels) */ static inline int16_t mavlink_msg_optical_flow_get_flow_y(const mavlink_message_t* msg) { diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_request_list.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_request_list.h index da61181b2c..39e0072741 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_request_list.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_request_list.h @@ -64,7 +64,7 @@ static inline uint16_t mavlink_msg_param_request_list_pack(uint8_t system_id, ui * @brief Pack a param_request_list message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -97,7 +97,7 @@ static inline uint16_t mavlink_msg_param_request_list_pack_chan(uint8_t system_i } /** - * @brief Encode a param_request_list struct into a message + * @brief Encode a param_request_list struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -109,6 +109,20 @@ static inline uint16_t mavlink_msg_param_request_list_encode(uint8_t system_id, return mavlink_msg_param_request_list_pack(system_id, component_id, msg, param_request_list->target_system, param_request_list->target_component); } +/** + * @brief Encode a param_request_list struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param param_request_list C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_param_request_list_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_param_request_list_t* param_request_list) +{ + return mavlink_msg_param_request_list_pack_chan(system_id, component_id, chan, msg, param_request_list->target_system, param_request_list->target_component); +} + /** * @brief Send a param_request_list message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_request_read.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_request_read.h index 6b15680260..5d9113114b 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_request_read.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_request_read.h @@ -72,7 +72,7 @@ static inline uint16_t mavlink_msg_param_request_read_pack(uint8_t system_id, ui * @brief Pack a param_request_read message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -109,7 +109,7 @@ static inline uint16_t mavlink_msg_param_request_read_pack_chan(uint8_t system_i } /** - * @brief Encode a param_request_read struct into a message + * @brief Encode a param_request_read struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -121,6 +121,20 @@ static inline uint16_t mavlink_msg_param_request_read_encode(uint8_t system_id, return mavlink_msg_param_request_read_pack(system_id, component_id, msg, param_request_read->target_system, param_request_read->target_component, param_request_read->param_id, param_request_read->param_index); } +/** + * @brief Encode a param_request_read struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param param_request_read C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_param_request_read_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_param_request_read_t* param_request_read) +{ + return mavlink_msg_param_request_read_pack_chan(system_id, component_id, chan, msg, param_request_read->target_system, param_request_read->target_component, param_request_read->param_id, param_request_read->param_index); +} + /** * @brief Send a param_request_read message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_set.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_set.h index 66b0f6629b..1bd1f00596 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_set.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_set.h @@ -77,7 +77,7 @@ static inline uint16_t mavlink_msg_param_set_pack(uint8_t system_id, uint8_t com * @brief Pack a param_set message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -117,7 +117,7 @@ static inline uint16_t mavlink_msg_param_set_pack_chan(uint8_t system_id, uint8_ } /** - * @brief Encode a param_set struct into a message + * @brief Encode a param_set struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -129,6 +129,20 @@ static inline uint16_t mavlink_msg_param_set_encode(uint8_t system_id, uint8_t c return mavlink_msg_param_set_pack(system_id, component_id, msg, param_set->target_system, param_set->target_component, param_set->param_id, param_set->param_value, param_set->param_type); } +/** + * @brief Encode a param_set struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param param_set C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_param_set_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_param_set_t* param_set) +{ + return mavlink_msg_param_set_pack_chan(system_id, component_id, chan, msg, param_set->target_system, param_set->target_component, param_set->param_id, param_set->param_value, param_set->param_type); +} + /** * @brief Send a param_set message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_value.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_value.h index 5991393746..17c759811f 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_value.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_param_value.h @@ -77,7 +77,7 @@ static inline uint16_t mavlink_msg_param_value_pack(uint8_t system_id, uint8_t c * @brief Pack a param_value message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param param_id Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string * @param param_value Onboard parameter value @@ -117,7 +117,7 @@ static inline uint16_t mavlink_msg_param_value_pack_chan(uint8_t system_id, uint } /** - * @brief Encode a param_value struct into a message + * @brief Encode a param_value struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -129,6 +129,20 @@ static inline uint16_t mavlink_msg_param_value_encode(uint8_t system_id, uint8_t return mavlink_msg_param_value_pack(system_id, component_id, msg, param_value->param_id, param_value->param_value, param_value->param_type, param_value->param_count, param_value->param_index); } +/** + * @brief Encode a param_value struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param param_value C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_param_value_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_param_value_t* param_value) +{ + return mavlink_msg_param_value_pack_chan(system_id, component_id, chan, msg, param_value->param_id, param_value->param_value, param_value->param_type, param_value->param_count, param_value->param_index); +} + /** * @brief Send a param_value message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_ping.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_ping.h index 5a4c50907d..0c68ca1765 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_ping.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_ping.h @@ -74,7 +74,7 @@ static inline uint16_t mavlink_msg_ping_pack(uint8_t system_id, uint8_t componen * @brief Pack a ping message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Unix timestamp in microseconds * @param seq PING sequence @@ -113,7 +113,7 @@ static inline uint16_t mavlink_msg_ping_pack_chan(uint8_t system_id, uint8_t com } /** - * @brief Encode a ping struct into a message + * @brief Encode a ping struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -125,6 +125,20 @@ static inline uint16_t mavlink_msg_ping_encode(uint8_t system_id, uint8_t compon return mavlink_msg_ping_pack(system_id, component_id, msg, ping->time_usec, ping->seq, ping->target_system, ping->target_component); } +/** + * @brief Encode a ping struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param ping C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_ping_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_ping_t* ping) +{ + return mavlink_msg_ping_pack_chan(system_id, component_id, chan, msg, ping->time_usec, ping->seq, ping->target_system, ping->target_component); +} + /** * @brief Send a ping message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_radio_status.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_radio_status.h index 06e6a55425..fceb7d1688 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_radio_status.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_radio_status.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_radio_status_pack(uint8_t system_id, uint8_t * @brief Pack a radio_status message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param rssi local signal strength * @param remrssi remote signal strength @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_radio_status_pack_chan(uint8_t system_id, uin } /** - * @brief Encode a radio_status struct into a message + * @brief Encode a radio_status struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_radio_status_encode(uint8_t system_id, uint8_ return mavlink_msg_radio_status_pack(system_id, component_id, msg, radio_status->rssi, radio_status->remrssi, radio_status->txbuf, radio_status->noise, radio_status->remnoise, radio_status->rxerrors, radio_status->fixed); } +/** + * @brief Encode a radio_status struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param radio_status C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_radio_status_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_radio_status_t* radio_status) +{ + return mavlink_msg_radio_status_pack_chan(system_id, component_id, chan, msg, radio_status->rssi, radio_status->remrssi, radio_status->txbuf, radio_status->noise, radio_status->remnoise, radio_status->rxerrors, radio_status->fixed); +} + /** * @brief Send a radio_status message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_raw_imu.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_raw_imu.h index ce88636473..62a9b6eeae 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_raw_imu.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_raw_imu.h @@ -104,7 +104,7 @@ static inline uint16_t mavlink_msg_raw_imu_pack(uint8_t system_id, uint8_t compo * @brief Pack a raw_imu message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) * @param xacc X acceleration (raw) @@ -161,7 +161,7 @@ static inline uint16_t mavlink_msg_raw_imu_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a raw_imu struct into a message + * @brief Encode a raw_imu struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -173,6 +173,20 @@ static inline uint16_t mavlink_msg_raw_imu_encode(uint8_t system_id, uint8_t com return mavlink_msg_raw_imu_pack(system_id, component_id, msg, raw_imu->time_usec, raw_imu->xacc, raw_imu->yacc, raw_imu->zacc, raw_imu->xgyro, raw_imu->ygyro, raw_imu->zgyro, raw_imu->xmag, raw_imu->ymag, raw_imu->zmag); } +/** + * @brief Encode a raw_imu struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param raw_imu C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_raw_imu_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_raw_imu_t* raw_imu) +{ + return mavlink_msg_raw_imu_pack_chan(system_id, component_id, chan, msg, raw_imu->time_usec, raw_imu->xacc, raw_imu->yacc, raw_imu->zacc, raw_imu->xgyro, raw_imu->ygyro, raw_imu->zgyro, raw_imu->xmag, raw_imu->ymag, raw_imu->zmag); +} + /** * @brief Send a raw_imu message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_raw_pressure.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_raw_pressure.h index dcc2cbe063..82c5fad4ab 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_raw_pressure.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_raw_pressure.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_raw_pressure_pack(uint8_t system_id, uint8_t * @brief Pack a raw_pressure message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) * @param press_abs Absolute pressure (raw) @@ -121,7 +121,7 @@ static inline uint16_t mavlink_msg_raw_pressure_pack_chan(uint8_t system_id, uin } /** - * @brief Encode a raw_pressure struct into a message + * @brief Encode a raw_pressure struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -133,6 +133,20 @@ static inline uint16_t mavlink_msg_raw_pressure_encode(uint8_t system_id, uint8_ return mavlink_msg_raw_pressure_pack(system_id, component_id, msg, raw_pressure->time_usec, raw_pressure->press_abs, raw_pressure->press_diff1, raw_pressure->press_diff2, raw_pressure->temperature); } +/** + * @brief Encode a raw_pressure struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param raw_pressure C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_raw_pressure_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_raw_pressure_t* raw_pressure) +{ + return mavlink_msg_raw_pressure_pack_chan(system_id, component_id, chan, msg, raw_pressure->time_usec, raw_pressure->press_abs, raw_pressure->press_diff1, raw_pressure->press_diff2, raw_pressure->temperature); +} + /** * @brief Send a raw_pressure message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_rc_channels_override.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_rc_channels_override.h index 9854a190ce..0d8a1514b1 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_rc_channels_override.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_rc_channels_override.h @@ -4,14 +4,14 @@ typedef struct __mavlink_rc_channels_override_t { - uint16_t chan1_raw; ///< RC channel 1 value, in microseconds - uint16_t chan2_raw; ///< RC channel 2 value, in microseconds - uint16_t chan3_raw; ///< RC channel 3 value, in microseconds - uint16_t chan4_raw; ///< RC channel 4 value, in microseconds - uint16_t chan5_raw; ///< RC channel 5 value, in microseconds - uint16_t chan6_raw; ///< RC channel 6 value, in microseconds - uint16_t chan7_raw; ///< RC channel 7 value, in microseconds - uint16_t chan8_raw; ///< RC channel 8 value, in microseconds + uint16_t chan1_raw; ///< RC channel 1 value, in microseconds. A value of UINT16_MAX means to ignore this field. + uint16_t chan2_raw; ///< RC channel 2 value, in microseconds. A value of UINT16_MAX means to ignore this field. + uint16_t chan3_raw; ///< RC channel 3 value, in microseconds. A value of UINT16_MAX means to ignore this field. + uint16_t chan4_raw; ///< RC channel 4 value, in microseconds. A value of UINT16_MAX means to ignore this field. + uint16_t chan5_raw; ///< RC channel 5 value, in microseconds. A value of UINT16_MAX means to ignore this field. + uint16_t chan6_raw; ///< RC channel 6 value, in microseconds. A value of UINT16_MAX means to ignore this field. + uint16_t chan7_raw; ///< RC channel 7 value, in microseconds. A value of UINT16_MAX means to ignore this field. + uint16_t chan8_raw; ///< RC channel 8 value, in microseconds. A value of UINT16_MAX means to ignore this field. uint8_t target_system; ///< System ID uint8_t target_component; ///< Component ID } mavlink_rc_channels_override_t; @@ -49,14 +49,14 @@ typedef struct __mavlink_rc_channels_override_t * * @param target_system System ID * @param target_component Component ID - * @param chan1_raw RC channel 1 value, in microseconds - * @param chan2_raw RC channel 2 value, in microseconds - * @param chan3_raw RC channel 3 value, in microseconds - * @param chan4_raw RC channel 4 value, in microseconds - * @param chan5_raw RC channel 5 value, in microseconds - * @param chan6_raw RC channel 6 value, in microseconds - * @param chan7_raw RC channel 7 value, in microseconds - * @param chan8_raw RC channel 8 value, in microseconds + * @param chan1_raw RC channel 1 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan2_raw RC channel 2 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan3_raw RC channel 3 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan4_raw RC channel 4 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan5_raw RC channel 5 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan6_raw RC channel 6 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan7_raw RC channel 7 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan8_raw RC channel 8 value, in microseconds. A value of UINT16_MAX means to ignore this field. * @return length of the message in bytes (excluding serial stream start sign) */ static inline uint16_t mavlink_msg_rc_channels_override_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, @@ -104,18 +104,18 @@ static inline uint16_t mavlink_msg_rc_channels_override_pack(uint8_t system_id, * @brief Pack a rc_channels_override message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID - * @param chan1_raw RC channel 1 value, in microseconds - * @param chan2_raw RC channel 2 value, in microseconds - * @param chan3_raw RC channel 3 value, in microseconds - * @param chan4_raw RC channel 4 value, in microseconds - * @param chan5_raw RC channel 5 value, in microseconds - * @param chan6_raw RC channel 6 value, in microseconds - * @param chan7_raw RC channel 7 value, in microseconds - * @param chan8_raw RC channel 8 value, in microseconds + * @param chan1_raw RC channel 1 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan2_raw RC channel 2 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan3_raw RC channel 3 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan4_raw RC channel 4 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan5_raw RC channel 5 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan6_raw RC channel 6 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan7_raw RC channel 7 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan8_raw RC channel 8 value, in microseconds. A value of UINT16_MAX means to ignore this field. * @return length of the message in bytes (excluding serial stream start sign) */ static inline uint16_t mavlink_msg_rc_channels_override_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, @@ -161,7 +161,7 @@ static inline uint16_t mavlink_msg_rc_channels_override_pack_chan(uint8_t system } /** - * @brief Encode a rc_channels_override struct into a message + * @brief Encode a rc_channels_override struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -173,20 +173,34 @@ static inline uint16_t mavlink_msg_rc_channels_override_encode(uint8_t system_id return mavlink_msg_rc_channels_override_pack(system_id, component_id, msg, rc_channels_override->target_system, rc_channels_override->target_component, rc_channels_override->chan1_raw, rc_channels_override->chan2_raw, rc_channels_override->chan3_raw, rc_channels_override->chan4_raw, rc_channels_override->chan5_raw, rc_channels_override->chan6_raw, rc_channels_override->chan7_raw, rc_channels_override->chan8_raw); } +/** + * @brief Encode a rc_channels_override struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param rc_channels_override C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_rc_channels_override_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_rc_channels_override_t* rc_channels_override) +{ + return mavlink_msg_rc_channels_override_pack_chan(system_id, component_id, chan, msg, rc_channels_override->target_system, rc_channels_override->target_component, rc_channels_override->chan1_raw, rc_channels_override->chan2_raw, rc_channels_override->chan3_raw, rc_channels_override->chan4_raw, rc_channels_override->chan5_raw, rc_channels_override->chan6_raw, rc_channels_override->chan7_raw, rc_channels_override->chan8_raw); +} + /** * @brief Send a rc_channels_override message * @param chan MAVLink channel to send the message * * @param target_system System ID * @param target_component Component ID - * @param chan1_raw RC channel 1 value, in microseconds - * @param chan2_raw RC channel 2 value, in microseconds - * @param chan3_raw RC channel 3 value, in microseconds - * @param chan4_raw RC channel 4 value, in microseconds - * @param chan5_raw RC channel 5 value, in microseconds - * @param chan6_raw RC channel 6 value, in microseconds - * @param chan7_raw RC channel 7 value, in microseconds - * @param chan8_raw RC channel 8 value, in microseconds + * @param chan1_raw RC channel 1 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan2_raw RC channel 2 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan3_raw RC channel 3 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan4_raw RC channel 4 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan5_raw RC channel 5 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan6_raw RC channel 6 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan7_raw RC channel 7 value, in microseconds. A value of UINT16_MAX means to ignore this field. + * @param chan8_raw RC channel 8 value, in microseconds. A value of UINT16_MAX means to ignore this field. */ #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS @@ -259,7 +273,7 @@ static inline uint8_t mavlink_msg_rc_channels_override_get_target_component(cons /** * @brief Get field chan1_raw from rc_channels_override message * - * @return RC channel 1 value, in microseconds + * @return RC channel 1 value, in microseconds. A value of UINT16_MAX means to ignore this field. */ static inline uint16_t mavlink_msg_rc_channels_override_get_chan1_raw(const mavlink_message_t* msg) { @@ -269,7 +283,7 @@ static inline uint16_t mavlink_msg_rc_channels_override_get_chan1_raw(const mavl /** * @brief Get field chan2_raw from rc_channels_override message * - * @return RC channel 2 value, in microseconds + * @return RC channel 2 value, in microseconds. A value of UINT16_MAX means to ignore this field. */ static inline uint16_t mavlink_msg_rc_channels_override_get_chan2_raw(const mavlink_message_t* msg) { @@ -279,7 +293,7 @@ static inline uint16_t mavlink_msg_rc_channels_override_get_chan2_raw(const mavl /** * @brief Get field chan3_raw from rc_channels_override message * - * @return RC channel 3 value, in microseconds + * @return RC channel 3 value, in microseconds. A value of UINT16_MAX means to ignore this field. */ static inline uint16_t mavlink_msg_rc_channels_override_get_chan3_raw(const mavlink_message_t* msg) { @@ -289,7 +303,7 @@ static inline uint16_t mavlink_msg_rc_channels_override_get_chan3_raw(const mavl /** * @brief Get field chan4_raw from rc_channels_override message * - * @return RC channel 4 value, in microseconds + * @return RC channel 4 value, in microseconds. A value of UINT16_MAX means to ignore this field. */ static inline uint16_t mavlink_msg_rc_channels_override_get_chan4_raw(const mavlink_message_t* msg) { @@ -299,7 +313,7 @@ static inline uint16_t mavlink_msg_rc_channels_override_get_chan4_raw(const mavl /** * @brief Get field chan5_raw from rc_channels_override message * - * @return RC channel 5 value, in microseconds + * @return RC channel 5 value, in microseconds. A value of UINT16_MAX means to ignore this field. */ static inline uint16_t mavlink_msg_rc_channels_override_get_chan5_raw(const mavlink_message_t* msg) { @@ -309,7 +323,7 @@ static inline uint16_t mavlink_msg_rc_channels_override_get_chan5_raw(const mavl /** * @brief Get field chan6_raw from rc_channels_override message * - * @return RC channel 6 value, in microseconds + * @return RC channel 6 value, in microseconds. A value of UINT16_MAX means to ignore this field. */ static inline uint16_t mavlink_msg_rc_channels_override_get_chan6_raw(const mavlink_message_t* msg) { @@ -319,7 +333,7 @@ static inline uint16_t mavlink_msg_rc_channels_override_get_chan6_raw(const mavl /** * @brief Get field chan7_raw from rc_channels_override message * - * @return RC channel 7 value, in microseconds + * @return RC channel 7 value, in microseconds. A value of UINT16_MAX means to ignore this field. */ static inline uint16_t mavlink_msg_rc_channels_override_get_chan7_raw(const mavlink_message_t* msg) { @@ -329,7 +343,7 @@ static inline uint16_t mavlink_msg_rc_channels_override_get_chan7_raw(const mavl /** * @brief Get field chan8_raw from rc_channels_override message * - * @return RC channel 8 value, in microseconds + * @return RC channel 8 value, in microseconds. A value of UINT16_MAX means to ignore this field. */ static inline uint16_t mavlink_msg_rc_channels_override_get_chan8_raw(const mavlink_message_t* msg) { diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_rc_channels_raw.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_rc_channels_raw.h index 4c1315bed2..3c0aed0202 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_rc_channels_raw.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_rc_channels_raw.h @@ -5,14 +5,14 @@ typedef struct __mavlink_rc_channels_raw_t { uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) - uint16_t chan1_raw; ///< RC channel 1 value, in microseconds. A value of 65535 implies the channel is unused. - uint16_t chan2_raw; ///< RC channel 2 value, in microseconds. A value of 65535 implies the channel is unused. - uint16_t chan3_raw; ///< RC channel 3 value, in microseconds. A value of 65535 implies the channel is unused. - uint16_t chan4_raw; ///< RC channel 4 value, in microseconds. A value of 65535 implies the channel is unused. - uint16_t chan5_raw; ///< RC channel 5 value, in microseconds. A value of 65535 implies the channel is unused. - uint16_t chan6_raw; ///< RC channel 6 value, in microseconds. A value of 65535 implies the channel is unused. - uint16_t chan7_raw; ///< RC channel 7 value, in microseconds. A value of 65535 implies the channel is unused. - uint16_t chan8_raw; ///< RC channel 8 value, in microseconds. A value of 65535 implies the channel is unused. + uint16_t chan1_raw; ///< RC channel 1 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + uint16_t chan2_raw; ///< RC channel 2 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + uint16_t chan3_raw; ///< RC channel 3 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + uint16_t chan4_raw; ///< RC channel 4 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + uint16_t chan5_raw; ///< RC channel 5 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + uint16_t chan6_raw; ///< RC channel 6 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + uint16_t chan7_raw; ///< RC channel 7 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + uint16_t chan8_raw; ///< RC channel 8 value, in microseconds. A value of UINT16_MAX implies the channel is unused. uint8_t port; ///< Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows for more than 8 servos. uint8_t rssi; ///< Receive signal strength indicator, 0: 0%, 100: 100%, 255: invalid/unknown. } mavlink_rc_channels_raw_t; @@ -51,14 +51,14 @@ typedef struct __mavlink_rc_channels_raw_t * * @param time_boot_ms Timestamp (milliseconds since system boot) * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows for more than 8 servos. - * @param chan1_raw RC channel 1 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan2_raw RC channel 2 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan3_raw RC channel 3 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan4_raw RC channel 4 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan5_raw RC channel 5 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan6_raw RC channel 6 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan7_raw RC channel 7 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan8_raw RC channel 8 value, in microseconds. A value of 65535 implies the channel is unused. + * @param chan1_raw RC channel 1 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan2_raw RC channel 2 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan3_raw RC channel 3 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan4_raw RC channel 4 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan5_raw RC channel 5 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan6_raw RC channel 6 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan7_raw RC channel 7 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan8_raw RC channel 8 value, in microseconds. A value of UINT16_MAX implies the channel is unused. * @param rssi Receive signal strength indicator, 0: 0%, 100: 100%, 255: invalid/unknown. * @return length of the message in bytes (excluding serial stream start sign) */ @@ -109,18 +109,18 @@ static inline uint16_t mavlink_msg_rc_channels_raw_pack(uint8_t system_id, uint8 * @brief Pack a rc_channels_raw message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows for more than 8 servos. - * @param chan1_raw RC channel 1 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan2_raw RC channel 2 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan3_raw RC channel 3 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan4_raw RC channel 4 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan5_raw RC channel 5 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan6_raw RC channel 6 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan7_raw RC channel 7 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan8_raw RC channel 8 value, in microseconds. A value of 65535 implies the channel is unused. + * @param chan1_raw RC channel 1 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan2_raw RC channel 2 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan3_raw RC channel 3 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan4_raw RC channel 4 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan5_raw RC channel 5 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan6_raw RC channel 6 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan7_raw RC channel 7 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan8_raw RC channel 8 value, in microseconds. A value of UINT16_MAX implies the channel is unused. * @param rssi Receive signal strength indicator, 0: 0%, 100: 100%, 255: invalid/unknown. * @return length of the message in bytes (excluding serial stream start sign) */ @@ -169,7 +169,7 @@ static inline uint16_t mavlink_msg_rc_channels_raw_pack_chan(uint8_t system_id, } /** - * @brief Encode a rc_channels_raw struct into a message + * @brief Encode a rc_channels_raw struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -181,20 +181,34 @@ static inline uint16_t mavlink_msg_rc_channels_raw_encode(uint8_t system_id, uin return mavlink_msg_rc_channels_raw_pack(system_id, component_id, msg, rc_channels_raw->time_boot_ms, rc_channels_raw->port, rc_channels_raw->chan1_raw, rc_channels_raw->chan2_raw, rc_channels_raw->chan3_raw, rc_channels_raw->chan4_raw, rc_channels_raw->chan5_raw, rc_channels_raw->chan6_raw, rc_channels_raw->chan7_raw, rc_channels_raw->chan8_raw, rc_channels_raw->rssi); } +/** + * @brief Encode a rc_channels_raw struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param rc_channels_raw C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_rc_channels_raw_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_rc_channels_raw_t* rc_channels_raw) +{ + return mavlink_msg_rc_channels_raw_pack_chan(system_id, component_id, chan, msg, rc_channels_raw->time_boot_ms, rc_channels_raw->port, rc_channels_raw->chan1_raw, rc_channels_raw->chan2_raw, rc_channels_raw->chan3_raw, rc_channels_raw->chan4_raw, rc_channels_raw->chan5_raw, rc_channels_raw->chan6_raw, rc_channels_raw->chan7_raw, rc_channels_raw->chan8_raw, rc_channels_raw->rssi); +} + /** * @brief Send a rc_channels_raw message * @param chan MAVLink channel to send the message * * @param time_boot_ms Timestamp (milliseconds since system boot) * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows for more than 8 servos. - * @param chan1_raw RC channel 1 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan2_raw RC channel 2 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan3_raw RC channel 3 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan4_raw RC channel 4 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan5_raw RC channel 5 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan6_raw RC channel 6 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan7_raw RC channel 7 value, in microseconds. A value of 65535 implies the channel is unused. - * @param chan8_raw RC channel 8 value, in microseconds. A value of 65535 implies the channel is unused. + * @param chan1_raw RC channel 1 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan2_raw RC channel 2 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan3_raw RC channel 3 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan4_raw RC channel 4 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan5_raw RC channel 5 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan6_raw RC channel 6 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan7_raw RC channel 7 value, in microseconds. A value of UINT16_MAX implies the channel is unused. + * @param chan8_raw RC channel 8 value, in microseconds. A value of UINT16_MAX implies the channel is unused. * @param rssi Receive signal strength indicator, 0: 0%, 100: 100%, 255: invalid/unknown. */ #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS @@ -270,7 +284,7 @@ static inline uint8_t mavlink_msg_rc_channels_raw_get_port(const mavlink_message /** * @brief Get field chan1_raw from rc_channels_raw message * - * @return RC channel 1 value, in microseconds. A value of 65535 implies the channel is unused. + * @return RC channel 1 value, in microseconds. A value of UINT16_MAX implies the channel is unused. */ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan1_raw(const mavlink_message_t* msg) { @@ -280,7 +294,7 @@ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan1_raw(const mavlink_m /** * @brief Get field chan2_raw from rc_channels_raw message * - * @return RC channel 2 value, in microseconds. A value of 65535 implies the channel is unused. + * @return RC channel 2 value, in microseconds. A value of UINT16_MAX implies the channel is unused. */ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan2_raw(const mavlink_message_t* msg) { @@ -290,7 +304,7 @@ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan2_raw(const mavlink_m /** * @brief Get field chan3_raw from rc_channels_raw message * - * @return RC channel 3 value, in microseconds. A value of 65535 implies the channel is unused. + * @return RC channel 3 value, in microseconds. A value of UINT16_MAX implies the channel is unused. */ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan3_raw(const mavlink_message_t* msg) { @@ -300,7 +314,7 @@ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan3_raw(const mavlink_m /** * @brief Get field chan4_raw from rc_channels_raw message * - * @return RC channel 4 value, in microseconds. A value of 65535 implies the channel is unused. + * @return RC channel 4 value, in microseconds. A value of UINT16_MAX implies the channel is unused. */ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan4_raw(const mavlink_message_t* msg) { @@ -310,7 +324,7 @@ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan4_raw(const mavlink_m /** * @brief Get field chan5_raw from rc_channels_raw message * - * @return RC channel 5 value, in microseconds. A value of 65535 implies the channel is unused. + * @return RC channel 5 value, in microseconds. A value of UINT16_MAX implies the channel is unused. */ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan5_raw(const mavlink_message_t* msg) { @@ -320,7 +334,7 @@ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan5_raw(const mavlink_m /** * @brief Get field chan6_raw from rc_channels_raw message * - * @return RC channel 6 value, in microseconds. A value of 65535 implies the channel is unused. + * @return RC channel 6 value, in microseconds. A value of UINT16_MAX implies the channel is unused. */ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan6_raw(const mavlink_message_t* msg) { @@ -330,7 +344,7 @@ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan6_raw(const mavlink_m /** * @brief Get field chan7_raw from rc_channels_raw message * - * @return RC channel 7 value, in microseconds. A value of 65535 implies the channel is unused. + * @return RC channel 7 value, in microseconds. A value of UINT16_MAX implies the channel is unused. */ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan7_raw(const mavlink_message_t* msg) { @@ -340,7 +354,7 @@ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan7_raw(const mavlink_m /** * @brief Get field chan8_raw from rc_channels_raw message * - * @return RC channel 8 value, in microseconds. A value of 65535 implies the channel is unused. + * @return RC channel 8 value, in microseconds. A value of UINT16_MAX implies the channel is unused. */ static inline uint16_t mavlink_msg_rc_channels_raw_get_chan8_raw(const mavlink_message_t* msg) { diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_rc_channels_scaled.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_rc_channels_scaled.h index be6322bcd3..2153ab3928 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_rc_channels_scaled.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_rc_channels_scaled.h @@ -5,14 +5,14 @@ typedef struct __mavlink_rc_channels_scaled_t { uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) - int16_t chan1_scaled; ///< RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - int16_t chan2_scaled; ///< RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - int16_t chan3_scaled; ///< RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - int16_t chan4_scaled; ///< RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - int16_t chan5_scaled; ///< RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - int16_t chan6_scaled; ///< RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - int16_t chan7_scaled; ///< RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - int16_t chan8_scaled; ///< RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. + int16_t chan1_scaled; ///< RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + int16_t chan2_scaled; ///< RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + int16_t chan3_scaled; ///< RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + int16_t chan4_scaled; ///< RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + int16_t chan5_scaled; ///< RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + int16_t chan6_scaled; ///< RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + int16_t chan7_scaled; ///< RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + int16_t chan8_scaled; ///< RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. uint8_t port; ///< Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows for more than 8 servos. uint8_t rssi; ///< Receive signal strength indicator, 0: 0%, 100: 100%, 255: invalid/unknown. } mavlink_rc_channels_scaled_t; @@ -51,14 +51,14 @@ typedef struct __mavlink_rc_channels_scaled_t * * @param time_boot_ms Timestamp (milliseconds since system boot) * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows for more than 8 servos. - * @param chan1_scaled RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan2_scaled RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan3_scaled RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan4_scaled RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan5_scaled RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan6_scaled RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan7_scaled RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan8_scaled RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. + * @param chan1_scaled RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan2_scaled RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan3_scaled RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan4_scaled RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan5_scaled RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan6_scaled RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan7_scaled RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan8_scaled RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. * @param rssi Receive signal strength indicator, 0: 0%, 100: 100%, 255: invalid/unknown. * @return length of the message in bytes (excluding serial stream start sign) */ @@ -109,18 +109,18 @@ static inline uint16_t mavlink_msg_rc_channels_scaled_pack(uint8_t system_id, ui * @brief Pack a rc_channels_scaled message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows for more than 8 servos. - * @param chan1_scaled RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan2_scaled RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan3_scaled RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan4_scaled RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan5_scaled RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan6_scaled RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan7_scaled RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan8_scaled RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. + * @param chan1_scaled RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan2_scaled RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan3_scaled RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan4_scaled RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan5_scaled RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan6_scaled RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan7_scaled RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan8_scaled RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. * @param rssi Receive signal strength indicator, 0: 0%, 100: 100%, 255: invalid/unknown. * @return length of the message in bytes (excluding serial stream start sign) */ @@ -169,7 +169,7 @@ static inline uint16_t mavlink_msg_rc_channels_scaled_pack_chan(uint8_t system_i } /** - * @brief Encode a rc_channels_scaled struct into a message + * @brief Encode a rc_channels_scaled struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -181,20 +181,34 @@ static inline uint16_t mavlink_msg_rc_channels_scaled_encode(uint8_t system_id, return mavlink_msg_rc_channels_scaled_pack(system_id, component_id, msg, rc_channels_scaled->time_boot_ms, rc_channels_scaled->port, rc_channels_scaled->chan1_scaled, rc_channels_scaled->chan2_scaled, rc_channels_scaled->chan3_scaled, rc_channels_scaled->chan4_scaled, rc_channels_scaled->chan5_scaled, rc_channels_scaled->chan6_scaled, rc_channels_scaled->chan7_scaled, rc_channels_scaled->chan8_scaled, rc_channels_scaled->rssi); } +/** + * @brief Encode a rc_channels_scaled struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param rc_channels_scaled C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_rc_channels_scaled_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_rc_channels_scaled_t* rc_channels_scaled) +{ + return mavlink_msg_rc_channels_scaled_pack_chan(system_id, component_id, chan, msg, rc_channels_scaled->time_boot_ms, rc_channels_scaled->port, rc_channels_scaled->chan1_scaled, rc_channels_scaled->chan2_scaled, rc_channels_scaled->chan3_scaled, rc_channels_scaled->chan4_scaled, rc_channels_scaled->chan5_scaled, rc_channels_scaled->chan6_scaled, rc_channels_scaled->chan7_scaled, rc_channels_scaled->chan8_scaled, rc_channels_scaled->rssi); +} + /** * @brief Send a rc_channels_scaled message * @param chan MAVLink channel to send the message * * @param time_boot_ms Timestamp (milliseconds since system boot) * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows for more than 8 servos. - * @param chan1_scaled RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan2_scaled RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan3_scaled RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan4_scaled RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan5_scaled RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan6_scaled RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan7_scaled RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. - * @param chan8_scaled RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. + * @param chan1_scaled RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan2_scaled RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan3_scaled RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan4_scaled RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan5_scaled RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan6_scaled RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan7_scaled RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. + * @param chan8_scaled RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. * @param rssi Receive signal strength indicator, 0: 0%, 100: 100%, 255: invalid/unknown. */ #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS @@ -270,7 +284,7 @@ static inline uint8_t mavlink_msg_rc_channels_scaled_get_port(const mavlink_mess /** * @brief Get field chan1_scaled from rc_channels_scaled message * - * @return RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. + * @return RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. */ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan1_scaled(const mavlink_message_t* msg) { @@ -280,7 +294,7 @@ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan1_scaled(const mavl /** * @brief Get field chan2_scaled from rc_channels_scaled message * - * @return RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. + * @return RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. */ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan2_scaled(const mavlink_message_t* msg) { @@ -290,7 +304,7 @@ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan2_scaled(const mavl /** * @brief Get field chan3_scaled from rc_channels_scaled message * - * @return RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. + * @return RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. */ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan3_scaled(const mavlink_message_t* msg) { @@ -300,7 +314,7 @@ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan3_scaled(const mavl /** * @brief Get field chan4_scaled from rc_channels_scaled message * - * @return RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. + * @return RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. */ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan4_scaled(const mavlink_message_t* msg) { @@ -310,7 +324,7 @@ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan4_scaled(const mavl /** * @brief Get field chan5_scaled from rc_channels_scaled message * - * @return RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. + * @return RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. */ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan5_scaled(const mavlink_message_t* msg) { @@ -320,7 +334,7 @@ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan5_scaled(const mavl /** * @brief Get field chan6_scaled from rc_channels_scaled message * - * @return RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. + * @return RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. */ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan6_scaled(const mavlink_message_t* msg) { @@ -330,7 +344,7 @@ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan6_scaled(const mavl /** * @brief Get field chan7_scaled from rc_channels_scaled message * - * @return RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. + * @return RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. */ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan7_scaled(const mavlink_message_t* msg) { @@ -340,7 +354,7 @@ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan7_scaled(const mavl /** * @brief Get field chan8_scaled from rc_channels_scaled message * - * @return RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) 32767. + * @return RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX. */ static inline int16_t mavlink_msg_rc_channels_scaled_get_chan8_scaled(const mavlink_message_t* msg) { diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_request_data_stream.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_request_data_stream.h index ee21d1fe07..c754ad8761 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_request_data_stream.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_request_data_stream.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_request_data_stream_pack(uint8_t system_id, u * @brief Pack a request_data_stream message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system The target requested to send the message stream. * @param target_component The target requested to send the message stream. @@ -121,7 +121,7 @@ static inline uint16_t mavlink_msg_request_data_stream_pack_chan(uint8_t system_ } /** - * @brief Encode a request_data_stream struct into a message + * @brief Encode a request_data_stream struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -133,6 +133,20 @@ static inline uint16_t mavlink_msg_request_data_stream_encode(uint8_t system_id, return mavlink_msg_request_data_stream_pack(system_id, component_id, msg, request_data_stream->target_system, request_data_stream->target_component, request_data_stream->req_stream_id, request_data_stream->req_message_rate, request_data_stream->start_stop); } +/** + * @brief Encode a request_data_stream struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param request_data_stream C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_request_data_stream_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_request_data_stream_t* request_data_stream) +{ + return mavlink_msg_request_data_stream_pack_chan(system_id, component_id, chan, msg, request_data_stream->target_system, request_data_stream->target_component, request_data_stream->req_stream_id, request_data_stream->req_message_rate, request_data_stream->start_stop); +} + /** * @brief Send a request_data_stream message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_rates_thrust_setpoint.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_rates_thrust_setpoint.h index a7e9df94be..ac3ef4fa9f 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_rates_thrust_setpoint.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_rates_thrust_setpoint.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_roll_pitch_yaw_rates_thrust_setpoint_pack(uin * @brief Pack a roll_pitch_yaw_rates_thrust_setpoint message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp in milliseconds since system boot * @param roll_rate Desired roll rate in radians per second @@ -121,7 +121,7 @@ static inline uint16_t mavlink_msg_roll_pitch_yaw_rates_thrust_setpoint_pack_cha } /** - * @brief Encode a roll_pitch_yaw_rates_thrust_setpoint struct into a message + * @brief Encode a roll_pitch_yaw_rates_thrust_setpoint struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -133,6 +133,20 @@ static inline uint16_t mavlink_msg_roll_pitch_yaw_rates_thrust_setpoint_encode(u return mavlink_msg_roll_pitch_yaw_rates_thrust_setpoint_pack(system_id, component_id, msg, roll_pitch_yaw_rates_thrust_setpoint->time_boot_ms, roll_pitch_yaw_rates_thrust_setpoint->roll_rate, roll_pitch_yaw_rates_thrust_setpoint->pitch_rate, roll_pitch_yaw_rates_thrust_setpoint->yaw_rate, roll_pitch_yaw_rates_thrust_setpoint->thrust); } +/** + * @brief Encode a roll_pitch_yaw_rates_thrust_setpoint struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param roll_pitch_yaw_rates_thrust_setpoint C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_roll_pitch_yaw_rates_thrust_setpoint_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_roll_pitch_yaw_rates_thrust_setpoint_t* roll_pitch_yaw_rates_thrust_setpoint) +{ + return mavlink_msg_roll_pitch_yaw_rates_thrust_setpoint_pack_chan(system_id, component_id, chan, msg, roll_pitch_yaw_rates_thrust_setpoint->time_boot_ms, roll_pitch_yaw_rates_thrust_setpoint->roll_rate, roll_pitch_yaw_rates_thrust_setpoint->pitch_rate, roll_pitch_yaw_rates_thrust_setpoint->yaw_rate, roll_pitch_yaw_rates_thrust_setpoint->thrust); +} + /** * @brief Send a roll_pitch_yaw_rates_thrust_setpoint message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint.h index 517797655c..626477322b 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_pack(uin * @brief Pack a roll_pitch_yaw_speed_thrust_setpoint message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp in milliseconds since system boot * @param roll_speed Desired roll angular speed in rad/s @@ -121,7 +121,7 @@ static inline uint16_t mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_pack_cha } /** - * @brief Encode a roll_pitch_yaw_speed_thrust_setpoint struct into a message + * @brief Encode a roll_pitch_yaw_speed_thrust_setpoint struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -133,6 +133,20 @@ static inline uint16_t mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_encode(u return mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_pack(system_id, component_id, msg, roll_pitch_yaw_speed_thrust_setpoint->time_boot_ms, roll_pitch_yaw_speed_thrust_setpoint->roll_speed, roll_pitch_yaw_speed_thrust_setpoint->pitch_speed, roll_pitch_yaw_speed_thrust_setpoint->yaw_speed, roll_pitch_yaw_speed_thrust_setpoint->thrust); } +/** + * @brief Encode a roll_pitch_yaw_speed_thrust_setpoint struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param roll_pitch_yaw_speed_thrust_setpoint C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_roll_pitch_yaw_speed_thrust_setpoint_t* roll_pitch_yaw_speed_thrust_setpoint) +{ + return mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_pack_chan(system_id, component_id, chan, msg, roll_pitch_yaw_speed_thrust_setpoint->time_boot_ms, roll_pitch_yaw_speed_thrust_setpoint->roll_speed, roll_pitch_yaw_speed_thrust_setpoint->pitch_speed, roll_pitch_yaw_speed_thrust_setpoint->yaw_speed, roll_pitch_yaw_speed_thrust_setpoint->thrust); +} + /** * @brief Send a roll_pitch_yaw_speed_thrust_setpoint message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_thrust_setpoint.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_thrust_setpoint.h index aee036022b..ffcdc547b4 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_thrust_setpoint.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_thrust_setpoint.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_roll_pitch_yaw_thrust_setpoint_pack(uint8_t s * @brief Pack a roll_pitch_yaw_thrust_setpoint message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp in milliseconds since system boot * @param roll Desired roll angle in radians @@ -121,7 +121,7 @@ static inline uint16_t mavlink_msg_roll_pitch_yaw_thrust_setpoint_pack_chan(uint } /** - * @brief Encode a roll_pitch_yaw_thrust_setpoint struct into a message + * @brief Encode a roll_pitch_yaw_thrust_setpoint struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -133,6 +133,20 @@ static inline uint16_t mavlink_msg_roll_pitch_yaw_thrust_setpoint_encode(uint8_t return mavlink_msg_roll_pitch_yaw_thrust_setpoint_pack(system_id, component_id, msg, roll_pitch_yaw_thrust_setpoint->time_boot_ms, roll_pitch_yaw_thrust_setpoint->roll, roll_pitch_yaw_thrust_setpoint->pitch, roll_pitch_yaw_thrust_setpoint->yaw, roll_pitch_yaw_thrust_setpoint->thrust); } +/** + * @brief Encode a roll_pitch_yaw_thrust_setpoint struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param roll_pitch_yaw_thrust_setpoint C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_roll_pitch_yaw_thrust_setpoint_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_roll_pitch_yaw_thrust_setpoint_t* roll_pitch_yaw_thrust_setpoint) +{ + return mavlink_msg_roll_pitch_yaw_thrust_setpoint_pack_chan(system_id, component_id, chan, msg, roll_pitch_yaw_thrust_setpoint->time_boot_ms, roll_pitch_yaw_thrust_setpoint->roll, roll_pitch_yaw_thrust_setpoint->pitch, roll_pitch_yaw_thrust_setpoint->yaw, roll_pitch_yaw_thrust_setpoint->thrust); +} + /** * @brief Send a roll_pitch_yaw_thrust_setpoint message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_safety_allowed_area.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_safety_allowed_area.h index 100fabf16e..fcd54cbb78 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_safety_allowed_area.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_safety_allowed_area.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_safety_allowed_area_pack(uint8_t system_id, u * @brief Pack a safety_allowed_area message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param frame Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down. * @param p1x x position 1 / Latitude 1 @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_safety_allowed_area_pack_chan(uint8_t system_ } /** - * @brief Encode a safety_allowed_area struct into a message + * @brief Encode a safety_allowed_area struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_safety_allowed_area_encode(uint8_t system_id, return mavlink_msg_safety_allowed_area_pack(system_id, component_id, msg, safety_allowed_area->frame, safety_allowed_area->p1x, safety_allowed_area->p1y, safety_allowed_area->p1z, safety_allowed_area->p2x, safety_allowed_area->p2y, safety_allowed_area->p2z); } +/** + * @brief Encode a safety_allowed_area struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param safety_allowed_area C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_safety_allowed_area_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_safety_allowed_area_t* safety_allowed_area) +{ + return mavlink_msg_safety_allowed_area_pack_chan(system_id, component_id, chan, msg, safety_allowed_area->frame, safety_allowed_area->p1x, safety_allowed_area->p1y, safety_allowed_area->p1z, safety_allowed_area->p2x, safety_allowed_area->p2y, safety_allowed_area->p2z); +} + /** * @brief Send a safety_allowed_area message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_safety_set_allowed_area.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_safety_set_allowed_area.h index d365b7aedc..61f6af1554 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_safety_set_allowed_area.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_safety_set_allowed_area.h @@ -99,7 +99,7 @@ static inline uint16_t mavlink_msg_safety_set_allowed_area_pack(uint8_t system_i * @brief Pack a safety_set_allowed_area message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -153,7 +153,7 @@ static inline uint16_t mavlink_msg_safety_set_allowed_area_pack_chan(uint8_t sys } /** - * @brief Encode a safety_set_allowed_area struct into a message + * @brief Encode a safety_set_allowed_area struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -165,6 +165,20 @@ static inline uint16_t mavlink_msg_safety_set_allowed_area_encode(uint8_t system return mavlink_msg_safety_set_allowed_area_pack(system_id, component_id, msg, safety_set_allowed_area->target_system, safety_set_allowed_area->target_component, safety_set_allowed_area->frame, safety_set_allowed_area->p1x, safety_set_allowed_area->p1y, safety_set_allowed_area->p1z, safety_set_allowed_area->p2x, safety_set_allowed_area->p2y, safety_set_allowed_area->p2z); } +/** + * @brief Encode a safety_set_allowed_area struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param safety_set_allowed_area C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_safety_set_allowed_area_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_safety_set_allowed_area_t* safety_set_allowed_area) +{ + return mavlink_msg_safety_set_allowed_area_pack_chan(system_id, component_id, chan, msg, safety_set_allowed_area->target_system, safety_set_allowed_area->target_component, safety_set_allowed_area->frame, safety_set_allowed_area->p1x, safety_set_allowed_area->p1y, safety_set_allowed_area->p1z, safety_set_allowed_area->p2x, safety_set_allowed_area->p2y, safety_set_allowed_area->p2z); +} + /** * @brief Send a safety_set_allowed_area message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_scaled_imu.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_scaled_imu.h index 2751ddfe7a..3010d051af 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_scaled_imu.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_scaled_imu.h @@ -104,7 +104,7 @@ static inline uint16_t mavlink_msg_scaled_imu_pack(uint8_t system_id, uint8_t co * @brief Pack a scaled_imu message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param xacc X acceleration (mg) @@ -161,7 +161,7 @@ static inline uint16_t mavlink_msg_scaled_imu_pack_chan(uint8_t system_id, uint8 } /** - * @brief Encode a scaled_imu struct into a message + * @brief Encode a scaled_imu struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -173,6 +173,20 @@ static inline uint16_t mavlink_msg_scaled_imu_encode(uint8_t system_id, uint8_t return mavlink_msg_scaled_imu_pack(system_id, component_id, msg, scaled_imu->time_boot_ms, scaled_imu->xacc, scaled_imu->yacc, scaled_imu->zacc, scaled_imu->xgyro, scaled_imu->ygyro, scaled_imu->zgyro, scaled_imu->xmag, scaled_imu->ymag, scaled_imu->zmag); } +/** + * @brief Encode a scaled_imu struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param scaled_imu C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_scaled_imu_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_scaled_imu_t* scaled_imu) +{ + return mavlink_msg_scaled_imu_pack_chan(system_id, component_id, chan, msg, scaled_imu->time_boot_ms, scaled_imu->xacc, scaled_imu->yacc, scaled_imu->zacc, scaled_imu->xgyro, scaled_imu->ygyro, scaled_imu->zgyro, scaled_imu->xmag, scaled_imu->ymag, scaled_imu->zmag); +} + /** * @brief Send a scaled_imu message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_scaled_pressure.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_scaled_pressure.h index f54e281958..10324bc941 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_scaled_pressure.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_scaled_pressure.h @@ -74,7 +74,7 @@ static inline uint16_t mavlink_msg_scaled_pressure_pack(uint8_t system_id, uint8 * @brief Pack a scaled_pressure message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param press_abs Absolute pressure (hectopascal) @@ -113,7 +113,7 @@ static inline uint16_t mavlink_msg_scaled_pressure_pack_chan(uint8_t system_id, } /** - * @brief Encode a scaled_pressure struct into a message + * @brief Encode a scaled_pressure struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -125,6 +125,20 @@ static inline uint16_t mavlink_msg_scaled_pressure_encode(uint8_t system_id, uin return mavlink_msg_scaled_pressure_pack(system_id, component_id, msg, scaled_pressure->time_boot_ms, scaled_pressure->press_abs, scaled_pressure->press_diff, scaled_pressure->temperature); } +/** + * @brief Encode a scaled_pressure struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param scaled_pressure C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_scaled_pressure_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_scaled_pressure_t* scaled_pressure) +{ + return mavlink_msg_scaled_pressure_pack_chan(system_id, component_id, chan, msg, scaled_pressure->time_boot_ms, scaled_pressure->press_abs, scaled_pressure->press_diff, scaled_pressure->temperature); +} + /** * @brief Send a scaled_pressure message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_servo_output_raw.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_servo_output_raw.h index 10bdcbc8c2..6a14e93ed3 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_servo_output_raw.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_servo_output_raw.h @@ -104,7 +104,7 @@ static inline uint16_t mavlink_msg_servo_output_raw_pack(uint8_t system_id, uint * @brief Pack a servo_output_raw message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_usec Timestamp (microseconds since system boot) * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. @@ -161,7 +161,7 @@ static inline uint16_t mavlink_msg_servo_output_raw_pack_chan(uint8_t system_id, } /** - * @brief Encode a servo_output_raw struct into a message + * @brief Encode a servo_output_raw struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -173,6 +173,20 @@ static inline uint16_t mavlink_msg_servo_output_raw_encode(uint8_t system_id, ui return mavlink_msg_servo_output_raw_pack(system_id, component_id, msg, servo_output_raw->time_usec, servo_output_raw->port, servo_output_raw->servo1_raw, servo_output_raw->servo2_raw, servo_output_raw->servo3_raw, servo_output_raw->servo4_raw, servo_output_raw->servo5_raw, servo_output_raw->servo6_raw, servo_output_raw->servo7_raw, servo_output_raw->servo8_raw); } +/** + * @brief Encode a servo_output_raw struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param servo_output_raw C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_servo_output_raw_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_servo_output_raw_t* servo_output_raw) +{ + return mavlink_msg_servo_output_raw_pack_chan(system_id, component_id, chan, msg, servo_output_raw->time_usec, servo_output_raw->port, servo_output_raw->servo1_raw, servo_output_raw->servo2_raw, servo_output_raw->servo3_raw, servo_output_raw->servo4_raw, servo_output_raw->servo5_raw, servo_output_raw->servo6_raw, servo_output_raw->servo7_raw, servo_output_raw->servo8_raw); +} + /** * @brief Send a servo_output_raw message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_global_position_setpoint_int.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_global_position_setpoint_int.h index 0364b42415..6f0d7a69da 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_global_position_setpoint_int.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_global_position_setpoint_int.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_set_global_position_setpoint_int_pack(uint8_t * @brief Pack a set_global_position_setpoint_int message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_GLOBAL or MAV_FRAME_GLOBAL_RELATIVE_ALT * @param latitude Latitude (WGS84), in degrees * 1E7 @@ -121,7 +121,7 @@ static inline uint16_t mavlink_msg_set_global_position_setpoint_int_pack_chan(ui } /** - * @brief Encode a set_global_position_setpoint_int struct into a message + * @brief Encode a set_global_position_setpoint_int struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -133,6 +133,20 @@ static inline uint16_t mavlink_msg_set_global_position_setpoint_int_encode(uint8 return mavlink_msg_set_global_position_setpoint_int_pack(system_id, component_id, msg, set_global_position_setpoint_int->coordinate_frame, set_global_position_setpoint_int->latitude, set_global_position_setpoint_int->longitude, set_global_position_setpoint_int->altitude, set_global_position_setpoint_int->yaw); } +/** + * @brief Encode a set_global_position_setpoint_int struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param set_global_position_setpoint_int C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_global_position_setpoint_int_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_set_global_position_setpoint_int_t* set_global_position_setpoint_int) +{ + return mavlink_msg_set_global_position_setpoint_int_pack_chan(system_id, component_id, chan, msg, set_global_position_setpoint_int->coordinate_frame, set_global_position_setpoint_int->latitude, set_global_position_setpoint_int->longitude, set_global_position_setpoint_int->altitude, set_global_position_setpoint_int->yaw); +} + /** * @brief Send a set_global_position_setpoint_int message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_gps_global_origin.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_gps_global_origin.h index e3cd4f4419..c444d8d52c 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_gps_global_origin.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_gps_global_origin.h @@ -74,7 +74,7 @@ static inline uint16_t mavlink_msg_set_gps_global_origin_pack(uint8_t system_id, * @brief Pack a set_gps_global_origin message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param latitude Latitude (WGS84), in degrees * 1E7 @@ -113,7 +113,7 @@ static inline uint16_t mavlink_msg_set_gps_global_origin_pack_chan(uint8_t syste } /** - * @brief Encode a set_gps_global_origin struct into a message + * @brief Encode a set_gps_global_origin struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -125,6 +125,20 @@ static inline uint16_t mavlink_msg_set_gps_global_origin_encode(uint8_t system_i return mavlink_msg_set_gps_global_origin_pack(system_id, component_id, msg, set_gps_global_origin->target_system, set_gps_global_origin->latitude, set_gps_global_origin->longitude, set_gps_global_origin->altitude); } +/** + * @brief Encode a set_gps_global_origin struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param set_gps_global_origin C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_gps_global_origin_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_set_gps_global_origin_t* set_gps_global_origin) +{ + return mavlink_msg_set_gps_global_origin_pack_chan(system_id, component_id, chan, msg, set_gps_global_origin->target_system, set_gps_global_origin->latitude, set_gps_global_origin->longitude, set_gps_global_origin->altitude); +} + /** * @brief Send a set_gps_global_origin message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_local_position_setpoint.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_local_position_setpoint.h index b92c0560e9..6f2835e031 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_local_position_setpoint.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_local_position_setpoint.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_set_local_position_setpoint_pack(uint8_t syst * @brief Pack a set_local_position_setpoint message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_set_local_position_setpoint_pack_chan(uint8_t } /** - * @brief Encode a set_local_position_setpoint struct into a message + * @brief Encode a set_local_position_setpoint struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_set_local_position_setpoint_encode(uint8_t sy return mavlink_msg_set_local_position_setpoint_pack(system_id, component_id, msg, set_local_position_setpoint->target_system, set_local_position_setpoint->target_component, set_local_position_setpoint->coordinate_frame, set_local_position_setpoint->x, set_local_position_setpoint->y, set_local_position_setpoint->z, set_local_position_setpoint->yaw); } +/** + * @brief Encode a set_local_position_setpoint struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param set_local_position_setpoint C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_local_position_setpoint_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_set_local_position_setpoint_t* set_local_position_setpoint) +{ + return mavlink_msg_set_local_position_setpoint_pack_chan(system_id, component_id, chan, msg, set_local_position_setpoint->target_system, set_local_position_setpoint->target_component, set_local_position_setpoint->coordinate_frame, set_local_position_setpoint->x, set_local_position_setpoint->y, set_local_position_setpoint->z, set_local_position_setpoint->yaw); +} + /** * @brief Send a set_local_position_setpoint message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_mode.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_mode.h index 08ec733098..1aff42cce3 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_mode.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_mode.h @@ -69,7 +69,7 @@ static inline uint16_t mavlink_msg_set_mode_pack(uint8_t system_id, uint8_t comp * @brief Pack a set_mode message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system The system setting the mode * @param base_mode The new base mode @@ -105,7 +105,7 @@ static inline uint16_t mavlink_msg_set_mode_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a set_mode struct into a message + * @brief Encode a set_mode struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -117,6 +117,20 @@ static inline uint16_t mavlink_msg_set_mode_encode(uint8_t system_id, uint8_t co return mavlink_msg_set_mode_pack(system_id, component_id, msg, set_mode->target_system, set_mode->base_mode, set_mode->custom_mode); } +/** + * @brief Encode a set_mode struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param set_mode C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_mode_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_set_mode_t* set_mode) +{ + return mavlink_msg_set_mode_pack_chan(system_id, component_id, chan, msg, set_mode->target_system, set_mode->base_mode, set_mode->custom_mode); +} + /** * @brief Send a set_mode message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_quad_motors_setpoint.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_quad_motors_setpoint.h index b79114e1a5..8ceb8888fc 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_quad_motors_setpoint.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_quad_motors_setpoint.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_set_quad_motors_setpoint_pack(uint8_t system_ * @brief Pack a set_quad_motors_setpoint message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID of the system that should set these motor commands * @param motor_front_nw Front motor in + configuration, front left motor in x configuration @@ -121,7 +121,7 @@ static inline uint16_t mavlink_msg_set_quad_motors_setpoint_pack_chan(uint8_t sy } /** - * @brief Encode a set_quad_motors_setpoint struct into a message + * @brief Encode a set_quad_motors_setpoint struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -133,6 +133,20 @@ static inline uint16_t mavlink_msg_set_quad_motors_setpoint_encode(uint8_t syste return mavlink_msg_set_quad_motors_setpoint_pack(system_id, component_id, msg, set_quad_motors_setpoint->target_system, set_quad_motors_setpoint->motor_front_nw, set_quad_motors_setpoint->motor_right_ne, set_quad_motors_setpoint->motor_back_se, set_quad_motors_setpoint->motor_left_sw); } +/** + * @brief Encode a set_quad_motors_setpoint struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param set_quad_motors_setpoint C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_quad_motors_setpoint_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_set_quad_motors_setpoint_t* set_quad_motors_setpoint) +{ + return mavlink_msg_set_quad_motors_setpoint_pack_chan(system_id, component_id, chan, msg, set_quad_motors_setpoint->target_system, set_quad_motors_setpoint->motor_front_nw, set_quad_motors_setpoint->motor_right_ne, set_quad_motors_setpoint->motor_back_se, set_quad_motors_setpoint->motor_left_sw); +} + /** * @brief Send a set_quad_motors_setpoint message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust.h index 06223845f4..9ef294cc97 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust.h @@ -4,10 +4,10 @@ typedef struct __mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t { - int16_t roll[4]; ///< Desired roll angle in radians +-PI (+-32767) - int16_t pitch[4]; ///< Desired pitch angle in radians +-PI (+-32767) - int16_t yaw[4]; ///< Desired yaw angle in radians, scaled to int16 +-PI (+-32767) - uint16_t thrust[4]; ///< Collective thrust, scaled to uint16 (0..65535) + int16_t roll[4]; ///< Desired roll angle in radians +-PI (+-INT16_MAX) + int16_t pitch[4]; ///< Desired pitch angle in radians +-PI (+-INT16_MAX) + int16_t yaw[4]; ///< Desired yaw angle in radians, scaled to int16 +-PI (+-INT16_MAX) + uint16_t thrust[4]; ///< Collective thrust, scaled to uint16 (0..UINT16_MAX) uint8_t group; ///< ID of the quadrotor group (0 - 255, up to 256 groups supported) uint8_t mode; ///< ID of the flight mode (0 - 255, up to 256 modes supported) uint8_t led_red[4]; ///< RGB red channel (0-255) @@ -56,10 +56,10 @@ typedef struct __mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t * @param led_red RGB red channel (0-255) * @param led_blue RGB green channel (0-255) * @param led_green RGB blue channel (0-255) - * @param roll Desired roll angle in radians +-PI (+-32767) - * @param pitch Desired pitch angle in radians +-PI (+-32767) - * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-32767) - * @param thrust Collective thrust, scaled to uint16 (0..65535) + * @param roll Desired roll angle in radians +-PI (+-INT16_MAX) + * @param pitch Desired pitch angle in radians +-PI (+-INT16_MAX) + * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-INT16_MAX) + * @param thrust Collective thrust, scaled to uint16 (0..UINT16_MAX) * @return length of the message in bytes (excluding serial stream start sign) */ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, @@ -103,17 +103,17 @@ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_pack * @brief Pack a set_quad_swarm_led_roll_pitch_yaw_thrust message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param group ID of the quadrotor group (0 - 255, up to 256 groups supported) * @param mode ID of the flight mode (0 - 255, up to 256 modes supported) * @param led_red RGB red channel (0-255) * @param led_blue RGB green channel (0-255) * @param led_green RGB blue channel (0-255) - * @param roll Desired roll angle in radians +-PI (+-32767) - * @param pitch Desired pitch angle in radians +-PI (+-32767) - * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-32767) - * @param thrust Collective thrust, scaled to uint16 (0..65535) + * @param roll Desired roll angle in radians +-PI (+-INT16_MAX) + * @param pitch Desired pitch angle in radians +-PI (+-INT16_MAX) + * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-INT16_MAX) + * @param thrust Collective thrust, scaled to uint16 (0..UINT16_MAX) * @return length of the message in bytes (excluding serial stream start sign) */ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, @@ -155,7 +155,7 @@ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_pack } /** - * @brief Encode a set_quad_swarm_led_roll_pitch_yaw_thrust struct into a message + * @brief Encode a set_quad_swarm_led_roll_pitch_yaw_thrust struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -167,6 +167,20 @@ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_enco return mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_pack(system_id, component_id, msg, set_quad_swarm_led_roll_pitch_yaw_thrust->group, set_quad_swarm_led_roll_pitch_yaw_thrust->mode, set_quad_swarm_led_roll_pitch_yaw_thrust->led_red, set_quad_swarm_led_roll_pitch_yaw_thrust->led_blue, set_quad_swarm_led_roll_pitch_yaw_thrust->led_green, set_quad_swarm_led_roll_pitch_yaw_thrust->roll, set_quad_swarm_led_roll_pitch_yaw_thrust->pitch, set_quad_swarm_led_roll_pitch_yaw_thrust->yaw, set_quad_swarm_led_roll_pitch_yaw_thrust->thrust); } +/** + * @brief Encode a set_quad_swarm_led_roll_pitch_yaw_thrust struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param set_quad_swarm_led_roll_pitch_yaw_thrust C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t* set_quad_swarm_led_roll_pitch_yaw_thrust) +{ + return mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_pack_chan(system_id, component_id, chan, msg, set_quad_swarm_led_roll_pitch_yaw_thrust->group, set_quad_swarm_led_roll_pitch_yaw_thrust->mode, set_quad_swarm_led_roll_pitch_yaw_thrust->led_red, set_quad_swarm_led_roll_pitch_yaw_thrust->led_blue, set_quad_swarm_led_roll_pitch_yaw_thrust->led_green, set_quad_swarm_led_roll_pitch_yaw_thrust->roll, set_quad_swarm_led_roll_pitch_yaw_thrust->pitch, set_quad_swarm_led_roll_pitch_yaw_thrust->yaw, set_quad_swarm_led_roll_pitch_yaw_thrust->thrust); +} + /** * @brief Send a set_quad_swarm_led_roll_pitch_yaw_thrust message * @param chan MAVLink channel to send the message @@ -176,10 +190,10 @@ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_enco * @param led_red RGB red channel (0-255) * @param led_blue RGB green channel (0-255) * @param led_green RGB blue channel (0-255) - * @param roll Desired roll angle in radians +-PI (+-32767) - * @param pitch Desired pitch angle in radians +-PI (+-32767) - * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-32767) - * @param thrust Collective thrust, scaled to uint16 (0..65535) + * @param roll Desired roll angle in radians +-PI (+-INT16_MAX) + * @param pitch Desired pitch angle in radians +-PI (+-INT16_MAX) + * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-INT16_MAX) + * @param thrust Collective thrust, scaled to uint16 (0..UINT16_MAX) */ #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS @@ -278,7 +292,7 @@ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_ /** * @brief Get field roll from set_quad_swarm_led_roll_pitch_yaw_thrust message * - * @return Desired roll angle in radians +-PI (+-32767) + * @return Desired roll angle in radians +-PI (+-INT16_MAX) */ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_roll(const mavlink_message_t* msg, int16_t *roll) { @@ -288,7 +302,7 @@ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_ /** * @brief Get field pitch from set_quad_swarm_led_roll_pitch_yaw_thrust message * - * @return Desired pitch angle in radians +-PI (+-32767) + * @return Desired pitch angle in radians +-PI (+-INT16_MAX) */ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_pitch(const mavlink_message_t* msg, int16_t *pitch) { @@ -298,7 +312,7 @@ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_ /** * @brief Get field yaw from set_quad_swarm_led_roll_pitch_yaw_thrust message * - * @return Desired yaw angle in radians, scaled to int16 +-PI (+-32767) + * @return Desired yaw angle in radians, scaled to int16 +-PI (+-INT16_MAX) */ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_yaw(const mavlink_message_t* msg, int16_t *yaw) { @@ -308,7 +322,7 @@ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_ /** * @brief Get field thrust from set_quad_swarm_led_roll_pitch_yaw_thrust message * - * @return Collective thrust, scaled to uint16 (0..65535) + * @return Collective thrust, scaled to uint16 (0..UINT16_MAX) */ static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_thrust(const mavlink_message_t* msg, uint16_t *thrust) { diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust.h index 6c62b35305..7d8d526f8b 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust.h @@ -4,10 +4,10 @@ typedef struct __mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t { - int16_t roll[4]; ///< Desired roll angle in radians +-PI (+-32767) - int16_t pitch[4]; ///< Desired pitch angle in radians +-PI (+-32767) - int16_t yaw[4]; ///< Desired yaw angle in radians, scaled to int16 +-PI (+-32767) - uint16_t thrust[4]; ///< Collective thrust, scaled to uint16 (0..65535) + int16_t roll[4]; ///< Desired roll angle in radians +-PI (+-INT16_MAX) + int16_t pitch[4]; ///< Desired pitch angle in radians +-PI (+-INT16_MAX) + int16_t yaw[4]; ///< Desired yaw angle in radians, scaled to int16 +-PI (+-INT16_MAX) + uint16_t thrust[4]; ///< Collective thrust, scaled to uint16 (0..UINT16_MAX) uint8_t group; ///< ID of the quadrotor group (0 - 255, up to 256 groups supported) uint8_t mode; ///< ID of the flight mode (0 - 255, up to 256 modes supported) } mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t; @@ -44,10 +44,10 @@ typedef struct __mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t * * @param group ID of the quadrotor group (0 - 255, up to 256 groups supported) * @param mode ID of the flight mode (0 - 255, up to 256 modes supported) - * @param roll Desired roll angle in radians +-PI (+-32767) - * @param pitch Desired pitch angle in radians +-PI (+-32767) - * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-32767) - * @param thrust Collective thrust, scaled to uint16 (0..65535) + * @param roll Desired roll angle in radians +-PI (+-INT16_MAX) + * @param pitch Desired pitch angle in radians +-PI (+-INT16_MAX) + * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-INT16_MAX) + * @param thrust Collective thrust, scaled to uint16 (0..UINT16_MAX) * @return length of the message in bytes (excluding serial stream start sign) */ static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, @@ -85,14 +85,14 @@ static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_pack(uin * @brief Pack a set_quad_swarm_roll_pitch_yaw_thrust message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param group ID of the quadrotor group (0 - 255, up to 256 groups supported) * @param mode ID of the flight mode (0 - 255, up to 256 modes supported) - * @param roll Desired roll angle in radians +-PI (+-32767) - * @param pitch Desired pitch angle in radians +-PI (+-32767) - * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-32767) - * @param thrust Collective thrust, scaled to uint16 (0..65535) + * @param roll Desired roll angle in radians +-PI (+-INT16_MAX) + * @param pitch Desired pitch angle in radians +-PI (+-INT16_MAX) + * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-INT16_MAX) + * @param thrust Collective thrust, scaled to uint16 (0..UINT16_MAX) * @return length of the message in bytes (excluding serial stream start sign) */ static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, @@ -128,7 +128,7 @@ static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_pack_cha } /** - * @brief Encode a set_quad_swarm_roll_pitch_yaw_thrust struct into a message + * @brief Encode a set_quad_swarm_roll_pitch_yaw_thrust struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -140,16 +140,30 @@ static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_encode(u return mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_pack(system_id, component_id, msg, set_quad_swarm_roll_pitch_yaw_thrust->group, set_quad_swarm_roll_pitch_yaw_thrust->mode, set_quad_swarm_roll_pitch_yaw_thrust->roll, set_quad_swarm_roll_pitch_yaw_thrust->pitch, set_quad_swarm_roll_pitch_yaw_thrust->yaw, set_quad_swarm_roll_pitch_yaw_thrust->thrust); } +/** + * @brief Encode a set_quad_swarm_roll_pitch_yaw_thrust struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param set_quad_swarm_roll_pitch_yaw_thrust C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t* set_quad_swarm_roll_pitch_yaw_thrust) +{ + return mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_pack_chan(system_id, component_id, chan, msg, set_quad_swarm_roll_pitch_yaw_thrust->group, set_quad_swarm_roll_pitch_yaw_thrust->mode, set_quad_swarm_roll_pitch_yaw_thrust->roll, set_quad_swarm_roll_pitch_yaw_thrust->pitch, set_quad_swarm_roll_pitch_yaw_thrust->yaw, set_quad_swarm_roll_pitch_yaw_thrust->thrust); +} + /** * @brief Send a set_quad_swarm_roll_pitch_yaw_thrust message * @param chan MAVLink channel to send the message * * @param group ID of the quadrotor group (0 - 255, up to 256 groups supported) * @param mode ID of the flight mode (0 - 255, up to 256 modes supported) - * @param roll Desired roll angle in radians +-PI (+-32767) - * @param pitch Desired pitch angle in radians +-PI (+-32767) - * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-32767) - * @param thrust Collective thrust, scaled to uint16 (0..65535) + * @param roll Desired roll angle in radians +-PI (+-INT16_MAX) + * @param pitch Desired pitch angle in radians +-PI (+-INT16_MAX) + * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-INT16_MAX) + * @param thrust Collective thrust, scaled to uint16 (0..UINT16_MAX) */ #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS @@ -212,7 +226,7 @@ static inline uint8_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_mode( /** * @brief Get field roll from set_quad_swarm_roll_pitch_yaw_thrust message * - * @return Desired roll angle in radians +-PI (+-32767) + * @return Desired roll angle in radians +-PI (+-INT16_MAX) */ static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_roll(const mavlink_message_t* msg, int16_t *roll) { @@ -222,7 +236,7 @@ static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_roll /** * @brief Get field pitch from set_quad_swarm_roll_pitch_yaw_thrust message * - * @return Desired pitch angle in radians +-PI (+-32767) + * @return Desired pitch angle in radians +-PI (+-INT16_MAX) */ static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_pitch(const mavlink_message_t* msg, int16_t *pitch) { @@ -232,7 +246,7 @@ static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_pitc /** * @brief Get field yaw from set_quad_swarm_roll_pitch_yaw_thrust message * - * @return Desired yaw angle in radians, scaled to int16 +-PI (+-32767) + * @return Desired yaw angle in radians, scaled to int16 +-PI (+-INT16_MAX) */ static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_yaw(const mavlink_message_t* msg, int16_t *yaw) { @@ -242,7 +256,7 @@ static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_yaw( /** * @brief Get field thrust from set_quad_swarm_roll_pitch_yaw_thrust message * - * @return Collective thrust, scaled to uint16 (0..65535) + * @return Collective thrust, scaled to uint16 (0..UINT16_MAX) */ static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_thrust(const mavlink_message_t* msg, uint16_t *thrust) { diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_speed_thrust.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_speed_thrust.h index c379a75d9b..5846ba41f7 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_speed_thrust.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_speed_thrust.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_set_roll_pitch_yaw_speed_thrust_pack(uint8_t * @brief Pack a set_roll_pitch_yaw_speed_thrust message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_set_roll_pitch_yaw_speed_thrust_pack_chan(uin } /** - * @brief Encode a set_roll_pitch_yaw_speed_thrust struct into a message + * @brief Encode a set_roll_pitch_yaw_speed_thrust struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_set_roll_pitch_yaw_speed_thrust_encode(uint8_ return mavlink_msg_set_roll_pitch_yaw_speed_thrust_pack(system_id, component_id, msg, set_roll_pitch_yaw_speed_thrust->target_system, set_roll_pitch_yaw_speed_thrust->target_component, set_roll_pitch_yaw_speed_thrust->roll_speed, set_roll_pitch_yaw_speed_thrust->pitch_speed, set_roll_pitch_yaw_speed_thrust->yaw_speed, set_roll_pitch_yaw_speed_thrust->thrust); } +/** + * @brief Encode a set_roll_pitch_yaw_speed_thrust struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param set_roll_pitch_yaw_speed_thrust C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_roll_pitch_yaw_speed_thrust_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_set_roll_pitch_yaw_speed_thrust_t* set_roll_pitch_yaw_speed_thrust) +{ + return mavlink_msg_set_roll_pitch_yaw_speed_thrust_pack_chan(system_id, component_id, chan, msg, set_roll_pitch_yaw_speed_thrust->target_system, set_roll_pitch_yaw_speed_thrust->target_component, set_roll_pitch_yaw_speed_thrust->roll_speed, set_roll_pitch_yaw_speed_thrust->pitch_speed, set_roll_pitch_yaw_speed_thrust->yaw_speed, set_roll_pitch_yaw_speed_thrust->thrust); +} + /** * @brief Send a set_roll_pitch_yaw_speed_thrust message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_thrust.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_thrust.h index 146891eafb..334fd39e36 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_thrust.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_thrust.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_set_roll_pitch_yaw_thrust_pack(uint8_t system * @brief Pack a set_roll_pitch_yaw_thrust message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_set_roll_pitch_yaw_thrust_pack_chan(uint8_t s } /** - * @brief Encode a set_roll_pitch_yaw_thrust struct into a message + * @brief Encode a set_roll_pitch_yaw_thrust struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_set_roll_pitch_yaw_thrust_encode(uint8_t syst return mavlink_msg_set_roll_pitch_yaw_thrust_pack(system_id, component_id, msg, set_roll_pitch_yaw_thrust->target_system, set_roll_pitch_yaw_thrust->target_component, set_roll_pitch_yaw_thrust->roll, set_roll_pitch_yaw_thrust->pitch, set_roll_pitch_yaw_thrust->yaw, set_roll_pitch_yaw_thrust->thrust); } +/** + * @brief Encode a set_roll_pitch_yaw_thrust struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param set_roll_pitch_yaw_thrust C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_roll_pitch_yaw_thrust_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_set_roll_pitch_yaw_thrust_t* set_roll_pitch_yaw_thrust) +{ + return mavlink_msg_set_roll_pitch_yaw_thrust_pack_chan(system_id, component_id, chan, msg, set_roll_pitch_yaw_thrust->target_system, set_roll_pitch_yaw_thrust->target_component, set_roll_pitch_yaw_thrust->roll, set_roll_pitch_yaw_thrust->pitch, set_roll_pitch_yaw_thrust->yaw, set_roll_pitch_yaw_thrust->thrust); +} + /** * @brief Send a set_roll_pitch_yaw_thrust message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_setpoint_6dof.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_setpoint_6dof.h index f352617a26..93ce345b65 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_setpoint_6dof.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_setpoint_6dof.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_setpoint_6dof_pack(uint8_t system_id, uint8_t * @brief Pack a setpoint_6dof message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param trans_x Translational Component in x @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_setpoint_6dof_pack_chan(uint8_t system_id, ui } /** - * @brief Encode a setpoint_6dof struct into a message + * @brief Encode a setpoint_6dof struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_setpoint_6dof_encode(uint8_t system_id, uint8 return mavlink_msg_setpoint_6dof_pack(system_id, component_id, msg, setpoint_6dof->target_system, setpoint_6dof->trans_x, setpoint_6dof->trans_y, setpoint_6dof->trans_z, setpoint_6dof->rot_x, setpoint_6dof->rot_y, setpoint_6dof->rot_z); } +/** + * @brief Encode a setpoint_6dof struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param setpoint_6dof C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_setpoint_6dof_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_setpoint_6dof_t* setpoint_6dof) +{ + return mavlink_msg_setpoint_6dof_pack_chan(system_id, component_id, chan, msg, setpoint_6dof->target_system, setpoint_6dof->trans_x, setpoint_6dof->trans_y, setpoint_6dof->trans_z, setpoint_6dof->rot_x, setpoint_6dof->rot_y, setpoint_6dof->rot_z); +} + /** * @brief Send a setpoint_6dof message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_setpoint_8dof.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_setpoint_8dof.h index d7622b6965..de80e46459 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_setpoint_8dof.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_setpoint_8dof.h @@ -99,7 +99,7 @@ static inline uint16_t mavlink_msg_setpoint_8dof_pack(uint8_t system_id, uint8_t * @brief Pack a setpoint_8dof message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param val1 Value 1 @@ -153,7 +153,7 @@ static inline uint16_t mavlink_msg_setpoint_8dof_pack_chan(uint8_t system_id, ui } /** - * @brief Encode a setpoint_8dof struct into a message + * @brief Encode a setpoint_8dof struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -165,6 +165,20 @@ static inline uint16_t mavlink_msg_setpoint_8dof_encode(uint8_t system_id, uint8 return mavlink_msg_setpoint_8dof_pack(system_id, component_id, msg, setpoint_8dof->target_system, setpoint_8dof->val1, setpoint_8dof->val2, setpoint_8dof->val3, setpoint_8dof->val4, setpoint_8dof->val5, setpoint_8dof->val6, setpoint_8dof->val7, setpoint_8dof->val8); } +/** + * @brief Encode a setpoint_8dof struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param setpoint_8dof C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_setpoint_8dof_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_setpoint_8dof_t* setpoint_8dof) +{ + return mavlink_msg_setpoint_8dof_pack_chan(system_id, component_id, chan, msg, setpoint_8dof->target_system, setpoint_8dof->val1, setpoint_8dof->val2, setpoint_8dof->val3, setpoint_8dof->val4, setpoint_8dof->val5, setpoint_8dof->val6, setpoint_8dof->val7, setpoint_8dof->val8); +} + /** * @brief Send a setpoint_8dof message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_sim_state.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_sim_state.h index 6fd32abd25..ebd657cf38 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_sim_state.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_sim_state.h @@ -159,7 +159,7 @@ static inline uint16_t mavlink_msg_sim_state_pack(uint8_t system_id, uint8_t com * @brief Pack a sim_state message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param q1 True attitude quaternion component 1 * @param q2 True attitude quaternion component 2 @@ -249,7 +249,7 @@ static inline uint16_t mavlink_msg_sim_state_pack_chan(uint8_t system_id, uint8_ } /** - * @brief Encode a sim_state struct into a message + * @brief Encode a sim_state struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -261,6 +261,20 @@ static inline uint16_t mavlink_msg_sim_state_encode(uint8_t system_id, uint8_t c return mavlink_msg_sim_state_pack(system_id, component_id, msg, sim_state->q1, sim_state->q2, sim_state->q3, sim_state->q4, sim_state->roll, sim_state->pitch, sim_state->yaw, sim_state->xacc, sim_state->yacc, sim_state->zacc, sim_state->xgyro, sim_state->ygyro, sim_state->zgyro, sim_state->lat, sim_state->lon, sim_state->alt, sim_state->std_dev_horz, sim_state->std_dev_vert, sim_state->vn, sim_state->ve, sim_state->vd); } +/** + * @brief Encode a sim_state struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param sim_state C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_sim_state_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_sim_state_t* sim_state) +{ + return mavlink_msg_sim_state_pack_chan(system_id, component_id, chan, msg, sim_state->q1, sim_state->q2, sim_state->q3, sim_state->q4, sim_state->roll, sim_state->pitch, sim_state->yaw, sim_state->xacc, sim_state->yacc, sim_state->zacc, sim_state->xgyro, sim_state->ygyro, sim_state->zgyro, sim_state->lat, sim_state->lon, sim_state->alt, sim_state->std_dev_horz, sim_state->std_dev_vert, sim_state->vn, sim_state->ve, sim_state->vd); +} + /** * @brief Send a sim_state message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_state_correction.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_state_correction.h index 8a002fc113..2db627b96a 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_state_correction.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_state_correction.h @@ -99,7 +99,7 @@ static inline uint16_t mavlink_msg_state_correction_pack(uint8_t system_id, uint * @brief Pack a state_correction message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param xErr x position error * @param yErr y position error @@ -153,7 +153,7 @@ static inline uint16_t mavlink_msg_state_correction_pack_chan(uint8_t system_id, } /** - * @brief Encode a state_correction struct into a message + * @brief Encode a state_correction struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -165,6 +165,20 @@ static inline uint16_t mavlink_msg_state_correction_encode(uint8_t system_id, ui return mavlink_msg_state_correction_pack(system_id, component_id, msg, state_correction->xErr, state_correction->yErr, state_correction->zErr, state_correction->rollErr, state_correction->pitchErr, state_correction->yawErr, state_correction->vxErr, state_correction->vyErr, state_correction->vzErr); } +/** + * @brief Encode a state_correction struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param state_correction C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_state_correction_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_state_correction_t* state_correction) +{ + return mavlink_msg_state_correction_pack_chan(system_id, component_id, chan, msg, state_correction->xErr, state_correction->yErr, state_correction->zErr, state_correction->rollErr, state_correction->pitchErr, state_correction->yawErr, state_correction->vxErr, state_correction->vyErr, state_correction->vzErr); +} + /** * @brief Send a state_correction message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_statustext.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_statustext.h index 103486863c..536ca06349 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_statustext.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_statustext.h @@ -62,7 +62,7 @@ static inline uint16_t mavlink_msg_statustext_pack(uint8_t system_id, uint8_t co * @brief Pack a statustext message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param severity Severity of status. Relies on the definitions within RFC-5424. See enum MAV_SEVERITY. * @param text Status text message, without null termination character @@ -93,7 +93,7 @@ static inline uint16_t mavlink_msg_statustext_pack_chan(uint8_t system_id, uint8 } /** - * @brief Encode a statustext struct into a message + * @brief Encode a statustext struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -105,6 +105,20 @@ static inline uint16_t mavlink_msg_statustext_encode(uint8_t system_id, uint8_t return mavlink_msg_statustext_pack(system_id, component_id, msg, statustext->severity, statustext->text); } +/** + * @brief Encode a statustext struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param statustext C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_statustext_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_statustext_t* statustext) +{ + return mavlink_msg_statustext_pack_chan(system_id, component_id, chan, msg, statustext->severity, statustext->text); +} + /** * @brief Send a statustext message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_sys_status.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_sys_status.h index 916bc4f07b..058c630ddd 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_sys_status.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_sys_status.h @@ -119,7 +119,7 @@ static inline uint16_t mavlink_msg_sys_status_pack(uint8_t system_id, uint8_t co * @brief Pack a sys_status message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param onboard_control_sensors_present Bitmask showing which onboard controllers and sensors are present. Value of 0: not present. Value of 1: present. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control * @param onboard_control_sensors_enabled Bitmask showing which onboard controllers and sensors are enabled: Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control @@ -185,7 +185,7 @@ static inline uint16_t mavlink_msg_sys_status_pack_chan(uint8_t system_id, uint8 } /** - * @brief Encode a sys_status struct into a message + * @brief Encode a sys_status struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -197,6 +197,20 @@ static inline uint16_t mavlink_msg_sys_status_encode(uint8_t system_id, uint8_t return mavlink_msg_sys_status_pack(system_id, component_id, msg, sys_status->onboard_control_sensors_present, sys_status->onboard_control_sensors_enabled, sys_status->onboard_control_sensors_health, sys_status->load, sys_status->voltage_battery, sys_status->current_battery, sys_status->battery_remaining, sys_status->drop_rate_comm, sys_status->errors_comm, sys_status->errors_count1, sys_status->errors_count2, sys_status->errors_count3, sys_status->errors_count4); } +/** + * @brief Encode a sys_status struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param sys_status C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_sys_status_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_sys_status_t* sys_status) +{ + return mavlink_msg_sys_status_pack_chan(system_id, component_id, chan, msg, sys_status->onboard_control_sensors_present, sys_status->onboard_control_sensors_enabled, sys_status->onboard_control_sensors_health, sys_status->load, sys_status->voltage_battery, sys_status->current_battery, sys_status->battery_remaining, sys_status->drop_rate_comm, sys_status->errors_comm, sys_status->errors_count1, sys_status->errors_count2, sys_status->errors_count3, sys_status->errors_count4); +} + /** * @brief Send a sys_status message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_system_time.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_system_time.h index b235fe2056..1807567aea 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_system_time.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_system_time.h @@ -64,7 +64,7 @@ static inline uint16_t mavlink_msg_system_time_pack(uint8_t system_id, uint8_t c * @brief Pack a system_time message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_unix_usec Timestamp of the master clock in microseconds since UNIX epoch. * @param time_boot_ms Timestamp of the component clock since boot time in milliseconds. @@ -97,7 +97,7 @@ static inline uint16_t mavlink_msg_system_time_pack_chan(uint8_t system_id, uint } /** - * @brief Encode a system_time struct into a message + * @brief Encode a system_time struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -109,6 +109,20 @@ static inline uint16_t mavlink_msg_system_time_encode(uint8_t system_id, uint8_t return mavlink_msg_system_time_pack(system_id, component_id, msg, system_time->time_unix_usec, system_time->time_boot_ms); } +/** + * @brief Encode a system_time struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param system_time C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_system_time_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_system_time_t* system_time) +{ + return mavlink_msg_system_time_pack_chan(system_id, component_id, chan, msg, system_time->time_unix_usec, system_time->time_boot_ms); +} + /** * @brief Send a system_time message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vfr_hud.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vfr_hud.h index 9d459921fe..5b1093a3d7 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vfr_hud.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vfr_hud.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_vfr_hud_pack(uint8_t system_id, uint8_t compo * @brief Pack a vfr_hud message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param airspeed Current airspeed in m/s * @param groundspeed Current ground speed in m/s @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_vfr_hud_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a vfr_hud struct into a message + * @brief Encode a vfr_hud struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_vfr_hud_encode(uint8_t system_id, uint8_t com return mavlink_msg_vfr_hud_pack(system_id, component_id, msg, vfr_hud->airspeed, vfr_hud->groundspeed, vfr_hud->heading, vfr_hud->throttle, vfr_hud->alt, vfr_hud->climb); } +/** + * @brief Encode a vfr_hud struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param vfr_hud C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_vfr_hud_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_vfr_hud_t* vfr_hud) +{ + return mavlink_msg_vfr_hud_pack_chan(system_id, component_id, chan, msg, vfr_hud->airspeed, vfr_hud->groundspeed, vfr_hud->heading, vfr_hud->throttle, vfr_hud->alt, vfr_hud->climb); +} + /** * @brief Send a vfr_hud message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vicon_position_estimate.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vicon_position_estimate.h index 75e4b5b7ab..a254202e4e 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vicon_position_estimate.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vicon_position_estimate.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_vicon_position_estimate_pack(uint8_t system_i * @brief Pack a vicon_position_estimate message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param usec Timestamp (microseconds, synced to UNIX time or since system boot) * @param x Global X position @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_vicon_position_estimate_pack_chan(uint8_t sys } /** - * @brief Encode a vicon_position_estimate struct into a message + * @brief Encode a vicon_position_estimate struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_vicon_position_estimate_encode(uint8_t system return mavlink_msg_vicon_position_estimate_pack(system_id, component_id, msg, vicon_position_estimate->usec, vicon_position_estimate->x, vicon_position_estimate->y, vicon_position_estimate->z, vicon_position_estimate->roll, vicon_position_estimate->pitch, vicon_position_estimate->yaw); } +/** + * @brief Encode a vicon_position_estimate struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param vicon_position_estimate C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_vicon_position_estimate_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_vicon_position_estimate_t* vicon_position_estimate) +{ + return mavlink_msg_vicon_position_estimate_pack_chan(system_id, component_id, chan, msg, vicon_position_estimate->usec, vicon_position_estimate->x, vicon_position_estimate->y, vicon_position_estimate->z, vicon_position_estimate->roll, vicon_position_estimate->pitch, vicon_position_estimate->yaw); +} + /** * @brief Send a vicon_position_estimate message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vision_position_estimate.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vision_position_estimate.h index 47ccb11ec0..f7a741b09e 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vision_position_estimate.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vision_position_estimate.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_vision_position_estimate_pack(uint8_t system_ * @brief Pack a vision_position_estimate message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param usec Timestamp (microseconds, synced to UNIX time or since system boot) * @param x Global X position @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_vision_position_estimate_pack_chan(uint8_t sy } /** - * @brief Encode a vision_position_estimate struct into a message + * @brief Encode a vision_position_estimate struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_vision_position_estimate_encode(uint8_t syste return mavlink_msg_vision_position_estimate_pack(system_id, component_id, msg, vision_position_estimate->usec, vision_position_estimate->x, vision_position_estimate->y, vision_position_estimate->z, vision_position_estimate->roll, vision_position_estimate->pitch, vision_position_estimate->yaw); } +/** + * @brief Encode a vision_position_estimate struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param vision_position_estimate C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_vision_position_estimate_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_vision_position_estimate_t* vision_position_estimate) +{ + return mavlink_msg_vision_position_estimate_pack_chan(system_id, component_id, chan, msg, vision_position_estimate->usec, vision_position_estimate->x, vision_position_estimate->y, vision_position_estimate->z, vision_position_estimate->roll, vision_position_estimate->pitch, vision_position_estimate->yaw); +} + /** * @brief Send a vision_position_estimate message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vision_speed_estimate.h b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vision_speed_estimate.h index c38eee62c0..6602251283 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vision_speed_estimate.h +++ b/libs/mavlink/include/mavlink/v1.0/common/mavlink_msg_vision_speed_estimate.h @@ -74,7 +74,7 @@ static inline uint16_t mavlink_msg_vision_speed_estimate_pack(uint8_t system_id, * @brief Pack a vision_speed_estimate message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param usec Timestamp (microseconds, synced to UNIX time or since system boot) * @param x Global X speed @@ -113,7 +113,7 @@ static inline uint16_t mavlink_msg_vision_speed_estimate_pack_chan(uint8_t syste } /** - * @brief Encode a vision_speed_estimate struct into a message + * @brief Encode a vision_speed_estimate struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -125,6 +125,20 @@ static inline uint16_t mavlink_msg_vision_speed_estimate_encode(uint8_t system_i return mavlink_msg_vision_speed_estimate_pack(system_id, component_id, msg, vision_speed_estimate->usec, vision_speed_estimate->x, vision_speed_estimate->y, vision_speed_estimate->z); } +/** + * @brief Encode a vision_speed_estimate struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param vision_speed_estimate C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_vision_speed_estimate_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_vision_speed_estimate_t* vision_speed_estimate) +{ + return mavlink_msg_vision_speed_estimate_pack_chan(system_id, component_id, chan, msg, vision_speed_estimate->usec, vision_speed_estimate->x, vision_speed_estimate->y, vision_speed_estimate->z); +} + /** * @brief Send a vision_speed_estimate message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/common/version.h b/libs/mavlink/include/mavlink/v1.0/common/version.h index c91a641de8..3c354f4229 100644 --- a/libs/mavlink/include/mavlink/v1.0/common/version.h +++ b/libs/mavlink/include/mavlink/v1.0/common/version.h @@ -5,7 +5,7 @@ #ifndef MAVLINK_VERSION_H #define MAVLINK_VERSION_H -#define MAVLINK_BUILD_DATE "Thu Jul 4 13:47:40 2013" +#define MAVLINK_BUILD_DATE "Tue Sep 10 23:50:05 2013" #define MAVLINK_WIRE_PROTOCOL_VERSION "1.0" #define MAVLINK_MAX_DIALECT_PAYLOAD_SIZE 254 diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/matrixpilot.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/matrixpilot.h index f5576255ed..f590cda800 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/matrixpilot.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/matrixpilot.h @@ -77,6 +77,7 @@ enum MAV_CMD MAV_CMD_DO_SET_SERVO=183, /* Set a servo to a desired PWM value. |Servo number| PWM (microseconds, 1000 to 2000 typical)| Empty| Empty| Empty| Empty| Empty| */ MAV_CMD_DO_REPEAT_SERVO=184, /* Cycle a between its nominal setting and a desired PWM for a desired number of cycles with a desired period. |Servo number| PWM (microseconds, 1000 to 2000 typical)| Cycle count| Cycle time (seconds)| Empty| Empty| Empty| */ MAV_CMD_DO_CONTROL_VIDEO=200, /* Control onboard camera system. |Camera ID (-1 for all)| Transmission: 0: disabled, 1: enabled compressed, 2: enabled raw| Transmission mode: 0: video stream, >0: single images every n seconds (decimal)| Recording: 0: disabled, 1: enabled compressed, 2: enabled raw| Empty| Empty| Empty| */ + MAV_CMD_DO_SET_ROI=201, /* Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. |Region of intereset mode. (see MAV_ROI enum)| MISSION index/ target ID. (see MAV_ROI enum)| ROI index (allows a vehicle to manage multiple ROI's)| Empty| x the location of the fixed ROI (see MAV_FRAME)| y| z| */ MAV_CMD_DO_LAST=240, /* NOP - This command is only used to mark the upper limit of the DO commands in the enumeration |Empty| Empty| Empty| Empty| Empty| Empty| Empty| */ MAV_CMD_PREFLIGHT_CALIBRATION=241, /* Trigger calibration. This command will be only accepted if in pre-flight mode. |Gyro calibration: 0: no, 1: yes| Magnetometer calibration: 0: no, 1: yes| Ground pressure: 0: no, 1: yes| Radio calibration: 0: no, 1: yes| Accelerometer calibration: 0: no, 1: yes| Empty| Empty| */ MAV_CMD_PREFLIGHT_SET_SENSOR_OFFSETS=242, /* Set sensor offsets. This command will be only accepted if in pre-flight mode. |Sensor to adjust the offsets for: 0: gyros, 1: accelerometer, 2: magnetometer, 3: barometer, 4: optical flow| X axis offset (or generic dimension 1), in the sensor's raw units| Y axis offset (or generic dimension 2), in the sensor's raw units| Z axis offset (or generic dimension 3), in the sensor's raw units| Generic dimension 4, in the sensor's raw units| Generic dimension 5, in the sensor's raw units| Generic dimension 6, in the sensor's raw units| */ @@ -85,7 +86,8 @@ enum MAV_CMD MAV_CMD_OVERRIDE_GOTO=252, /* Hold / continue the current action |MAV_GOTO_DO_HOLD: hold MAV_GOTO_DO_CONTINUE: continue with next item in mission plan| MAV_GOTO_HOLD_AT_CURRENT_POSITION: Hold at current position MAV_GOTO_HOLD_AT_SPECIFIED_POSITION: hold at specified position| MAV_FRAME coordinate frame of hold point| Desired yaw angle in degrees| Latitude / X position| Longitude / Y position| Altitude / Z position| */ MAV_CMD_MISSION_START=300, /* start running a mission |first_item: the first mission item to run| last_item: the last mission item to run (after this item is run, the mission ends)| */ MAV_CMD_COMPONENT_ARM_DISARM=400, /* Arms / Disarms a component |1 to arm, 0 to disarm| */ - MAV_CMD_ENUM_END=401, /* | */ + MAV_CMD_START_RX_PAIR=500, /* Starts receiver pairing |0:Spektrum| 0:Spektrum DSM2, 1:Spektrum DSMX| */ + MAV_CMD_ENUM_END=501, /* | */ }; #endif diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_airspeeds.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_airspeeds.h index bd0be342fa..bc47a547ad 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_airspeeds.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_airspeeds.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_airspeeds_pack(uint8_t system_id, uint8_t com * @brief Pack a airspeeds message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param airspeed_imu Airspeed estimate from IMU, cm/s @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_airspeeds_pack_chan(uint8_t system_id, uint8_ } /** - * @brief Encode a airspeeds struct into a message + * @brief Encode a airspeeds struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_airspeeds_encode(uint8_t system_id, uint8_t c return mavlink_msg_airspeeds_pack(system_id, component_id, msg, airspeeds->time_boot_ms, airspeeds->airspeed_imu, airspeeds->airspeed_pitot, airspeeds->airspeed_hot_wire, airspeeds->airspeed_ultrasonic, airspeeds->aoa, airspeeds->aoy); } +/** + * @brief Encode a airspeeds struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param airspeeds C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_airspeeds_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_airspeeds_t* airspeeds) +{ + return mavlink_msg_airspeeds_pack_chan(system_id, component_id, chan, msg, airspeeds->time_boot_ms, airspeeds->airspeed_imu, airspeeds->airspeed_pitot, airspeeds->airspeed_hot_wire, airspeeds->airspeed_ultrasonic, airspeeds->aoa, airspeeds->aoy); +} + /** * @brief Send a airspeeds message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_altitudes.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_altitudes.h index c1ce66875c..e64787cc73 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_altitudes.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_altitudes.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_altitudes_pack(uint8_t system_id, uint8_t com * @brief Pack a altitudes message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param time_boot_ms Timestamp (milliseconds since system boot) * @param alt_gps GPS altitude in meters, expressed as * 1000 (millimeters), above MSL @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_altitudes_pack_chan(uint8_t system_id, uint8_ } /** - * @brief Encode a altitudes struct into a message + * @brief Encode a altitudes struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_altitudes_encode(uint8_t system_id, uint8_t c return mavlink_msg_altitudes_pack(system_id, component_id, msg, altitudes->time_boot_ms, altitudes->alt_gps, altitudes->alt_imu, altitudes->alt_barometric, altitudes->alt_optical_flow, altitudes->alt_range_finder, altitudes->alt_extra); } +/** + * @brief Encode a altitudes struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param altitudes C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_altitudes_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_altitudes_t* altitudes) +{ + return mavlink_msg_altitudes_pack_chan(system_id, component_id, chan, msg, altitudes->time_boot_ms, altitudes->alt_gps, altitudes->alt_imu, altitudes->alt_barometric, altitudes->alt_optical_flow, altitudes->alt_range_finder, altitudes->alt_extra); +} + /** * @brief Send a altitudes message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_buffer_function.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_buffer_function.h index d72a4dcacb..581bd35dc5 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_buffer_function.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_buffer_function.h @@ -87,7 +87,7 @@ static inline uint16_t mavlink_msg_flexifunction_buffer_function_pack(uint8_t sy * @brief Pack a flexifunction_buffer_function message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -133,7 +133,7 @@ static inline uint16_t mavlink_msg_flexifunction_buffer_function_pack_chan(uint8 } /** - * @brief Encode a flexifunction_buffer_function struct into a message + * @brief Encode a flexifunction_buffer_function struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -145,6 +145,20 @@ static inline uint16_t mavlink_msg_flexifunction_buffer_function_encode(uint8_t return mavlink_msg_flexifunction_buffer_function_pack(system_id, component_id, msg, flexifunction_buffer_function->target_system, flexifunction_buffer_function->target_component, flexifunction_buffer_function->func_index, flexifunction_buffer_function->func_count, flexifunction_buffer_function->data_address, flexifunction_buffer_function->data_size, flexifunction_buffer_function->data); } +/** + * @brief Encode a flexifunction_buffer_function struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param flexifunction_buffer_function C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_flexifunction_buffer_function_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_flexifunction_buffer_function_t* flexifunction_buffer_function) +{ + return mavlink_msg_flexifunction_buffer_function_pack_chan(system_id, component_id, chan, msg, flexifunction_buffer_function->target_system, flexifunction_buffer_function->target_component, flexifunction_buffer_function->func_index, flexifunction_buffer_function->func_count, flexifunction_buffer_function->data_address, flexifunction_buffer_function->data_size, flexifunction_buffer_function->data); +} + /** * @brief Send a flexifunction_buffer_function message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_buffer_function_ack.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_buffer_function_ack.h index 58f1786ef9..790afd52b3 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_buffer_function_ack.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_buffer_function_ack.h @@ -74,7 +74,7 @@ static inline uint16_t mavlink_msg_flexifunction_buffer_function_ack_pack(uint8_ * @brief Pack a flexifunction_buffer_function_ack message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -113,7 +113,7 @@ static inline uint16_t mavlink_msg_flexifunction_buffer_function_ack_pack_chan(u } /** - * @brief Encode a flexifunction_buffer_function_ack struct into a message + * @brief Encode a flexifunction_buffer_function_ack struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -125,6 +125,20 @@ static inline uint16_t mavlink_msg_flexifunction_buffer_function_ack_encode(uint return mavlink_msg_flexifunction_buffer_function_ack_pack(system_id, component_id, msg, flexifunction_buffer_function_ack->target_system, flexifunction_buffer_function_ack->target_component, flexifunction_buffer_function_ack->func_index, flexifunction_buffer_function_ack->result); } +/** + * @brief Encode a flexifunction_buffer_function_ack struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param flexifunction_buffer_function_ack C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_flexifunction_buffer_function_ack_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_flexifunction_buffer_function_ack_t* flexifunction_buffer_function_ack) +{ + return mavlink_msg_flexifunction_buffer_function_ack_pack_chan(system_id, component_id, chan, msg, flexifunction_buffer_function_ack->target_system, flexifunction_buffer_function_ack->target_component, flexifunction_buffer_function_ack->func_index, flexifunction_buffer_function_ack->result); +} + /** * @brief Send a flexifunction_buffer_function_ack message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_command.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_command.h index 2f6668cf95..ce722c8a4d 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_command.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_command.h @@ -69,7 +69,7 @@ static inline uint16_t mavlink_msg_flexifunction_command_pack(uint8_t system_id, * @brief Pack a flexifunction_command message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -105,7 +105,7 @@ static inline uint16_t mavlink_msg_flexifunction_command_pack_chan(uint8_t syste } /** - * @brief Encode a flexifunction_command struct into a message + * @brief Encode a flexifunction_command struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -117,6 +117,20 @@ static inline uint16_t mavlink_msg_flexifunction_command_encode(uint8_t system_i return mavlink_msg_flexifunction_command_pack(system_id, component_id, msg, flexifunction_command->target_system, flexifunction_command->target_component, flexifunction_command->command_type); } +/** + * @brief Encode a flexifunction_command struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param flexifunction_command C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_flexifunction_command_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_flexifunction_command_t* flexifunction_command) +{ + return mavlink_msg_flexifunction_command_pack_chan(system_id, component_id, chan, msg, flexifunction_command->target_system, flexifunction_command->target_component, flexifunction_command->command_type); +} + /** * @brief Send a flexifunction_command message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_command_ack.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_command_ack.h index 4798febb01..070dc4bf8d 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_command_ack.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_command_ack.h @@ -64,7 +64,7 @@ static inline uint16_t mavlink_msg_flexifunction_command_ack_pack(uint8_t system * @brief Pack a flexifunction_command_ack message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param command_type Command acknowledged * @param result result of acknowledge @@ -97,7 +97,7 @@ static inline uint16_t mavlink_msg_flexifunction_command_ack_pack_chan(uint8_t s } /** - * @brief Encode a flexifunction_command_ack struct into a message + * @brief Encode a flexifunction_command_ack struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -109,6 +109,20 @@ static inline uint16_t mavlink_msg_flexifunction_command_ack_encode(uint8_t syst return mavlink_msg_flexifunction_command_ack_pack(system_id, component_id, msg, flexifunction_command_ack->command_type, flexifunction_command_ack->result); } +/** + * @brief Encode a flexifunction_command_ack struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param flexifunction_command_ack C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_flexifunction_command_ack_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_flexifunction_command_ack_t* flexifunction_command_ack) +{ + return mavlink_msg_flexifunction_command_ack_pack_chan(system_id, component_id, chan, msg, flexifunction_command_ack->command_type, flexifunction_command_ack->result); +} + /** * @brief Send a flexifunction_command_ack message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_directory.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_directory.h index 947bfc5911..ef262a6b1d 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_directory.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_directory.h @@ -82,7 +82,7 @@ static inline uint16_t mavlink_msg_flexifunction_directory_pack(uint8_t system_i * @brief Pack a flexifunction_directory message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -125,7 +125,7 @@ static inline uint16_t mavlink_msg_flexifunction_directory_pack_chan(uint8_t sys } /** - * @brief Encode a flexifunction_directory struct into a message + * @brief Encode a flexifunction_directory struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -137,6 +137,20 @@ static inline uint16_t mavlink_msg_flexifunction_directory_encode(uint8_t system return mavlink_msg_flexifunction_directory_pack(system_id, component_id, msg, flexifunction_directory->target_system, flexifunction_directory->target_component, flexifunction_directory->directory_type, flexifunction_directory->start_index, flexifunction_directory->count, flexifunction_directory->directory_data); } +/** + * @brief Encode a flexifunction_directory struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param flexifunction_directory C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_flexifunction_directory_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_flexifunction_directory_t* flexifunction_directory) +{ + return mavlink_msg_flexifunction_directory_pack_chan(system_id, component_id, chan, msg, flexifunction_directory->target_system, flexifunction_directory->target_component, flexifunction_directory->directory_type, flexifunction_directory->start_index, flexifunction_directory->count, flexifunction_directory->directory_data); +} + /** * @brief Send a flexifunction_directory message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_directory_ack.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_directory_ack.h index 5489dd6b5e..d3a386ce54 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_directory_ack.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_directory_ack.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_flexifunction_directory_ack_pack(uint8_t syst * @brief Pack a flexifunction_directory_ack message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_flexifunction_directory_ack_pack_chan(uint8_t } /** - * @brief Encode a flexifunction_directory_ack struct into a message + * @brief Encode a flexifunction_directory_ack struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_flexifunction_directory_ack_encode(uint8_t sy return mavlink_msg_flexifunction_directory_ack_pack(system_id, component_id, msg, flexifunction_directory_ack->target_system, flexifunction_directory_ack->target_component, flexifunction_directory_ack->directory_type, flexifunction_directory_ack->start_index, flexifunction_directory_ack->count, flexifunction_directory_ack->result); } +/** + * @brief Encode a flexifunction_directory_ack struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param flexifunction_directory_ack C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_flexifunction_directory_ack_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_flexifunction_directory_ack_t* flexifunction_directory_ack) +{ + return mavlink_msg_flexifunction_directory_ack_pack_chan(system_id, component_id, chan, msg, flexifunction_directory_ack->target_system, flexifunction_directory_ack->target_component, flexifunction_directory_ack->directory_type, flexifunction_directory_ack->start_index, flexifunction_directory_ack->count, flexifunction_directory_ack->result); +} + /** * @brief Send a flexifunction_directory_ack message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_read_req.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_read_req.h index 9ffc2caa5f..e50f77b080 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_read_req.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_read_req.h @@ -74,7 +74,7 @@ static inline uint16_t mavlink_msg_flexifunction_read_req_pack(uint8_t system_id * @brief Pack a flexifunction_read_req message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -113,7 +113,7 @@ static inline uint16_t mavlink_msg_flexifunction_read_req_pack_chan(uint8_t syst } /** - * @brief Encode a flexifunction_read_req struct into a message + * @brief Encode a flexifunction_read_req struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -125,6 +125,20 @@ static inline uint16_t mavlink_msg_flexifunction_read_req_encode(uint8_t system_ return mavlink_msg_flexifunction_read_req_pack(system_id, component_id, msg, flexifunction_read_req->target_system, flexifunction_read_req->target_component, flexifunction_read_req->read_req_type, flexifunction_read_req->data_index); } +/** + * @brief Encode a flexifunction_read_req struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param flexifunction_read_req C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_flexifunction_read_req_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_flexifunction_read_req_t* flexifunction_read_req) +{ + return mavlink_msg_flexifunction_read_req_pack_chan(system_id, component_id, chan, msg, flexifunction_read_req->target_system, flexifunction_read_req->target_component, flexifunction_read_req->read_req_type, flexifunction_read_req->data_index); +} + /** * @brief Send a flexifunction_read_req message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_set.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_set.h index fc7d1d2f8e..41afb3811d 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_set.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_flexifunction_set.h @@ -64,7 +64,7 @@ static inline uint16_t mavlink_msg_flexifunction_set_pack(uint8_t system_id, uin * @brief Pack a flexifunction_set message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -97,7 +97,7 @@ static inline uint16_t mavlink_msg_flexifunction_set_pack_chan(uint8_t system_id } /** - * @brief Encode a flexifunction_set struct into a message + * @brief Encode a flexifunction_set struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -109,6 +109,20 @@ static inline uint16_t mavlink_msg_flexifunction_set_encode(uint8_t system_id, u return mavlink_msg_flexifunction_set_pack(system_id, component_id, msg, flexifunction_set->target_system, flexifunction_set->target_component); } +/** + * @brief Encode a flexifunction_set struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param flexifunction_set C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_flexifunction_set_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_flexifunction_set_t* flexifunction_set) +{ + return mavlink_msg_flexifunction_set_pack_chan(system_id, component_id, chan, msg, flexifunction_set->target_system, flexifunction_set->target_component); +} + /** * @brief Send a flexifunction_set message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f13.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f13.h index df5645e765..d21ab48168 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f13.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f13.h @@ -74,7 +74,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f13_pack(uint8_t system_id, * @brief Pack a serial_udb_extra_f13 message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param sue_week_no Serial UDB Extra GPS Week Number * @param sue_lat_origin Serial UDB Extra MP Origin Latitude @@ -113,7 +113,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f13_pack_chan(uint8_t system } /** - * @brief Encode a serial_udb_extra_f13 struct into a message + * @brief Encode a serial_udb_extra_f13 struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -125,6 +125,20 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f13_encode(uint8_t system_id return mavlink_msg_serial_udb_extra_f13_pack(system_id, component_id, msg, serial_udb_extra_f13->sue_week_no, serial_udb_extra_f13->sue_lat_origin, serial_udb_extra_f13->sue_lon_origin, serial_udb_extra_f13->sue_alt_origin); } +/** + * @brief Encode a serial_udb_extra_f13 struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param serial_udb_extra_f13 C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_serial_udb_extra_f13_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_serial_udb_extra_f13_t* serial_udb_extra_f13) +{ + return mavlink_msg_serial_udb_extra_f13_pack_chan(system_id, component_id, chan, msg, serial_udb_extra_f13->sue_week_no, serial_udb_extra_f13->sue_lat_origin, serial_udb_extra_f13->sue_lon_origin, serial_udb_extra_f13->sue_alt_origin); +} + /** * @brief Send a serial_udb_extra_f13 message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f14.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f14.h index 5e38a590a4..6ac12f28a6 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f14.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f14.h @@ -109,7 +109,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f14_pack(uint8_t system_id, * @brief Pack a serial_udb_extra_f14 message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param sue_WIND_ESTIMATION Serial UDB Extra Wind Estimation Enabled * @param sue_GPS_TYPE Serial UDB Extra Type of GPS Unit @@ -169,7 +169,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f14_pack_chan(uint8_t system } /** - * @brief Encode a serial_udb_extra_f14 struct into a message + * @brief Encode a serial_udb_extra_f14 struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -181,6 +181,20 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f14_encode(uint8_t system_id return mavlink_msg_serial_udb_extra_f14_pack(system_id, component_id, msg, serial_udb_extra_f14->sue_WIND_ESTIMATION, serial_udb_extra_f14->sue_GPS_TYPE, serial_udb_extra_f14->sue_DR, serial_udb_extra_f14->sue_BOARD_TYPE, serial_udb_extra_f14->sue_AIRFRAME, serial_udb_extra_f14->sue_RCON, serial_udb_extra_f14->sue_TRAP_FLAGS, serial_udb_extra_f14->sue_TRAP_SOURCE, serial_udb_extra_f14->sue_osc_fail_count, serial_udb_extra_f14->sue_CLOCK_CONFIG, serial_udb_extra_f14->sue_FLIGHT_PLAN_TYPE); } +/** + * @brief Encode a serial_udb_extra_f14 struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param serial_udb_extra_f14 C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_serial_udb_extra_f14_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_serial_udb_extra_f14_t* serial_udb_extra_f14) +{ + return mavlink_msg_serial_udb_extra_f14_pack_chan(system_id, component_id, chan, msg, serial_udb_extra_f14->sue_WIND_ESTIMATION, serial_udb_extra_f14->sue_GPS_TYPE, serial_udb_extra_f14->sue_DR, serial_udb_extra_f14->sue_BOARD_TYPE, serial_udb_extra_f14->sue_AIRFRAME, serial_udb_extra_f14->sue_RCON, serial_udb_extra_f14->sue_TRAP_FLAGS, serial_udb_extra_f14->sue_TRAP_SOURCE, serial_udb_extra_f14->sue_osc_fail_count, serial_udb_extra_f14->sue_CLOCK_CONFIG, serial_udb_extra_f14->sue_FLIGHT_PLAN_TYPE); +} + /** * @brief Send a serial_udb_extra_f14 message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f15.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f15.h index 8779b25ff5..10c3f4ca4f 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f15.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f15.h @@ -65,7 +65,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f15_pack(uint8_t system_id, * @brief Pack a serial_udb_extra_f15 message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param sue_ID_VEHICLE_MODEL_NAME Serial UDB Extra Model Name Of Vehicle * @param sue_ID_VEHICLE_REGISTRATION Serial UDB Extra Registraton Number of Vehicle @@ -98,7 +98,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f15_pack_chan(uint8_t system } /** - * @brief Encode a serial_udb_extra_f15 struct into a message + * @brief Encode a serial_udb_extra_f15 struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -110,6 +110,20 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f15_encode(uint8_t system_id return mavlink_msg_serial_udb_extra_f15_pack(system_id, component_id, msg, serial_udb_extra_f15->sue_ID_VEHICLE_MODEL_NAME, serial_udb_extra_f15->sue_ID_VEHICLE_REGISTRATION); } +/** + * @brief Encode a serial_udb_extra_f15 struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param serial_udb_extra_f15 C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_serial_udb_extra_f15_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_serial_udb_extra_f15_t* serial_udb_extra_f15) +{ + return mavlink_msg_serial_udb_extra_f15_pack_chan(system_id, component_id, chan, msg, serial_udb_extra_f15->sue_ID_VEHICLE_MODEL_NAME, serial_udb_extra_f15->sue_ID_VEHICLE_REGISTRATION); +} + /** * @brief Send a serial_udb_extra_f15 message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f16.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f16.h index 1a173bfe44..659e6b7c52 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f16.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f16.h @@ -65,7 +65,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f16_pack(uint8_t system_id, * @brief Pack a serial_udb_extra_f16 message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param sue_ID_LEAD_PILOT Serial UDB Extra Name of Expected Lead Pilot * @param sue_ID_DIY_DRONES_URL Serial UDB Extra URL of Lead Pilot or Team @@ -98,7 +98,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f16_pack_chan(uint8_t system } /** - * @brief Encode a serial_udb_extra_f16 struct into a message + * @brief Encode a serial_udb_extra_f16 struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -110,6 +110,20 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f16_encode(uint8_t system_id return mavlink_msg_serial_udb_extra_f16_pack(system_id, component_id, msg, serial_udb_extra_f16->sue_ID_LEAD_PILOT, serial_udb_extra_f16->sue_ID_DIY_DRONES_URL); } +/** + * @brief Encode a serial_udb_extra_f16 struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param serial_udb_extra_f16 C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_serial_udb_extra_f16_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_serial_udb_extra_f16_t* serial_udb_extra_f16) +{ + return mavlink_msg_serial_udb_extra_f16_pack_chan(system_id, component_id, chan, msg, serial_udb_extra_f16->sue_ID_LEAD_PILOT, serial_udb_extra_f16->sue_ID_DIY_DRONES_URL); +} + /** * @brief Send a serial_udb_extra_f16 message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f2_a.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f2_a.h index ddfc236ba4..15ba68a346 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f2_a.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f2_a.h @@ -194,7 +194,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f2_a_pack(uint8_t system_id, * @brief Pack a serial_udb_extra_f2_a message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param sue_time Serial UDB Extra Time * @param sue_status Serial UDB Extra Status @@ -305,7 +305,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f2_a_pack_chan(uint8_t syste } /** - * @brief Encode a serial_udb_extra_f2_a struct into a message + * @brief Encode a serial_udb_extra_f2_a struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -317,6 +317,20 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f2_a_encode(uint8_t system_i return mavlink_msg_serial_udb_extra_f2_a_pack(system_id, component_id, msg, serial_udb_extra_f2_a->sue_time, serial_udb_extra_f2_a->sue_status, serial_udb_extra_f2_a->sue_latitude, serial_udb_extra_f2_a->sue_longitude, serial_udb_extra_f2_a->sue_altitude, serial_udb_extra_f2_a->sue_waypoint_index, serial_udb_extra_f2_a->sue_rmat0, serial_udb_extra_f2_a->sue_rmat1, serial_udb_extra_f2_a->sue_rmat2, serial_udb_extra_f2_a->sue_rmat3, serial_udb_extra_f2_a->sue_rmat4, serial_udb_extra_f2_a->sue_rmat5, serial_udb_extra_f2_a->sue_rmat6, serial_udb_extra_f2_a->sue_rmat7, serial_udb_extra_f2_a->sue_rmat8, serial_udb_extra_f2_a->sue_cog, serial_udb_extra_f2_a->sue_sog, serial_udb_extra_f2_a->sue_cpu_load, serial_udb_extra_f2_a->sue_voltage_milis, serial_udb_extra_f2_a->sue_air_speed_3DIMU, serial_udb_extra_f2_a->sue_estimated_wind_0, serial_udb_extra_f2_a->sue_estimated_wind_1, serial_udb_extra_f2_a->sue_estimated_wind_2, serial_udb_extra_f2_a->sue_magFieldEarth0, serial_udb_extra_f2_a->sue_magFieldEarth1, serial_udb_extra_f2_a->sue_magFieldEarth2, serial_udb_extra_f2_a->sue_svs, serial_udb_extra_f2_a->sue_hdop); } +/** + * @brief Encode a serial_udb_extra_f2_a struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param serial_udb_extra_f2_a C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_serial_udb_extra_f2_a_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_serial_udb_extra_f2_a_t* serial_udb_extra_f2_a) +{ + return mavlink_msg_serial_udb_extra_f2_a_pack_chan(system_id, component_id, chan, msg, serial_udb_extra_f2_a->sue_time, serial_udb_extra_f2_a->sue_status, serial_udb_extra_f2_a->sue_latitude, serial_udb_extra_f2_a->sue_longitude, serial_udb_extra_f2_a->sue_altitude, serial_udb_extra_f2_a->sue_waypoint_index, serial_udb_extra_f2_a->sue_rmat0, serial_udb_extra_f2_a->sue_rmat1, serial_udb_extra_f2_a->sue_rmat2, serial_udb_extra_f2_a->sue_rmat3, serial_udb_extra_f2_a->sue_rmat4, serial_udb_extra_f2_a->sue_rmat5, serial_udb_extra_f2_a->sue_rmat6, serial_udb_extra_f2_a->sue_rmat7, serial_udb_extra_f2_a->sue_rmat8, serial_udb_extra_f2_a->sue_cog, serial_udb_extra_f2_a->sue_sog, serial_udb_extra_f2_a->sue_cpu_load, serial_udb_extra_f2_a->sue_voltage_milis, serial_udb_extra_f2_a->sue_air_speed_3DIMU, serial_udb_extra_f2_a->sue_estimated_wind_0, serial_udb_extra_f2_a->sue_estimated_wind_1, serial_udb_extra_f2_a->sue_estimated_wind_2, serial_udb_extra_f2_a->sue_magFieldEarth0, serial_udb_extra_f2_a->sue_magFieldEarth1, serial_udb_extra_f2_a->sue_magFieldEarth2, serial_udb_extra_f2_a->sue_svs, serial_udb_extra_f2_a->sue_hdop); +} + /** * @brief Send a serial_udb_extra_f2_a message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f2_b.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f2_b.h index 74da8416d8..7cb8c87da5 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f2_b.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f2_b.h @@ -219,7 +219,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f2_b_pack(uint8_t system_id, * @brief Pack a serial_udb_extra_f2_b message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param sue_time Serial UDB Extra Time * @param sue_pwm_input_1 Serial UDB Extra PWM Input Channel 1 @@ -345,7 +345,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f2_b_pack_chan(uint8_t syste } /** - * @brief Encode a serial_udb_extra_f2_b struct into a message + * @brief Encode a serial_udb_extra_f2_b struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -357,6 +357,20 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f2_b_encode(uint8_t system_i return mavlink_msg_serial_udb_extra_f2_b_pack(system_id, component_id, msg, serial_udb_extra_f2_b->sue_time, serial_udb_extra_f2_b->sue_pwm_input_1, serial_udb_extra_f2_b->sue_pwm_input_2, serial_udb_extra_f2_b->sue_pwm_input_3, serial_udb_extra_f2_b->sue_pwm_input_4, serial_udb_extra_f2_b->sue_pwm_input_5, serial_udb_extra_f2_b->sue_pwm_input_6, serial_udb_extra_f2_b->sue_pwm_input_7, serial_udb_extra_f2_b->sue_pwm_input_8, serial_udb_extra_f2_b->sue_pwm_input_9, serial_udb_extra_f2_b->sue_pwm_input_10, serial_udb_extra_f2_b->sue_pwm_output_1, serial_udb_extra_f2_b->sue_pwm_output_2, serial_udb_extra_f2_b->sue_pwm_output_3, serial_udb_extra_f2_b->sue_pwm_output_4, serial_udb_extra_f2_b->sue_pwm_output_5, serial_udb_extra_f2_b->sue_pwm_output_6, serial_udb_extra_f2_b->sue_pwm_output_7, serial_udb_extra_f2_b->sue_pwm_output_8, serial_udb_extra_f2_b->sue_pwm_output_9, serial_udb_extra_f2_b->sue_pwm_output_10, serial_udb_extra_f2_b->sue_imu_location_x, serial_udb_extra_f2_b->sue_imu_location_y, serial_udb_extra_f2_b->sue_imu_location_z, serial_udb_extra_f2_b->sue_flags, serial_udb_extra_f2_b->sue_osc_fails, serial_udb_extra_f2_b->sue_imu_velocity_x, serial_udb_extra_f2_b->sue_imu_velocity_y, serial_udb_extra_f2_b->sue_imu_velocity_z, serial_udb_extra_f2_b->sue_waypoint_goal_x, serial_udb_extra_f2_b->sue_waypoint_goal_y, serial_udb_extra_f2_b->sue_waypoint_goal_z, serial_udb_extra_f2_b->sue_memory_stack_free); } +/** + * @brief Encode a serial_udb_extra_f2_b struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param serial_udb_extra_f2_b C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_serial_udb_extra_f2_b_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_serial_udb_extra_f2_b_t* serial_udb_extra_f2_b) +{ + return mavlink_msg_serial_udb_extra_f2_b_pack_chan(system_id, component_id, chan, msg, serial_udb_extra_f2_b->sue_time, serial_udb_extra_f2_b->sue_pwm_input_1, serial_udb_extra_f2_b->sue_pwm_input_2, serial_udb_extra_f2_b->sue_pwm_input_3, serial_udb_extra_f2_b->sue_pwm_input_4, serial_udb_extra_f2_b->sue_pwm_input_5, serial_udb_extra_f2_b->sue_pwm_input_6, serial_udb_extra_f2_b->sue_pwm_input_7, serial_udb_extra_f2_b->sue_pwm_input_8, serial_udb_extra_f2_b->sue_pwm_input_9, serial_udb_extra_f2_b->sue_pwm_input_10, serial_udb_extra_f2_b->sue_pwm_output_1, serial_udb_extra_f2_b->sue_pwm_output_2, serial_udb_extra_f2_b->sue_pwm_output_3, serial_udb_extra_f2_b->sue_pwm_output_4, serial_udb_extra_f2_b->sue_pwm_output_5, serial_udb_extra_f2_b->sue_pwm_output_6, serial_udb_extra_f2_b->sue_pwm_output_7, serial_udb_extra_f2_b->sue_pwm_output_8, serial_udb_extra_f2_b->sue_pwm_output_9, serial_udb_extra_f2_b->sue_pwm_output_10, serial_udb_extra_f2_b->sue_imu_location_x, serial_udb_extra_f2_b->sue_imu_location_y, serial_udb_extra_f2_b->sue_imu_location_z, serial_udb_extra_f2_b->sue_flags, serial_udb_extra_f2_b->sue_osc_fails, serial_udb_extra_f2_b->sue_imu_velocity_x, serial_udb_extra_f2_b->sue_imu_velocity_y, serial_udb_extra_f2_b->sue_imu_velocity_z, serial_udb_extra_f2_b->sue_waypoint_goal_x, serial_udb_extra_f2_b->sue_waypoint_goal_y, serial_udb_extra_f2_b->sue_waypoint_goal_z, serial_udb_extra_f2_b->sue_memory_stack_free); +} + /** * @brief Send a serial_udb_extra_f2_b message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f4.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f4.h index 83ccbbedb4..77c616cc2e 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f4.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f4.h @@ -104,7 +104,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f4_pack(uint8_t system_id, u * @brief Pack a serial_udb_extra_f4 message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param sue_ROLL_STABILIZATION_AILERONS Serial UDB Extra Roll Stabilization with Ailerons Enabled * @param sue_ROLL_STABILIZATION_RUDDER Serial UDB Extra Roll Stabilization with Rudder Enabled @@ -161,7 +161,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f4_pack_chan(uint8_t system_ } /** - * @brief Encode a serial_udb_extra_f4 struct into a message + * @brief Encode a serial_udb_extra_f4 struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -173,6 +173,20 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f4_encode(uint8_t system_id, return mavlink_msg_serial_udb_extra_f4_pack(system_id, component_id, msg, serial_udb_extra_f4->sue_ROLL_STABILIZATION_AILERONS, serial_udb_extra_f4->sue_ROLL_STABILIZATION_RUDDER, serial_udb_extra_f4->sue_PITCH_STABILIZATION, serial_udb_extra_f4->sue_YAW_STABILIZATION_RUDDER, serial_udb_extra_f4->sue_YAW_STABILIZATION_AILERON, serial_udb_extra_f4->sue_AILERON_NAVIGATION, serial_udb_extra_f4->sue_RUDDER_NAVIGATION, serial_udb_extra_f4->sue_ALTITUDEHOLD_STABILIZED, serial_udb_extra_f4->sue_ALTITUDEHOLD_WAYPOINT, serial_udb_extra_f4->sue_RACING_MODE); } +/** + * @brief Encode a serial_udb_extra_f4 struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param serial_udb_extra_f4 C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_serial_udb_extra_f4_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_serial_udb_extra_f4_t* serial_udb_extra_f4) +{ + return mavlink_msg_serial_udb_extra_f4_pack_chan(system_id, component_id, chan, msg, serial_udb_extra_f4->sue_ROLL_STABILIZATION_AILERONS, serial_udb_extra_f4->sue_ROLL_STABILIZATION_RUDDER, serial_udb_extra_f4->sue_PITCH_STABILIZATION, serial_udb_extra_f4->sue_YAW_STABILIZATION_RUDDER, serial_udb_extra_f4->sue_YAW_STABILIZATION_AILERON, serial_udb_extra_f4->sue_AILERON_NAVIGATION, serial_udb_extra_f4->sue_RUDDER_NAVIGATION, serial_udb_extra_f4->sue_ALTITUDEHOLD_STABILIZED, serial_udb_extra_f4->sue_ALTITUDEHOLD_WAYPOINT, serial_udb_extra_f4->sue_RACING_MODE); +} + /** * @brief Send a serial_udb_extra_f4 message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f5.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f5.h index 2b2451f00d..e115a9b445 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f5.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f5.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f5_pack(uint8_t system_id, u * @brief Pack a serial_udb_extra_f5 message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param sue_YAWKP_AILERON Serial UDB YAWKP_AILERON Gain for Proporional control of navigation * @param sue_YAWKD_AILERON Serial UDB YAWKD_AILERON Gain for Rate control of navigation @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f5_pack_chan(uint8_t system_ } /** - * @brief Encode a serial_udb_extra_f5 struct into a message + * @brief Encode a serial_udb_extra_f5 struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f5_encode(uint8_t system_id, return mavlink_msg_serial_udb_extra_f5_pack(system_id, component_id, msg, serial_udb_extra_f5->sue_YAWKP_AILERON, serial_udb_extra_f5->sue_YAWKD_AILERON, serial_udb_extra_f5->sue_ROLLKP, serial_udb_extra_f5->sue_ROLLKD, serial_udb_extra_f5->sue_YAW_STABILIZATION_AILERON, serial_udb_extra_f5->sue_AILERON_BOOST); } +/** + * @brief Encode a serial_udb_extra_f5 struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param serial_udb_extra_f5 C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_serial_udb_extra_f5_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_serial_udb_extra_f5_t* serial_udb_extra_f5) +{ + return mavlink_msg_serial_udb_extra_f5_pack_chan(system_id, component_id, chan, msg, serial_udb_extra_f5->sue_YAWKP_AILERON, serial_udb_extra_f5->sue_YAWKD_AILERON, serial_udb_extra_f5->sue_ROLLKP, serial_udb_extra_f5->sue_ROLLKD, serial_udb_extra_f5->sue_YAW_STABILIZATION_AILERON, serial_udb_extra_f5->sue_AILERON_BOOST); +} + /** * @brief Send a serial_udb_extra_f5 message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f6.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f6.h index 9d58ca9a8e..656103d090 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f6.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f6.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f6_pack(uint8_t system_id, u * @brief Pack a serial_udb_extra_f6 message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param sue_PITCHGAIN Serial UDB Extra PITCHGAIN Proportional Control * @param sue_PITCHKD Serial UDB Extra Pitch Rate Control @@ -121,7 +121,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f6_pack_chan(uint8_t system_ } /** - * @brief Encode a serial_udb_extra_f6 struct into a message + * @brief Encode a serial_udb_extra_f6 struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -133,6 +133,20 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f6_encode(uint8_t system_id, return mavlink_msg_serial_udb_extra_f6_pack(system_id, component_id, msg, serial_udb_extra_f6->sue_PITCHGAIN, serial_udb_extra_f6->sue_PITCHKD, serial_udb_extra_f6->sue_RUDDER_ELEV_MIX, serial_udb_extra_f6->sue_ROLL_ELEV_MIX, serial_udb_extra_f6->sue_ELEVATOR_BOOST); } +/** + * @brief Encode a serial_udb_extra_f6 struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param serial_udb_extra_f6 C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_serial_udb_extra_f6_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_serial_udb_extra_f6_t* serial_udb_extra_f6) +{ + return mavlink_msg_serial_udb_extra_f6_pack_chan(system_id, component_id, chan, msg, serial_udb_extra_f6->sue_PITCHGAIN, serial_udb_extra_f6->sue_PITCHKD, serial_udb_extra_f6->sue_RUDDER_ELEV_MIX, serial_udb_extra_f6->sue_ROLL_ELEV_MIX, serial_udb_extra_f6->sue_ELEVATOR_BOOST); +} + /** * @brief Send a serial_udb_extra_f6 message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f7.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f7.h index ab73b967e0..51c98e6b7a 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f7.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f7.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f7_pack(uint8_t system_id, u * @brief Pack a serial_udb_extra_f7 message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param sue_YAWKP_RUDDER Serial UDB YAWKP_RUDDER Gain for Proporional control of navigation * @param sue_YAWKD_RUDDER Serial UDB YAWKD_RUDDER Gain for Rate control of navigation @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f7_pack_chan(uint8_t system_ } /** - * @brief Encode a serial_udb_extra_f7 struct into a message + * @brief Encode a serial_udb_extra_f7 struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f7_encode(uint8_t system_id, return mavlink_msg_serial_udb_extra_f7_pack(system_id, component_id, msg, serial_udb_extra_f7->sue_YAWKP_RUDDER, serial_udb_extra_f7->sue_YAWKD_RUDDER, serial_udb_extra_f7->sue_ROLLKP_RUDDER, serial_udb_extra_f7->sue_ROLLKD_RUDDER, serial_udb_extra_f7->sue_RUDDER_BOOST, serial_udb_extra_f7->sue_RTL_PITCH_DOWN); } +/** + * @brief Encode a serial_udb_extra_f7 struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param serial_udb_extra_f7 C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_serial_udb_extra_f7_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_serial_udb_extra_f7_t* serial_udb_extra_f7) +{ + return mavlink_msg_serial_udb_extra_f7_pack_chan(system_id, component_id, chan, msg, serial_udb_extra_f7->sue_YAWKP_RUDDER, serial_udb_extra_f7->sue_YAWKD_RUDDER, serial_udb_extra_f7->sue_ROLLKP_RUDDER, serial_udb_extra_f7->sue_ROLLKD_RUDDER, serial_udb_extra_f7->sue_RUDDER_BOOST, serial_udb_extra_f7->sue_RTL_PITCH_DOWN); +} + /** * @brief Send a serial_udb_extra_f7 message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f8.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f8.h index 310246e8e7..8557a95e27 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f8.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/mavlink_msg_serial_udb_extra_f8.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f8_pack(uint8_t system_id, u * @brief Pack a serial_udb_extra_f8 message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param sue_HEIGHT_TARGET_MAX Serial UDB Extra HEIGHT_TARGET_MAX * @param sue_HEIGHT_TARGET_MIN Serial UDB Extra HEIGHT_TARGET_MIN @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f8_pack_chan(uint8_t system_ } /** - * @brief Encode a serial_udb_extra_f8 struct into a message + * @brief Encode a serial_udb_extra_f8 struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_serial_udb_extra_f8_encode(uint8_t system_id, return mavlink_msg_serial_udb_extra_f8_pack(system_id, component_id, msg, serial_udb_extra_f8->sue_HEIGHT_TARGET_MAX, serial_udb_extra_f8->sue_HEIGHT_TARGET_MIN, serial_udb_extra_f8->sue_ALT_HOLD_THROTTLE_MIN, serial_udb_extra_f8->sue_ALT_HOLD_THROTTLE_MAX, serial_udb_extra_f8->sue_ALT_HOLD_PITCH_MIN, serial_udb_extra_f8->sue_ALT_HOLD_PITCH_MAX, serial_udb_extra_f8->sue_ALT_HOLD_PITCH_HIGH); } +/** + * @brief Encode a serial_udb_extra_f8 struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param serial_udb_extra_f8 C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_serial_udb_extra_f8_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_serial_udb_extra_f8_t* serial_udb_extra_f8) +{ + return mavlink_msg_serial_udb_extra_f8_pack_chan(system_id, component_id, chan, msg, serial_udb_extra_f8->sue_HEIGHT_TARGET_MAX, serial_udb_extra_f8->sue_HEIGHT_TARGET_MIN, serial_udb_extra_f8->sue_ALT_HOLD_THROTTLE_MIN, serial_udb_extra_f8->sue_ALT_HOLD_THROTTLE_MAX, serial_udb_extra_f8->sue_ALT_HOLD_PITCH_MIN, serial_udb_extra_f8->sue_ALT_HOLD_PITCH_MAX, serial_udb_extra_f8->sue_ALT_HOLD_PITCH_HIGH); +} + /** * @brief Send a serial_udb_extra_f8 message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/matrixpilot/version.h b/libs/mavlink/include/mavlink/v1.0/matrixpilot/version.h index ea0265298b..59f3d2ded2 100644 --- a/libs/mavlink/include/mavlink/v1.0/matrixpilot/version.h +++ b/libs/mavlink/include/mavlink/v1.0/matrixpilot/version.h @@ -5,7 +5,7 @@ #ifndef MAVLINK_VERSION_H #define MAVLINK_VERSION_H -#define MAVLINK_BUILD_DATE "Thu Jul 4 13:11:50 2013" +#define MAVLINK_BUILD_DATE "Tue Sep 10 23:49:51 2013" #define MAVLINK_WIRE_PROTOCOL_VERSION "1.0" #define MAVLINK_MAX_DIALECT_PAYLOAD_SIZE 254 diff --git a/libs/mavlink/include/mavlink/v1.0/mavlink_helpers.h b/libs/mavlink/include/mavlink/v1.0/mavlink_helpers.h index 72cf91fb9f..96672f847f 100644 --- a/libs/mavlink/include/mavlink/v1.0/mavlink_helpers.h +++ b/libs/mavlink/include/mavlink/v1.0/mavlink_helpers.h @@ -16,7 +16,12 @@ #ifndef MAVLINK_GET_CHANNEL_STATUS MAVLINK_HELPER mavlink_status_t* mavlink_get_channel_status(uint8_t chan) { +#if MAVLINK_EXTERNAL_RX_STATUS + // No m_mavlink_status array defined in function, + // has to be defined externally +#else static mavlink_status_t m_mavlink_status[MAVLINK_COMM_NUM_BUFFERS]; +#endif return &m_mavlink_status[chan]; } #endif @@ -29,11 +34,8 @@ MAVLINK_HELPER mavlink_message_t* mavlink_get_channel_buffer(uint8_t chan) { #if MAVLINK_EXTERNAL_RX_BUFFER - // No m_mavlink_message array defined in function, + // No m_mavlink_buffer array defined in function, // has to be defined externally -#ifndef m_mavlink_message -#error ERROR: IF #define MAVLINK_EXTERNAL_RX_BUFFER IS SET, THE BUFFER HAS TO BE ALLOCATED OUTSIDE OF THIS FUNCTION (mavlink_message_t m_mavlink_buffer[MAVLINK_COMM_NUM_BUFFERS];) -#endif #else static mavlink_message_t m_mavlink_buffer[MAVLINK_COMM_NUM_BUFFERS]; #endif diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_attitude_control.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_attitude_control.h index 1aac8395df..ef5354d5e1 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_attitude_control.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_attitude_control.h @@ -99,7 +99,7 @@ static inline uint16_t mavlink_msg_attitude_control_pack(uint8_t system_id, uint * @brief Pack a attitude_control message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target The system to be controlled * @param roll roll @@ -153,7 +153,7 @@ static inline uint16_t mavlink_msg_attitude_control_pack_chan(uint8_t system_id, } /** - * @brief Encode a attitude_control struct into a message + * @brief Encode a attitude_control struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -165,6 +165,20 @@ static inline uint16_t mavlink_msg_attitude_control_encode(uint8_t system_id, ui return mavlink_msg_attitude_control_pack(system_id, component_id, msg, attitude_control->target, attitude_control->roll, attitude_control->pitch, attitude_control->yaw, attitude_control->thrust, attitude_control->roll_manual, attitude_control->pitch_manual, attitude_control->yaw_manual, attitude_control->thrust_manual); } +/** + * @brief Encode a attitude_control struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param attitude_control C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_attitude_control_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_attitude_control_t* attitude_control) +{ + return mavlink_msg_attitude_control_pack_chan(system_id, component_id, chan, msg, attitude_control->target, attitude_control->roll, attitude_control->pitch, attitude_control->yaw, attitude_control->thrust, attitude_control->roll_manual, attitude_control->pitch_manual, attitude_control->yaw_manual, attitude_control->thrust_manual); +} + /** * @brief Send a attitude_control message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_brief_feature.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_brief_feature.h index 353e105814..d41093792e 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_brief_feature.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_brief_feature.h @@ -92,7 +92,7 @@ static inline uint16_t mavlink_msg_brief_feature_pack(uint8_t system_id, uint8_t * @brief Pack a brief_feature message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param x x position in m * @param y y position in m @@ -141,7 +141,7 @@ static inline uint16_t mavlink_msg_brief_feature_pack_chan(uint8_t system_id, ui } /** - * @brief Encode a brief_feature struct into a message + * @brief Encode a brief_feature struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -153,6 +153,20 @@ static inline uint16_t mavlink_msg_brief_feature_encode(uint8_t system_id, uint8 return mavlink_msg_brief_feature_pack(system_id, component_id, msg, brief_feature->x, brief_feature->y, brief_feature->z, brief_feature->orientation_assignment, brief_feature->size, brief_feature->orientation, brief_feature->descriptor, brief_feature->response); } +/** + * @brief Encode a brief_feature struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param brief_feature C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_brief_feature_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_brief_feature_t* brief_feature) +{ + return mavlink_msg_brief_feature_pack_chan(system_id, component_id, chan, msg, brief_feature->x, brief_feature->y, brief_feature->z, brief_feature->orientation_assignment, brief_feature->size, brief_feature->orientation, brief_feature->descriptor, brief_feature->response); +} + /** * @brief Send a brief_feature message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_data_transmission_handshake.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_data_transmission_handshake.h index 5251c35c32..a7af8c8ebb 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_data_transmission_handshake.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_data_transmission_handshake.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_data_transmission_handshake_pack(uint8_t syst * @brief Pack a data_transmission_handshake message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param type type of requested/acknowledged data (as defined in ENUM DATA_TYPES in mavlink/include/mavlink_types.h) * @param size total data size in bytes (set on ACK only) @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_data_transmission_handshake_pack_chan(uint8_t } /** - * @brief Encode a data_transmission_handshake struct into a message + * @brief Encode a data_transmission_handshake struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_data_transmission_handshake_encode(uint8_t sy return mavlink_msg_data_transmission_handshake_pack(system_id, component_id, msg, data_transmission_handshake->type, data_transmission_handshake->size, data_transmission_handshake->width, data_transmission_handshake->height, data_transmission_handshake->packets, data_transmission_handshake->payload, data_transmission_handshake->jpg_quality); } +/** + * @brief Encode a data_transmission_handshake struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param data_transmission_handshake C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_data_transmission_handshake_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_data_transmission_handshake_t* data_transmission_handshake) +{ + return mavlink_msg_data_transmission_handshake_pack_chan(system_id, component_id, chan, msg, data_transmission_handshake->type, data_transmission_handshake->size, data_transmission_handshake->width, data_transmission_handshake->height, data_transmission_handshake->packets, data_transmission_handshake->payload, data_transmission_handshake->jpg_quality); +} + /** * @brief Send a data_transmission_handshake message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_encapsulated_data.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_encapsulated_data.h index feeef6f398..40001dc309 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_encapsulated_data.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_encapsulated_data.h @@ -62,7 +62,7 @@ static inline uint16_t mavlink_msg_encapsulated_data_pack(uint8_t system_id, uin * @brief Pack a encapsulated_data message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param seqnr sequence number (starting with 0 on every transmission) * @param data image data bytes @@ -93,7 +93,7 @@ static inline uint16_t mavlink_msg_encapsulated_data_pack_chan(uint8_t system_id } /** - * @brief Encode a encapsulated_data struct into a message + * @brief Encode a encapsulated_data struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -105,6 +105,20 @@ static inline uint16_t mavlink_msg_encapsulated_data_encode(uint8_t system_id, u return mavlink_msg_encapsulated_data_pack(system_id, component_id, msg, encapsulated_data->seqnr, encapsulated_data->data); } +/** + * @brief Encode a encapsulated_data struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param encapsulated_data C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_encapsulated_data_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_encapsulated_data_t* encapsulated_data) +{ + return mavlink_msg_encapsulated_data_pack_chan(system_id, component_id, chan, msg, encapsulated_data->seqnr, encapsulated_data->data); +} + /** * @brief Send a encapsulated_data message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_image_available.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_image_available.h index 6d1d9cca76..ae4db825df 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_image_available.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_image_available.h @@ -169,7 +169,7 @@ static inline uint16_t mavlink_msg_image_available_pack(uint8_t system_id, uint8 * @brief Pack a image_available message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param cam_id Camera id * @param cam_no Camera # (starts with 0) @@ -265,7 +265,7 @@ static inline uint16_t mavlink_msg_image_available_pack_chan(uint8_t system_id, } /** - * @brief Encode a image_available struct into a message + * @brief Encode a image_available struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -277,6 +277,20 @@ static inline uint16_t mavlink_msg_image_available_encode(uint8_t system_id, uin return mavlink_msg_image_available_pack(system_id, component_id, msg, image_available->cam_id, image_available->cam_no, image_available->timestamp, image_available->valid_until, image_available->img_seq, image_available->img_buf_index, image_available->width, image_available->height, image_available->depth, image_available->channels, image_available->key, image_available->exposure, image_available->gain, image_available->roll, image_available->pitch, image_available->yaw, image_available->local_z, image_available->lat, image_available->lon, image_available->alt, image_available->ground_x, image_available->ground_y, image_available->ground_z); } +/** + * @brief Encode a image_available struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param image_available C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_image_available_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_image_available_t* image_available) +{ + return mavlink_msg_image_available_pack_chan(system_id, component_id, chan, msg, image_available->cam_id, image_available->cam_no, image_available->timestamp, image_available->valid_until, image_available->img_seq, image_available->img_buf_index, image_available->width, image_available->height, image_available->depth, image_available->channels, image_available->key, image_available->exposure, image_available->gain, image_available->roll, image_available->pitch, image_available->yaw, image_available->local_z, image_available->lat, image_available->lon, image_available->alt, image_available->ground_x, image_available->ground_y, image_available->ground_z); +} + /** * @brief Send a image_available message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_image_trigger_control.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_image_trigger_control.h index 784cedf8b5..664574be94 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_image_trigger_control.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_image_trigger_control.h @@ -59,7 +59,7 @@ static inline uint16_t mavlink_msg_image_trigger_control_pack(uint8_t system_id, * @brief Pack a image_trigger_control message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param enable 0 to disable, 1 to enable * @return length of the message in bytes (excluding serial stream start sign) @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_image_trigger_control_pack_chan(uint8_t syste } /** - * @brief Encode a image_trigger_control struct into a message + * @brief Encode a image_trigger_control struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -101,6 +101,20 @@ static inline uint16_t mavlink_msg_image_trigger_control_encode(uint8_t system_i return mavlink_msg_image_trigger_control_pack(system_id, component_id, msg, image_trigger_control->enable); } +/** + * @brief Encode a image_trigger_control struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param image_trigger_control C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_image_trigger_control_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_image_trigger_control_t* image_trigger_control) +{ + return mavlink_msg_image_trigger_control_pack_chan(system_id, component_id, chan, msg, image_trigger_control->enable); +} + /** * @brief Send a image_trigger_control message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_image_triggered.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_image_triggered.h index 05b0d775fd..f3a2243afc 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_image_triggered.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_image_triggered.h @@ -114,7 +114,7 @@ static inline uint16_t mavlink_msg_image_triggered_pack(uint8_t system_id, uint8 * @brief Pack a image_triggered message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param timestamp Timestamp * @param seq IMU seq @@ -177,7 +177,7 @@ static inline uint16_t mavlink_msg_image_triggered_pack_chan(uint8_t system_id, } /** - * @brief Encode a image_triggered struct into a message + * @brief Encode a image_triggered struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -189,6 +189,20 @@ static inline uint16_t mavlink_msg_image_triggered_encode(uint8_t system_id, uin return mavlink_msg_image_triggered_pack(system_id, component_id, msg, image_triggered->timestamp, image_triggered->seq, image_triggered->roll, image_triggered->pitch, image_triggered->yaw, image_triggered->local_z, image_triggered->lat, image_triggered->lon, image_triggered->alt, image_triggered->ground_x, image_triggered->ground_y, image_triggered->ground_z); } +/** + * @brief Encode a image_triggered struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param image_triggered C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_image_triggered_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_image_triggered_t* image_triggered) +{ + return mavlink_msg_image_triggered_pack_chan(system_id, component_id, chan, msg, image_triggered->timestamp, image_triggered->seq, image_triggered->roll, image_triggered->pitch, image_triggered->yaw, image_triggered->local_z, image_triggered->lat, image_triggered->lon, image_triggered->alt, image_triggered->ground_x, image_triggered->ground_y, image_triggered->ground_z); +} + /** * @brief Send a image_triggered message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_marker.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_marker.h index 817ec60a20..6bdcceaf9a 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_marker.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_marker.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_marker_pack(uint8_t system_id, uint8_t compon * @brief Pack a marker message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param id ID * @param x x position @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_marker_pack_chan(uint8_t system_id, uint8_t c } /** - * @brief Encode a marker struct into a message + * @brief Encode a marker struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_marker_encode(uint8_t system_id, uint8_t comp return mavlink_msg_marker_pack(system_id, component_id, msg, marker->id, marker->x, marker->y, marker->z, marker->roll, marker->pitch, marker->yaw); } +/** + * @brief Encode a marker struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param marker C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_marker_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_marker_t* marker) +{ + return mavlink_msg_marker_pack_chan(system_id, component_id, chan, msg, marker->id, marker->x, marker->y, marker->z, marker->roll, marker->pitch, marker->yaw); +} + /** * @brief Send a marker message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_pattern_detected.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_pattern_detected.h index 7e29d71525..aa7b827a36 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_pattern_detected.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_pattern_detected.h @@ -72,7 +72,7 @@ static inline uint16_t mavlink_msg_pattern_detected_pack(uint8_t system_id, uint * @brief Pack a pattern_detected message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param type 0: Pattern, 1: Letter * @param confidence Confidence of detection @@ -109,7 +109,7 @@ static inline uint16_t mavlink_msg_pattern_detected_pack_chan(uint8_t system_id, } /** - * @brief Encode a pattern_detected struct into a message + * @brief Encode a pattern_detected struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -121,6 +121,20 @@ static inline uint16_t mavlink_msg_pattern_detected_encode(uint8_t system_id, ui return mavlink_msg_pattern_detected_pack(system_id, component_id, msg, pattern_detected->type, pattern_detected->confidence, pattern_detected->file, pattern_detected->detected); } +/** + * @brief Encode a pattern_detected struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param pattern_detected C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_pattern_detected_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_pattern_detected_t* pattern_detected) +{ + return mavlink_msg_pattern_detected_pack_chan(system_id, component_id, chan, msg, pattern_detected->type, pattern_detected->confidence, pattern_detected->file, pattern_detected->detected); +} + /** * @brief Send a pattern_detected message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_point_of_interest.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_point_of_interest.h index a6faebbb5a..913a52897e 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_point_of_interest.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_point_of_interest.h @@ -92,7 +92,7 @@ static inline uint16_t mavlink_msg_point_of_interest_pack(uint8_t system_id, uin * @brief Pack a point_of_interest message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param type 0: Notice, 1: Warning, 2: Critical, 3: Emergency, 4: Debug * @param color 0: blue, 1: yellow, 2: red, 3: orange, 4: green, 5: magenta @@ -141,7 +141,7 @@ static inline uint16_t mavlink_msg_point_of_interest_pack_chan(uint8_t system_id } /** - * @brief Encode a point_of_interest struct into a message + * @brief Encode a point_of_interest struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -153,6 +153,20 @@ static inline uint16_t mavlink_msg_point_of_interest_encode(uint8_t system_id, u return mavlink_msg_point_of_interest_pack(system_id, component_id, msg, point_of_interest->type, point_of_interest->color, point_of_interest->coordinate_system, point_of_interest->timeout, point_of_interest->x, point_of_interest->y, point_of_interest->z, point_of_interest->name); } +/** + * @brief Encode a point_of_interest struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param point_of_interest C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_point_of_interest_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_point_of_interest_t* point_of_interest) +{ + return mavlink_msg_point_of_interest_pack_chan(system_id, component_id, chan, msg, point_of_interest->type, point_of_interest->color, point_of_interest->coordinate_system, point_of_interest->timeout, point_of_interest->x, point_of_interest->y, point_of_interest->z, point_of_interest->name); +} + /** * @brief Send a point_of_interest message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_point_of_interest_connection.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_point_of_interest_connection.h index 8d02f9e5c4..e244364318 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_point_of_interest_connection.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_point_of_interest_connection.h @@ -107,7 +107,7 @@ static inline uint16_t mavlink_msg_point_of_interest_connection_pack(uint8_t sys * @brief Pack a point_of_interest_connection message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param type 0: Notice, 1: Warning, 2: Critical, 3: Emergency, 4: Debug * @param color 0: blue, 1: yellow, 2: red, 3: orange, 4: green, 5: magenta @@ -165,7 +165,7 @@ static inline uint16_t mavlink_msg_point_of_interest_connection_pack_chan(uint8_ } /** - * @brief Encode a point_of_interest_connection struct into a message + * @brief Encode a point_of_interest_connection struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -177,6 +177,20 @@ static inline uint16_t mavlink_msg_point_of_interest_connection_encode(uint8_t s return mavlink_msg_point_of_interest_connection_pack(system_id, component_id, msg, point_of_interest_connection->type, point_of_interest_connection->color, point_of_interest_connection->coordinate_system, point_of_interest_connection->timeout, point_of_interest_connection->xp1, point_of_interest_connection->yp1, point_of_interest_connection->zp1, point_of_interest_connection->xp2, point_of_interest_connection->yp2, point_of_interest_connection->zp2, point_of_interest_connection->name); } +/** + * @brief Encode a point_of_interest_connection struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param point_of_interest_connection C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_point_of_interest_connection_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_point_of_interest_connection_t* point_of_interest_connection) +{ + return mavlink_msg_point_of_interest_connection_pack_chan(system_id, component_id, chan, msg, point_of_interest_connection->type, point_of_interest_connection->color, point_of_interest_connection->coordinate_system, point_of_interest_connection->timeout, point_of_interest_connection->xp1, point_of_interest_connection->yp1, point_of_interest_connection->zp1, point_of_interest_connection->xp2, point_of_interest_connection->yp2, point_of_interest_connection->zp2, point_of_interest_connection->name); +} + /** * @brief Send a point_of_interest_connection message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_position_control_setpoint.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_position_control_setpoint.h index 6c86be3ab5..6f4ca510ae 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_position_control_setpoint.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_position_control_setpoint.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_position_control_setpoint_pack(uint8_t system * @brief Pack a position_control_setpoint message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param id ID of waypoint, 0 for plain position * @param x x position @@ -121,7 +121,7 @@ static inline uint16_t mavlink_msg_position_control_setpoint_pack_chan(uint8_t s } /** - * @brief Encode a position_control_setpoint struct into a message + * @brief Encode a position_control_setpoint struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -133,6 +133,20 @@ static inline uint16_t mavlink_msg_position_control_setpoint_encode(uint8_t syst return mavlink_msg_position_control_setpoint_pack(system_id, component_id, msg, position_control_setpoint->id, position_control_setpoint->x, position_control_setpoint->y, position_control_setpoint->z, position_control_setpoint->yaw); } +/** + * @brief Encode a position_control_setpoint struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param position_control_setpoint C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_position_control_setpoint_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_position_control_setpoint_t* position_control_setpoint) +{ + return mavlink_msg_position_control_setpoint_pack_chan(system_id, component_id, chan, msg, position_control_setpoint->id, position_control_setpoint->x, position_control_setpoint->y, position_control_setpoint->z, position_control_setpoint->yaw); +} + /** * @brief Send a position_control_setpoint message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_raw_aux.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_raw_aux.h index 0a0dbdb378..08cedbb4b2 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_raw_aux.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_raw_aux.h @@ -89,7 +89,7 @@ static inline uint16_t mavlink_msg_raw_aux_pack(uint8_t system_id, uint8_t compo * @brief Pack a raw_aux message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param adc1 ADC1 (J405 ADC3, LPC2148 AD0.6) * @param adc2 ADC2 (J405 ADC5, LPC2148 AD0.2) @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_raw_aux_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a raw_aux struct into a message + * @brief Encode a raw_aux struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_raw_aux_encode(uint8_t system_id, uint8_t com return mavlink_msg_raw_aux_pack(system_id, component_id, msg, raw_aux->adc1, raw_aux->adc2, raw_aux->adc3, raw_aux->adc4, raw_aux->vbat, raw_aux->temp, raw_aux->baro); } +/** + * @brief Encode a raw_aux struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param raw_aux C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_raw_aux_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_raw_aux_t* raw_aux) +{ + return mavlink_msg_raw_aux_pack_chan(system_id, component_id, chan, msg, raw_aux->adc1, raw_aux->adc2, raw_aux->adc3, raw_aux->adc4, raw_aux->vbat, raw_aux->temp, raw_aux->baro); +} + /** * @brief Send a raw_aux message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_set_cam_shutter.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_set_cam_shutter.h index 7be6409119..b26d748c25 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_set_cam_shutter.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_set_cam_shutter.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_set_cam_shutter_pack(uint8_t system_id, uint8 * @brief Pack a set_cam_shutter message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param cam_no Camera id * @param cam_mode Camera mode: 0 = auto, 1 = manual @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_set_cam_shutter_pack_chan(uint8_t system_id, } /** - * @brief Encode a set_cam_shutter struct into a message + * @brief Encode a set_cam_shutter struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_set_cam_shutter_encode(uint8_t system_id, uin return mavlink_msg_set_cam_shutter_pack(system_id, component_id, msg, set_cam_shutter->cam_no, set_cam_shutter->cam_mode, set_cam_shutter->trigger_pin, set_cam_shutter->interval, set_cam_shutter->exposure, set_cam_shutter->gain); } +/** + * @brief Encode a set_cam_shutter struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param set_cam_shutter C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_cam_shutter_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_set_cam_shutter_t* set_cam_shutter) +{ + return mavlink_msg_set_cam_shutter_pack_chan(system_id, component_id, chan, msg, set_cam_shutter->cam_no, set_cam_shutter->cam_mode, set_cam_shutter->trigger_pin, set_cam_shutter->interval, set_cam_shutter->exposure, set_cam_shutter->gain); +} + /** * @brief Send a set_cam_shutter message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_set_position_control_offset.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_set_position_control_offset.h index 25bff659ed..f1f9e698f8 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_set_position_control_offset.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_set_position_control_offset.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_set_position_control_offset_pack(uint8_t syst * @brief Pack a set_position_control_offset message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system System ID * @param target_component Component ID @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_set_position_control_offset_pack_chan(uint8_t } /** - * @brief Encode a set_position_control_offset struct into a message + * @brief Encode a set_position_control_offset struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_set_position_control_offset_encode(uint8_t sy return mavlink_msg_set_position_control_offset_pack(system_id, component_id, msg, set_position_control_offset->target_system, set_position_control_offset->target_component, set_position_control_offset->x, set_position_control_offset->y, set_position_control_offset->z, set_position_control_offset->yaw); } +/** + * @brief Encode a set_position_control_offset struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param set_position_control_offset C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_position_control_offset_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_set_position_control_offset_t* set_position_control_offset) +{ + return mavlink_msg_set_position_control_offset_pack_chan(system_id, component_id, chan, msg, set_position_control_offset->target_system, set_position_control_offset->target_component, set_position_control_offset->x, set_position_control_offset->y, set_position_control_offset->z, set_position_control_offset->yaw); +} + /** * @brief Send a set_position_control_offset message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_command.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_command.h index 4267880186..9458087da9 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_command.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_command.h @@ -74,7 +74,7 @@ static inline uint16_t mavlink_msg_watchdog_command_pack(uint8_t system_id, uint * @brief Pack a watchdog_command message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target_system_id Target system ID * @param watchdog_id Watchdog ID @@ -113,7 +113,7 @@ static inline uint16_t mavlink_msg_watchdog_command_pack_chan(uint8_t system_id, } /** - * @brief Encode a watchdog_command struct into a message + * @brief Encode a watchdog_command struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -125,6 +125,20 @@ static inline uint16_t mavlink_msg_watchdog_command_encode(uint8_t system_id, ui return mavlink_msg_watchdog_command_pack(system_id, component_id, msg, watchdog_command->target_system_id, watchdog_command->watchdog_id, watchdog_command->process_id, watchdog_command->command_id); } +/** + * @brief Encode a watchdog_command struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param watchdog_command C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_watchdog_command_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_watchdog_command_t* watchdog_command) +{ + return mavlink_msg_watchdog_command_pack_chan(system_id, component_id, chan, msg, watchdog_command->target_system_id, watchdog_command->watchdog_id, watchdog_command->process_id, watchdog_command->command_id); +} + /** * @brief Send a watchdog_command message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_heartbeat.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_heartbeat.h index 49478999ce..3f4295ee5d 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_heartbeat.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_heartbeat.h @@ -64,7 +64,7 @@ static inline uint16_t mavlink_msg_watchdog_heartbeat_pack(uint8_t system_id, ui * @brief Pack a watchdog_heartbeat message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param watchdog_id Watchdog ID * @param process_count Number of processes @@ -97,7 +97,7 @@ static inline uint16_t mavlink_msg_watchdog_heartbeat_pack_chan(uint8_t system_i } /** - * @brief Encode a watchdog_heartbeat struct into a message + * @brief Encode a watchdog_heartbeat struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -109,6 +109,20 @@ static inline uint16_t mavlink_msg_watchdog_heartbeat_encode(uint8_t system_id, return mavlink_msg_watchdog_heartbeat_pack(system_id, component_id, msg, watchdog_heartbeat->watchdog_id, watchdog_heartbeat->process_count); } +/** + * @brief Encode a watchdog_heartbeat struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param watchdog_heartbeat C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_watchdog_heartbeat_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_watchdog_heartbeat_t* watchdog_heartbeat) +{ + return mavlink_msg_watchdog_heartbeat_pack_chan(system_id, component_id, chan, msg, watchdog_heartbeat->watchdog_id, watchdog_heartbeat->process_count); +} + /** * @brief Send a watchdog_heartbeat message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_process_info.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_process_info.h index d706ef85e1..55853cdde4 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_process_info.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_process_info.h @@ -78,7 +78,7 @@ static inline uint16_t mavlink_msg_watchdog_process_info_pack(uint8_t system_id, * @brief Pack a watchdog_process_info message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param watchdog_id Watchdog ID * @param process_id Process ID @@ -118,7 +118,7 @@ static inline uint16_t mavlink_msg_watchdog_process_info_pack_chan(uint8_t syste } /** - * @brief Encode a watchdog_process_info struct into a message + * @brief Encode a watchdog_process_info struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -130,6 +130,20 @@ static inline uint16_t mavlink_msg_watchdog_process_info_encode(uint8_t system_i return mavlink_msg_watchdog_process_info_pack(system_id, component_id, msg, watchdog_process_info->watchdog_id, watchdog_process_info->process_id, watchdog_process_info->name, watchdog_process_info->arguments, watchdog_process_info->timeout); } +/** + * @brief Encode a watchdog_process_info struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param watchdog_process_info C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_watchdog_process_info_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_watchdog_process_info_t* watchdog_process_info) +{ + return mavlink_msg_watchdog_process_info_pack_chan(system_id, component_id, chan, msg, watchdog_process_info->watchdog_id, watchdog_process_info->process_id, watchdog_process_info->name, watchdog_process_info->arguments, watchdog_process_info->timeout); +} + /** * @brief Send a watchdog_process_info message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_process_status.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_process_status.h index b1bbaaae7b..a0410d803e 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_process_status.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/mavlink_msg_watchdog_process_status.h @@ -84,7 +84,7 @@ static inline uint16_t mavlink_msg_watchdog_process_status_pack(uint8_t system_i * @brief Pack a watchdog_process_status message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param watchdog_id Watchdog ID * @param process_id Process ID @@ -129,7 +129,7 @@ static inline uint16_t mavlink_msg_watchdog_process_status_pack_chan(uint8_t sys } /** - * @brief Encode a watchdog_process_status struct into a message + * @brief Encode a watchdog_process_status struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -141,6 +141,20 @@ static inline uint16_t mavlink_msg_watchdog_process_status_encode(uint8_t system return mavlink_msg_watchdog_process_status_pack(system_id, component_id, msg, watchdog_process_status->watchdog_id, watchdog_process_status->process_id, watchdog_process_status->state, watchdog_process_status->muted, watchdog_process_status->pid, watchdog_process_status->crashes); } +/** + * @brief Encode a watchdog_process_status struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param watchdog_process_status C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_watchdog_process_status_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_watchdog_process_status_t* watchdog_process_status) +{ + return mavlink_msg_watchdog_process_status_pack_chan(system_id, component_id, chan, msg, watchdog_process_status->watchdog_id, watchdog_process_status->process_id, watchdog_process_status->state, watchdog_process_status->muted, watchdog_process_status->pid, watchdog_process_status->crashes); +} + /** * @brief Send a watchdog_process_status message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/pixhawk.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/pixhawk.h index a2d0d0e14e..3fc9e64773 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/pixhawk.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/pixhawk.h @@ -72,6 +72,7 @@ enum MAV_CMD MAV_CMD_DO_SET_SERVO=183, /* Set a servo to a desired PWM value. |Servo number| PWM (microseconds, 1000 to 2000 typical)| Empty| Empty| Empty| Empty| Empty| */ MAV_CMD_DO_REPEAT_SERVO=184, /* Cycle a between its nominal setting and a desired PWM for a desired number of cycles with a desired period. |Servo number| PWM (microseconds, 1000 to 2000 typical)| Cycle count| Cycle time (seconds)| Empty| Empty| Empty| */ MAV_CMD_DO_CONTROL_VIDEO=200, /* Control onboard camera system. |Camera ID (-1 for all)| Transmission: 0: disabled, 1: enabled compressed, 2: enabled raw| Transmission mode: 0: video stream, >0: single images every n seconds (decimal)| Recording: 0: disabled, 1: enabled compressed, 2: enabled raw| Empty| Empty| Empty| */ + MAV_CMD_DO_SET_ROI=201, /* Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. |Region of intereset mode. (see MAV_ROI enum)| MISSION index/ target ID. (see MAV_ROI enum)| ROI index (allows a vehicle to manage multiple ROI's)| Empty| x the location of the fixed ROI (see MAV_FRAME)| y| z| */ MAV_CMD_DO_LAST=240, /* NOP - This command is only used to mark the upper limit of the DO commands in the enumeration |Empty| Empty| Empty| Empty| Empty| Empty| Empty| */ MAV_CMD_PREFLIGHT_CALIBRATION=241, /* Trigger calibration. This command will be only accepted if in pre-flight mode. |Gyro calibration: 0: no, 1: yes| Magnetometer calibration: 0: no, 1: yes| Ground pressure: 0: no, 1: yes| Radio calibration: 0: no, 1: yes| Accelerometer calibration: 0: no, 1: yes| Empty| Empty| */ MAV_CMD_PREFLIGHT_SET_SENSOR_OFFSETS=242, /* Set sensor offsets. This command will be only accepted if in pre-flight mode. |Sensor to adjust the offsets for: 0: gyros, 1: accelerometer, 2: magnetometer, 3: barometer, 4: optical flow| X axis offset (or generic dimension 1), in the sensor's raw units| Y axis offset (or generic dimension 2), in the sensor's raw units| Z axis offset (or generic dimension 3), in the sensor's raw units| Generic dimension 4, in the sensor's raw units| Generic dimension 5, in the sensor's raw units| Generic dimension 6, in the sensor's raw units| */ @@ -80,7 +81,8 @@ enum MAV_CMD MAV_CMD_OVERRIDE_GOTO=252, /* Hold / continue the current action |MAV_GOTO_DO_HOLD: hold MAV_GOTO_DO_CONTINUE: continue with next item in mission plan| MAV_GOTO_HOLD_AT_CURRENT_POSITION: Hold at current position MAV_GOTO_HOLD_AT_SPECIFIED_POSITION: hold at specified position| MAV_FRAME coordinate frame of hold point| Desired yaw angle in degrees| Latitude / X position| Longitude / Y position| Altitude / Z position| */ MAV_CMD_MISSION_START=300, /* start running a mission |first_item: the first mission item to run| last_item: the last mission item to run (after this item is run, the mission ends)| */ MAV_CMD_COMPONENT_ARM_DISARM=400, /* Arms / Disarms a component |1 to arm, 0 to disarm| */ - MAV_CMD_ENUM_END=401, /* | */ + MAV_CMD_START_RX_PAIR=500, /* Starts receiver pairing |0:Spektrum| 0:Spektrum DSM2, 1:Spektrum DSMX| */ + MAV_CMD_ENUM_END=501, /* | */ MAV_CMD_DO_START_SEARCH=10001, /* Starts a search |1 to arm, 0 to disarm| */ MAV_CMD_DO_FINISH_SEARCH=10002, /* Starts a search |1 to arm, 0 to disarm| */ MAV_CMD_NAV_SWEEP=10003, /* Starts a search |1 to arm, 0 to disarm| */ diff --git a/libs/mavlink/include/mavlink/v1.0/pixhawk/version.h b/libs/mavlink/include/mavlink/v1.0/pixhawk/version.h index 61fe6e930d..07831a4256 100644 --- a/libs/mavlink/include/mavlink/v1.0/pixhawk/version.h +++ b/libs/mavlink/include/mavlink/v1.0/pixhawk/version.h @@ -5,7 +5,7 @@ #ifndef MAVLINK_VERSION_H #define MAVLINK_VERSION_H -#define MAVLINK_BUILD_DATE "Thu Jul 4 13:12:05 2013" +#define MAVLINK_BUILD_DATE "Tue Sep 10 23:49:13 2013" #define MAVLINK_WIRE_PROTOCOL_VERSION "1.0" #define MAVLINK_MAX_DIALECT_PAYLOAD_SIZE 255 diff --git a/libs/mavlink/include/mavlink/v1.0/protocol.h b/libs/mavlink/include/mavlink/v1.0/protocol.h index ddacae59c4..86e7ff588b 100644 --- a/libs/mavlink/include/mavlink/v1.0/protocol.h +++ b/libs/mavlink/include/mavlink/v1.0/protocol.h @@ -162,7 +162,7 @@ static inline void byte_copy_8(char *dst, const char *src) /* like memcpy(), but if src is NULL, do a memset to zero */ -static void mav_array_memcpy(void *dest, const void *src, size_t n) +static inline void mav_array_memcpy(void *dest, const void *src, size_t n) { if (src == NULL) { memset(dest, 0, n); diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_cmd_airspeed_ack.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_cmd_airspeed_ack.h index 5cdd584561..73e9d75dbc 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_cmd_airspeed_ack.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_cmd_airspeed_ack.h @@ -72,7 +72,7 @@ static inline uint16_t mavlink_msg_cmd_airspeed_ack_pack(uint8_t system_id, uint * @brief Pack a cmd_airspeed_ack message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param spCmd @@ -109,7 +109,7 @@ static inline uint16_t mavlink_msg_cmd_airspeed_ack_pack_chan(uint8_t system_id, } /** - * @brief Encode a cmd_airspeed_ack struct into a message + * @brief Encode a cmd_airspeed_ack struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -121,6 +121,20 @@ static inline uint16_t mavlink_msg_cmd_airspeed_ack_encode(uint8_t system_id, ui return mavlink_msg_cmd_airspeed_ack_pack(system_id, component_id, msg, cmd_airspeed_ack->spCmd, cmd_airspeed_ack->ack); } +/** + * @brief Encode a cmd_airspeed_ack struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param cmd_airspeed_ack C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_cmd_airspeed_ack_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_cmd_airspeed_ack_t* cmd_airspeed_ack) +{ + return mavlink_msg_cmd_airspeed_ack_pack_chan(system_id, component_id, chan, msg, cmd_airspeed_ack->spCmd, cmd_airspeed_ack->ack); +} + /** * @brief Send a cmd_airspeed_ack message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_cmd_airspeed_chng.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_cmd_airspeed_chng.h index 2a4894fe72..b6b567f993 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_cmd_airspeed_chng.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_cmd_airspeed_chng.h @@ -72,7 +72,7 @@ static inline uint16_t mavlink_msg_cmd_airspeed_chng_pack(uint8_t system_id, uin * @brief Pack a cmd_airspeed_chng message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param target @@ -109,7 +109,7 @@ static inline uint16_t mavlink_msg_cmd_airspeed_chng_pack_chan(uint8_t system_id } /** - * @brief Encode a cmd_airspeed_chng struct into a message + * @brief Encode a cmd_airspeed_chng struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -121,6 +121,20 @@ static inline uint16_t mavlink_msg_cmd_airspeed_chng_encode(uint8_t system_id, u return mavlink_msg_cmd_airspeed_chng_pack(system_id, component_id, msg, cmd_airspeed_chng->target, cmd_airspeed_chng->spCmd); } +/** + * @brief Encode a cmd_airspeed_chng struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param cmd_airspeed_chng C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_cmd_airspeed_chng_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_cmd_airspeed_chng_t* cmd_airspeed_chng) +{ + return mavlink_msg_cmd_airspeed_chng_pack_chan(system_id, component_id, chan, msg, cmd_airspeed_chng->target, cmd_airspeed_chng->spCmd); +} + /** * @brief Send a cmd_airspeed_chng message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_filt_rot_vel.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_filt_rot_vel.h index d600e91749..642f7aab93 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_filt_rot_vel.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_filt_rot_vel.h @@ -63,7 +63,7 @@ static inline uint16_t mavlink_msg_filt_rot_vel_pack(uint8_t system_id, uint8_t * @brief Pack a filt_rot_vel message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param rotVel @@ -95,7 +95,7 @@ static inline uint16_t mavlink_msg_filt_rot_vel_pack_chan(uint8_t system_id, uin } /** - * @brief Encode a filt_rot_vel struct into a message + * @brief Encode a filt_rot_vel struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -107,6 +107,20 @@ static inline uint16_t mavlink_msg_filt_rot_vel_encode(uint8_t system_id, uint8_ return mavlink_msg_filt_rot_vel_pack(system_id, component_id, msg, filt_rot_vel->rotVel); } +/** + * @brief Encode a filt_rot_vel struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param filt_rot_vel C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_filt_rot_vel_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_filt_rot_vel_t* filt_rot_vel) +{ + return mavlink_msg_filt_rot_vel_pack_chan(system_id, component_id, chan, msg, filt_rot_vel->rotVel); +} + /** * @brief Send a filt_rot_vel message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_llc_out.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_llc_out.h index cb1c86f436..0f8369881a 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_llc_out.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_llc_out.h @@ -73,7 +73,7 @@ static inline uint16_t mavlink_msg_llc_out_pack(uint8_t system_id, uint8_t compo * @brief Pack a llc_out message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param servoOut @@ -110,7 +110,7 @@ static inline uint16_t mavlink_msg_llc_out_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a llc_out struct into a message + * @brief Encode a llc_out struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -122,6 +122,20 @@ static inline uint16_t mavlink_msg_llc_out_encode(uint8_t system_id, uint8_t com return mavlink_msg_llc_out_pack(system_id, component_id, msg, llc_out->servoOut, llc_out->MotorOut); } +/** + * @brief Encode a llc_out struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param llc_out C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_llc_out_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_llc_out_t* llc_out) +{ + return mavlink_msg_llc_out_pack_chan(system_id, component_id, chan, msg, llc_out->servoOut, llc_out->MotorOut); +} + /** * @brief Send a llc_out message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_air_temp.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_air_temp.h index b6bd0d9e52..5d93823262 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_air_temp.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_air_temp.h @@ -63,7 +63,7 @@ static inline uint16_t mavlink_msg_obs_air_temp_pack(uint8_t system_id, uint8_t * @brief Pack a obs_air_temp message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param airT @@ -95,7 +95,7 @@ static inline uint16_t mavlink_msg_obs_air_temp_pack_chan(uint8_t system_id, uin } /** - * @brief Encode a obs_air_temp struct into a message + * @brief Encode a obs_air_temp struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -107,6 +107,20 @@ static inline uint16_t mavlink_msg_obs_air_temp_encode(uint8_t system_id, uint8_ return mavlink_msg_obs_air_temp_pack(system_id, component_id, msg, obs_air_temp->airT); } +/** + * @brief Encode a obs_air_temp struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param obs_air_temp C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_obs_air_temp_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_obs_air_temp_t* obs_air_temp) +{ + return mavlink_msg_obs_air_temp_pack_chan(system_id, component_id, chan, msg, obs_air_temp->airT); +} + /** * @brief Send a obs_air_temp message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_air_velocity.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_air_velocity.h index 87a65cfa06..35d813ca15 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_air_velocity.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_air_velocity.h @@ -81,7 +81,7 @@ static inline uint16_t mavlink_msg_obs_air_velocity_pack(uint8_t system_id, uint * @brief Pack a obs_air_velocity message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param magnitude @@ -123,7 +123,7 @@ static inline uint16_t mavlink_msg_obs_air_velocity_pack_chan(uint8_t system_id, } /** - * @brief Encode a obs_air_velocity struct into a message + * @brief Encode a obs_air_velocity struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -135,6 +135,20 @@ static inline uint16_t mavlink_msg_obs_air_velocity_encode(uint8_t system_id, ui return mavlink_msg_obs_air_velocity_pack(system_id, component_id, msg, obs_air_velocity->magnitude, obs_air_velocity->aoa, obs_air_velocity->slip); } +/** + * @brief Encode a obs_air_velocity struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param obs_air_velocity C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_obs_air_velocity_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_obs_air_velocity_t* obs_air_velocity) +{ + return mavlink_msg_obs_air_velocity_pack_chan(system_id, component_id, chan, msg, obs_air_velocity->magnitude, obs_air_velocity->aoa, obs_air_velocity->slip); +} + /** * @brief Send a obs_air_velocity message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_attitude.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_attitude.h index 602eafc80b..9c80cd66eb 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_attitude.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_attitude.h @@ -63,7 +63,7 @@ static inline uint16_t mavlink_msg_obs_attitude_pack(uint8_t system_id, uint8_t * @brief Pack a obs_attitude message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param quat @@ -95,7 +95,7 @@ static inline uint16_t mavlink_msg_obs_attitude_pack_chan(uint8_t system_id, uin } /** - * @brief Encode a obs_attitude struct into a message + * @brief Encode a obs_attitude struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -107,6 +107,20 @@ static inline uint16_t mavlink_msg_obs_attitude_encode(uint8_t system_id, uint8_ return mavlink_msg_obs_attitude_pack(system_id, component_id, msg, obs_attitude->quat); } +/** + * @brief Encode a obs_attitude struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param obs_attitude C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_obs_attitude_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_obs_attitude_t* obs_attitude) +{ + return mavlink_msg_obs_attitude_pack_chan(system_id, component_id, chan, msg, obs_attitude->quat); +} + /** * @brief Send a obs_attitude message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_bias.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_bias.h index 3ab855ba81..24dd43b579 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_bias.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_bias.h @@ -73,7 +73,7 @@ static inline uint16_t mavlink_msg_obs_bias_pack(uint8_t system_id, uint8_t comp * @brief Pack a obs_bias message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param accBias @@ -110,7 +110,7 @@ static inline uint16_t mavlink_msg_obs_bias_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a obs_bias struct into a message + * @brief Encode a obs_bias struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -122,6 +122,20 @@ static inline uint16_t mavlink_msg_obs_bias_encode(uint8_t system_id, uint8_t co return mavlink_msg_obs_bias_pack(system_id, component_id, msg, obs_bias->accBias, obs_bias->gyroBias); } +/** + * @brief Encode a obs_bias struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param obs_bias C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_obs_bias_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_obs_bias_t* obs_bias) +{ + return mavlink_msg_obs_bias_pack_chan(system_id, component_id, chan, msg, obs_bias->accBias, obs_bias->gyroBias); +} + /** * @brief Send a obs_bias message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_position.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_position.h index ec494d51a2..cfc2fe7e10 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_position.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_position.h @@ -81,7 +81,7 @@ static inline uint16_t mavlink_msg_obs_position_pack(uint8_t system_id, uint8_t * @brief Pack a obs_position message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param lon @@ -123,7 +123,7 @@ static inline uint16_t mavlink_msg_obs_position_pack_chan(uint8_t system_id, uin } /** - * @brief Encode a obs_position struct into a message + * @brief Encode a obs_position struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -135,6 +135,20 @@ static inline uint16_t mavlink_msg_obs_position_encode(uint8_t system_id, uint8_ return mavlink_msg_obs_position_pack(system_id, component_id, msg, obs_position->lon, obs_position->lat, obs_position->alt); } +/** + * @brief Encode a obs_position struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param obs_position C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_obs_position_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_obs_position_t* obs_position) +{ + return mavlink_msg_obs_position_pack_chan(system_id, component_id, chan, msg, obs_position->lon, obs_position->lat, obs_position->alt); +} + /** * @brief Send a obs_position message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_qff.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_qff.h index e42b0261fa..24e272bf7a 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_qff.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_qff.h @@ -63,7 +63,7 @@ static inline uint16_t mavlink_msg_obs_qff_pack(uint8_t system_id, uint8_t compo * @brief Pack a obs_qff message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param qff @@ -95,7 +95,7 @@ static inline uint16_t mavlink_msg_obs_qff_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a obs_qff struct into a message + * @brief Encode a obs_qff struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -107,6 +107,20 @@ static inline uint16_t mavlink_msg_obs_qff_encode(uint8_t system_id, uint8_t com return mavlink_msg_obs_qff_pack(system_id, component_id, msg, obs_qff->qff); } +/** + * @brief Encode a obs_qff struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param obs_qff C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_obs_qff_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_obs_qff_t* obs_qff) +{ + return mavlink_msg_obs_qff_pack_chan(system_id, component_id, chan, msg, obs_qff->qff); +} + /** * @brief Send a obs_qff message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_velocity.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_velocity.h index 2fa6e9111f..6e3776632b 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_velocity.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_velocity.h @@ -63,7 +63,7 @@ static inline uint16_t mavlink_msg_obs_velocity_pack(uint8_t system_id, uint8_t * @brief Pack a obs_velocity message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param vel @@ -95,7 +95,7 @@ static inline uint16_t mavlink_msg_obs_velocity_pack_chan(uint8_t system_id, uin } /** - * @brief Encode a obs_velocity struct into a message + * @brief Encode a obs_velocity struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -107,6 +107,20 @@ static inline uint16_t mavlink_msg_obs_velocity_encode(uint8_t system_id, uint8_ return mavlink_msg_obs_velocity_pack(system_id, component_id, msg, obs_velocity->vel); } +/** + * @brief Encode a obs_velocity struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param obs_velocity C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_obs_velocity_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_obs_velocity_t* obs_velocity) +{ + return mavlink_msg_obs_velocity_pack_chan(system_id, component_id, chan, msg, obs_velocity->vel); +} + /** * @brief Send a obs_velocity message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_wind.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_wind.h index bc9f6e4eff..55f7cb2ae1 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_wind.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_obs_wind.h @@ -63,7 +63,7 @@ static inline uint16_t mavlink_msg_obs_wind_pack(uint8_t system_id, uint8_t comp * @brief Pack a obs_wind message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param wind @@ -95,7 +95,7 @@ static inline uint16_t mavlink_msg_obs_wind_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a obs_wind struct into a message + * @brief Encode a obs_wind struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -107,6 +107,20 @@ static inline uint16_t mavlink_msg_obs_wind_encode(uint8_t system_id, uint8_t co return mavlink_msg_obs_wind_pack(system_id, component_id, msg, obs_wind->wind); } +/** + * @brief Encode a obs_wind struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param obs_wind C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_obs_wind_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_obs_wind_t* obs_wind) +{ + return mavlink_msg_obs_wind_pack_chan(system_id, component_id, chan, msg, obs_wind->wind); +} + /** * @brief Send a obs_wind message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_pm_elec.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_pm_elec.h index 0799af07f8..e0963ece79 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_pm_elec.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_pm_elec.h @@ -79,7 +79,7 @@ static inline uint16_t mavlink_msg_pm_elec_pack(uint8_t system_id, uint8_t compo * @brief Pack a pm_elec message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param PwCons @@ -119,7 +119,7 @@ static inline uint16_t mavlink_msg_pm_elec_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a pm_elec struct into a message + * @brief Encode a pm_elec struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -131,6 +131,20 @@ static inline uint16_t mavlink_msg_pm_elec_encode(uint8_t system_id, uint8_t com return mavlink_msg_pm_elec_pack(system_id, component_id, msg, pm_elec->PwCons, pm_elec->BatStat, pm_elec->PwGen); } +/** + * @brief Encode a pm_elec struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param pm_elec C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_pm_elec_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_pm_elec_t* pm_elec) +{ + return mavlink_msg_pm_elec_pack_chan(system_id, component_id, chan, msg, pm_elec->PwCons, pm_elec->BatStat, pm_elec->PwGen); +} + /** * @brief Send a pm_elec message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_sys_stat.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_sys_stat.h index e5e483a73a..94f3e58bb9 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_sys_stat.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/mavlink_msg_sys_stat.h @@ -90,7 +90,7 @@ static inline uint16_t mavlink_msg_sys_stat_pack(uint8_t system_id, uint8_t comp * @brief Pack a sys_stat message on a channel * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) - * @param chan The MAVLink channel this message was sent over + * @param chan The MAVLink channel this message will be sent over * @param msg The MAVLink message to compress the data into * @param gps @@ -137,7 +137,7 @@ static inline uint16_t mavlink_msg_sys_stat_pack_chan(uint8_t system_id, uint8_t } /** - * @brief Encode a sys_stat struct into a message + * @brief Encode a sys_stat struct * * @param system_id ID of this system * @param component_id ID of this component (e.g. 200 for IMU) @@ -149,6 +149,20 @@ static inline uint16_t mavlink_msg_sys_stat_encode(uint8_t system_id, uint8_t co return mavlink_msg_sys_stat_pack(system_id, component_id, msg, sys_stat->gps, sys_stat->act, sys_stat->mod, sys_stat->commRssi); } +/** + * @brief Encode a sys_stat struct on a channel + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message will be sent over + * @param msg The MAVLink message to compress the data into + * @param sys_stat C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_sys_stat_encode_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t* msg, const mavlink_sys_stat_t* sys_stat) +{ + return mavlink_msg_sys_stat_pack_chan(system_id, component_id, chan, msg, sys_stat->gps, sys_stat->act, sys_stat->mod, sys_stat->commRssi); +} + /** * @brief Send a sys_stat message * @param chan MAVLink channel to send the message diff --git a/libs/mavlink/include/mavlink/v1.0/sensesoar/version.h b/libs/mavlink/include/mavlink/v1.0/sensesoar/version.h index 4633e6eb5c..ab3f47b9df 100644 --- a/libs/mavlink/include/mavlink/v1.0/sensesoar/version.h +++ b/libs/mavlink/include/mavlink/v1.0/sensesoar/version.h @@ -5,7 +5,7 @@ #ifndef MAVLINK_VERSION_H #define MAVLINK_VERSION_H -#define MAVLINK_BUILD_DATE "Thu Jul 4 13:12:22 2013" +#define MAVLINK_BUILD_DATE "Tue Sep 10 23:50:02 2013" #define MAVLINK_WIRE_PROTOCOL_VERSION "1.0" #define MAVLINK_MAX_DIALECT_PAYLOAD_SIZE 254 -- GitLab From 3ffc683599bef2161ba4ad79753129554b2075dc Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Wed, 11 Sep 2013 01:16:41 +0200 Subject: [PATCH 378/460] Improved airframe config and removed debug output --- src/uas/UAS.cc | 1 - src/ui/px4_configuration/QGCPX4AirframeConfig.cc | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 2408409dbe..275350f8ac 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -1864,7 +1864,6 @@ void UAS::sendMessage(mavlink_message_t message) { if (link->isConnected()) sendMessage(link, message); - qDebug() << "SENT MESSAGE id" << message.msgid << "component" << message.compid; } else { diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index 28a7b85b4a..de1ae066ce 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -161,7 +161,7 @@ void QGCPX4AirframeConfig::setAirframeID(int id) ui->flyingWingComboBox->setCurrentIndex(ui->flyingWingComboBox->findData(id)); ui->statusLabel->setText(tr("Selected flying wing (ID: #%1)").arg(selectedId)); } - else if (id >= 100 && id < 150) + else if (id >= 100 && id < 150 || id >= 1000 <= 2000) { ui->planePushButton->setChecked(true); ui->planeComboBox->setCurrentIndex(ui->planeComboBox->findData(id)); -- GitLab From ffddac5111205a258b289ff31f75e9fa3684043d Mon Sep 17 00:00:00 2001 From: Jean Cyr Date: Tue, 10 Sep 2013 19:46:46 -0400 Subject: [PATCH 379/460] Put build copies in their proper place - DLL copying belongs in qgroundcontrol.pro, not qupdate.pro - Turn on link time code generation for better (global) optimization --- qgroundcontrol.pri | 9 +++++++++ qgroundcontrol.pro | 6 ++---- qupgrade.pro | 2 -- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/qgroundcontrol.pri b/qgroundcontrol.pri index fdf608780b..3ced14d4ba 100644 --- a/qgroundcontrol.pri +++ b/qgroundcontrol.pri @@ -371,9 +371,16 @@ win32-msvc2008|win32-msvc2010|win32-msvc2012 { QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtWebKitd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXmld4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXmlPatternsd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) + QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtDeclaratived4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) + QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtScriptd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) } CONFIG(release, debug|release) { + + # Use link time code generation for beteer optimization (I believe this is supported in msvc express, but not 100% sure) + QMAKE_LFLAGS_LTCG = /LTCG + QMAKE_CFLAGS_LTCG = -GL + # Copy supporting library DLLs QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\libs\\lib\\sdl\\win32\\SDL.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\libs\\mavlink" "$$TARGETDIR_WIN\\release\\mavlink" /E /I $$escape_expand(\\n)) @@ -397,6 +404,8 @@ win32-msvc2008|win32-msvc2010|win32-msvc2012 { QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtWebKit4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXml4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXmlPatterns4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n)) + QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtDeclarative4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) + QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtScript4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(del /F "$$TARGETDIR_WIN\\release\\qgroundcontrol.exp"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(del /F "$$TARGETDIR_WIN\\release\\qgroundcontrol.lib"$$escape_expand(\\n)) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 2788a190bf..1b8eceb858 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -22,7 +22,6 @@ CONFIG += qt \ thread \ console -# serialport QT += network \ opengl \ @@ -34,7 +33,7 @@ QT += network \ declarative TEMPLATE = app -TARGET = qgroundcontrol +TARGET = qgroundcontrol2 BASEDIR = $${IN_PWD} linux-g++|linux-g++-64{ debug { @@ -108,7 +107,7 @@ DEPENDPATH += \ INCLUDEPATH += \ libs/utils \ libs \ - libs/opmapcontrol \ + libs/opmapcontrol # If the user config file exists, it will be included. # if the variable MAVLINK_CONF contains the name of an @@ -129,7 +128,6 @@ isEmpty(MAVLINK_CONF) { INCLUDEPATH += $$MAVLINKPATH/common } else { INCLUDEPATH += $$MAVLINKPATH/$$MAVLINK_CONF - #DEFINES += 'MAVLINK_CONF="$${MAVLINK_CONF}.h"' DEFINES += $$sprintf('QGC_USE_%1_MESSAGES', $$upper($$MAVLINK_CONF)) } diff --git a/qupgrade.pro b/qupgrade.pro index 296785ff82..50ed222009 100644 --- a/qupgrade.pro +++ b/qupgrade.pro @@ -223,8 +223,6 @@ win32-msvc2008|win32-msvc2010 { QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtWebKitd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXmld4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXmlPatternsd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) - QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtDeclaratived4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) - QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtScriptd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) } CONFIG(release, debug|release) { -- GitLab From a27dd82ad857f215d463e88cc7f11de69de5b562 Mon Sep 17 00:00:00 2001 From: Jean Cyr Date: Tue, 10 Sep 2013 20:50:39 -0400 Subject: [PATCH 380/460] Fix copy target for release build --- qgroundcontrol.pri | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qgroundcontrol.pri b/qgroundcontrol.pri index 3ced14d4ba..eb1bb1bf72 100644 --- a/qgroundcontrol.pri +++ b/qgroundcontrol.pri @@ -404,8 +404,8 @@ win32-msvc2008|win32-msvc2010|win32-msvc2012 { QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtWebKit4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXml4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXmlPatterns4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n)) - QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtDeclarative4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) - QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtScript4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) + QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtDeclarative4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n)) + QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtScript4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(del /F "$$TARGETDIR_WIN\\release\\qgroundcontrol.exp"$$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(del /F "$$TARGETDIR_WIN\\release\\qgroundcontrol.lib"$$escape_expand(\\n)) -- GitLab From 7dfaf20b7659aff2fbb336c548d40ebf1efee8e3 Mon Sep 17 00:00:00 2001 From: Jean Cyr Date: Wed, 11 Sep 2013 10:26:46 -0400 Subject: [PATCH 381/460] Revert to original target name in win32 build --- qgroundcontrol.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 1b8eceb858..3fb4c02810 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -33,7 +33,7 @@ QT += network \ declarative TEMPLATE = app -TARGET = qgroundcontrol2 +TARGET = qgroundcontrol BASEDIR = $${IN_PWD} linux-g++|linux-g++-64{ debug { -- GitLab From 34920fe235907948cf4a27c35cb6bb0d31551779 Mon Sep 17 00:00:00 2001 From: Jean Cyr Date: Wed, 11 Sep 2013 14:25:15 -0400 Subject: [PATCH 382/460] Fix crash under Windows invoking the APM autopilot - APM resources were not installed --- qgroundcontrol.pri | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qgroundcontrol.pri b/qgroundcontrol.pri index eb1bb1bf72..cff2724729 100644 --- a/qgroundcontrol.pri +++ b/qgroundcontrol.pri @@ -356,6 +356,7 @@ win32-msvc2008|win32-msvc2010|win32-msvc2012 { # Copy application resources QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\files" "$$TARGETDIR_WIN\\debug\\files" /E /I $$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\models" "$$TARGETDIR_WIN\\debug\\models" /E /I $$escape_expand(\\n)) + QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\qml" "$$TARGETDIR_WIN\\debug\\qml" /E /I $$escape_expand(\\n)) # Copy Qt DLLs QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\plugins" "$$TARGETDIR_WIN\\debug" /E /I $$escape_expand(\\n)) @@ -389,6 +390,7 @@ win32-msvc2008|win32-msvc2010|win32-msvc2012 { # Copy application resources QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\files" "$$TARGETDIR_WIN\\release\\files" /E /I $$escape_expand(\\n)) QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\models" "$$TARGETDIR_WIN\\release\\models" /E /I $$escape_expand(\\n)) + QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\qml" "$$TARGETDIR_WIN\\release\\qml" /E /I $$escape_expand(\\n)) # Copy Qt DLLs QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\plugins" "$$TARGETDIR_WIN\\release" /E /I $$escape_expand(\\n)) -- GitLab From 51e21f9f7fac85378c853fe70af06e15dea5b2c7 Mon Sep 17 00:00:00 2001 From: Jean Cyr Date: Wed, 11 Sep 2013 21:17:39 -0400 Subject: [PATCH 383/460] Implement message driven receiver pairing --- src/uas/UAS.cc | 11 +++++++++++ src/uas/UAS.h | 3 +++ src/uas/UASInterface.h | 2 ++ src/ui/QGCPX4VehicleConfig.cc | 11 ++++------- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 275350f8ac..0d3e7c6fdb 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -2866,6 +2866,17 @@ void UAS::land() sendMessage(msg); } +/** +* Order the robot to land on the runway +*/ +void UAS::pairRX(int rxType, int rxSubType) +{ + mavlink_message_t msg; + + mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_ALL, MAV_CMD_START_RX_PAIR, 0, rxType, rxSubType, 0, 0, 0, 0, 0); + sendMessage(msg); +} + /** * The MAV starts the emergency landing procedure. The behaviour depends on the onboard implementation * and might differ between systems. diff --git a/src/uas/UAS.h b/src/uas/UAS.h index 6b5d34f8d6..8a60d343ea 100644 --- a/src/uas/UAS.h +++ b/src/uas/UAS.h @@ -723,6 +723,9 @@ public slots: void home(); /** @brief Order the robot to land **/ void land(); + /** @brief Order the robot to pair its receiver **/ + void pairRX(int rxType, int rxSubType); + void halt(); void go(); diff --git a/src/uas/UASInterface.h b/src/uas/UASInterface.h index 7a0640eddd..e97ca675ed 100644 --- a/src/uas/UASInterface.h +++ b/src/uas/UASInterface.h @@ -290,6 +290,8 @@ public slots: virtual void home() = 0; /** @brief Order the robot to land **/ virtual void land() = 0; + /** @brief Order the robot to pair its receiver **/ + virtual void pairRX(int rxType, int rxSubType) = 0; /** @brief Halt the system */ virtual void halt() = 0; /** @brief Start/continue the current robot action */ diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index c06fdd54ee..1a30cdaf7d 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -343,15 +343,12 @@ void QGCPX4VehicleConfig::toggleSpektrumPairing(bool enabled) warnMsgBox.setStandardButtons(QMessageBox::Ok); warnMsgBox.setDefaultButton(QMessageBox::Ok); (void)warnMsgBox.exec(); + return; } - int mode = 1; // DSM2 - if (ui->dsmxRadioButton->isChecked()) - mode = 2; // DSMX - - mav->getParamManager()->setPendingParam(0, "RC_DSM_BIND", mode, true); - // Do not save this parameter, just set in RAM - mav->getParamManager()->sendPendingParameters(false, true); + UASInterface* mav = UASManager::instance()->getActiveUAS(); + if (mav) + mav->pairRX(0, ui->dsmxRadioButton->isChecked() ? 1 : 0); } void QGCPX4VehicleConfig::setTrimPositions() -- GitLab From dfa368c8f97c3457e6a0c0f1c45f38fe289cce06 Mon Sep 17 00:00:00 2001 From: Jean Cyr Date: Wed, 11 Sep 2013 22:20:04 -0400 Subject: [PATCH 384/460] Fix receiver pairing comment --- src/uas/UAS.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 0d3e7c6fdb..8167978449 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -2867,7 +2867,7 @@ void UAS::land() } /** -* Order the robot to land on the runway +* Order the robot to start receiver pairing */ void UAS::pairRX(int rxType, int rxSubType) { -- GitLab From d8ec1c381f5032ef43251387c46d93ccccb62e3e Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 12 Sep 2013 10:04:51 +0200 Subject: [PATCH 385/460] Improving RC ui --- src/ui/QGCPX4VehicleConfig.cc | 16 ++++---- src/ui/QGCPX4VehicleConfig.ui | 69 ++++++++++++++++++++--------------- 2 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index c06fdd54ee..ca8574fad8 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -469,15 +469,10 @@ void QGCPX4VehicleConfig::startCalibrationRC() identifyChannelMapping(i); } - // Try to identify inverted channels, but only for R/P/Y/T - for (int i = 0; i < 4; i++) { - detectChannelInversion(i); - } - //QMessageBox::information(0,"Information","Additional channels have not been mapped, but can be mapped in the channel table below."); configEnabled = false; - QMessageBox::information(0,"Information","Click OK, then move all sticks to their extreme positions, watching the min/max values to ensure you get the most range from your controller. This includes all switches"); - ui->rcCalibrationButton->setText(tr("Save RC Calibration")); + QMessageBox::information(0, tr("Information"),tr("Click OK, then move all sticks to their extreme positions, watching the min/max values to ensure you get the most range from your controller. This includes all switches")); + ui->rcCalibrationButton->setText(tr("Finish RC Calibration")); resetCalibrationRC(); calibrationEnabled = true; ui->rollWidget->showMinMax(); @@ -488,6 +483,8 @@ void QGCPX4VehicleConfig::startCalibrationRC() ui->radio6Widget->showMinMax(); ui->radio7Widget->showMinMax(); ui->radio8Widget->showMinMax(); + + QMessageBox::information(0, tr("Information"), tr("Please click on the button once finished")); } void QGCPX4VehicleConfig::stopCalibrationRC() @@ -495,6 +492,11 @@ void QGCPX4VehicleConfig::stopCalibrationRC() if (!calibrationEnabled) return; + // Try to identify inverted channels, but only for R/P/Y/T + for (int i = 0; i < 4; i++) { + detectChannelInversion(i); + } + QMessageBox::information(0,"Trims","Ensure all controls are centered and throttle is in the lowest position. Click OK to continue"); calibrationEnabled = false; diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 26210d1c87..7c9fe43e2f 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -198,30 +198,6 @@ - - - - Spektrum RC Pairing - - - - - - - DSM2 Mode - - - true - - - - - - - DSMX Mode - - - @@ -235,6 +211,39 @@ + + + + Spektrum RC + + + + + + Pair Receiver + + + + + + + DSM2 Mode + + + true + + + + + + + DSMX Mode + + + + + + @@ -870,8 +879,8 @@ 0 0 - 98 - 28 + 16 + 16 @@ -907,8 +916,8 @@ 0 0 - 98 - 28 + 16 + 16 @@ -958,8 +967,8 @@ 0 0 - 98 - 28 + 16 + 16 -- GitLab From 1c889b1d2a494c3d2bc4b50a97c0223929b72cc6 Mon Sep 17 00:00:00 2001 From: Jean Cyr Date: Fri, 13 Sep 2013 01:12:21 -0400 Subject: [PATCH 386/460] Fix duplicated inputs --- qupgrade.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qupgrade.pro b/qupgrade.pro index 50ed222009..72096c1de0 100644 --- a/qupgrade.pro +++ b/qupgrade.pro @@ -84,7 +84,7 @@ include(qserialport.pri) macx|macx-g++|macx-g++42::SOURCES += libs/qextserialport/qextserialenumerator_osx.cpp linux-g++::SOURCES += libs/qextserialport/qextserialenumerator_unix.cpp linux-g++-64::SOURCES += libs/qextserialport/qextserialenumerator_unix.cpp -win32::SOURCES += libs/qextserialport/qextserialenumerator_win.cpp +win32-g++::SOURCES += libs/qextserialport/qextserialenumerator_win.cpp win32-msvc2008|win32-msvc2010::SOURCES += libs/qextserialport/qextserialenumerator_win.cpp # ------------------------------------------------- -- GitLab From 1ce28cb938cdbad3fde04386908503144ffdae51 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Fri, 13 Sep 2013 18:30:02 +0200 Subject: [PATCH 387/460] Fixed sensor config --- src/ui/px4_configuration/QGCPX4SensorCalibration.cc | 9 ++++++--- src/ui/px4_configuration/QGCPX4SensorCalibration.h | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc index 6ba8f4c4e2..dcb4b12d3a 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc @@ -118,7 +118,7 @@ QGCPX4SensorCalibration::QGCPX4SensorCalibration(QWidget *parent) : connect(ui->autopilotComboBox, SIGNAL(activated(int)), this, SLOT(setAutopilotOrientation(int))); connect(ui->magComboBox, SIGNAL(activated(int)), this, SLOT(setGpsOrientation(int))); - // XXX ask for params (if not loaded) + updateIcons(); } QGCPX4SensorCalibration::~QGCPX4SensorCalibration() @@ -282,9 +282,8 @@ void QGCPX4SensorCalibration::setGpsImage(const QString &path) ui->gpsLabel->setPixmap(gpsIcon.scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation)); } -void QGCPX4SensorCalibration::resizeEvent(QResizeEvent* event) +void QGCPX4SensorCalibration::updateIcons() { - int w = ui->iconLabel->width(); int h = ui->iconLabel->height(); ui->iconLabel->setPixmap(instructionIcon.scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation)); @@ -296,7 +295,11 @@ void QGCPX4SensorCalibration::resizeEvent(QResizeEvent* event) int wg = ui->gpsLabel->width(); int hg = ui->gpsLabel->height(); ui->gpsLabel->setPixmap(gpsIcon.scaled(wg, hg, Qt::KeepAspectRatio, Qt::SmoothTransformation)); +} +void QGCPX4SensorCalibration::resizeEvent(QResizeEvent* event) +{ + updateIcons(); QWidget::resizeEvent(event); } diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.h b/src/ui/px4_configuration/QGCPX4SensorCalibration.h index 50500a83c5..35d0dc2fd8 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.h +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.h @@ -75,9 +75,12 @@ protected: void setMagCalibrated(bool calibrated); void setGyroCalibrated(bool calibrated); void setAccelCalibrated(bool calibrated); + + void updateIcons(); private: Ui::QGCPX4SensorCalibration *ui; + }; #endif // QGCPX4SENSORCALIBRATION_H -- GitLab From ad3307bf7185f5502ae9e1eda362e7100fac09f4 Mon Sep 17 00:00:00 2001 From: Jean Cyr Date: Mon, 16 Sep 2013 20:35:52 -0400 Subject: [PATCH 388/460] Fix toolbar battery voltage not updating --- src/ui/QGCToolBar.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index b71ea8f95a..8bda720b1a 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -464,7 +464,9 @@ void QGCToolBar::updateView() } } - toolBarBatteryVoltageLabel->setText(tr("%1 V").arg(batteryVoltage, 4, 'f', 1, ' ')); + } + if (toolBarBatteryVoltageLabel->isVisible()) { + toolBarBatteryVoltageLabel->setText(tr("%1 V").arg(batteryVoltage, 4, 'f', 1, ' ')); } -- GitLab From d618eb27f62ada9cd2a785d1b40b8d399cebbd5c Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Tue, 17 Sep 2013 17:48:56 +0200 Subject: [PATCH 389/460] Disabled debug output --- src/uas/UASParameterCommsMgr.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index cbc0bb2082..fe7383d9a9 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -387,7 +387,7 @@ void UASParameterCommsMgr::updateSilenceTimer() void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg, ParamCommsStatusLevel_t level) { - qDebug() << "parameterStatusMsg: " << msg; + //qDebug() << "parameterStatusMsg: " << msg; emit parameterStatusMsgUpdated(msg,level); } @@ -395,7 +395,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para { Q_UNUSED(uas); //this object is assigned to one UAS only lastReceiveTime = QGC::groundTimeMilliseconds(); - qDebug() << "compId" << compId << "receivedParameterUpdate:" << paramName; + // qDebug() << "compId" << compId << "receivedParameterUpdate:" << paramName; //notify the data model that we have an updated param paramDataModel->handleParamUpdate(compId,paramName,value); -- GitLab From 8b1f5624cd3c63e7d502a9cf4ee57daec3a7eccb Mon Sep 17 00:00:00 2001 From: "Hyon Lim (Retina)" Date: Thu, 19 Sep 2013 03:30:11 +0900 Subject: [PATCH 390/460] There was an HILS bug that bypass raw RC signal (range from 900 to around 2000) to XPlane. This commit disabled RC RAW signal callback. --- src/comm/QGCXPlaneLink.cc | 77 +++++++++++++++++++++++++-------------- src/uas/UAS.cc | 2 + 2 files changed, 52 insertions(+), 27 deletions(-) diff --git a/src/comm/QGCXPlaneLink.cc b/src/comm/QGCXPlaneLink.cc index b96046b5a8..5ae7b592cf 100644 --- a/src/comm/QGCXPlaneLink.cc +++ b/src/comm/QGCXPlaneLink.cc @@ -292,15 +292,6 @@ void QGCXPlaneLink::updateActuators(uint64_t time, float act1, float act2, float void QGCXPlaneLink::updateControls(uint64_t time, float rollAilerons, float pitchElevator, float yawRudder, float throttle, uint8_t systemMode, uint8_t navMode) { - // Do not update this control type for - // all multirotors - if (mav->getSystemType() == MAV_TYPE_QUADROTOR || - mav->getSystemType() == MAV_TYPE_HEXAROTOR || - mav->getSystemType() == MAV_TYPE_OCTOROTOR) - { - return; - } - #pragma pack(push, 1) struct payload { char b[5]; @@ -315,7 +306,11 @@ void QGCXPlaneLink::updateControls(uint64_t time, float rollAilerons, float pitc p.b[3] = 'A'; p.b[4] = '\0'; - p.index = 12; + Q_UNUSED(time); + Q_UNUSED(systemMode); + Q_UNUSED(navMode); + + bool isFixedWing = true; if (mav->getAirframe() == UASInterface::QGC_AIRFRAME_X8 || mav->getAirframe() == UASInterface::QGC_AIRFRAME_VIPER_2_0 || @@ -329,31 +324,59 @@ void QGCXPlaneLink::updateControls(uint64_t time, float rollAilerons, float pitc // yaw p.f[2] = 0.0f; } + else if (mav->getSystemType() == MAV_TYPE_QUADROTOR) + { + qDebug() << "MAV_TYPE_QUADROTOR"; + + // Individual effort will be provided directly to the actuators on Xplane quadrotor. +#if 1 + p.f[0] = rollAilerons; + p.f[1] = pitchElevator; + p.f[2] = yawRudder; + p.f[3] = throttle; +#endif +#if 0 + p.f[0] = throttle; + p.f[1] = rollAilerons; + p.f[2] = pitchElevator; + p.f[3] = yawRudder; +#endif + isFixedWing = false; + } else { - // direct pass-through + // direct pass-through, normal fixed-wing. p.f[0] = -pitchElevator; p.f[1] = rollAilerons; p.f[2] = yawRudder; } - Q_UNUSED(time); - Q_UNUSED(systemMode); - Q_UNUSED(navMode); + if(isFixedWing) + { + // Ail / Elevon / Rudder + p.index = 12; // XPlane, wing sweep + writeBytes((const char*)&p, sizeof(p)); + + p.index = 8; // XPlane, joystick? why? + writeBytes((const char*)&p, sizeof(p)); + + p.index = 25; // Thrust + memset(p.f, 0, sizeof(p.f)); + p.f[0] = throttle; + p.f[1] = throttle; + p.f[2] = throttle; + p.f[3] = throttle; + + // Throttle + writeBytes((const char*)&p, sizeof(p)); + } + else + { + qDebug() << "Transmitting p.index = 25"; + p.index = 25; // XPlane, throttle command. + writeBytes((const char*)&p, sizeof(p)); + } - // Ail / Elevon / Rudder - writeBytes((const char*)&p, sizeof(p)); - p.index = 8; - writeBytes((const char*)&p, sizeof(p)); - - p.index = 25; - memset(p.f, 0, sizeof(p.f)); - p.f[0] = throttle; - p.f[1] = throttle; - p.f[2] = throttle; - p.f[3] = throttle; - // Throttle - writeBytes((const char*)&p, sizeof(p)); } Eigen::Matrix3f euler_to_wRo(double yaw, double pitch, double roll) { diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 8c47c2acd2..ac1f6895e5 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -1326,6 +1326,7 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message) } } break; +#if 0 case MAVLINK_MSG_ID_SERVO_OUTPUT_RAW: { mavlink_servo_output_raw_t raw; @@ -1340,6 +1341,7 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message) } } break; +#endif #ifdef MAVLINK_ENABLED_PIXHAWK case MAVLINK_MSG_ID_DATA_TRANSMISSION_HANDSHAKE: { -- GitLab From 943391db9c59a6fe3a2243ae92db036e28b219cf Mon Sep 17 00:00:00 2001 From: "Hyon Lim (Retina)" Date: Thu, 19 Sep 2013 04:08:25 +0900 Subject: [PATCH 391/460] Motor order has been determined --- src/comm/QGCXPlaneLink.cc | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/comm/QGCXPlaneLink.cc b/src/comm/QGCXPlaneLink.cc index 5ae7b592cf..c1286235b1 100644 --- a/src/comm/QGCXPlaneLink.cc +++ b/src/comm/QGCXPlaneLink.cc @@ -329,18 +329,11 @@ void QGCXPlaneLink::updateControls(uint64_t time, float rollAilerons, float pitc qDebug() << "MAV_TYPE_QUADROTOR"; // Individual effort will be provided directly to the actuators on Xplane quadrotor. -#if 1 - p.f[0] = rollAilerons; - p.f[1] = pitchElevator; - p.f[2] = yawRudder; - p.f[3] = throttle; -#endif -#if 0 - p.f[0] = throttle; + p.f[0] = yawRudder; p.f[1] = rollAilerons; - p.f[2] = pitchElevator; - p.f[3] = yawRudder; -#endif + p.f[2] = throttle; + p.f[3] = pitchElevator; + isFixedWing = false; } else -- GitLab From b73c9116700fe476fc501b4fccc23faf0a1eedc3 Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Thu, 19 Sep 2013 00:14:43 +0200 Subject: [PATCH 392/460] Flightgear sensor HIL --- .../Protocol/qgroundcontrol-fixed-wing.xml | 45 +++++- src/comm/QGCFlightGearLink.cc | 142 ++++++++++++++---- src/comm/QGCFlightGearLink.h | 4 + src/uas/UAS.cc | 3 +- src/uas/UAS.h | 2 +- src/ui/QGCHilConfiguration.cc | 2 +- src/ui/QGCHilFlightGearConfiguration.cc | 2 +- src/ui/QGCHilFlightGearConfiguration.ui | 31 +++- 8 files changed, 194 insertions(+), 37 deletions(-) diff --git a/files/flightgear/Protocol/qgroundcontrol-fixed-wing.xml b/files/flightgear/Protocol/qgroundcontrol-fixed-wing.xml index 94a60ded59..5fe0ad2b0c 100644 --- a/files/flightgear/Protocol/qgroundcontrol-fixed-wing.xml +++ b/files/flightgear/Protocol/qgroundcontrol-fixed-wing.xml @@ -141,6 +141,49 @@ /velocities/airspeed-kt 0.514444444444444 + + + airspeed-indicated-mps + float + %.8f + /instrumentation/indicated-speed-kt + 0.514444444444444 + + + + + Magnetic Variation (rad) + float + %.8f + /environment/magnetic-variation-deg + 0.01745329251994329576 + + + + Magnetic Dip (rad) + float + %.8f + /environment/magnetic-dip-deg + 0.01745329251994329576 + + + + + Temperature (deg C) + float + %.8f + /environment/temperature-degc + 1 + + + + + Pressure (hPa) + float + %.8f + /environment/pressure-inhg + 33.86389 + @@ -184,4 +227,4 @@ - \ No newline at end of file + diff --git a/src/comm/QGCFlightGearLink.cc b/src/comm/QGCFlightGearLink.cc index 61341b0488..d8bc240ee3 100644 --- a/src/comm/QGCFlightGearLink.cc +++ b/src/comm/QGCFlightGearLink.cc @@ -26,6 +26,7 @@ This file is part of the QGROUNDCONTROL project * @brief Definition of UDP connection (server) for unmanned vehicles * @see Flightgear Manual http://mapserver.flightgear.org/getstart.pdf * @author Lorenz Meier + * @author Thomas Gubler * */ @@ -44,7 +45,8 @@ QGCFlightGearLink::QGCFlightGearLink(UASInterface* mav, QString startupArguments process(NULL), terraSync(NULL), flightGearVersion(0), - startupArguments(startupArguments) + startupArguments(startupArguments), + _sensorHilEnabled(true) { this->host = host; this->port = port+mav->getUASID(); @@ -172,6 +174,7 @@ void QGCFlightGearLink::updateControls(uint64_t time, float rollAilerons, float QString state("%1\t%2\t%3\t%4\t%5\n"); state = state.arg(rollAilerons).arg(pitchElevator).arg(yawRudder).arg(true).arg(throttle); writeBytes(state.toAscii().constData(), state.length()); +// qDebug() << "updated controls" << rollAilerons << pitchElevator << yawRudder << throttle; } else { @@ -227,49 +230,133 @@ void QGCFlightGearLink::readBytes() // Print string QString state(b); - //qDebug() << "FG LINK GOT:" << state; +// qDebug() << "FG LINK GOT:" << state; QStringList values = state.split("\t"); // Check length - if (values.size() != 17) + if (values.size() != 22) { - qDebug() << "RETURN LENGTH MISMATCHING EXPECTED" << 17 << "BUT GOT" << values.size(); + qDebug() << "RETURN LENGTH MISMATCHING EXPECTED" << 22 << "BUT GOT" << values.size(); qDebug() << state; return; } // Parse string float roll, pitch, yaw, rollspeed, pitchspeed, yawspeed; - double lat, lon, alt; + double lat, lon, alt; + float ind_airspeed; + float true_airspeed; + float vx, vy, vz, xacc, yacc, zacc; + float diff_pressure; + float temperature; + float abs_pressure; + float mag_variation, mag_dip, xmag_ned, ymag_ned, zmag_ned, xmag_body, ymag_body, zmag_body; - // XXX add - float ind_airspeed = 0.0f; - float true_airspeed = 0.0f; - double vx, vy, vz, xacc, yacc, zacc; lat = values.at(1).toDouble(); lon = values.at(2).toDouble(); alt = values.at(3).toDouble(); - roll = values.at(4).toDouble(); - pitch = values.at(5).toDouble(); - yaw = values.at(6).toDouble(); - rollspeed = values.at(7).toDouble(); - pitchspeed = values.at(8).toDouble(); - yawspeed = values.at(9).toDouble(); + roll = values.at(4).toFloat(); + pitch = values.at(5).toFloat(); + yaw = values.at(6).toFloat(); + rollspeed = values.at(7).toFloat(); + pitchspeed = values.at(8).toFloat(); + yawspeed = values.at(9).toFloat(); - xacc = values.at(10).toDouble(); - yacc = values.at(11).toDouble(); - zacc = values.at(12).toDouble(); + xacc = values.at(10).toFloat(); + yacc = values.at(11).toFloat(); + zacc = values.at(12).toFloat(); - vx = values.at(13).toDouble(); - vy = values.at(14).toDouble(); - vz = values.at(15).toDouble(); + vx = values.at(13).toFloat(); + vy = values.at(14).toFloat(); + vz = values.at(15).toFloat(); + + true_airspeed = values.at(16).toFloat(); + ind_airspeed = values.at(17).toFloat(); + + mag_variation = values.at(18).toFloat(); + mag_dip = values.at(19).toFloat(); + + temperature = values.at(20).toFloat(); + abs_pressure = values.at(21).toFloat(); // Send updated state - emit hilStateChanged(QGC::groundTimeUsecs(), roll, pitch, yaw, rollspeed, + //qDebug() << "sensorHilEnabled: " << sensorHilEnabled; + if (_sensorHilEnabled) + { + quint16 fields_changed = 0xFFF; //set all 12 used bits + + //calculate differential pressure + const float air_gas_constant = 287.1f; // J/(kg * K) + const float absolute_null_celsius = -273.15f; // °C + float density = abs_pressure / (air_gas_constant * (temperature - absolute_null_celsius)); + diff_pressure = true_airspeed * true_airspeed * density / 2.0f; + + float pressure_alt = alt; + + xmag_ned = cosf(mag_variation); + ymag_ned = sinf(mag_variation); + zmag_ned = sinf(mag_dip); + float tempMagLength = sqrtf(xmag_ned*xmag_ned + ymag_ned*ymag_ned + zmag_ned*zmag_ned); + xmag_ned = xmag_ned / tempMagLength; + ymag_ned = ymag_ned / tempMagLength; + zmag_ned = zmag_ned / tempMagLength; + + //transform magnetic measurement to body frame coordinates + double cosPhi = cos(roll); + double sinPhi = sin(roll); + double cosThe = cos(pitch); + double sinThe = sin(pitch); + double cosPsi = cos(yaw); + double sinPsi = sin(yaw); + + float R_B_N[3][3]; + + R_B_N[0][0] = cosThe * cosPsi; + R_B_N[0][1] = -cosPhi * sinPsi + sinPhi * sinThe * cosPsi; + R_B_N[0][2] = sinPhi * sinPsi + cosPhi * sinThe * cosPsi; + + R_B_N[1][0] = cosThe * sinPsi; + R_B_N[1][1] = cosPhi * cosPsi + sinPhi * sinThe * sinPsi; + R_B_N[1][2] = -sinPhi * cosPsi + cosPhi * sinThe * sinPsi; + + R_B_N[2][0] = -sinThe; + R_B_N[2][1] = sinPhi * cosThe; + R_B_N[2][2] = cosPhi * cosThe; + + Eigen::Matrix3f R_B_N_M = Eigen::Map((float*)R_B_N).eval(); + + Eigen::Vector3f mag_ned(xmag_ned, ymag_ned, zmag_ned); + + Eigen::Vector3f mag_body = R_B_N_M * mag_ned; + + xmag_body = mag_body(0); + ymag_body = mag_body(1); + zmag_body = mag_body(2); + + emit sensorHilRawImuChanged(QGC::groundTimeUsecs(), xacc, yacc, zacc, rollspeed, pitchspeed, yawspeed, + xmag_body, ymag_body, zmag_body, abs_pressure, diff_pressure, pressure_alt, temperature, fields_changed); + +// qDebug() << "sensorHilRawImuChanged " << xacc << yacc << zacc << rollspeed << pitchspeed << yawspeed << xmag << ymag << zmag << abs_pressure << diff_pressure << pressure_alt << temperature; + int gps_fix_type = 3; + float eph = 0.3; + float epv = 0.6; + float vel = sqrt(vx*vx + vy*vy + vz*vz); + float cog = yaw; + int satellites = 8; + + emit sensorHilGpsChanged(QGC::groundTimeUsecs(), lat, lon, alt, gps_fix_type, eph, epv, vel, vx, vy, vz, cog, satellites); + +// qDebug() << "sensorHilGpsChanged " << lat << lon << alt << vel; + } else { + emit hilStateChanged(QGC::groundTimeUsecs(), roll, pitch, yaw, rollspeed, pitchspeed, yawspeed, lat, lon, alt, - vx, vy, vz, ind_airspeed, true_airspeed, xacc, yacc, zacc); + vx, vy, vz, + ind_airspeed, true_airspeed, + xacc, yacc, zacc); + //qDebug() << "hilStateChanged " << (int32_t)lat << (int32_t)lon << (int32_t)alt; + } // // Echo data for debugging purposes // std::cerr << __FILE__ << __LINE__ << "Received datagram:" << std::endl; @@ -303,7 +390,9 @@ bool QGCFlightGearLink::disconnectSimulation() disconnect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError))); disconnect(mav, SIGNAL(hilControlsChanged(uint64_t, float, float, float, float, uint8_t, uint8_t)), this, SLOT(updateControls(uint64_t,float,float,float,float,uint8_t,uint8_t))); - disconnect(this, SIGNAL(hilStateChanged(quint64,float,float,float,float,float,float,double,double,double,float,float,float,float,float,float,float,float)), mav, SLOT(sendHilState(quint64,float,float,float,float,float,float,double,double,double,float,float,float,float,float,float,float,float))); + disconnect(this, SIGNAL(hilStateChanged(quint64, float, float, float, float,float, float, double, double, double, float, float, float, float, float, float, float, float)), mav, SLOT(sendHilState(quint64, float, float, float, float,float, float, double, double, double, float, float, float, float, float, float, float, float))); + disconnect(this, SIGNAL(sensorHilGpsChanged(quint64, double, double, double, int, float, float, float, float, float, float, float, int)), mav, SLOT(sendHilGps(quint64, double, double, double, int, float, float, float, float, float, float, float, int))); + disconnect(this, SIGNAL(sensorHilRawImuChanged(quint64,float,float,float,float,float,float,float,float,float,float,float,float,float,quint32)), mav, SLOT(sendHilSensors(quint64,float,float,float,float,float,float,float,float,float,float,float,float,float,quint32))); if (process) { @@ -350,8 +439,9 @@ bool QGCFlightGearLink::connectSimulation() terraSync = new QProcess(this); connect(mav, SIGNAL(hilControlsChanged(uint64_t, float, float, float, float, uint8_t, uint8_t)), this, SLOT(updateControls(uint64_t,float,float,float,float,uint8_t,uint8_t))); - connect(this, SIGNAL(hilStateChanged(quint64,float,float,float,float,float,float,double,double,double,float,float,float,float,float,float,float,float)), mav, SLOT(sendHilState(quint64,float,float,float,float,float,float,double,double,double,float,float,float,float,float,float,float,float))); - + connect(this, SIGNAL(hilStateChanged(quint64, float, float, float, float,float, float, double, double, double, float, float, float, float, float, float, float, float)), mav, SLOT(sendHilState(quint64, float, float, float, float,float, float, double, double, double, float, float, float, float, float, float, float, float))); + connect(this, SIGNAL(sensorHilGpsChanged(quint64, double, double, double, int, float, float, float, float, float, float, float, int)), mav, SLOT(sendHilGps(quint64, double, double, double, int, float, float, float, float, float, float, float, int))); + connect(this, SIGNAL(sensorHilRawImuChanged(quint64,float,float,float,float,float,float,float,float,float,float,float,float,float,quint32)), mav, SLOT(sendHilSensors(quint64,float,float,float,float,float,float,float,float,float,float,float,float,float,quint32))); UAS* uas = dynamic_cast(mav); if (uas) diff --git a/src/comm/QGCFlightGearLink.h b/src/comm/QGCFlightGearLink.h index 9bdda2e5d5..d043d3c63b 100644 --- a/src/comm/QGCFlightGearLink.h +++ b/src/comm/QGCFlightGearLink.h @@ -83,6 +83,10 @@ public: return _sensorHilEnabled; } + void sensorHilEnabled(bool sensorHilEnabled) { + _sensorHilEnabled = sensorHilEnabled; + } + void run(); public slots: diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 1c727cd5bb..94d73f1edc 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -2930,7 +2930,7 @@ bool UAS::emergencyKILL() /** * If enabled, connect the flight gear link. */ -void UAS::enableHilFlightGear(bool enable, QString options) +void UAS::enableHilFlightGear(bool enable, QString options, bool sensorHil) { QGCFlightGearLink* link = dynamic_cast(simulation); if (!link || !simulation) { @@ -2944,6 +2944,7 @@ void UAS::enableHilFlightGear(bool enable, QString options) // Connect Flight Gear Link link = dynamic_cast(simulation); link->setStartupArguments(options); + link->sensorHilEnabled(sensorHil); if (enable) { startHil(); diff --git a/src/uas/UAS.h b/src/uas/UAS.h index 8a60d343ea..e30946a67c 100644 --- a/src/uas/UAS.h +++ b/src/uas/UAS.h @@ -730,7 +730,7 @@ public slots: void go(); /** @brief Enable / disable HIL */ - void enableHilFlightGear(bool enable, QString options); + void enableHilFlightGear(bool enable, QString options, bool sensorHil); void enableHilJSBSim(bool enable, QString options); void enableHilXPlane(bool enable); diff --git a/src/ui/QGCHilConfiguration.cc b/src/ui/QGCHilConfiguration.cc index 37467fb137..e501e8c6aa 100644 --- a/src/ui/QGCHilConfiguration.cc +++ b/src/ui/QGCHilConfiguration.cc @@ -64,7 +64,7 @@ void QGCHilConfiguration::on_simComboBox_currentIndexChanged(int index) if(1 == index) { // Ensure the sim exists and is disabled - mav->enableHilFlightGear(false, ""); + mav->enableHilFlightGear(false, "", true); QGCHilFlightGearConfiguration* hfgconf = new QGCHilFlightGearConfiguration(mav, this); hfgconf->show(); ui->simulatorConfigurationLayout->addWidget(hfgconf); diff --git a/src/ui/QGCHilFlightGearConfiguration.cc b/src/ui/QGCHilFlightGearConfiguration.cc index 6a39a257e9..ddbccb7c7f 100644 --- a/src/ui/QGCHilFlightGearConfiguration.cc +++ b/src/ui/QGCHilFlightGearConfiguration.cc @@ -40,7 +40,7 @@ void QGCHilFlightGearConfiguration::on_startButton_clicked() //XXX check validity of inputs QString options = ui->optionsPlainTextEdit->toPlainText(); options.append(" --aircraft=" + ui->aircraftComboBox->currentText()); - mav->enableHilFlightGear(true, options); + mav->enableHilFlightGear(true, options, ui->sensorHilCheckBox->isChecked()); } void QGCHilFlightGearConfiguration::on_stopButton_clicked() diff --git a/src/ui/QGCHilFlightGearConfiguration.ui b/src/ui/QGCHilFlightGearConfiguration.ui index 2a4cb315b1..d06f174223 100644 --- a/src/ui/QGCHilFlightGearConfiguration.ui +++ b/src/ui/QGCHilFlightGearConfiguration.ui @@ -25,8 +25,17 @@ false - - + + + 0 + + + 0 + + + 0 + + 0 @@ -52,14 +61,14 @@ - + <html><head/><body><p>Additional Options:</p></body></html> - + @@ -72,7 +81,7 @@ - + @@ -85,13 +94,23 @@ - + Stop + + + + Sensor HIL + + + true + + + -- GitLab From b82d37f8182a213d236c5af76621c8951d211e65 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 26 Sep 2013 08:07:49 +0200 Subject: [PATCH 393/460] Cleanup of airframe config, removed debug line --- src/comm/MAVLinkProtocol.cc | 2 +- src/ui/px4_configuration/QGCPX4AirframeConfig.cc | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/comm/MAVLinkProtocol.cc b/src/comm/MAVLinkProtocol.cc index 3a24378912..d78cdac774 100644 --- a/src/comm/MAVLinkProtocol.cc +++ b/src/comm/MAVLinkProtocol.cc @@ -539,7 +539,7 @@ void MAVLinkProtocol::sendMessage(mavlink_message_t message) for (i = links.begin(); i != links.end(); ++i) { sendMessage(*i, message); - qDebug() << __FILE__ << __LINE__ << "SENT MESSAGE OVER" << ((LinkInterface*)*i)->getName() << "LIST SIZE:" << links.size(); +// qDebug() << __FILE__ << __LINE__ << "SENT MESSAGE OVER" << ((LinkInterface*)*i)->getName() << "LIST SIZE:" << links.size(); } } diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index de1ae066ce..48d321b11b 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -301,7 +301,7 @@ void QGCPX4AirframeConfig::checkConfigState() // Reboot //TODO right now this relies upon the above send & persist finishing before the reboot command is received... - unsigned pendingMax = 20; + unsigned pendingMax = 17; qDebug() << "PENDING PARAMS REBOOT BEFORE" << pendingParams; @@ -338,14 +338,6 @@ void QGCPX4AirframeConfig::checkConfigState() qDebug() << "CONNECT AIRFRAME"; LinkManager::instance()->connectAll(); } - if (pendingParams == 15) { - qDebug() << "DISCONNECT AIRFRAME"; - LinkManager::instance()->disconnectAll(); - } - if (pendingParams == 16) { - qDebug() << "CONNECT AIRFRAME"; - LinkManager::instance()->connectAll(); - } if (pendingParams < pendingMax) { progress->setValue(pendingParams); -- GitLab From 1f983e59a1c688cff724f84ee084c48ba38c8007 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Mon, 7 Oct 2013 21:25:18 +0100 Subject: [PATCH 394/460] Do not crash in an empty symmetric IncrementalPlot This crash could be reproduced by starting QGroundControl, switching to plot, then clicking the "Symmetric" checkbox. --- src/ui/linechart/IncrementalPlot.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ui/linechart/IncrementalPlot.cc b/src/ui/linechart/IncrementalPlot.cc index 4b90fcf9fe..d227105c49 100644 --- a/src/ui/linechart/IncrementalPlot.cc +++ b/src/ui/linechart/IncrementalPlot.cc @@ -214,6 +214,9 @@ void IncrementalPlot::resetScaling() void IncrementalPlot::updateScale() { const double margin = 0.05; + if(xmin == DBL_MAX) + return; + double xMinRange = xmin-(qAbs(xmin*margin)); double xMaxRange = xmax+(qAbs(xmax*margin)); double yMinRange = ymin-(qAbs(ymin*margin)); -- GitLab From 13e5381d3af23b765066c037a2f3b1be7bb1dfc7 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Tue, 8 Oct 2013 17:11:34 +0100 Subject: [PATCH 395/460] DataPlot - Don't crash if the user cancels saving the data or image file --- src/ui/QGCDataPlot2D.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ui/QGCDataPlot2D.cc b/src/ui/QGCDataPlot2D.cc index 02dc9d1721..4a24151a14 100644 --- a/src/ui/QGCDataPlot2D.cc +++ b/src/ui/QGCDataPlot2D.cc @@ -120,6 +120,8 @@ void QGCDataPlot2D::savePlot() fileName = QFileDialog::getSaveFileName( this, "Export File Name", QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), "PDF Documents (*.pdf);;SVG Images (*.svg)"); + if (fileName.isEmpty()) + return; if (!fileName.contains(".")) { // .pdf is default extension @@ -138,6 +140,8 @@ void QGCDataPlot2D::savePlot() fileName = QFileDialog::getSaveFileName( this, "Export File Name", QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), "PDF Documents (*.pdf);;SVG Images (*.svg)"); + if (fileName.isEmpty()) + return; //Abort if cancelled } if (fileName.endsWith(".pdf")) { @@ -689,6 +693,8 @@ void QGCDataPlot2D::saveCsvLog() fileName = QFileDialog::getSaveFileName( this, "Export CSV File Name", QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), "CSV file (*.csv);;Text file (*.txt)"); + if (fileName.isEmpty()) + return; //User cancelled if (!fileName.contains(".")) { // .csv is default extension -- GitLab From c90c55d4803faef1d4d26326f6c35cd037dd3c21 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Tue, 8 Oct 2013 22:42:52 +0100 Subject: [PATCH 396/460] CommConfigurationWindow - make it a proper QDialog, and not a floating widget --- src/ui/CommConfigurationWindow.cc | 2 +- src/ui/CommConfigurationWindow.h | 4 ++-- src/ui/MainWindow.cc | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/CommConfigurationWindow.cc b/src/ui/CommConfigurationWindow.cc index 099c28f464..223abd9186 100644 --- a/src/ui/CommConfigurationWindow.cc +++ b/src/ui/CommConfigurationWindow.cc @@ -55,7 +55,7 @@ This file is part of the QGROUNDCONTROL project #include "LinkManager.h" #include "MainWindow.h" -CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolInterface* protocol, QWidget *parent) : QWidget(parent) +CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolInterface* protocol, QWidget *parent) : QDialog(parent) { this->link = link; diff --git a/src/ui/CommConfigurationWindow.h b/src/ui/CommConfigurationWindow.h index 4333e5ad62..65912b03b2 100644 --- a/src/ui/CommConfigurationWindow.h +++ b/src/ui/CommConfigurationWindow.h @@ -33,7 +33,7 @@ This file is part of the QGROUNDCONTROL project #define _COMMCONFIGURATIONWINDOW_H_ #include -#include +#include #include #include "LinkInterface.h" #include "ProtocolInterface.h" @@ -62,7 +62,7 @@ enum qgc_protocol_t { /** * @brief Configuration window for communication links */ -class CommConfigurationWindow : public QWidget +class CommConfigurationWindow : public QDialog { Q_OBJECT diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 354c73b4b1..2a5450c73f 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -1683,7 +1683,7 @@ void MainWindow::addLink(LinkInterface *link) if (!found) { - CommConfigurationWindow* commWidget = new CommConfigurationWindow(link, mavlink, NULL); + CommConfigurationWindow* commWidget = new CommConfigurationWindow(link, mavlink, this); commsWidgetList.append(commWidget); connect(commWidget,SIGNAL(destroyed(QObject*)),this,SLOT(commsWidgetDestroyed(QObject*))); QAction* action = commWidget->getAction(); -- GitLab From b9bd45928ffc74b2400123213e189eb30c965a1e Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Tue, 8 Oct 2013 22:54:25 +0100 Subject: [PATCH 397/460] CommConfigurationWindow - don't try to manually center, now that it is a proper QDialog --- src/ui/CommConfigurationWindow.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/ui/CommConfigurationWindow.cc b/src/ui/CommConfigurationWindow.cc index 223abd9186..ffb163bb9d 100644 --- a/src/ui/CommConfigurationWindow.cc +++ b/src/ui/CommConfigurationWindow.cc @@ -62,11 +62,6 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn // Setup the user interface according to link type ui.setupUi(this); - // Center the window on the screen. - QRect position = frameGeometry(); - position.moveCenter(QDesktopWidget().availableGeometry().center()); - move(position.topLeft()); - // Initialize basic ui state // Do not allow changes here unless advanced is checked -- GitLab From 6f8802dabb09f1287e25e6d0543fc41a1d382788 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Tue, 8 Oct 2013 23:26:50 +0100 Subject: [PATCH 398/460] CommConfigurationWindow - changing the link type should update the window --- src/ui/CommConfigurationWindow.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ui/CommConfigurationWindow.cc b/src/ui/CommConfigurationWindow.cc index ffb163bb9d..81bb4b6484 100644 --- a/src/ui/CommConfigurationWindow.cc +++ b/src/ui/CommConfigurationWindow.cc @@ -183,9 +183,7 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn qDebug() << "Link is NOT a known link, can't open configuration window"; } -#ifdef XBEELINK connect(ui.linkType,SIGNAL(currentIndexChanged(int)),this,SLOT(setLinkType(int))); -#endif // XBEELINK // Open details pane for MAVLink if necessary MAVLinkProtocol* mavlink = dynamic_cast(protocol); -- GitLab From 96ab4dc87d428348b0588037167bccf053978b43 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Wed, 9 Oct 2013 00:18:47 +0100 Subject: [PATCH 399/460] Comm Settings - move the "link type" combobox to the top, and clean it up * The "Simulation" option is now not selectable. * If the link is a simulation, then you can't change it to a different link type. * The OPAL option is not shown if support is not compiled in. * Fix the buddy, tab order and accelerators in the GUI. --- src/ui/CommConfigurationWindow.cc | 38 +++++++++----- src/ui/CommConfigurationWindow.h | 7 ++- src/ui/CommSettings.ui | 87 +++++++++++++++++++++++-------- 3 files changed, 94 insertions(+), 38 deletions(-) diff --git a/src/ui/CommConfigurationWindow.cc b/src/ui/CommConfigurationWindow.cc index 81bb4b6484..462f1c42cb 100644 --- a/src/ui/CommConfigurationWindow.cc +++ b/src/ui/CommConfigurationWindow.cc @@ -66,7 +66,6 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn // Do not allow changes here unless advanced is checked ui.connectionType->setEnabled(false); - ui.linkType->setEnabled(false); ui.protocolGroupBox->setVisible(false); ui.protocolTypeGroupBox->setVisible(false); @@ -78,14 +77,19 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn //connect(ui.advCheckBox,SIGNAL(clicked(bool)),ui.advancedOptionsCheckBox,SLOT(setChecked(bool))); connect(ui.advCheckBox,SIGNAL(clicked(bool)),ui.protocolTypeGroupBox,SLOT(setVisible(bool))); connect(ui.advCheckBox, SIGNAL(clicked(bool)), ui.connectionType, SLOT(setEnabled(bool))); - connect(ui.advCheckBox, SIGNAL(clicked(bool)), ui.linkType, SLOT(setEnabled(bool))); connect(ui.advCheckBox, SIGNAL(clicked(bool)), ui.protocolGroupBox, SLOT(setVisible(bool))); // add link types ui.linkType->addItem(tr("Serial"), QGC_LINK_SERIAL); ui.linkType->addItem(tr("UDP"), QGC_LINK_UDP); - ui.linkType->addItem(tr("Simulation"), QGC_LINK_SIMULATION); + if(dynamic_cast(link)) { + //Only show simulation option if already setup elsewhere as a simulation + ui.linkType->addItem(tr("Simulation"), QGC_LINK_SIMULATION); + } + +#ifdef OPAL_RT ui.linkType->addItem(tr("Opal-RT Link"), QGC_LINK_OPAL); +#endif #ifdef XBEELINK ui.linkType->addItem(tr("Xbee API"),QGC_LINK_XBEE); #endif // XBEELINK @@ -135,18 +139,19 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn QWidget* conf = new SerialConfigurationWindow(serial, this); ui.linkScrollArea->setWidget(conf); ui.linkGroupBox->setTitle(tr("Serial Link")); - ui.linkType->setCurrentIndex(0); + ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_SERIAL)); } UDPLink* udp = dynamic_cast(link); if (udp != 0) { QWidget* conf = new QGCUDPLinkConfiguration(udp, this); ui.linkScrollArea->setWidget(conf); ui.linkGroupBox->setTitle(tr("UDP Link")); - ui.linkType->setCurrentIndex(1); + ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_UDP)); } MAVLinkSimulationLink* sim = dynamic_cast(link); if (sim != 0) { - ui.linkType->setCurrentIndex(2); + ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_SIMULATION)); + ui.linkType->setEnabled(false); //Don't allow the user to change to a non-simulation ui.linkGroupBox->setTitle(tr("MAVLink Simulation Link")); } #ifdef OPAL_RT @@ -156,7 +161,7 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight, ui.linkGroupBox); layout->addWidget(conf); ui.linkGroupBox->setLayout(layout); - ui.linkType->setCurrentIndex(3); + ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_OPAL)); ui.linkGroupBox->setTitle(tr("Opal-RT Link")); } #endif @@ -167,7 +172,7 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn QWidget* conf = new XbeeConfigurationWindow(xbee,this); ui.linkScrollArea->setWidget(conf); ui.linkGroupBox->setTitle(tr("Xbee Link")); - ui.linkType->setCurrentIndex(4); + ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_XBEE)); connect(xbee,SIGNAL(tryConnectBegin(bool)),ui.actionConnect,SLOT(setDisabled(bool))); connect(xbee,SIGNAL(tryConnectEnd(bool)),ui.actionConnect,SLOT(setEnabled(bool))); } @@ -183,7 +188,7 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn qDebug() << "Link is NOT a known link, can't open configuration window"; } - connect(ui.linkType,SIGNAL(currentIndexChanged(int)),this,SLOT(setLinkType(int))); + connect(ui.linkType,SIGNAL(currentIndexChanged(int)),this,SLOT(linkCurrentIndexChanged(int))); // Open details pane for MAVLink if necessary MAVLinkProtocol* mavlink = dynamic_cast(protocol); @@ -213,7 +218,12 @@ QAction* CommConfigurationWindow::getAction() return action; } -void CommConfigurationWindow::setLinkType(int linktype) +void CommConfigurationWindow::linkCurrentIndexChanged(int currentIndex) +{ + setLinkType(static_cast(ui.linkType->itemData(currentIndex).toInt())); +} + +void CommConfigurationWindow::setLinkType(qgc_link_t linktype) { if(link->isConnected()) { @@ -230,7 +240,7 @@ void CommConfigurationWindow::setLinkType(int linktype) switch(linktype) { #ifdef XBEELINK - case 4: + case QGC_LINK_XBEE: { XbeeLink *xbee = new XbeeLink(); tmpLink = xbee; @@ -238,7 +248,7 @@ void CommConfigurationWindow::setLinkType(int linktype) break; } #endif // XBEELINK - case 1: + case QGC_LINK_UDP: { UDPLink *udp = new UDPLink(); tmpLink = udp; @@ -247,7 +257,7 @@ void CommConfigurationWindow::setLinkType(int linktype) } #ifdef OPAL_RT - case 3: + case QGC_LINK_OPAL: { OpalLink* opal = new OpalLink(); tmpLink = opal; @@ -258,7 +268,7 @@ void CommConfigurationWindow::setLinkType(int linktype) default: { } - case 0: + case QGC_LINK_SERIAL: { SerialLink *serial = new SerialLink(); tmpLink = serial; diff --git a/src/ui/CommConfigurationWindow.h b/src/ui/CommConfigurationWindow.h index 65912b03b2..47e2b4c8ff 100644 --- a/src/ui/CommConfigurationWindow.h +++ b/src/ui/CommConfigurationWindow.h @@ -47,7 +47,9 @@ enum qgc_link_t { #ifdef XBEELINK QGC_LINK_XBEE, #endif +#ifdef OPAL_RT QGC_LINK_OPAL +#endif }; enum qgc_protocol_t { @@ -71,9 +73,12 @@ public: ~CommConfigurationWindow(); QAction* getAction(); + void setLinkType(qgc_link_t linktype); + +private slots: + void linkCurrentIndexChanged(int currentIndex); public slots: - void setLinkType(int linktype); /** @brief Set the protocol for this link */ void setProtocol(int protocol); void setConnection(); diff --git a/src/ui/CommSettings.ui b/src/ui/CommSettings.ui index 73b4d76efc..e04678c17a 100644 --- a/src/ui/CommSettings.ui +++ b/src/ui/CommSettings.ui @@ -14,6 +14,23 @@ Form + + + + + + Link &Type: + + + linkType + + + + + + + + @@ -23,7 +40,16 @@ 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -36,8 +62,8 @@ 0 0 - 292 - 81 + 298 + 90 @@ -49,7 +75,7 @@ - Show Advanced Protocol Options + &Show Advanced Protocol Options @@ -61,34 +87,27 @@ - - - - Link Type - - - - - - -1 - - + + - Advanced Options + &Protocol: + + + connectionType - - + + - Protocol + &Advanced Options @@ -113,7 +132,16 @@ 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -126,8 +154,8 @@ 0 0 - 292 - 81 + 298 + 90 @@ -217,7 +245,20 @@ connectionStatusLabel advCheckBox protocolTypeGroupBox + linkType + label + + linkType + linkScrollArea + advCheckBox + connectionType + advancedOptionsCheckBox + protocolScrollArea + connectButton + deleteButton + closeButton + -- GitLab From b0d4abacd47c37ddda1b6ad13099b94bd125fde2 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Thu, 10 Oct 2013 11:27:36 +0100 Subject: [PATCH 400/460] Change QString function parameters to const QString & --- src/ui/linechart/ChartPlot.cc | 2 +- src/ui/linechart/ChartPlot.h | 2 +- src/ui/linechart/IncrementalPlot.cc | 8 ++++---- src/ui/linechart/IncrementalPlot.h | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ui/linechart/ChartPlot.cc b/src/ui/linechart/ChartPlot.cc index 665ff52336..a1741f85cf 100644 --- a/src/ui/linechart/ChartPlot.cc +++ b/src/ui/linechart/ChartPlot.cc @@ -70,7 +70,7 @@ QColor ChartPlot::getNextColor() return colors[nextColorIndex++]; } -QColor ChartPlot::getColorForCurve(QString id) +QColor ChartPlot::getColorForCurve(const QString &id) { return curves.value(id)->pen().color(); } diff --git a/src/ui/linechart/ChartPlot.h b/src/ui/linechart/ChartPlot.h index 74a232039e..c5196ae8b5 100644 --- a/src/ui/linechart/ChartPlot.h +++ b/src/ui/linechart/ChartPlot.h @@ -17,7 +17,7 @@ public: QColor getNextColor(); /** @brief Get color for curve id */ - QColor getColorForCurve(QString id); + QColor getColorForCurve(const QString &id); /** @brief Reset color map */ void shuffleColors(); diff --git a/src/ui/linechart/IncrementalPlot.cc b/src/ui/linechart/IncrementalPlot.cc index d227105c49..6a5e13f4de 100644 --- a/src/ui/linechart/IncrementalPlot.cc +++ b/src/ui/linechart/IncrementalPlot.cc @@ -155,7 +155,7 @@ void IncrementalPlot::showLegend(bool show) * * @param style Formatting string for line/data point style */ -void IncrementalPlot::setStyleText(QString style) +void IncrementalPlot::setStyleText(const QString &style) { foreach (QwtPlotCurve* curve, curves) { // Style of datapoints @@ -250,12 +250,12 @@ void IncrementalPlot::updateScale() zoomer->setZoomBase(true); } -void IncrementalPlot::appendData(QString key, double x, double y) +void IncrementalPlot::appendData(const QString &key, double x, double y) { appendData(key, &x, &y, 1); } -void IncrementalPlot::appendData(QString key, double *x, double *y, int size) +void IncrementalPlot::appendData(const QString &key, double *x, double *y, int size) { CurveData* data; QwtPlotCurve* curve; @@ -349,7 +349,7 @@ void IncrementalPlot::appendData(QString key, double *x, double *y, int size) /** * @return Number of copied data points, 0 on failure */ -int IncrementalPlot::data(QString key, double* r_x, double* r_y, int maxSize) +int IncrementalPlot::data(const QString &key, double* r_x, double* r_y, int maxSize) { int result = 0; if (d_data.contains(key)) { diff --git a/src/ui/linechart/IncrementalPlot.h b/src/ui/linechart/IncrementalPlot.h index 06dee02ff0..0b7f2d3b4f 100644 --- a/src/ui/linechart/IncrementalPlot.h +++ b/src/ui/linechart/IncrementalPlot.h @@ -84,14 +84,14 @@ public: bool gridEnabled(); /** @brief Read out data from a curve */ - int data(QString key, double* r_x, double* r_y, int maxSize); + int data(const QString &key, double* r_x, double* r_y, int maxSize); public slots: /** @brief Append one data point */ - void appendData(QString key, double x, double y); + void appendData(const QString &key, double x, double y); /** @brief Append multiple data points */ - void appendData(QString key, double* x, double* y, int size); + void appendData(const QString &key, double* x, double* y, int size); /** @brief Reset the plot scaling to the default value */ void resetScaling(); @@ -109,7 +109,7 @@ public slots: void showGrid(bool show); /** @brief Set new plot style */ - void setStyleText(QString style); + void setStyleText(const QString &style); /** @brief Set symmetric axis scaling mode */ void setSymmetric(bool symmetric); -- GitLab From 8538e1a8da14e251eb3423221a705b9db0d7d0e6 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Thu, 10 Oct 2013 13:32:23 +0100 Subject: [PATCH 401/460] LinechartWidget - Make the scaling log button a propper toggle button --- src/ui/linechart/LinechartWidget.cc | 40 +++++++++++++---------------- src/ui/linechart/LinechartWidget.h | 4 +-- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/ui/linechart/LinechartWidget.cc b/src/ui/linechart/LinechartWidget.cc index 53dcac360c..459022c07a 100644 --- a/src/ui/linechart/LinechartWidget.cc +++ b/src/ui/linechart/LinechartWidget.cc @@ -225,23 +225,14 @@ void LinechartWidget::createLayout() layout->setRowStretch(0, 10); layout->setRowStretch(1, 1); - // Linear scaling button - scalingLinearButton = createButton(this); - scalingLinearButton->setDefaultAction(setScalingLinear); - scalingLinearButton->setCheckable(true); - scalingLinearButton->setToolTip(tr("Set linear scale for Y axis")); - scalingLinearButton->setWhatsThis(tr("Set linear scale for Y axis")); - layout->addWidget(scalingLinearButton, 1, 0); - layout->setColumnStretch(0, 0); - // Logarithmic scaling button scalingLogButton = createButton(this); - scalingLogButton->setDefaultAction(setScalingLogarithmic); + scalingLogButton->setText(tr("LOG")); scalingLogButton->setCheckable(true); scalingLogButton->setToolTip(tr("Set logarithmic scale for Y axis")); scalingLogButton->setWhatsThis(tr("Set logarithmic scale for Y axis")); - layout->addWidget(scalingLogButton, 1, 1); - layout->setColumnStretch(1, 0); + layout->addWidget(scalingLogButton, 1, 0); + layout->setColumnStretch(0, 0); // Averaging spin box averageSpinBox = new QSpinBox(this); @@ -251,8 +242,8 @@ void LinechartWidget::createLayout() averageSpinBox->setValue(200); setAverageWindow(200); averageSpinBox->setMaximum(9999); - layout->addWidget(averageSpinBox, 1, 2); - layout->setColumnStretch(2, 0); + layout->addWidget(averageSpinBox, 1, 1); + layout->setColumnStretch(1, 0); connect(averageSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAverageWindow(int))); // Log Button @@ -260,8 +251,8 @@ void LinechartWidget::createLayout() logButton->setToolTip(tr("Start to log curve data into a CSV or TXT file")); logButton->setWhatsThis(tr("Start to log curve data into a CSV or TXT file")); logButton->setText(tr("Start Logging")); - layout->addWidget(logButton, 1, 3); - layout->setColumnStretch(3, 0); + layout->addWidget(logButton, 1, 2); + layout->setColumnStretch(2, 0); connect(logButton, SIGNAL(clicked()), this, SLOT(startLogging())); // Ground time button @@ -269,8 +260,8 @@ void LinechartWidget::createLayout() timeButton->setText(tr("Ground Time")); timeButton->setToolTip(tr("Overwrite timestamp of data from vehicle with ground receive time. Helps if the plots are not visible because of missing or invalid onboard time.")); timeButton->setWhatsThis(tr("Overwrite timestamp of data from vehicle with ground receive time. Helps if the plots are not visible because of missing or invalid onboard time.")); - layout->addWidget(timeButton, 1, 4); - layout->setColumnStretch(4, 0); + layout->addWidget(timeButton, 1, 3); + layout->setColumnStretch(3, 0); connect(timeButton, SIGNAL(clicked(bool)), activePlot, SLOT(enforceGroundTime(bool))); connect(timeButton, SIGNAL(clicked()), this, SLOT(writeSettings())); @@ -294,8 +285,15 @@ void LinechartWidget::createLayout() connect(this, SIGNAL(plotWindowPositionUpdated(quint64)), activePlot, SLOT(setWindowPosition(quint64))); // Set scaling - connect(scalingLinearButton, SIGNAL(clicked()), activePlot, SLOT(setLinearScaling())); - connect(scalingLogButton, SIGNAL(clicked()), activePlot, SLOT(setLogarithmicScaling())); + connect(scalingLogButton, SIGNAL(toggled(bool)), this, SLOT(toggleLogarithmicScaling(bool))); +} + +void LinechartWidget::toggleLogarithmicScaling(bool checked) +{ + if(checked) + activePlot->setLogarithmicScaling(); + else + activePlot->setLinearScaling(); } void LinechartWidget::appendData(int uasId, const QString& curve, const QString& unit, qint8 value, quint64 usec) @@ -626,8 +624,6 @@ void LinechartWidget::setAverageWindow(int windowSize) void LinechartWidget::createActions() { - setScalingLogarithmic = new QAction("LOG", this); - setScalingLinear = new QAction("LIN", this); } /** diff --git a/src/ui/linechart/LinechartWidget.h b/src/ui/linechart/LinechartWidget.h index a775c303f1..e9caf11669 100644 --- a/src/ui/linechart/LinechartWidget.h +++ b/src/ui/linechart/LinechartWidget.h @@ -96,6 +96,7 @@ public slots: /** @brief Append double data to the given curve. */ void appendData(int uasId, const QString& curve, const QString& unit, double value, quint64 usec); + void toggleLogarithmicScaling(bool toggled); void takeButtonClick(bool checked); void setPlotWindowPosition(int scrollBarValue); void setPlotWindowPosition(quint64 position); @@ -152,14 +153,11 @@ protected: QScrollBar* scrollbar; ///< The plot window scroll bar QSpinBox* averageSpinBox; ///< Spin box to setup average window filter size - QAction* setScalingLogarithmic; ///< Set logarithmic scaling - QAction* setScalingLinear; ///< Set linear scaling QAction* addNewCurve; ///< Add curve candidate to the active curves QMenu* curveMenu; QGridLayout* mainLayout; - QToolButton* scalingLinearButton; QToolButton* scalingLogButton; QToolButton* logButton; QPointer timeButton; -- GitLab From d046a5f2fd0f526ce208b08f610cf887b8dbb723 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Fri, 11 Oct 2013 17:43:06 +0100 Subject: [PATCH 402/460] Linechart - Make it possible to change time axis range --- src/ui/linechart/LinechartPlot.cc | 28 +++++++++++---- src/ui/linechart/LinechartWidget.cc | 56 ++++++++++++++++++++--------- src/ui/linechart/LinechartWidget.h | 6 +++- 3 files changed, 66 insertions(+), 24 deletions(-) diff --git a/src/ui/linechart/LinechartPlot.cc b/src/ui/linechart/LinechartPlot.cc index 9a6c995fef..4b64564597 100644 --- a/src/ui/linechart/LinechartPlot.cc +++ b/src/ui/linechart/LinechartPlot.cc @@ -566,13 +566,29 @@ quint64 LinechartPlot::getPlotInterval() **/ void LinechartPlot::setPlotInterval(int interval) { - plotInterval = interval; - QMap::iterator j; - for(j = data.begin(); j != data.end(); ++j) - { - TimeSeriesData* d = data.value(j.key()); - d->setInterval(interval); + //Only ever increase the amount of stored data, + // so that we allow the user to change between + // different intervals without constantly losing + // data points + if((unsigned)interval > plotInterval) { + + QMap::iterator j; + for(j = data.begin(); j != data.end(); ++j) + { + TimeSeriesData* d = data.value(j.key()); + d->setInterval(interval); + } } + plotInterval = interval; + if(plotInterval > 5*60*1000) //If the interval is longer than 4 minutes, change the time scale step to 2 minutes + timeScaleStep = 2*60*1000; + else if(plotInterval >= 4*60*1000) //If the interval is longer than 4 minutes, change the time scale step to 1 minutes + timeScaleStep = 1*60*1000; + else if(plotInterval >= 60*1000) //If the interval is longer than a minute, change the time scale step to 30 seconds + timeScaleStep = 30*1000; + else + timeScaleStep = DEFAULT_SCALE_INTERVAL; + } /** diff --git a/src/ui/linechart/LinechartWidget.cc b/src/ui/linechart/LinechartWidget.cc index 459022c07a..1c154f9812 100644 --- a/src/ui/linechart/LinechartWidget.cc +++ b/src/ui/linechart/LinechartWidget.cc @@ -207,10 +207,9 @@ void LinechartWidget::createLayout() createActions(); // Setup the plot group box area layout - QGridLayout* layout = new QGridLayout(ui.diagramGroupBox); - mainLayout = layout; - layout->setSpacing(4); - layout->setMargin(2); + QVBoxLayout* vlayout = new QVBoxLayout(ui.diagramGroupBox); + vlayout->setSpacing(4); + vlayout->setMargin(2); // Create plot container widget activePlot = new LinechartPlot(this, sysid); @@ -221,9 +220,10 @@ void LinechartWidget::createLayout() // activePlot = getPlot(0); // plotContainer->setPlot(activePlot); - layout->addWidget(activePlot, 0, 0, 1, 6); - layout->setRowStretch(0, 10); - layout->setRowStretch(1, 1); + vlayout->addWidget(activePlot); + + QHBoxLayout *hlayout = new QHBoxLayout; + vlayout->addLayout(hlayout); // Logarithmic scaling button scalingLogButton = createButton(this); @@ -231,8 +231,7 @@ void LinechartWidget::createLayout() scalingLogButton->setCheckable(true); scalingLogButton->setToolTip(tr("Set logarithmic scale for Y axis")); scalingLogButton->setWhatsThis(tr("Set logarithmic scale for Y axis")); - layout->addWidget(scalingLogButton, 1, 0); - layout->setColumnStretch(0, 0); + hlayout->addWidget(scalingLogButton); // Averaging spin box averageSpinBox = new QSpinBox(this); @@ -242,8 +241,7 @@ void LinechartWidget::createLayout() averageSpinBox->setValue(200); setAverageWindow(200); averageSpinBox->setMaximum(9999); - layout->addWidget(averageSpinBox, 1, 1); - layout->setColumnStretch(1, 0); + hlayout->addWidget(averageSpinBox); connect(averageSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAverageWindow(int))); // Log Button @@ -251,8 +249,7 @@ void LinechartWidget::createLayout() logButton->setToolTip(tr("Start to log curve data into a CSV or TXT file")); logButton->setWhatsThis(tr("Start to log curve data into a CSV or TXT file")); logButton->setText(tr("Start Logging")); - layout->addWidget(logButton, 1, 2); - layout->setColumnStretch(2, 0); + hlayout->addWidget(logButton); connect(logButton, SIGNAL(clicked()), this, SLOT(startLogging())); // Ground time button @@ -260,17 +257,37 @@ void LinechartWidget::createLayout() timeButton->setText(tr("Ground Time")); timeButton->setToolTip(tr("Overwrite timestamp of data from vehicle with ground receive time. Helps if the plots are not visible because of missing or invalid onboard time.")); timeButton->setWhatsThis(tr("Overwrite timestamp of data from vehicle with ground receive time. Helps if the plots are not visible because of missing or invalid onboard time.")); - layout->addWidget(timeButton, 1, 3); - layout->setColumnStretch(3, 0); + hlayout->addWidget(timeButton); connect(timeButton, SIGNAL(clicked(bool)), activePlot, SLOT(enforceGroundTime(bool))); connect(timeButton, SIGNAL(clicked()), this, SLOT(writeSettings())); + hlayout->addStretch(); + + QLabel *timeScaleLabel = new QLabel("Time axis:"); + hlayout->addWidget(timeScaleLabel); + + timeScaleCmb = new QComboBox(this); + timeScaleCmb->addItem("10 seconds", 10); + timeScaleCmb->addItem("20 seconds", 20); + timeScaleCmb->addItem("30 seconds", 30); + timeScaleCmb->addItem("40 seconds", 40); + timeScaleCmb->addItem("50 seconds", 50); + timeScaleCmb->addItem("1 minute", 60); + timeScaleCmb->addItem("2 minutes", 60*2); + timeScaleCmb->addItem("3 minutes", 60*3); + timeScaleCmb->addItem("4 minutes", 60*4); + timeScaleCmb->addItem("5 minutes", 60*5); + timeScaleCmb->addItem("10 minutes", 60*10); + //timeScaleCmb->setSizeAdjustPolicy(QComboBox::AdjustToContents); + timeScaleCmb->setMinimumContentsLength(12); + + hlayout->addWidget(timeScaleCmb); + connect(timeScaleCmb, SIGNAL(currentIndexChanged(int)), this, SLOT(timeScaleChanged(int))); + // Initialize the "Show units" checkbox. This is configured in the .ui file, so all // we do here is attach the clicked() signal. connect(ui.showUnitsCheckBox, SIGNAL(clicked()), this, SLOT(writeSettings())); - ui.diagramGroupBox->setLayout(layout); - // Add actions averageSpinBox->setValue(activePlot->getAverageWindow()); @@ -288,6 +305,11 @@ void LinechartWidget::createLayout() connect(scalingLogButton, SIGNAL(toggled(bool)), this, SLOT(toggleLogarithmicScaling(bool))); } +void LinechartWidget::timeScaleChanged(int index) +{ + activePlot->setPlotInterval(timeScaleCmb->itemData(index).toInt()*1000); +} + void LinechartWidget::toggleLogarithmicScaling(bool checked) { if(checked) diff --git a/src/ui/linechart/LinechartWidget.h b/src/ui/linechart/LinechartWidget.h index e9caf11669..de090b92fd 100644 --- a/src/ui/linechart/LinechartWidget.h +++ b/src/ui/linechart/LinechartWidget.h @@ -123,6 +123,10 @@ public slots: /** @brief Select all curves */ void selectAllCurves(bool all); +private slots: + /** Called when the user changes the time scale combobox. */ + void timeScaleChanged(int index); + protected: void addCurveToList(QString curve); void removeCurveFromList(QString curve); @@ -156,7 +160,7 @@ protected: QAction* addNewCurve; ///< Add curve candidate to the active curves QMenu* curveMenu; - QGridLayout* mainLayout; + QComboBox *timeScaleCmb; QToolButton* scalingLogButton; QToolButton* logButton; -- GitLab From a16f9bdf6ec10dd2e72ab4bbc8c879019c8c8949 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sat, 12 Oct 2013 23:30:09 +0100 Subject: [PATCH 403/460] Improve the UI for editing a text label --- src/ui/designer/QGCTextLabel.cc | 35 ++----- src/ui/designer/QGCTextLabel.h | 1 + src/ui/designer/QGCTextLabel.ui | 160 +++++++++++++++----------------- 3 files changed, 82 insertions(+), 114 deletions(-) diff --git a/src/ui/designer/QGCTextLabel.cc b/src/ui/designer/QGCTextLabel.cc index dd2bbf940c..b1b1731c7b 100644 --- a/src/ui/designer/QGCTextLabel.cc +++ b/src/ui/designer/QGCTextLabel.cc @@ -19,13 +19,7 @@ QGCTextLabel::QGCTextLabel(QWidget *parent) : // Hide all edit items ui->editFinishButton->hide(); ui->editNameLabel->hide(); - ui->editTextParam->hide(); - ui->editComponentSpinBox->hide(); ui->editLine1->hide(); - ui->editLine2->hide(); - - // Add commands to combo box - } QGCTextLabel::~QGCTextLabel() @@ -37,13 +31,9 @@ void QGCTextLabel::startEditMode() { // Hide elements ui->nameLabel->hide(); - - ui->editTextParam->show(); ui->editFinishButton->show(); ui->editNameLabel->show(); - ui->editComponentSpinBox->show(); ui->editLine1->show(); - ui->editLine2->show(); // Attempt to undock the dock widget QWidget* p = this; @@ -66,12 +56,8 @@ void QGCTextLabel::startEditMode() void QGCTextLabel::endEditMode() { ui->editFinishButton->hide(); - ui->editTextParam->hide(); ui->editNameLabel->hide(); - ui->editComponentSpinBox->hide(); ui->editLine1->hide(); - ui->editLine2->hide(); - ui->nameLabel->show(); // Write to settings @@ -105,23 +91,17 @@ void QGCTextLabel::writeSettings(QSettings& settings) } void QGCTextLabel::readSettings(const QString& pre,const QVariantMap& settings) { - ui->editTextParam->setText(settings.value(pre + "QGC_TEXT_SOURCE", "UNKNOWN").toString()); - //ui->editCommandComboBox->setCurrentIndex(settings.value(pre + "QGC_COMMAND_BUTTON_COMMANDID", 0).toInt()); - if (ui->editTextParam->text() == "NONE") + ui->isMavCommand->setChecked(settings.value(pre + "QGC_TEXT_SOURCE", "NONE").toString() == "MAV"); + if (!ui->isMavCommand->isChecked()) { ui->editNameLabel->setText(settings.value(pre + "QGC_TEXT_TEXT","").toString()); ui->nameLabel->setText(ui->editNameLabel->text()); } - else if (ui->editTextParam->text() == "MAV") + else { //MAV command text connect(uas,SIGNAL(textMessageReceived(int,int,int,QString)),this,SLOT(textMessageReceived(int,int,int,QString))); } - - //int commandId = settings.value(pre + "QGC_COMMAND_BUTTON_COMMANDID", 0).toInt(); - - //ui->editNameLabel->setText(settings.value(pre + "QGC_COMMAND_BUTTON_DESCRIPTION", "ERROR LOADING BUTTON").toString()); - //ui->nameLabel->setText(settings.value(pre + "QGC_COMMAND_BUTTON_DESCRIPTION", "ERROR LOADING BUTTON").toString()); } void QGCTextLabel::textMessageReceived(int uasid, int component, int severity, QString message) { @@ -148,17 +128,14 @@ void QGCTextLabel::textMessageReceived(int uasid, int component, int severity, Q void QGCTextLabel::readSettings(const QSettings& settings) { - //ui->editNameLabel->setText(settings.value("QGC_COMMAND_BUTTON_DESCRIPTION", "ERROR LOADING BUTTON").toString()); - //ui->nameLabel->setText(settings.value("QGC_COMMAND_BUTTON_DESCRIPTION", "ERROR LOADING BUTTON").toString()); - ui->editTextParam->setText(settings.value("QGC_TEXT_SOURCE", "UNKNOWN").toString()); + ui->isMavCommand->setChecked(settings.value("QGC_TEXT_SOURCE", "NONE").toString() == "MAV"); ui->editNameLabel->setText(settings.value("QGC_TEXT_TEXT","").toString()); - //ui->editCommandComboBox->setCurrentIndex(settings.value(pre + "QGC_COMMAND_BUTTON_COMMANDID", 0).toInt()); - if (ui->editTextParam->text() == "NONE") + if (!ui->isMavCommand->isChecked()) { ui->textLabel->setText(ui->editNameLabel->text()); ui->nameLabel->setText(""); } - else if (ui->editTextParam->text() == "MAV") + else { //MAV command text ui->nameLabel->setText(ui->editNameLabel->text()); diff --git a/src/ui/designer/QGCTextLabel.h b/src/ui/designer/QGCTextLabel.h index 3828d734fc..f4c23d2c78 100644 --- a/src/ui/designer/QGCTextLabel.h +++ b/src/ui/designer/QGCTextLabel.h @@ -26,6 +26,7 @@ public slots: void readSettings(const QSettings& settings); void readSettings(const QString& pre,const QVariantMap& settings); void textMessageReceived(int uasid, int componentId, int severity, QString message); + private: int enabledNum; Ui::QGCTextLabel *ui; diff --git a/src/ui/designer/QGCTextLabel.ui b/src/ui/designer/QGCTextLabel.ui index 78ba1dda55..24d446ed46 100644 --- a/src/ui/designer/QGCTextLabel.ui +++ b/src/ui/designer/QGCTextLabel.ui @@ -6,34 +6,36 @@ 0 0 - 1183 - 166 + 554 + 107 Form - - - 6 - - - 3 - - - 6 - - - 3 - - - - - <Label Description Label (in front of text)> - - + + + + + + + + + + Label Description + + + + + + + Mav Command + + + + - + @@ -46,68 +48,56 @@ - - - - - 50 - 0 - - - - Description - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - <Text Param> - - + + + + + + + 50 + 0 + + + + Description + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + TextLabel + + + + - - - - Done - - - - - - - Component ID: - - - 0 - - - 255 - - - - - - - - 0 - 0 - - - - Qt::Horizontal - - - - - - - TextLabel - - + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Done + + + + @@ -120,8 +110,8 @@ setText(QString) - 114 - 22 + 280 + 32 114 -- GitLab From e53b332e59b2a61e98b59b3684cbbd715e135f71 Mon Sep 17 00:00:00 2001 From: Jean Cyr Date: Sat, 12 Oct 2013 20:10:39 -0400 Subject: [PATCH 404/460] Bind support for DSMX with 8 or more channels --- src/ui/QGCPX4VehicleConfig.cc | 14 +++++++++++--- src/ui/QGCPX4VehicleConfig.ui | 9 ++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 3e1c28d5d0..d2419ec37a 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -335,7 +335,7 @@ void QGCPX4VehicleConfig::toggleCalibrationRC(bool enabled) void QGCPX4VehicleConfig::toggleSpektrumPairing(bool enabled) { - if (!ui->dsm2RadioButton->isChecked() && !ui->dsmxRadioButton) { + if (!ui->dsm2RadioButton->isChecked() && !ui->dsmxRadioButton && !ui->dsmx8RadioButton) { // Reject QMessageBox warnMsgBox; warnMsgBox.setText(tr("Please select a Spektrum Protocol Version")); @@ -347,8 +347,16 @@ void QGCPX4VehicleConfig::toggleSpektrumPairing(bool enabled) } UASInterface* mav = UASManager::instance()->getActiveUAS(); - if (mav) - mav->pairRX(0, ui->dsmxRadioButton->isChecked() ? 1 : 0); + if (mav) { + int rxSubType; + if (ui->dsm2RadioButton->isChecked()) + rxSubType = 0; + else if (ui->dsmxRadioButton->isChecked()) + rxSubType = 1; + else // if (ui->dsmx8RadioButton->isChecked()) + rxSubType = 2; + mav->pairRX(0, rxSubType); + } } void QGCPX4VehicleConfig::setTrimPositions() diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index 7c9fe43e2f..ffd58d5f00 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -237,7 +237,14 @@ - DSMX Mode + DSMX Mode (3 to 7 channels) + + + + + + + DSMX Mode (8 or more channels) -- GitLab From 42d68e1d4c3c2f1543b4e62a91677cecee9e478c Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sun, 13 Oct 2013 11:00:02 +0100 Subject: [PATCH 405/460] MainWindow - remove unnecessary static_cast --- src/ui/MainWindow.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 2a5450c73f..0f4da285e5 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -450,7 +450,7 @@ void MainWindow::buildCustomWidget() ui.menuTools->addAction(showAction);*/ // Load dock widget location (default is bottom) - Qt::DockWidgetArea location = static_cast (tool->getDockWidgetArea(currentView)); + Qt::DockWidgetArea location = tool->getDockWidgetArea(currentView); //addDockWidget(location, dock); //dock->hide(); -- GitLab From 9143c8c5cbba701c775fe28080895b5d3fd3f73f Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sun, 13 Oct 2013 13:11:51 +0100 Subject: [PATCH 406/460] Improve the UI for editing the Text Label --- src/ui/designer/QGCTextLabel.cc | 71 ++++++++++++++++++-------------- src/ui/designer/QGCTextLabel.h | 3 ++ src/ui/designer/QGCTextLabel.ui | 62 +++++++++++++++++++++------- src/ui/designer/QGCToolWidget.cc | 3 +- 4 files changed, 93 insertions(+), 46 deletions(-) diff --git a/src/ui/designer/QGCTextLabel.cc b/src/ui/designer/QGCTextLabel.cc index b1b1731c7b..ceb645ffcf 100644 --- a/src/ui/designer/QGCTextLabel.cc +++ b/src/ui/designer/QGCTextLabel.cc @@ -7,7 +7,7 @@ #include "UASManager.h" QGCTextLabel::QGCTextLabel(QWidget *parent) : - QGCToolWidgetItem("Command Button", parent), + QGCToolWidgetItem("Text Label", parent), ui(new Ui::QGCTextLabel) { uas = 0; @@ -15,11 +15,15 @@ QGCTextLabel::QGCTextLabel(QWidget *parent) : ui->setupUi(this); connect(ui->editFinishButton, SIGNAL(clicked()), this, SLOT(endEditMode())); + connect(ui->isMavCommand, SIGNAL(toggled(bool)), this, SLOT(update_isMavCommand())); // Hide all edit items ui->editFinishButton->hide(); ui->editNameLabel->hide(); ui->editLine1->hide(); + ui->editLine2->hide(); + ui->isMavCommand->hide(); + ui->textLabel->setText(QString()); } QGCTextLabel::~QGCTextLabel() @@ -30,10 +34,11 @@ QGCTextLabel::~QGCTextLabel() void QGCTextLabel::startEditMode() { // Hide elements - ui->nameLabel->hide(); ui->editFinishButton->show(); ui->editNameLabel->show(); ui->editLine1->show(); + ui->editLine2->show(); + ui->isMavCommand->show(); // Attempt to undock the dock widget QWidget* p = this; @@ -55,10 +60,12 @@ void QGCTextLabel::startEditMode() void QGCTextLabel::endEditMode() { + update_isMavCommand(); ui->editFinishButton->hide(); ui->editNameLabel->hide(); ui->editLine1->hide(); - ui->nameLabel->show(); + ui->editLine2->hide(); + ui->isMavCommand->hide(); // Write to settings emit editingFinished(); @@ -83,25 +90,17 @@ void QGCTextLabel::endEditMode() void QGCTextLabel::writeSettings(QSettings& settings) { - qDebug() << "COMMAND BUTTON WRITING SETTINGS"; - settings.setValue("TYPE", "COMMANDBUTTON"); - settings.setValue("QGC_COMMAND_BUTTON_DESCRIPTION", ui->nameLabel->text()); + settings.setValue("TYPE", "TEXT"); + settings.setValue("QGC_TEXT_TEXT", ui->editNameLabel->text()); + settings.setValue("QGC_TEXT_SOURCE", ui->isMavCommand->isChecked()?"MAV":"NONE"); settings.sync(); } void QGCTextLabel::readSettings(const QString& pre,const QVariantMap& settings) { + ui->editNameLabel->setText(settings.value(pre + "QGC_TEXT_TEXT","").toString()); ui->isMavCommand->setChecked(settings.value(pre + "QGC_TEXT_SOURCE", "NONE").toString() == "MAV"); - if (!ui->isMavCommand->isChecked()) - { - ui->editNameLabel->setText(settings.value(pre + "QGC_TEXT_TEXT","").toString()); - ui->nameLabel->setText(ui->editNameLabel->text()); - } - else - { - //MAV command text - connect(uas,SIGNAL(textMessageReceived(int,int,int,QString)),this,SLOT(textMessageReceived(int,int,int,QString))); - } + update_isMavCommand(); } void QGCTextLabel::textMessageReceived(int uasid, int component, int severity, QString message) { @@ -128,28 +127,40 @@ void QGCTextLabel::textMessageReceived(int uasid, int component, int severity, Q void QGCTextLabel::readSettings(const QSettings& settings) { + ui->editNameLabel->setText(settings.value("QGC_TEXT_TEXT","").toString()); //Place this before setting isMavCommand ui->isMavCommand->setChecked(settings.value("QGC_TEXT_SOURCE", "NONE").toString() == "MAV"); - ui->editNameLabel->setText(settings.value("QGC_TEXT_TEXT","").toString()); - if (!ui->isMavCommand->isChecked()) - { - ui->textLabel->setText(ui->editNameLabel->text()); - ui->nameLabel->setText(""); - } - else - { - //MAV command text - ui->nameLabel->setText(ui->editNameLabel->text()); - ui->textLabel->setText(""); - connect(uas,SIGNAL(textMessageReceived(int,int,int,QString)),this,SLOT(textMessageReceived(int,int,int,QString))); - } + update_isMavCommand(); } + void QGCTextLabel::enableText(int num) { enabledNum = num; - } void QGCTextLabel::setActiveUAS(UASInterface *uas) { + if(this->uas) + this->uas->disconnect(this); this->uas = uas; + update_isMavCommand(); //Might need to update the signal connections +} + +void QGCTextLabel::update_isMavCommand() +{ + ui->textLabel->setText(""); + if (!ui->isMavCommand->isChecked()) + { + ui->nameLabel->setText(ui->editNameLabel->text()); + if(this->uas) + disconnect(uas,SIGNAL(textMessageReceived(int,int,int,QString)),this,SLOT(textMessageReceived(int,int,int,QString))); + if(ui->nameLabel->text().isEmpty()) + ui->nameLabel->setText(tr("Text Label")); //Show something, so that we don't end up with just an empty label + } + else + { + //MAV command text + ui->nameLabel->setText(ui->editNameLabel->text()); + if(this->uas) + connect(uas,SIGNAL(textMessageReceived(int,int,int,QString)),this,SLOT(textMessageReceived(int,int,int,QString))); + } } diff --git a/src/ui/designer/QGCTextLabel.h b/src/ui/designer/QGCTextLabel.h index f4c23d2c78..a1c1d1d6cb 100644 --- a/src/ui/designer/QGCTextLabel.h +++ b/src/ui/designer/QGCTextLabel.h @@ -27,6 +27,9 @@ public slots: void readSettings(const QString& pre,const QVariantMap& settings); void textMessageReceived(int uasid, int componentId, int severity, QString message); +private slots: + void update_isMavCommand(); + private: int enabledNum; Ui::QGCTextLabel *ui; diff --git a/src/ui/designer/QGCTextLabel.ui b/src/ui/designer/QGCTextLabel.ui index 24d446ed46..f5f909d1fb 100644 --- a/src/ui/designer/QGCTextLabel.ui +++ b/src/ui/designer/QGCTextLabel.ui @@ -14,6 +14,19 @@ Form + + + + + 0 + 0 + + + + Qt::Horizontal + + + @@ -28,6 +41,9 @@ + + This is only for advanced use, and allows a label to display the results of a Command Button. + Mav Command @@ -35,19 +51,6 @@ - - - - - 0 - 0 - - - - Qt::Horizontal - - - @@ -59,7 +62,7 @@ - Description + Text Label Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -69,7 +72,7 @@ - TextLabel + mav result @@ -99,6 +102,19 @@ + + + + + 0 + 0 + + + + Qt::Horizontal + + + @@ -119,5 +135,21 @@ + + editNameLabel + returnPressed() + editFinishButton + animateClick() + + + 136 + 20 + + + 498 + 86 + + + diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index 7f976f68ae..f5302d7b21 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -296,7 +296,7 @@ void QGCToolWidget::loadSettings(QVariantMap& settings) else if (type == "COMBO") { item = new QGCComboBox(this); - //qDebug() << "CREATED PARAM COMBOBOX"; + //qDebug() << "CREATED COMBOBOX"; } if (item) { @@ -482,6 +482,7 @@ void QGCToolWidget::contextMenuEvent (QContextMenuEvent* event) QMenu menu(this); menu.addAction(addParamAction); menu.addAction(addCommandAction); + menu.addAction(addLabelAction); menu.addSeparator(); menu.addAction(setTitleAction); menu.addAction(exportAction); -- GitLab From ca68c1e93ab7afc9eb51937a177b2b3987cd5b28 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sun, 13 Oct 2013 13:13:26 +0100 Subject: [PATCH 407/460] Allow user to add a label to a custom widget --- src/ui/designer/QGCToolWidget.cc | 12 ++++++++++++ src/ui/designer/QGCToolWidget.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index f5302d7b21..df998b8919 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -518,6 +518,10 @@ void QGCToolWidget::createActions() addCommandAction->setStatusTip(tr("Add a new action button to the tool")); connect(addCommandAction, SIGNAL(triggered()), this, SLOT(addCommand())); + addLabelAction = new QAction(tr("New &Text Label"), this); + addLabelAction->setStatusTip(tr("Add a new label to the tool")); + connect(addLabelAction, SIGNAL(triggered()), this, SLOT(addLabel())); + setTitleAction = new QAction(tr("Set Widget Title"), this); setTitleAction->setStatusTip(tr("Set the title caption of this tool widget")); connect(setTitleAction, SIGNAL(triggered()), this, SLOT(setTitle())); @@ -591,6 +595,14 @@ void QGCToolWidget::addCommand() button->startEditMode(); } +void QGCToolWidget::addLabel() +{ + QGCTextLabel* label= new QGCTextLabel(this); + connect(label, SIGNAL(destroyed()), this, SLOT(storeSettings())); + toolLayout->addWidget(label); + label->startEditMode(); +} + void QGCToolWidget::addToolWidget(QGCToolWidgetItem* widget) { if (ui->hintLabel) diff --git a/src/ui/designer/QGCToolWidget.h b/src/ui/designer/QGCToolWidget.h index c3abb0faf2..818140e80f 100644 --- a/src/ui/designer/QGCToolWidget.h +++ b/src/ui/designer/QGCToolWidget.h @@ -74,6 +74,7 @@ protected: QVariantMap settingsMap; QAction* addParamAction; QAction* addCommandAction; + QAction* addLabelAction; QAction* setTitleAction; QAction* deleteAction; QAction* exportAction; @@ -99,6 +100,7 @@ public slots: protected slots: void addParam(); void addCommand(); + void addLabel(); void setTitle(); void setWindowTitle(const QString& title); -- GitLab From 661b9aeb996770623d456db73533e67ad1edfaea Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sun, 13 Oct 2013 17:47:44 +0100 Subject: [PATCH 408/460] Fix changing the dock window title when not in advanced mode --- qgroundcontrol.pro | 6 ++-- src/ui/MainWindow.cc | 4 ++- src/ui/designer/QGCToolWidget.cc | 57 ++++++-------------------------- src/ui/dockwidgeteventfilter.cpp | 21 ++++++++++++ src/ui/dockwidgeteventfilter.h | 16 +++++++++ 5 files changed, 55 insertions(+), 49 deletions(-) create mode 100644 src/ui/dockwidgeteventfilter.cpp create mode 100644 src/ui/dockwidgeteventfilter.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 3fb4c02810..fcf375d399 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -506,7 +506,8 @@ HEADERS += src/MG.h \ src/ui/px4_configuration/QGCPX4AirframeConfig.h \ src/ui/QGCBaseParamWidget.h \ src/ui/px4_configuration/QGCPX4MulticopterConfig.h \ - src/ui/px4_configuration/QGCPX4SensorCalibration.h + src/ui/px4_configuration/QGCPX4SensorCalibration.h \ + src/ui/dockwidgeteventfilter.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -728,7 +729,8 @@ SOURCES += src/main.cc \ src/ui/px4_configuration/QGCPX4AirframeConfig.cc \ src/ui/QGCBaseParamWidget.cc \ src/ui/px4_configuration/QGCPX4MulticopterConfig.cc \ - src/ui/px4_configuration/QGCPX4SensorCalibration.cc + src/ui/px4_configuration/QGCPX4SensorCalibration.cc \ + src/ui/dockwidgeteventfilter.cpp # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 0f4da285e5..454c44d9d2 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -40,6 +40,7 @@ This file is part of the QGROUNDCONTROL project #include #include #include "dockwidgettitlebareventfilter.h" +#include "dockwidgeteventfilter.h" #include "QGC.h" #include "MAVLinkSimulationLink.h" #include "SerialLink.h" @@ -895,7 +896,8 @@ void MainWindow::setDockWidgetTitleBar(QDockWidget* widget) { QLabel* label = new QLabel(this); label->setText(widget->windowTitle()); - label->installEventFilter(new DockWidgetTitleBarEventFilter()); + label->installEventFilter(new DockWidgetTitleBarEventFilter()); //Ignore mouse clicks + widget->installEventFilter(new DockWidgetEventFilter()); //Update label if window title changes widget->setTitleBarWidget(label); } // And if nothing should be shown, use an empty widget. diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index df998b8919..bbd140d5a7 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -33,26 +33,12 @@ QGCToolWidget::QGCToolWidget(const QString& title, QWidget *parent, QSettings* s } //qDebug() << "WidgetTitle" << widgetTitle; - setObjectName(widgetTitle); createActions(); toolLayout = ui->toolLayout; toolLayout->setAlignment(Qt::AlignTop); toolLayout->setSpacing(8); - QDockWidget* dock = dynamic_cast(this->parentWidget()); - if (dock) { - dock->setWindowTitle(widgetTitle); - dock->setObjectName(widgetTitle+"DOCK"); - } - - // Try with parent - dock = dynamic_cast(parent); - if (dock) { - dock->setWindowTitle(widgetTitle); - dock->setObjectName(widgetTitle+"DOCK"); - } - - this->setWindowTitle(widgetTitle); + this->setTitle(widgetTitle); QList systems = UASManager::instance()->getUASList(); foreach (UASInterface* uas, systems) { @@ -63,7 +49,6 @@ QGCToolWidget::QGCToolWidget(const QString& title, QWidget *parent, QSettings* s } } connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(addUAS(UASInterface*))); - if (!instances()->contains(widgetTitle)) instances()->insert(widgetTitle, this); // Enforce storage if this not loaded from settings // is MUST NOT BE SAVED if it was loaded from settings! @@ -80,13 +65,7 @@ QGCToolWidget::~QGCToolWidget() void QGCToolWidget::setParent(QWidget *parent) { QWidget::setParent(parent); - // Try with parent - QDockWidget* dock = dynamic_cast(parent); - if (dock) - { - dock->setWindowTitle(getTitle()); - dock->setObjectName(getTitle()+"DOCK"); - } + setTitle(getTitle()); //Update titles } /** @@ -654,34 +633,20 @@ void QGCToolWidget::setTitle() } } -void QGCToolWidget::setWindowTitle(const QString& title) +void QGCToolWidget::setTitle(const QString& title) { - // Sets title and calls setWindowTitle on QWidget - widgetTitle = title; - QWidget::setWindowTitle(title); -} - -void QGCToolWidget::setTitle(QString title) -{ - // Remove references to old title - /*QSettings settings; - settings.beginGroup(widgetTitle); - settings.remove(""); - settings.endGroup(); - settings.sync();*/ - if (instances()->contains(widgetTitle)) instances()->remove(widgetTitle); + if (!instances()->contains(title)) instances()->insert(title, this); - // Switch to new title + // Sets title and calls setWindowTitle on QWidget widgetTitle = title; - - if (!instances()->contains(title)) instances()->insert(title, this); QWidget::setWindowTitle(title); - QDockWidget* parent = dynamic_cast(this->parentWidget()); - if (parent) parent->setWindowTitle(title); - // Store all widgets - //storeWidgetsToSettings(); - + setObjectName(widgetTitle); + QDockWidget* dock = dynamic_cast(this->parentWidget()); + if (dock) { + dock->setWindowTitle(widgetTitle); + dock->setObjectName(widgetTitle+"DOCK"); + } emit titleChanged(title); if (mainMenuAction) mainMenuAction->setText(title); } diff --git a/src/ui/dockwidgeteventfilter.cpp b/src/ui/dockwidgeteventfilter.cpp new file mode 100644 index 0000000000..260e3a5466 --- /dev/null +++ b/src/ui/dockwidgeteventfilter.cpp @@ -0,0 +1,21 @@ +#include +#include +#include + +#include "dockwidgeteventfilter.h" + +DockWidgetEventFilter::DockWidgetEventFilter(QObject *parent) : QObject(parent) {} + +bool DockWidgetEventFilter::eventFilter(QObject *object,QEvent *event) +{ + if (event->type() == QEvent::WindowTitleChange) + { + QDockWidget *dock = dynamic_cast(object); + if(dock) { + QLabel *label = dynamic_cast(dock->titleBarWidget()); + if(label) + label->setText(dock->windowTitle()); + } + } + return QObject::eventFilter(object,event); +} diff --git a/src/ui/dockwidgeteventfilter.h b/src/ui/dockwidgeteventfilter.h new file mode 100644 index 0000000000..60de1e4002 --- /dev/null +++ b/src/ui/dockwidgeteventfilter.h @@ -0,0 +1,16 @@ +#ifndef DOCKWIDGETEVENTFILTER_H +#define DOCKWIDGETEVENTFILTER_H + +#include + +/** Event filter to update a QLabel titleBarWidget if the window's title changes */ +class DockWidgetEventFilter : public QObject +{ + Q_OBJECT +public: + DockWidgetEventFilter(QObject *parent = 0); +protected: + virtual bool eventFilter(QObject *object,QEvent *event) override; +}; + +#endif // DOCKWIDGETEVENTFILTER_H -- GitLab From 311a82aea112fa366960dee7796ecea6d982b2f8 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sun, 13 Oct 2013 18:11:34 +0100 Subject: [PATCH 409/460] Fix stupid small compilation mistakes that I made in the last merge --- src/ui/designer/QGCToolWidget.cc | 5 +++++ src/ui/designer/QGCToolWidget.h | 5 +---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index bbd140d5a7..52072e8df1 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -578,6 +578,11 @@ void QGCToolWidget::addLabel() { QGCTextLabel* label= new QGCTextLabel(this); connect(label, SIGNAL(destroyed()), this, SLOT(storeSettings())); + if (ui->hintLabel) + { + ui->hintLabel->deleteLater(); + ui->hintLabel = NULL; + } toolLayout->addWidget(label); label->startEditMode(); } diff --git a/src/ui/designer/QGCToolWidget.h b/src/ui/designer/QGCToolWidget.h index 818140e80f..5d1f56d0c9 100644 --- a/src/ui/designer/QGCToolWidget.h +++ b/src/ui/designer/QGCToolWidget.h @@ -95,7 +95,7 @@ protected: void hideEvent(QHideEvent* event); public slots: - void setTitle(QString title); + void setTitle(const QString &title); void addParam(int uas,int component,QString paramname,QVariant value); protected slots: void addParam(); @@ -103,9 +103,6 @@ protected slots: void addLabel(); void setTitle(); - void setWindowTitle(const QString& title); - - private: Ui::QGCToolWidget *ui; }; -- GitLab From 37d8faf2ff749e74ea042ff59e7254b59802b09c Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sun, 13 Oct 2013 21:33:43 +0100 Subject: [PATCH 410/460] Message view - only show "clear text" context menu when we are actually showing text --- src/ui/uas/QGCMessageView.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ui/uas/QGCMessageView.cc b/src/ui/uas/QGCMessageView.cc index a1fdcce52b..5c583e0e2f 100644 --- a/src/ui/uas/QGCMessageView.cc +++ b/src/ui/uas/QGCMessageView.cc @@ -87,7 +87,9 @@ void QGCMessageView::handleTextMessage(int uasid, int compId, int severity, QStr void QGCMessageView::contextMenuEvent(QContextMenuEvent* event) { - QMenu menu(this); - menu.addAction(clearAction); - menu.exec(event->globalPos()); + if(activeUAS) { + QMenu menu(this); + menu.addAction(clearAction); + menu.exec(event->globalPos()); + } } -- GitLab From b37fa76b4d872202d6fc63c84e77815d9787ec9a Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sun, 13 Oct 2013 23:12:53 +0100 Subject: [PATCH 411/460] Allow custom widget to be deleted --- src/ui/MainWindow.cc | 14 ++++++++++++-- src/ui/MainWindow.h | 4 ++++ src/ui/designer/QGCToolWidget.cc | 9 +++++---- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 454c44d9d2..57827bb689 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -753,6 +753,7 @@ void MainWindow::addTool(SubMainWindow *parent,VIEW_SECTIONS view,QDockWidget* w centralWidgetToDockWidgetsMap[view][widget->objectName()]= widget; connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); connect(widget, SIGNAL(visibilityChanged(bool)), tempAction, SLOT(setChecked(bool))); + connect(widget, SIGNAL(destroyed()), tempAction, SLOT(deleteLater())); tempAction->setChecked(widget->isVisible()); } else @@ -786,9 +787,20 @@ QDockWidget* MainWindow::createDockWidget(QWidget *parent,QWidget *child,QString widget->setMinimumWidth(minwidth); } addTool(qobject_cast(parent),view,widget,title,area); + connect(child, SIGNAL(destroyed()), widget, SLOT(deleteLater())); + connect(widget, SIGNAL(destroyed()), this, SLOT(dockWidgetDestroyed())); return widget; } +void MainWindow::dockWidgetDestroyed() +{ + QDockWidget *dock = dynamic_cast(QObject::sender()); + Q_ASSERT(dock); + if(!dock) return; + + dockWidgets.removeAll(dock); +} + void MainWindow::loadDockWidget(QString name) { if (centralWidgetToDockWidgetsMap[currentView].contains(name)) @@ -1039,8 +1051,6 @@ void MainWindow::createCustomWidget() settings.setValue(QString("TOOL_PARENT_") + tool->objectName(),currentView); settings.endGroup(); - - //connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater())); //dock->setWidget(tool); diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index c5db0bc26b..b5a5b50304 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -307,6 +307,10 @@ public slots: void commsWidgetDestroyed(QObject *obj); +protected slots: + /** @brief Called by a dock widget when it is has been deleted */ + void dockWidgetDestroyed(); + signals: void styleChanged(MainWindow::QGC_MAINWINDOW_STYLE newTheme); void styleChanged(); diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index 52072e8df1..73eae34c98 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -668,11 +668,12 @@ void QGCToolWidget::deleteWidget() // Hide this->hide(); instances()->remove(getTitle()); - /*QSettings settings; - settings.beginGroup(getTitle()); - settings.remove(""); + + QSettings settings; + settings.beginGroup("QGC_MAINWINDOW"); + settings.remove(QString("TOOL_PARENT_") + objectName()); settings.endGroup(); - storeWidgetsToSettings();*/ + storeWidgetsToSettings(); // Delete -- GitLab From 27c1dd274f7c45994981da417130779f33757d8c Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sun, 13 Oct 2013 23:33:31 +0100 Subject: [PATCH 412/460] Don't add two horizontal menu seperators for custom widgets --- src/ui/MainWindow.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 57827bb689..f3d65230bd 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -1038,7 +1038,7 @@ void MainWindow::createCustomWidget() //void MainWindow::createDockWidget(QWidget *parent,QWidget *child,QString title,QString objectname,VIEW_SECTIONS view,Qt::DockWidgetArea area,int minwidth,int minheight) //QDockWidget* dock = new QDockWidget("Unnamed Tool", this); - if (QGCToolWidget::instances()->size() < 2) + if (QGCToolWidget::instances()->isEmpty()) { // This is the first widget ui.menuTools->addSeparator(); -- GitLab From 0694a2ac1b63df0bcdab38297493b5800c7e7acf Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Mon, 14 Oct 2013 10:56:09 +0100 Subject: [PATCH 413/460] The helper text for a line edit should use placeHolderText, not Text --- src/ui/designer/QGCActionButton.ui | 4 ++-- src/ui/designer/QGCCommandButton.ui | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/designer/QGCActionButton.ui b/src/ui/designer/QGCActionButton.ui index 8f0fb544f6..93144ae188 100644 --- a/src/ui/designer/QGCActionButton.ui +++ b/src/ui/designer/QGCActionButton.ui @@ -61,14 +61,14 @@ - + Button name - + Description diff --git a/src/ui/designer/QGCCommandButton.ui b/src/ui/designer/QGCCommandButton.ui index eb26a6785c..854ca81c18 100644 --- a/src/ui/designer/QGCCommandButton.ui +++ b/src/ui/designer/QGCCommandButton.ui @@ -49,8 +49,8 @@ - - <Button Description Label (in front of button)> + + Button Description -- GitLab From a44dcf3cfe6c143be7dff8a17537683365e208fd Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Mon, 14 Oct 2013 15:21:55 +0100 Subject: [PATCH 414/460] Replace 9 seperate valueChanged() signals with just 1, and remove the resultant tons of code duplication --- src/uas/UASInterface.h | 11 +-- src/ui/HDDisplay.cc | 93 ++++--------------- src/ui/HDDisplay.h | 20 +---- src/ui/MAVLinkDecoder.h | 12 +-- src/ui/UASRawStatusView.cpp | 53 +++-------- src/ui/UASRawStatusView.h | 10 +-- src/ui/designer/QGCComboBox.ui | 4 +- src/ui/designer/QGCParamSlider.ui | 4 +- src/ui/linechart/LinechartWidget.cc | 133 +++------------------------- src/ui/linechart/LinechartWidget.h | 20 +---- src/ui/linechart/Linecharts.cc | 30 +------ src/ui/uas/UASQuickView.cc | 117 ++---------------------- src/ui/uas/UASQuickView.h | 13 +-- 13 files changed, 64 insertions(+), 456 deletions(-) diff --git a/src/uas/UASInterface.h b/src/uas/UASInterface.h index e97ca675ed..fba940b3b2 100644 --- a/src/uas/UASInterface.h +++ b/src/uas/UASInterface.h @@ -488,16 +488,7 @@ signals: * @param value the value that changed * @param msec the timestamp of the message, in milliseconds */ - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint8 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint8 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint16 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint16 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint32 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint32 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint64 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint64 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const double value, const quint64 msec); - void valueChanged(const int uasid, const QString& name, const QString& unit, const QVariant value,const quint64 msecs); + void valueChanged(const int uasid, const QString& name, const QString& unit, const QVariant &value,const quint64 msecs); void voltageChanged(int uasId, double voltage); void waypointUpdated(int uasId, int id, double x, double y, double z, double yaw, bool autocontinue, bool active); diff --git a/src/ui/HDDisplay.cc b/src/ui/HDDisplay.cc index fe6f280933..7c11cd86bd 100644 --- a/src/ui/HDDisplay.cc +++ b/src/ui/HDDisplay.cc @@ -865,93 +865,36 @@ float HDDisplay::refLineWidthToPen(float line) // Connect a generic source void HDDisplay::addSource(QObject* obj) { - //genericSources.append(obj); - // FIXME XXX HACK -// if (plots.size() > 0) -// { - connect(obj, SIGNAL(valueChanged(int,QString,QString,qint8,quint64)), this, SLOT(updateValue(int,QString,QString,qint8,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,quint8,quint64)), this, SLOT(updateValue(int,QString,QString,quint8,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,qint16,quint64)), this, SLOT(updateValue(int,QString,QString,qint16,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,quint16,quint64)), this, SLOT(updateValue(int,QString,QString,quint16,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,qint32,quint64)), this, SLOT(updateValue(int,QString,QString,qint32,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,quint32,quint64)), this, SLOT(updateValue(int,QString,QString,quint32,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,quint64,quint64)), this, SLOT(updateValue(int,QString,QString,quint64,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,qint64,quint64)), this, SLOT(updateValue(int,QString,QString,qint64,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,double,quint64)), this, SLOT(updateValue(int,QString,QString,double,quint64))); -// } + connect(obj, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), this, SLOT(updateValue(int,QString,QString,QVariant,quint64))); } // Disconnect a generic source void HDDisplay::removeSource(QObject* obj) { - //genericSources.append(obj); - // FIXME XXX HACK -// if (plots.size() > 0) -// { - disconnect(obj, SIGNAL(valueChanged(int,QString,QString,qint8,quint64)), this, SLOT(updateValue(int,QString,QString,qint8,quint64))); - disconnect(obj, SIGNAL(valueChanged(int,QString,QString,quint8,quint64)), this, SLOT(updateValue(int,QString,QString,quint8,quint64))); - disconnect(obj, SIGNAL(valueChanged(int,QString,QString,qint16,quint64)), this, SLOT(updateValue(int,QString,QString,qint16,quint64))); - disconnect(obj, SIGNAL(valueChanged(int,QString,QString,quint16,quint64)), this, SLOT(updateValue(int,QString,QString,quint16,quint64))); - disconnect(obj, SIGNAL(valueChanged(int,QString,QString,qint32,quint64)), this, SLOT(updateValue(int,QString,QString,qint32,quint64))); - disconnect(obj, SIGNAL(valueChanged(int,QString,QString,quint32,quint64)), this, SLOT(updateValue(int,QString,QString,quint32,quint64))); - disconnect(obj, SIGNAL(valueChanged(int,QString,QString,quint64,quint64)), this, SLOT(updateValue(int,QString,QString,quint64,quint64))); - disconnect(obj, SIGNAL(valueChanged(int,QString,QString,qint64,quint64)), this, SLOT(updateValue(int,QString,QString,qint64,quint64))); - disconnect(obj, SIGNAL(valueChanged(int,QString,QString,double,quint64)), this, SLOT(updateValue(int,QString,QString,double,quint64))); -// } -} - -void HDDisplay::updateValue(const int uasId, const QString& name, const QString& unit, const qint8 value, const quint64 msec) -{ - if (!intValues.contains(name)) intValues.insert(name, true); - updateValue(uasId, name, unit, (double)value, msec); -} - -void HDDisplay::updateValue(const int uasId, const QString& name, const QString& unit, const quint8 value, const quint64 msec) -{ - if (!intValues.contains(name)) intValues.insert(name, true); - updateValue(uasId, name, unit, (double)value, msec); -} - -void HDDisplay::updateValue(const int uasId, const QString& name, const QString& unit, const qint16 value, const quint64 msec) -{ - if (!intValues.contains(name)) intValues.insert(name, true); - updateValue(uasId, name, unit, (double)value, msec); -} - -void HDDisplay::updateValue(const int uasId, const QString& name, const QString& unit, const quint16 value, const quint64 msec) -{ - if (!intValues.contains(name)) intValues.insert(name, true); - updateValue(uasId, name, unit, (double)value, msec); + disconnect(obj, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), this, SLOT(updateValue(int,QString,QString,QVariant,quint64))); } -void HDDisplay::updateValue(const int uasId, const QString& name, const QString& unit, const qint32 value, const quint64 msec) +void HDDisplay::updateValue(const int uasId, const QString& name, const QString& unit, const QVariant &variant, const quint64 msec) { - if (!intValues.contains(name)) intValues.insert(name, true); - updateValue(uasId, name, unit, (double)value, msec); -} + Q_UNUSED(uasId); + Q_UNUSED(unit); -void HDDisplay::updateValue(const int uasId, const QString& name, const QString& unit, const quint32 value, const quint64 msec) -{ - if (!intValues.contains(name)) intValues.insert(name, true); - updateValue(uasId, name, unit, (double)value, msec); -} + QMetaType::Type type = static_cast< QMetaType::Type>(variant.type()); + if(type == QMetaType::QByteArray || type == QMetaType::QString) + return; -void HDDisplay::updateValue(const int uasId, const QString& name, const QString& unit, const qint64 value, const quint64 msec) -{ - if (!intValues.contains(name)) intValues.insert(name, true); - updateValue(uasId, name, unit, (double)value, msec); -} + bool ok; + double value = variant.toDouble(&ok); + if(!ok) + return; -void HDDisplay::updateValue(const int uasId, const QString& name, const QString& unit, const quint64 value, const quint64 msec) -{ - if (!intValues.contains(name)) intValues.insert(name, true); - updateValue(uasId, name, unit, (double)value, msec); -} + if(type == QMetaType::Int || type == QMetaType::UInt || type == QMetaType::Long || type == QMetaType::LongLong + || type == QMetaType::Short || type == QMetaType::Char || type == QMetaType::ULong || type == QMetaType::ULongLong + || type == QMetaType::UShort || type == QMetaType::UChar || type == QMetaType::Bool ) { + if (!intValues.contains(name)) + intValues.insert(name, true); + } -void HDDisplay::updateValue(const int uasId, const QString& name, const QString& unit, const double value, const quint64 msec) -{ - Q_UNUSED(uasId); - Q_UNUSED(unit); // Update mean const float oldMean = valuesMean.value(name, 0.0f); const int meanCount = valuesCount.value(name, 0); diff --git a/src/ui/HDDisplay.h b/src/ui/HDDisplay.h index 39934957fa..f6c5295d79 100644 --- a/src/ui/HDDisplay.h +++ b/src/ui/HDDisplay.h @@ -64,24 +64,8 @@ public: ~HDDisplay(); public slots: - /** @brief Update the HDD with new int8 data */ - void updateValue(const int uasId, const QString& name, const QString& unit, const qint8 value, const quint64 msec); - /** @brief Update the HDD with new uint8 data */ - void updateValue(const int uasId, const QString& name, const QString& unit, const quint8 value, const quint64 msec); - /** @brief Update the HDD with new int16 data */ - void updateValue(const int uasId, const QString& name, const QString& unit, const qint16 value, const quint64 msec); - /** @brief Update the HDD with new uint16 data */ - void updateValue(const int uasId, const QString& name, const QString& unit, const quint16 value, const quint64 msec); - /** @brief Update the HDD with new int32 data */ - void updateValue(const int uasId, const QString& name, const QString& unit, const qint32 value, const quint64 msec); - /** @brief Update the HDD with new uint32 data */ - void updateValue(const int uasId, const QString& name, const QString& unit, const quint32 value, const quint64 msec); - /** @brief Update the HDD with new int64 data */ - void updateValue(const int uasId, const QString& name, const QString& unit, const qint64 value, const quint64 msec); - /** @brief Update the HDD with new uint64 data */ - void updateValue(const int uasId, const QString& name, const QString& unit, const quint64 value, const quint64 msec); - /** @brief Update the HDD with new double data */ - void updateValue(const int uasId, const QString& name, const QString& unit, const double value, const quint64 msec); + /** @brief Update the HDD with new data */ + void updateValue(const int uasId, const QString& name, const QString& unit, const QVariant &value, const quint64 msec); virtual void setActiveUAS(UASInterface* uas); diff --git a/src/ui/MAVLinkDecoder.h b/src/ui/MAVLinkDecoder.h index 7031882e4f..2feaa63978 100644 --- a/src/ui/MAVLinkDecoder.h +++ b/src/ui/MAVLinkDecoder.h @@ -12,17 +12,7 @@ public: signals: void textMessageReceived(int uasid, int componentid, int severity, const QString& text); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint8 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint8 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint16 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint16 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint32 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint32 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint64 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint64 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const double value, const quint64 msec); - //void valueChanged(const int uasId, const QString& name, const QString& unit, const QVariant value, const quint64 msec); - + void valueChanged(const int uasId, const QString& name, const QString& unit, const QVariant& value, const quint64 msec); public slots: /** @brief Receive one message from the protocol and decode it */ diff --git a/src/ui/UASRawStatusView.cpp b/src/ui/UASRawStatusView.cpp index 5824ec65d9..b46af50268 100644 --- a/src/ui/UASRawStatusView.cpp +++ b/src/ui/UASRawStatusView.cpp @@ -20,51 +20,20 @@ UASRawStatusView::UASRawStatusView(QWidget *parent) : QWidget(parent) } void UASRawStatusView::addSource(MAVLinkDecoder *decoder) { - connect(decoder,SIGNAL(valueChanged(int,QString,QString,double,quint64)),this,SLOT(valueChanged(int,QString,QString,double,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint8,quint64)),this,SLOT(valueChanged(int,QString,QString,qint8,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint16,quint64)),this,SLOT(valueChanged(int,QString,QString,qint16,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint32,quint64)),this,SLOT(valueChanged(int,QString,QString,qint32,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint64,quint64)),this,SLOT(valueChanged(int,QString,QString,qint64,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,quint8,quint64)),this,SLOT(valueChanged(int,QString,QString,quint8,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint16,quint64)),this,SLOT(valueChanged(int,QString,QString,qint16,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,quint32,quint64)),this,SLOT(valueChanged(int,QString,QString,quint32,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,quint64,quint64)),this,SLOT(valueChanged(int,QString,QString,quint64,quint64))); + connect(decoder,SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)),this,SLOT(valueChanged(int,QString,QString,QVariant,quint64))); } -void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint8 value, const quint64 msec) +void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const QVariant &variant, const quint64 msec) { - valueChanged(uasId,name,unit,(double)value,msec); -} -void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint8 value, const quint64 msec) -{ - valueChanged(uasId,name,unit,(double)value,msec); -} -void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint16 value, const quint64 msec) -{ - valueChanged(uasId,name,unit,(double)value,msec); -} -void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint16 value, const quint64 msec) -{ - valueChanged(uasId,name,unit,(double)value,msec); -} -void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint32 value, const quint64 msec) -{ - valueChanged(uasId,name,unit,(double)value,msec); -} -void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint32 value, const quint64 msec) -{ - valueChanged(uasId,name,unit,(double)value,msec); -} -void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint64 value, const quint64 msec) -{ - valueChanged(uasId,name,unit,(double)value,msec); -} -void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint64 value, const quint64 msec) -{ - valueChanged(uasId,name,unit,(double)value,msec); -} + Q_UNUSED(uasId); + Q_UNUSED(unit); + Q_UNUSED(msec); + + bool ok; + double value = variant.toDouble(&ok); + QMetaType::Type type = static_cast(variant.type()); + if(!ok || type == QMetaType::QString || type == QMetaType::QByteArray) + return; -void UASRawStatusView::valueChanged(const int uasId, const QString& name, const QString& unit, const double value, const quint64 msec) -{ valueMap[name] = value; if (nameToUpdateWidgetMap.contains(name)) { diff --git a/src/ui/UASRawStatusView.h b/src/ui/UASRawStatusView.h index cc3828152d..2da632c33a 100644 --- a/src/ui/UASRawStatusView.h +++ b/src/ui/UASRawStatusView.h @@ -15,15 +15,7 @@ public: void addSource(MAVLinkDecoder *decoder); private slots: void updateTableTimerTick(); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint8 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint8 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint16 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint16 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint32 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint32 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint64 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint64 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const double value, const quint64 msec); + void valueChanged(const int uasId, const QString& name, const QString& unit, const QVariant& value, const quint64 msec); protected: void resizeEvent(QResizeEvent *event); private: diff --git a/src/ui/designer/QGCComboBox.ui b/src/ui/designer/QGCComboBox.ui index f9d4db90d2..fdfbc7935b 100644 --- a/src/ui/designer/QGCComboBox.ui +++ b/src/ui/designer/QGCComboBox.ui @@ -75,8 +75,8 @@ - - <Parameter Name / Label> + + Parameter Name diff --git a/src/ui/designer/QGCParamSlider.ui b/src/ui/designer/QGCParamSlider.ui index 4635f01e39..e38c1f28f3 100644 --- a/src/ui/designer/QGCParamSlider.ui +++ b/src/ui/designer/QGCParamSlider.ui @@ -190,8 +190,8 @@ - - <Parameter Name / Label> + + Parameter Name / Label diff --git a/src/ui/linechart/LinechartWidget.cc b/src/ui/linechart/LinechartWidget.cc index 1c154f9812..39f68c8f2e 100644 --- a/src/ui/linechart/LinechartWidget.cc +++ b/src/ui/linechart/LinechartWidget.cc @@ -318,38 +318,15 @@ void LinechartWidget::toggleLogarithmicScaling(bool checked) activePlot->setLinearScaling(); } -void LinechartWidget::appendData(int uasId, const QString& curve, const QString& unit, qint8 value, quint64 usec) +void LinechartWidget::appendData(int uasId, const QString& curve, const QString& unit, const QVariant &variant, quint64 usec) { - appendData(uasId, curve, unit, static_cast(value), usec); -} - -void LinechartWidget::appendData(int uasId, const QString& curve, const QString& unit, quint8 value, quint64 usec) -{ - appendData(uasId, curve, unit, static_cast(value), usec); -} - -void LinechartWidget::appendData(int uasId, const QString& curve, const QString& unit, qint16 value, quint64 usec) -{ - appendData(uasId, curve, unit, static_cast(value), usec); -} - -void LinechartWidget::appendData(int uasId, const QString& curve, const QString& unit, quint16 value, quint64 usec) -{ - appendData(uasId, curve, unit, static_cast(value), usec); -} - -void LinechartWidget::appendData(int uasId, const QString& curve, const QString& unit, qint32 value, quint64 usec) -{ - appendData(uasId, curve, unit, static_cast(value), usec); -} - -void LinechartWidget::appendData(int uasId, const QString& curve, const QString& unit, quint32 value, quint64 usec) -{ - appendData(uasId, curve, unit, static_cast(value), usec); -} + QMetaType::Type type = static_cast(variant.type()); + bool ok; + double value = variant.toDouble(&ok); + if(!ok || type == QMetaType::QByteArray || type == QMetaType::QString) + return; + bool isDouble = type == QMetaType::Float || type == QMetaType::Double; -void LinechartWidget::appendData(int uasId, const QString& curve, const QString& unit, qint64 value, quint64 usec) -{ if ((selectedMAV == -1 && isVisible()) || (selectedMAV == uasId && isVisible())) { // Order matters here, first append to plot, then update curve list @@ -359,12 +336,14 @@ void LinechartWidget::appendData(int uasId, const QString& curve, const QString& // Make sure the curve will be created if it does not yet exist if(!label) { - intData.insert(curve+unit, 0); + if(!isDouble) + intData.insert(curve+unit, 0); addCurve(curve, unit); } // Add int data - intData.insert(curve+unit, value); + if(!isDouble) + intData.insert(curve+unit, variant.toInt()); } if (lastTimestamp == 0 && usec != 0) @@ -394,96 +373,6 @@ void LinechartWidget::appendData(int uasId, const QString& curve, const QString& } } -void LinechartWidget::appendData(int uasId, const QString& curve, const QString& unit, quint64 value, quint64 usec) -{ - if ((selectedMAV == -1 && isVisible()) || (selectedMAV == uasId && isVisible())) - { - // Order matters here, first append to plot, then update curve list - activePlot->appendData(curve+unit, usec, value); - // Store data - QLabel* label = curveLabels->value(curve+unit, NULL); - // Make sure the curve will be created if it does not yet exist - if(!label) - { - intData.insert(curve+unit, 0); - addCurve(curve, unit); - } - - // Add int data - intData.insert(curve+unit, value); - } - - if (lastTimestamp == 0 && usec != 0) - { - lastTimestamp = usec; - } else if (usec != 0) { - // Difference larger than 5 secs, enforce ground time - if (abs((int)((qint64)usec - (quint64)lastTimestamp)) > 5000) - { - autoGroundTimeSet = true; - if (activePlot) activePlot->groundTime(); - } - } - - // Log data - if (logging) - { - if (activePlot->isVisible(curve+unit)) - { - if (usec == 0) usec = QGC::groundTimeMilliseconds(); - if (logStartTime == 0) logStartTime = usec; - qint64 time = usec - logStartTime; - if (time < 0) time = 0; - - logFile->write(QString(QString::number(time) + "\t" + QString::number(uasId) + "\t" + curve + "\t" + QString::number(value) + "\n").toLatin1()); - logFile->flush(); - } - } -} - -void LinechartWidget::appendData(int uasId, const QString& curve, const QString& unit, double value, quint64 usec) -{ - if ((selectedMAV == -1 && isVisible()) || (selectedMAV == uasId && isVisible())) - { - // Order matters here, first append to plot, then update curve list - activePlot->appendData(curve+unit, usec, value); - // Store data - QLabel* label = curveLabels->value(curve+unit, NULL); - // Make sure the curve will be created if it does not yet exist - if(!label) - { - addCurve(curve, unit); - } - } - - if (lastTimestamp == 0 && usec != 0) - { - lastTimestamp = usec; - } else if (usec != 0) { - // Difference larger than 1 sec, enforce ground time - if (abs((int)((qint64)usec - (quint64)lastTimestamp)) > 1000) - { - autoGroundTimeSet = true; - if (activePlot) activePlot->groundTime(); - } - } - - // Log data - if (logging) - { - if (activePlot->isVisible(curve+unit)) - { - if (usec == 0) usec = QGC::groundTimeMilliseconds(); - if (logStartTime == 0) logStartTime = usec; - qint64 time = usec - logStartTime; - if (time < 0) time = 0; - - logFile->write(QString(QString::number(time) + "\t" + QString::number(uasId) + "\t" + curve + "\t" + QString::number(value,'g',18) + "\n").toLatin1()); - logFile->flush(); - } - } -} - void LinechartWidget::refresh() { setUpdatesEnabled(false); diff --git a/src/ui/linechart/LinechartWidget.h b/src/ui/linechart/LinechartWidget.h index de090b92fd..4640f2c191 100644 --- a/src/ui/linechart/LinechartWidget.h +++ b/src/ui/linechart/LinechartWidget.h @@ -77,24 +77,8 @@ public slots: void recolor(); /** @brief Set short names for curves */ void setShortNames(bool enable); - /** @brief Append int8 data to the given curve. */ - void appendData(int uasId, const QString& curve, const QString& unit, qint8 value, quint64 usec); - /** @brief Append uint8 data to the given curve. */ - void appendData(int uasId, const QString& curve, const QString& unit, quint8 value, quint64 usec); - /** @brief Append int16 data to the given curve. */ - void appendData(int uasId, const QString& curve, const QString& unit, qint16 value, quint64 usec); - /** @brief Append uint16 data to the given curve. */ - void appendData(int uasId, const QString& curve, const QString& unit, quint16 value, quint64 usec); - /** @brief Append int32 data to the given curve. */ - void appendData(int uasId, const QString& curve, const QString& unit, qint32 value, quint64 usec); - /** @brief Append uint32 data to the given curve. */ - void appendData(int uasId, const QString& curve, const QString& unit, quint32 value, quint64 usec); - /** @brief Append int64 data to the given curve. */ - void appendData(int uasId, const QString& curve, const QString& unit, qint64 value, quint64 usec); - /** @brief Append uint64 data to the given curve. */ - void appendData(int uasId, const QString& curve, const QString& unit, quint64 value, quint64 usec); - /** @brief Append double data to the given curve. */ - void appendData(int uasId, const QString& curve, const QString& unit, double value, quint64 usec); + /** @brief Append data to the given curve. */ + void appendData(int uasId, const QString& curve, const QString& unit, const QVariant& value, quint64 usec); void toggleLogarithmicScaling(bool toggled); void takeButtonClick(bool checked); diff --git a/src/ui/linechart/Linecharts.cc b/src/ui/linechart/Linecharts.cc index 36d86d01e6..19469b8b69 100644 --- a/src/ui/linechart/Linecharts.cc +++ b/src/ui/linechart/Linecharts.cc @@ -100,15 +100,7 @@ void Linecharts::addSystem(UASInterface* uas) plots.insert(uasid, widget); // Connect valueChanged signals - connect(uas, SIGNAL(valueChanged(int,QString,QString,quint8,quint64)), widget, SLOT(appendData(int,QString,QString,quint8,quint64))); - connect(uas, SIGNAL(valueChanged(int,QString,QString,qint8,quint64)), widget, SLOT(appendData(int,QString,QString,qint8,quint64))); - connect(uas, SIGNAL(valueChanged(int,QString,QString,quint16,quint64)), widget, SLOT(appendData(int,QString,QString,quint16,quint64))); - connect(uas, SIGNAL(valueChanged(int,QString,QString,qint16,quint64)), widget, SLOT(appendData(int,QString,QString,qint16,quint64))); - connect(uas, SIGNAL(valueChanged(int,QString,QString,quint32,quint64)), widget, SLOT(appendData(int,QString,QString,quint32,quint64))); - connect(uas, SIGNAL(valueChanged(int,QString,QString,qint32,quint64)), widget, SLOT(appendData(int,QString,QString,qint32,quint64))); - connect(uas, SIGNAL(valueChanged(int,QString,QString,quint64,quint64)), widget, SLOT(appendData(int,QString,QString,quint64,quint64))); - connect(uas, SIGNAL(valueChanged(int,QString,QString,qint64,quint64)), widget, SLOT(appendData(int,QString,QString,qint64,quint64))); - connect(uas, SIGNAL(valueChanged(int,QString,QString,double,quint64)), widget, SLOT(appendData(int,QString,QString,double,quint64))); + connect(uas, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), widget, SLOT(appendData(int,QString,QString,QVariant,quint64))); connect(widget, SIGNAL(logfileWritten(QString)), this, SIGNAL(logfileWritten(QString))); // Set system active if this is the only system @@ -120,15 +112,7 @@ void Linecharts::addSystem(UASInterface* uas) // Connect generic sources for (int i = 0; i < genericSources.count(); ++i) { - connect(genericSources[i], SIGNAL(valueChanged(int,QString,QString,quint8,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,quint8,quint64))); - connect(genericSources[i], SIGNAL(valueChanged(int,QString,QString,qint8,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,qint8,quint64))); - connect(genericSources[i], SIGNAL(valueChanged(int,QString,QString,quint16,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,quint16,quint64))); - connect(genericSources[i], SIGNAL(valueChanged(int,QString,QString,qint16,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,qint16,quint64))); - connect(genericSources[i], SIGNAL(valueChanged(int,QString,QString,quint32,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,quint32,quint64))); - connect(genericSources[i], SIGNAL(valueChanged(int,QString,QString,qint32,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,qint32,quint64))); - connect(genericSources[i], SIGNAL(valueChanged(int,QString,QString,quint64,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,quint64,quint64))); - connect(genericSources[i], SIGNAL(valueChanged(int,QString,QString,qint64,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,qint64,quint64))); - connect(genericSources[i], SIGNAL(valueChanged(int,QString,QString,double,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,double,quint64))); + connect(genericSources[i], SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,QVariant,quint64))); } // Select system widget->setActive(true); @@ -145,14 +129,6 @@ void Linecharts::addSource(QObject* obj) if (plots.size() > 0) { // Connect generic source - connect(obj, SIGNAL(valueChanged(int,QString,QString,quint8,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,quint8,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,qint8,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,qint8,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,quint16,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,quint16,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,qint16,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,qint16,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,quint32,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,quint32,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,qint32,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,qint32,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,quint64,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,quint64,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,qint64,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,qint64,quint64))); - connect(obj, SIGNAL(valueChanged(int,QString,QString,double,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,double,quint64))); + connect(obj, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), plots.values().first(), SLOT(appendData(int,QString,QString,QVariant,quint64))); } } diff --git a/src/ui/uas/UASQuickView.cc b/src/ui/uas/UASQuickView.cc index 6d74b31a08..4eeeab5f4c 100644 --- a/src/ui/uas/UASQuickView.cc +++ b/src/ui/uas/UASQuickView.cc @@ -267,107 +267,18 @@ void UASQuickView::setActiveUAS(UASInterface* uas) } void UASQuickView::addSource(MAVLinkDecoder *decoder) { - connect(decoder,SIGNAL(valueChanged(int,QString,QString,double,quint64)),this,SLOT(valueChanged(int,QString,QString,double,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint8,quint64)),this,SLOT(valueChanged(int,QString,QString,qint8,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint16,quint64)),this,SLOT(valueChanged(int,QString,QString,qint16,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint32,quint64)),this,SLOT(valueChanged(int,QString,QString,qint32,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,qint64,quint64)),this,SLOT(valueChanged(int,QString,QString,qint64,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,quint8,quint64)),this,SLOT(valueChanged(int,QString,QString,quint8,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,quint16,quint64)),this,SLOT(valueChanged(int,QString,QString,quint16,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,quint32,quint64)),this,SLOT(valueChanged(int,QString,QString,quint32,quint64))); - connect(decoder,SIGNAL(valueChanged(int,QString,QString,quint64,quint64)),this,SLOT(valueChanged(int,QString,QString,quint64,quint64))); -} -void UASQuickView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint8 value, const quint64 msec) -{ - if (!uasPropertyValueMap.contains(name)) - { - if (quickViewSelectDialog) - { - quickViewSelectDialog->addItem(name); - } - } - uasPropertyValueMap[name] = value; + connect(decoder,SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)),this,SLOT(valueChanged(int,QString,QString,QVariant,quint64))); } -void UASQuickView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint8 value, const quint64 msec) -{ - if (!uasPropertyValueMap.contains(name)) - { - if (quickViewSelectDialog) - { - quickViewSelectDialog->addItem(name); - } - } - uasPropertyValueMap[name] = value; -} -void UASQuickView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint16 value, const quint64 msec) -{ - if (!uasPropertyValueMap.contains(name)) - { - if (quickViewSelectDialog) - { - quickViewSelectDialog->addItem(name); - } - } - uasPropertyValueMap[name] = value; -} -void UASQuickView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint16 value, const quint64 msec) -{ - if (!uasPropertyValueMap.contains(name)) - { - if (quickViewSelectDialog) - { - quickViewSelectDialog->addItem(name); - } - } - uasPropertyValueMap[name] = value; -} -void UASQuickView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint32 value, const quint64 msec) -{ - if (!uasPropertyValueMap.contains(name)) - { - if (quickViewSelectDialog) - { - quickViewSelectDialog->addItem(name); - } - } - uasPropertyValueMap[name] = value; -} -void UASQuickView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint32 value, const quint64 msec) -{ - if (!uasPropertyValueMap.contains(name)) - { - if (quickViewSelectDialog) - { - quickViewSelectDialog->addItem(name); - } - } - uasPropertyValueMap[name] = value; -} -void UASQuickView::valueChanged(const int uasId, const QString& name, const QString& unit, const quint64 value, const quint64 msec) -{ - if (!uasPropertyValueMap.contains(name)) - { - if (quickViewSelectDialog) - { - quickViewSelectDialog->addItem(name); - } - } - uasPropertyValueMap[name] = value; -} -void UASQuickView::valueChanged(const int uasId, const QString& name, const QString& unit, const qint64 value, const quint64 msec) -{ - if (!uasPropertyValueMap.contains(name)) - { - if (quickViewSelectDialog) - { - quickViewSelectDialog->addItem(name); - } - } - uasPropertyValueMap[name] = value; -} -void UASQuickView::valueChanged(const int uasId, const QString& name, const QString& unit, const double value, const quint64 msec) +void UASQuickView::valueChanged(const int uasId, const QString& name, const QString& unit, const QVariant &variant, const quint64 msec) { + Q_UNUSED(uasId); + Q_UNUSED(unit); + bool ok; + double value = variant.toDouble(&ok); + if(!ok || variant.type() == QMetaType::QString || variant.type() == QMetaType::QByteArray) + return; + if (!uasPropertyValueMap.contains(name)) { if (quickViewSelectDialog) @@ -410,13 +321,3 @@ void UASQuickView::actionTriggered(bool checked) } } -void UASQuickView::valueChanged(const int uasid, const QString& name, const QString& unit, const QVariant value,const quint64 msecs) -{ - uasPropertyValueMap[name] = value.toDouble(); -} - -void UASQuickView::valChanged(double val,QString type) -{ - //qDebug() << "Value changed:" << type << val; - // uasPropertyValueMap[type] = val; -} diff --git a/src/ui/uas/UASQuickView.h b/src/ui/uas/UASQuickView.h index 33075bda81..1204f59525 100644 --- a/src/ui/uas/UASQuickView.h +++ b/src/ui/uas/UASQuickView.h @@ -59,23 +59,12 @@ protected: signals: public slots: - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint8 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint8 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint16 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint16 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint32 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint32 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const quint64 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const qint64 value, const quint64 msec); - void valueChanged(const int uasId, const QString& name, const QString& unit, const double value, const quint64 msec); - - void valueChanged(const int uasid, const QString& name, const QString& unit, const QVariant value,const quint64 msecs); + void valueChanged(const int uasid, const QString& name, const QString& unit, const QVariant& value,const quint64 msecs); void actionTriggered(bool checked); void actionTriggered(); void updateTimerTick(); void addUAS(UASInterface* uas); void setActiveUAS(UASInterface* uas); - void valChanged(double val,QString type); void selectDialogClosed(); void valueEnabled(QString value); void valueDisabled(QString value); -- GitLab From fa209ea7bf98e0db3fa33c6697da4e262cb7f760 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 17 Oct 2013 08:39:46 +0200 Subject: [PATCH 415/460] Eleminate flicker in HIL --- src/ui/QGCHilConfiguration.ui | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ui/QGCHilConfiguration.ui b/src/ui/QGCHilConfiguration.ui index cffe03b91d..1db3ec1b62 100644 --- a/src/ui/QGCHilConfiguration.ui +++ b/src/ui/QGCHilConfiguration.ui @@ -20,13 +20,6 @@ Form - - - - No simulator active.. - - - @@ -73,6 +66,13 @@ + + + + No simulator active.. + + + -- GitLab From 257f547cbec2364a438742126814bd427e80b8d1 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Tue, 15 Oct 2013 07:01:07 +0100 Subject: [PATCH 416/460] Move all the menu/action manipulation over to a new class, so that it's self contained This fixes a bunch of bugs with setting the title for widgets, deleting widgets, etc. It also reduces the amount of code duplication, which is always a good thing. --- qgroundcontrol.pro | 6 +- src/ui/HDDisplay.cc | 9 +- src/ui/HDDisplay.h | 2 +- src/ui/HSIDisplay.cc | 2 +- src/ui/MainWindow.cc | 364 +++++------------------ src/ui/MainWindow.h | 49 ++- src/ui/QGCPX4VehicleConfig.cc | 14 +- src/ui/QGCVehicleConfig.cc | 24 +- src/ui/designer/QGCToolWidget.cc | 37 +-- src/ui/designer/QGCToolWidget.h | 9 +- src/ui/dockwidgeteventfilter.cpp | 21 -- src/ui/dockwidgeteventfilter.h | 16 - src/ui/dockwidgettitlebareventfilter.cpp | 14 - src/ui/dockwidgettitlebareventfilter.h | 19 -- src/ui/menuactionhelper.cpp | 184 ++++++++++++ src/ui/menuactionhelper.h | 50 ++++ 16 files changed, 369 insertions(+), 451 deletions(-) delete mode 100644 src/ui/dockwidgeteventfilter.cpp delete mode 100644 src/ui/dockwidgeteventfilter.h delete mode 100644 src/ui/dockwidgettitlebareventfilter.cpp delete mode 100644 src/ui/dockwidgettitlebareventfilter.h create mode 100644 src/ui/menuactionhelper.cpp create mode 100644 src/ui/menuactionhelper.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index fcf375d399..bf5ace6e15 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -449,7 +449,6 @@ HEADERS += src/MG.h \ src/ui/designer/QGCComboBox.h \ src/ui/designer/QGCTextLabel.h \ src/ui/submainwindow.h \ - src/ui/dockwidgettitlebareventfilter.h \ src/ui/uas/UASQuickView.h \ src/ui/uas/UASQuickViewItem.h \ src/ui/linechart/ChartPlot.h \ @@ -507,7 +506,7 @@ HEADERS += src/MG.h \ src/ui/QGCBaseParamWidget.h \ src/ui/px4_configuration/QGCPX4MulticopterConfig.h \ src/ui/px4_configuration/QGCPX4SensorCalibration.h \ - src/ui/dockwidgeteventfilter.h + src/ui/menuactionhelper.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -672,7 +671,6 @@ SOURCES += src/main.cc \ src/ui/designer/QGCComboBox.cc \ src/ui/designer/QGCTextLabel.cc \ src/ui/submainwindow.cpp \ - src/ui/dockwidgettitlebareventfilter.cpp \ src/ui/uas/UASQuickViewItem.cc \ src/ui/uas/UASQuickView.cc \ src/ui/linechart/ChartPlot.cc \ @@ -730,7 +728,7 @@ SOURCES += src/main.cc \ src/ui/QGCBaseParamWidget.cc \ src/ui/px4_configuration/QGCPX4MulticopterConfig.cc \ src/ui/px4_configuration/QGCPX4SensorCalibration.cc \ - src/ui/dockwidgeteventfilter.cpp + src/ui/menuactionhelper.cpp # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/HDDisplay.cc b/src/ui/HDDisplay.cc index 7c11cd86bd..d3c12290aa 100644 --- a/src/ui/HDDisplay.cc +++ b/src/ui/HDDisplay.cc @@ -27,7 +27,7 @@ #include "MainWindow.h" #include -HDDisplay::HDDisplay(QStringList* plotList, QString title, QWidget *parent) : +HDDisplay::HDDisplay(const QStringList &plotList, QString title, QWidget *parent) : QGraphicsView(parent), uas(NULL), xCenterOffset(0.0f), @@ -60,11 +60,8 @@ HDDisplay::HDDisplay(QStringList* plotList, QString title, QWidget *parent) : setAutoFillBackground(true); // Add all items in accept list to gauge - if (plotList) { - for(int i = 0; i < plotList->length(); ++i) { - addGauge(plotList->at(i)); - } - } + for(int i = 0; i < plotList.length(); ++i) + addGauge(plotList.at(i)); restoreState(); // Set preferred size diff --git a/src/ui/HDDisplay.h b/src/ui/HDDisplay.h index f6c5295d79..e39090d7c4 100644 --- a/src/ui/HDDisplay.h +++ b/src/ui/HDDisplay.h @@ -60,7 +60,7 @@ class HDDisplay : public QGraphicsView { Q_OBJECT public: - HDDisplay(QStringList* plotList, QString title="", QWidget *parent = 0); + HDDisplay(const QStringList& plotList, QString title="", QWidget *parent = 0); ~HDDisplay(); public slots: diff --git a/src/ui/HSIDisplay.cc b/src/ui/HSIDisplay.cc index a1e0cc1c89..4e05a479a6 100644 --- a/src/ui/HSIDisplay.cc +++ b/src/ui/HSIDisplay.cc @@ -49,7 +49,7 @@ This file is part of the QGROUNDCONTROL project HSIDisplay::HSIDisplay(QWidget *parent) : - HDDisplay(NULL, "HSI", parent), + HDDisplay(QStringList(), "HSI", parent), dragStarted(false), leftDragStarted(false), mouseHasMoved(false), diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index f3d65230bd..31662b8ba2 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -39,8 +39,6 @@ This file is part of the QGROUNDCONTROL project #include #include #include -#include "dockwidgettitlebareventfilter.h" -#include "dockwidgeteventfilter.h" #include "QGC.h" #include "MAVLinkSimulationLink.h" #include "SerialLink.h" @@ -72,6 +70,7 @@ This file is part of the QGROUNDCONTROL project #include #include "SerialSettingsDialog.h" #include "terminalconsole.h" +#include "menuactionhelper.h" #ifdef QGC_OSG_ENABLED #include "Q3DWidgetFactory.h" @@ -128,12 +127,12 @@ MainWindow::MainWindow(QWidget *parent): autoReconnect(false), simulationLink(NULL), lowPowerMode(false), - isAdvancedMode(false), mavlink(new MAVLinkProtocol()), - dockWidgetTitleBarEnabled(true), - customMode(CUSTOM_MODE_NONE) + customMode(CUSTOM_MODE_NONE), + menuActionHelper(new MenuActionHelper()) { this->setAttribute(Qt::WA_DeleteOnClose); + connect(menuActionHelper, SIGNAL(needToShowDockWidget(QString,bool)),SLOT(showDockWidget(QString,bool))); //TODO: move protocol outside UI connect(mavlink, SIGNAL(protocolStatusMessage(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection); loadSettings(); @@ -155,7 +154,7 @@ void MainWindow::init() if (settings.contains("ADVANCED_MODE")) { - isAdvancedMode = settings.value("ADVANCED_MODE").toBool(); + menuActionHelper->setAdvancedMode(settings.value("ADVANCED_MODE").toBool()); } if (!settings.contains("CURRENT_VIEW")) @@ -182,6 +181,7 @@ void MainWindow::init() // Setup user interface ui.setupUi(this); hide(); + menuActionHelper->setMenu(ui.menuTools); // We only need this menu if we have more than one system // ui.menuConnected_Systems->setEnabled(false); @@ -386,12 +386,8 @@ MainWindow::~MainWindow() } } // Delete all UAS objects - - - if (debugConsole) - { - delete debugConsole; - } + delete debugConsole; + delete menuActionHelper; for (int i=0;ideleteLater(); @@ -439,17 +435,6 @@ void MainWindow::buildCustomWidget() QSettings settings; settings.beginGroup("QGC_MAINWINDOW"); - /*QDockWidget* dock = new QDockWidget(tool->windowTitle(), this); - dock->setObjectName(tool->objectName()+"_DOCK"); - dock->setWidget(tool); - connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater())); - QAction* showAction = new QAction(widgets.at(i)->windowTitle(), this); - showAction->setCheckable(true); - connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool))); - connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool))); - widgets.at(i)->setMainMenuAction(showAction); - ui.menuTools->addAction(showAction);*/ - // Load dock widget location (default is bottom) Qt::DockWidgetArea location = tool->getDockWidgetArea(currentView); @@ -577,36 +562,19 @@ void MainWindow::buildCommonWidgets() } // Dock widgets - QAction* tempAction = ui.menuTools->addAction(tr("Control")); - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - createDockWidget(simView,new UASControlWidget(this),tr("Control"),"UNMANNED_SYSTEM_CONTROL_DOCKWIDGET",VIEW_SIMULATION,Qt::LeftDockWidgetArea); createDockWidget(plannerView,new UASListWidget(this),tr("Unmanned Systems"),"UNMANNED_SYSTEM_LIST_DOCKWIDGET",VIEW_MISSION,Qt::LeftDockWidgetArea); createDockWidget(plannerView,new QGCWaypointListMulti(this),tr("Mission Plan"),"WAYPOINT_LIST_DOCKWIDGET",VIEW_MISSION,Qt::BottomDockWidgetArea); - { - //createDockWidget(plannerView,new QGCWaypointListMulti(this),tr("Mission Plan"),"WAYPOINT_LIST_DOCKWIDGET",VIEW_MISSION,Qt::BottomDockWidgetArea); - QAction* tempAction = ui.menuTools->addAction(tr("Mission Plan")); - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - menuToDockNameMap[tempAction] = "WAYPOINT_LIST_DOCKWIDGET"; - } - createDockWidget(simView,new QGCWaypointListMulti(this),tr("Mission Plan"),"WAYPOINT_LIST_DOCKWIDGET",VIEW_SIMULATION,Qt::BottomDockWidgetArea); createDockWidget(engineeringView,new QGCMAVLinkInspector(mavlink,this),tr("MAVLink Inspector"),"MAVLINK_INSPECTOR_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea); createDockWidget(engineeringView,new ParameterInterface(this),tr("Onboard Parameters"),"PARAMETER_INTERFACE_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea); createDockWidget(simView,new ParameterInterface(this),tr("Onboard Parameters"),"PARAMETER_INTERFACE_DOCKWIDGET",VIEW_SIMULATION,Qt::RightDockWidgetArea); + menuActionHelper->createToolAction(tr("Status Details"), "UAS_STATUS_DETAILS_DOCKWIDGET"); - { - QAction* tempAction = ui.menuTools->addAction(tr("Status Details")); - menuToDockNameMap[tempAction] = "UAS_STATUS_DETAILS_DOCKWIDGET"; - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - } { if (!debugConsole) { @@ -614,40 +582,22 @@ void MainWindow::buildCommonWidgets() debugConsole->setWindowTitle("Communications Console"); debugConsole->hide(); QAction* tempAction = ui.menuTools->addAction(tr("Communication Console")); - //menuToDockNameMap[tempAction] = "COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET"; tempAction->setCheckable(true); connect(tempAction,SIGNAL(triggered(bool)),debugConsole,SLOT(setShown(bool))); - } } createDockWidget(simView,new HSIDisplay(this),tr("Horizontal Situation"),"HORIZONTAL_SITUATION_INDICATOR_DOCKWIDGET",VIEW_SIMULATION,Qt::BottomDockWidgetArea); - { - QAction* tempAction = ui.menuTools->addAction(tr("Flight Display")); - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - menuToDockNameMap[tempAction] = "HEAD_DOWN_DISPLAY_1_DOCKWIDGET"; - } - - { - QAction* tempAction = ui.menuTools->addAction(tr("Actuator Status")); - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - menuToDockNameMap[tempAction] = "HEAD_DOWN_DISPLAY_2_DOCKWIDGET"; - } - - { - QAction* tempAction = ui.menuTools->addAction(tr("Radio Control")); - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - } + menuActionHelper->createToolAction(tr("Flight Display"), "HEAD_DOWN_DISPLAY_1_DOCKWIDGET"); + menuActionHelper->createToolAction(tr("Actuator Status"), "HEAD_DOWN_DISPLAY_2_DOCKWIDGET"); + menuActionHelper->createToolAction(tr("Radio Control")); - createDockWidget(engineeringView,new HUD(320,240,this),tr("Video Downlink"),"HEAD_UP_DISPLAY_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea,this->width()/1.5); + createDockWidget(engineeringView,new HUD(320,240,this),tr("Video Downlink"),"HEAD_UP_DISPLAY_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea,QSize(this->width()/1.5,0)); - createDockWidget(engineeringView,new HUD(320,240,this),tr("Video Downlink"),"HEAD_UP_DISPLAY_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea,this->width()/1.5); + createDockWidget(engineeringView,new HUD(320,240,this),tr("Video Downlink"),"HEAD_UP_DISPLAY_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea,QSize(this->width()/1.5,0)); - createDockWidget(simView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_SIMULATION,Qt::RightDockWidgetArea,this->width()/1.5); - createDockWidget(pilotView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea,this->width()/1.8); + createDockWidget(simView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_SIMULATION,Qt::RightDockWidgetArea,QSize(this->width()/1.5,0)); + createDockWidget(pilotView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea,QSize(this->width()/1.8,0)); QGCTabbedInfoView *infoview = new QGCTabbedInfoView(this); infoview->addSource(mavlinkDecoder); @@ -730,83 +680,38 @@ void MainWindow::buildCommonWidgets() void MainWindow::addTool(SubMainWindow *parent,VIEW_SECTIONS view,QDockWidget* widget, const QString& title, Qt::DockWidgetArea area) { - QList actionlist = ui.menuTools->actions(); - bool found = false; - QAction *targetAction; - for (int i=0;itext() == title) - { - found = true; - targetAction = actionlist[i]; - } - } - if (!found) - { - QAction* tempAction = ui.menuTools->addAction(title); - tempAction->setCheckable(true); - menuToDockNameMap[tempAction] = widget->objectName(); - if (!centralWidgetToDockWidgetsMap.contains(view)) - { - centralWidgetToDockWidgetsMap[view] = QMap(); - } - centralWidgetToDockWidgetsMap[view][widget->objectName()]= widget; - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - connect(widget, SIGNAL(visibilityChanged(bool)), tempAction, SLOT(setChecked(bool))); - connect(widget, SIGNAL(destroyed()), tempAction, SLOT(deleteLater())); - tempAction->setChecked(widget->isVisible()); - } - else - { - if (!menuToDockNameMap.contains(targetAction)) - { - menuToDockNameMap[targetAction] = widget->objectName(); - //menuToDockNameMap[targetAction] = title; - } - if (!centralWidgetToDockWidgetsMap.contains(view)) - { - centralWidgetToDockWidgetsMap[view] = QMap(); - } - centralWidgetToDockWidgetsMap[view][widget->objectName()]= widget; - connect(widget, SIGNAL(visibilityChanged(bool)), targetAction, SLOT(setChecked(bool))); - } + menuActionHelper->createToolActionForCustomDockWidget(title, widget->objectName(), widget, view); parent->addDockWidget(area,widget); } -QDockWidget* MainWindow::createDockWidget(QWidget *parent,QWidget *child,QString title,QString objectname,VIEW_SECTIONS view,Qt::DockWidgetArea area,int minwidth,int minheight) +QDockWidget* MainWindow::createDockWidget(QWidget *subMainWindowParent,QWidget *child,const QString& title,const QString& objectName,VIEW_SECTIONS view,Qt::DockWidgetArea area,const QSize& minSize) { - child->setObjectName(objectname); - QDockWidget *widget = new QDockWidget(title,this); - dockWidgets.append(widget); - setDockWidgetTitleBar(widget); - widget->setObjectName(child->objectName()); - widget->setWidget(child); - if (minheight != 0 || minwidth != 0) - { - widget->setMinimumHeight(minheight); - widget->setMinimumWidth(minwidth); - } - addTool(qobject_cast(parent),view,widget,title,area); - connect(child, SIGNAL(destroyed()), widget, SLOT(deleteLater())); - connect(widget, SIGNAL(destroyed()), this, SLOT(dockWidgetDestroyed())); + SubMainWindow *parent = qobject_cast(subMainWindowParent); + Q_ASSERT(parent); + QDockWidget* dockWidget = menuActionHelper->createDockWidget(title, objectName); + child->setObjectName(objectName); + dockWidget->setWidget(child); //Set child objectName before setting dockwidget, since the dock widget might react to object name changes + connect(child, SIGNAL(destroyed()), dockWidget, SLOT(deleteLater())); //Our dockwidget only has only child widget, so kill the dock widget if the child is deleted - return widget; + if (!minSize.isNull()) + dockWidget->setMinimumSize(minSize); + addTool(parent,view,dockWidget,title,area); + return dockWidget; } -void MainWindow::dockWidgetDestroyed() -{ - QDockWidget *dock = dynamic_cast(QObject::sender()); - Q_ASSERT(dock); - if(!dock) return; - dockWidgets.removeAll(dock); +void MainWindow::showDockWidget(const QString& name, bool show) +{ + QDockWidget *dockWidget = menuActionHelper->getDockWidget(currentView, name); + if(dockWidget) + dockWidget->setVisible(show); + else if (show) + loadDockWidget(name); } -void MainWindow::loadDockWidget(QString name) +void MainWindow::loadDockWidget(const QString& name) { - if (centralWidgetToDockWidgetsMap[currentView].contains(name)) - { + if(menuActionHelper->containsDockWidget(currentView, name)) return; - } if (name.startsWith("HIL_CONFIG")) { //It's a HIL widget. @@ -839,8 +744,6 @@ void MainWindow::loadDockWidget(QString name) else if (name == "COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET") { //This is now a permanently detached window. - //centralWidgetToDockWidgetsMap[currentView][name] = console; - //createDockWidget(centerStack->currentWidget(),new DebugConsole(this),tr("Communication Console"),"COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET",currentView,Qt::BottomDockWidgetArea); } else if (name == "HORIZONTAL_SITUATION_INDICATOR_DOCKWIDGET") { @@ -848,21 +751,19 @@ void MainWindow::loadDockWidget(QString name) } else if (name == "HEAD_DOWN_DISPLAY_1_DOCKWIDGET") { - //FIXME: memory of acceptList will never be freed again - QStringList* acceptList = new QStringList(); - acceptList->append("-3.3,ATTITUDE.roll,rad,+3.3,s"); - acceptList->append("-3.3,ATTITUDE.pitch,deg,+3.3,s"); - acceptList->append("-3.3,ATTITUDE.yaw,deg,+3.3,s"); + QStringList acceptList; + acceptList.append("-3.3,ATTITUDE.roll,rad,+3.3,s"); + acceptList.append("-3.3,ATTITUDE.pitch,deg,+3.3,s"); + acceptList.append("-3.3,ATTITUDE.yaw,deg,+3.3,s"); HDDisplay *hddisplay = new HDDisplay(acceptList,"Flight Display",this); hddisplay->addSource(mavlinkDecoder); createDockWidget(centerStack->currentWidget(),hddisplay,tr("Flight Display"),"HEAD_DOWN_DISPLAY_1_DOCKWIDGET",currentView,Qt::RightDockWidgetArea); } else if (name == "HEAD_DOWN_DISPLAY_2_DOCKWIDGET") { - //FIXME: memory of acceptList2 will never be freed again - QStringList* acceptList2 = new QStringList(); - acceptList2->append("0,RAW_PRESSURE.pres_abs,hPa,65500"); - HDDisplay *hddisplay = new HDDisplay(acceptList2,"Actuator Status",this); + QStringList acceptList; + acceptList.append("0,RAW_PRESSURE.pres_abs,hPa,65500"); + HDDisplay *hddisplay = new HDDisplay(acceptList,"Actuator Status",this); hddisplay->addSource(mavlinkDecoder); createDockWidget(centerStack->currentWidget(),hddisplay,tr("Actuator Status"),"HEAD_DOWN_DISPLAY_2_DOCKWIDGET",currentView,Qt::RightDockWidgetArea); } @@ -873,7 +774,6 @@ void MainWindow::loadDockWidget(QString name) } else if (name == "PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET") { - // createDockWidget(centerStack->currentWidget(),new HUD(320,240,this),tr("Head Up Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",currentView,Qt::RightDockWidgetArea); createDockWidget(centerStack->currentWidget(),new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"HEAD_UP_DISPLAY_DOCKWIDGET",currentView,Qt::RightDockWidgetArea); } else if (name == "UAS_INFO_QUICKVIEW_DOCKWIDGET") @@ -894,80 +794,6 @@ void MainWindow::loadDockWidget(QString name) } } -void MainWindow::setDockWidgetTitleBar(QDockWidget* widget) -{ - QWidget* oldTitleBar = widget->titleBarWidget(); - - // In advanced mode, we use the default titlebar provided by Qt. - if (isAdvancedMode) - { - widget->setTitleBarWidget(0); - } - // Otherwise, if just a textlabel should be shown, make that the titlebar. - else if (dockWidgetTitleBarEnabled) - { - QLabel* label = new QLabel(this); - label->setText(widget->windowTitle()); - label->installEventFilter(new DockWidgetTitleBarEventFilter()); //Ignore mouse clicks - widget->installEventFilter(new DockWidgetEventFilter()); //Update label if window title changes - widget->setTitleBarWidget(label); - } - // And if nothing should be shown, use an empty widget. - else - { - QWidget* newTitleBar = new QWidget(this); - widget->setTitleBarWidget(newTitleBar); - } - - // Be sure to clean up the old titlebar. When using QDockWidget::setTitleBarWidget(), - // it doesn't delete the old titlebar object. - if (oldTitleBar) - { - delete oldTitleBar; - } -} - -void MainWindow::showTool(bool show) -{ - //Called when a menu item is clicked on, regardless of view. - - QAction* act = qobject_cast(sender()); - if (menuToDockNameMap.contains(act)) - { - QString name = menuToDockNameMap[act]; - if (centralWidgetToDockWidgetsMap.contains(currentView)) - { - if (centralWidgetToDockWidgetsMap[currentView].contains(name)) - { - if (show) - { - centralWidgetToDockWidgetsMap[currentView][name]->show(); - } - else - { - centralWidgetToDockWidgetsMap[currentView][name]->hide(); - } - } - else if (show) - { - loadDockWidget(name); - } - } - } - //QWidget* widget = qVariantValue(act->data()); - //widget->setVisible(show); -} -/*void addToolByName(QString name,SubMainWindow parent,const QString& title, Qt::DockWidgetArea area) -{ - if (name == "Control") - { - QDockWidget *widget = new QDockWidget(tr("Control"),this); - dockToTitleBarMap[widget] = widget->titleBarWidget(); - widget->setObjectName("UNMANNED_SYSTEM_CONTROL_DOCKWIDGET"); - widget->setWidget(new UASControlWidget(this)); - addTool(parent,VIEW_SIMULATION,widget,tr("Control"),area); - } -}*/ void MainWindow::addToCentralStackedWidget(QWidget* widget, VIEW_SECTIONS viewSection, const QString& title) { Q_UNUSED(title); @@ -977,7 +803,6 @@ void MainWindow::addToCentralStackedWidget(QWidget* widget, VIEW_SECTIONS viewSe if (centerStack->indexOf(widget) == -1) { centerStack->addWidget(widget); - centralWidgetToDockWidgetsMap[viewSection] = QMap(); } } @@ -996,18 +821,10 @@ void MainWindow::showHILConfigurationWidget(UASInterface* uas) if (mav && !hilDocks.contains(mav->getUASID())) { - //QGCToolWidget* tool = new QGCToolWidget("Unnamed Tool " + QString::number(ui.menuTools->actions().size())); - //createDockWidget(centerStack->currentWidget(),tool,"Unnamed Tool " + QString::number(ui.menuTools->actions().size()),"UNNAMED_TOOL_" + QString::number(ui.menuTools->actions().size())+"DOCK",currentView,Qt::BottomDockWidgetArea); - QGCHilConfiguration* hconf = new QGCHilConfiguration(mav, this); QString hilDockName = tr("HIL Config %1").arg(uas->getUASName()); QDockWidget* hilDock = createDockWidget(simView, hconf,hilDockName, hilDockName.toUpper().replace(" ", "_"),VIEW_SIMULATION,Qt::LeftDockWidgetArea); hilDocks.insert(mav->getUASID(), hilDock); - - // if (currentView != VIEW_SIMULATION) - // hilDock->hide(); - // else - // hilDock->show(); } } @@ -1035,33 +852,20 @@ void MainWindow::connectCommonWidgets() void MainWindow::createCustomWidget() { - //void MainWindow::createDockWidget(QWidget *parent,QWidget *child,QString title,QString objectname,VIEW_SECTIONS view,Qt::DockWidgetArea area,int minwidth,int minheight) - //QDockWidget* dock = new QDockWidget("Unnamed Tool", this); - if (QGCToolWidget::instances()->isEmpty()) { // This is the first widget ui.menuTools->addSeparator(); } - QGCToolWidget* tool = new QGCToolWidget("Unnamed Tool " + QString::number(ui.menuTools->actions().size())); - createDockWidget(centerStack->currentWidget(),tool,"Unnamed Tool " + QString::number(ui.menuTools->actions().size()),"UNNAMED_TOOL_" + QString::number(ui.menuTools->actions().size())+"DOCK",currentView,Qt::BottomDockWidgetArea); - //tool->setObjectName("UNNAMED_TOOL_" + QString::number(ui.menuTools->actions().size())); + QString title = "Unnamed Tool " + QString::number(ui.menuTools->actions().size()); + QString objectName = "UNNAMED_TOOL_" + QString::number(ui.menuTools->actions().size())+"DOCK"; + QGCToolWidget* tool = new QGCToolWidget(objectName, title); + createDockWidget(centerStack->currentWidget(),tool,title,objectName,currentView,Qt::BottomDockWidgetArea); + QSettings settings; settings.beginGroup("QGC_MAINWINDOW"); settings.setValue(QString("TOOL_PARENT_") + tool->objectName(),currentView); settings.endGroup(); - - //connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater())); - //dock->setWidget(tool); - - //QAction* showAction = new QAction(tool->getTitle(), this); - //showAction->setCheckable(true); - //connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool))); - //connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool))); - //tool->setMainMenuAction(showAction); - //ui.menuTools->addAction(showAction); - //this->addDockWidget(Qt::BottomDockWidgetArea, dock); - //dock->setVisible(true); } void MainWindow::loadCustomWidget() @@ -1072,7 +876,7 @@ void MainWindow::loadCustomWidget() } void MainWindow::loadCustomWidget(const QString& fileName, int view) { - QGCToolWidget* tool = new QGCToolWidget("", this); + QGCToolWidget* tool = new QGCToolWidget("", "", this); if (tool->loadSettings(fileName, true)) { qDebug() << "Loading custom tool:" << tool->getTitle() << tool->objectName(); @@ -1091,16 +895,12 @@ void MainWindow::loadCustomWidget(const QString& fileName, int view) createDockWidget(plannerView,tool,tool->getTitle(),tool->objectName()+"DOCK",(VIEW_SECTIONS)view,Qt::LeftDockWidgetArea); break; default: - { + { //Delete tool, create menu item to tie it to. customWidgetNameToFilenameMap[tool->objectName()+"DOCK"] = fileName; - QAction* tempAction = ui.menuTools->addAction(tool->getTitle()); - menuToDockNameMap[tempAction] = tool->objectName()+"DOCK"; - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); + menuActionHelper->createToolAction(tool->getTitle(), tool->objectName()+"DOCK"); tool->deleteLater(); - //createDockWidget(centerStack->currentWidget(),tool,tool->getTitle(),tool->objectName()+"DOCK",(VIEW_SECTIONS)view,Qt::LeftDockWidgetArea); - } + } break; } } @@ -1112,7 +912,7 @@ void MainWindow::loadCustomWidget(const QString& fileName, int view) void MainWindow::loadCustomWidget(const QString& fileName, bool singleinstance) { - QGCToolWidget* tool = new QGCToolWidget("", this); + QGCToolWidget* tool = new QGCToolWidget("", "", this); if (tool->loadSettings(fileName, true) || !singleinstance) { qDebug() << "Loading custom tool:" << tool->getTitle() << tool->objectName(); @@ -1136,35 +936,18 @@ void MainWindow::loadCustomWidget(const QString& fileName, bool singleinstance) createDockWidget(plannerView,tool,tool->getTitle(),tool->objectName()+"DOCK",(VIEW_SECTIONS)view,Qt::LeftDockWidgetArea); break; default: - { + { //Delete tool, create menu item to tie it to. customWidgetNameToFilenameMap[tool->objectName()+"DOCK"] = fileName; - QAction* tempAction = ui.menuTools->addAction(tool->getTitle()); - menuToDockNameMap[tempAction] = tool->objectName()+"DOCK"; - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); + QAction *action = menuActionHelper->createToolAction(tool->getTitle(), tool->objectName()+"DOCK"); + ui.menuTools->addAction(action); tool->deleteLater(); - //createDockWidget(centerStack->currentWidget(),tool,tool->getTitle(),tool->objectName()+"DOCK",(VIEW_SECTIONS)view,Qt::LeftDockWidgetArea); - } + } break; } settings.endGroup(); - // Add widget to UI - /*QDockWidget* dock = new QDockWidget(tool->getTitle(), this); - connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater())); - dock->setWidget(tool); - tool->setParent(dock); - - QAction* showAction = new QAction(tool->getTitle(), this); - showAction->setCheckable(true); - connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool))); - connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool))); - tool->setMainMenuAction(showAction); - ui.menuTools->addAction(showAction); - this->addDockWidget(Qt::BottomDockWidgetArea, dock); - dock->hide();*/ } else { @@ -1214,7 +997,7 @@ void MainWindow::loadSettings() darkStyleFileName = settings.value("DARK_STYLE_FILENAME", darkStyleFileName).toString(); lightStyleFileName = settings.value("LIGHT_STYLE_FILENAME", lightStyleFileName).toString(); lowPowerMode = settings.value("LOW_POWER_MODE", lowPowerMode).toBool(); - dockWidgetTitleBarEnabled = settings.value("DOCK_WIDGET_TITLEBARS",dockWidgetTitleBarEnabled).toBool(); + bool dockWidgetTitleBarEnabled = settings.value("DOCK_WIDGET_TITLEBARS",menuActionHelper->dockWidgetTitleBarsEnabled()).toBool(); settings.endGroup(); enableDockWidgetTitleBars(dockWidgetTitleBarEnabled); } @@ -1308,17 +1091,12 @@ void MainWindow::saveScreen() } void MainWindow::enableDockWidgetTitleBars(bool enabled) { - dockWidgetTitleBarEnabled = enabled; + menuActionHelper->setDockWidgetTitleBarsEnabled(enabled); QSettings settings; settings.beginGroup("QGC_MAINWINDOW"); - settings.setValue("DOCK_WIDGET_TITLEBARS",dockWidgetTitleBarEnabled); + settings.setValue("DOCK_WIDGET_TITLEBARS",enabled); settings.endGroup(); settings.sync(); - - for (int i = 0; i < dockWidgets.size(); i++) - { - setDockWidgetTitleBar(dockWidgets[i]); - } } void MainWindow::enableAutoReconnect(bool enabled) @@ -1488,8 +1266,8 @@ void MainWindow::connectCommonActions() // Connect actions from ui connect(ui.actionAdd_Link, SIGNAL(triggered()), this, SLOT(addLink())); - ui.actionAdvanced_Mode->setChecked(isAdvancedMode); - connect(ui.actionAdvanced_Mode,SIGNAL(triggered()),this,SLOT(setAdvancedMode())); + ui.actionAdvanced_Mode->setChecked(menuActionHelper->isAdvancedMode()); + connect(ui.actionAdvanced_Mode,SIGNAL(toggled(bool)),this,SLOT(setAdvancedMode(bool))); // Connect internal actions connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(UASCreated(UASInterface*))); @@ -2085,16 +1863,11 @@ void MainWindow::loadViewState() win->restoreState(settings.value(getWindowStateKey()).toByteArray(), QGC::applicationVersion()); } } -void MainWindow::setAdvancedMode() +void MainWindow::setAdvancedMode(bool isAdvancedMode) { - isAdvancedMode = !isAdvancedMode; + menuActionHelper->setAdvancedMode(isAdvancedMode); ui.actionAdvanced_Mode->setChecked(isAdvancedMode); settings.setValue("ADVANCED_MODE",isAdvancedMode); - - for (int i = 0; i < dockWidgets.size(); i++) - { - setDockWidgetTitleBar(dockWidgets[i]); - } } void MainWindow::loadEngineerView() @@ -2217,11 +1990,16 @@ void MainWindow::loadMAVLinkView() //} -QList MainWindow::listLinkMenuActions(void) +QList MainWindow::listLinkMenuActions() { return ui.menuNetwork->actions(); } +bool MainWindow::dockWidgetTitleBarsEnabled() const +{ + return menuActionHelper->dockWidgetTitleBarsEnabled(); +} + #ifdef MOUSE_ENABLED_LINUX bool MainWindow::x11Event(XEvent *event) { diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index b5a5b50304..9390d6fd2c 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -86,6 +86,7 @@ class QGCStatusBar; class Linecharts; class QGCDataPlot2D; class JoystickWidget; +class MenuActionHelper; /** * @brief Main Application Window @@ -142,41 +143,38 @@ public: static const QString defaultLightStyle; /** @brief Get current visual style */ - QGC_MAINWINDOW_STYLE getStyle() + QGC_MAINWINDOW_STYLE getStyle() const { return currentStyle; } /** @brief Get current light visual stylesheet */ - QString getLightStyleSheet() + QString getLightStyleSheet() const { return lightStyleFileName; } /** @brief Get current dark visual stylesheet */ - QString getDarkStyleSheet() + QString getDarkStyleSheet() const { return darkStyleFileName; } /** @brief Get auto link reconnect setting */ - bool autoReconnectEnabled() + bool autoReconnectEnabled() const { return autoReconnect; } /** @brief Get title bar mode setting */ - bool dockWidgetTitleBarsEnabled() - { - return dockWidgetTitleBarEnabled; - } + bool dockWidgetTitleBarsEnabled() const; /** @brief Get low power mode setting */ - bool lowPowerModeEnabled() + bool lowPowerModeEnabled() const { return lowPowerMode; } - void setCustomMode(enum MainWindow::CUSTOM_MODE mode) + void setCustomMode(MainWindow::CUSTOM_MODE mode) { if (mode != CUSTOM_MODE_UNCHANGED) { @@ -184,12 +182,12 @@ public: } } - enum MainWindow::CUSTOM_MODE getCustomMode() + MainWindow::CUSTOM_MODE getCustomMode() const { return customMode; } - QList listLinkMenuActions(void); + QList listLinkMenuActions(); public slots: /** @brief Shows a status message on the bottom status bar */ @@ -224,7 +222,7 @@ public slots: void saveScreen(); /** @brief Sets advanced mode, allowing for editing of tool widget locations */ - void setAdvancedMode(); + void setAdvancedMode(bool isAdvancedMode); /** @brief Load configuration views */ void loadHardwareConfigView(); void loadSoftwareConfigView(); @@ -283,16 +281,6 @@ public slots: /** @brief Load data view, allowing to plot flight data */ // void loadDataView(QString fileName); - /** - * @brief Shows a Docked Widget based on the action sender - * - * This slot is written to be used in conjunction with the addTool() function - * It shows the QDockedWidget based on the action sender - * - */ - void showTool(bool visible); - - /** * @brief Shows a Widget from the center stack based on the action sender * @@ -308,8 +296,7 @@ public slots: void commsWidgetDestroyed(QObject *obj); protected slots: - /** @brief Called by a dock widget when it is has been deleted */ - void dockWidgetDestroyed(); + void showDockWidget(const QString &name, bool show); signals: void styleChanged(MainWindow::QGC_MAINWINDOW_STYLE newTheme); @@ -362,8 +349,9 @@ protected: * @param location The default location for the QDockedWidget in case there is no previous key in the settings */ void addTool(SubMainWindow *parent,VIEW_SECTIONS view,QDockWidget* widget, const QString& title, Qt::DockWidgetArea area); - void loadDockWidget(QString name); - QDockWidget* createDockWidget(QWidget *parent,QWidget *child,QString title,QString objectname,VIEW_SECTIONS view,Qt::DockWidgetArea area,int minwidth=0,int minheight=0); + void loadDockWidget(const QString &name); + + QDockWidget* createDockWidget(QWidget *subMainWindowParent,QWidget *child,const QString& title,const QString& objectname,VIEW_SECTIONS view,Qt::DockWidgetArea area,const QSize& minSize = QSize()); /** * @brief Adds an already instantiated QWidget to the center stack * @@ -514,11 +502,7 @@ protected: private: QList commsWidgetList; QMap customWidgetNameToFilenameMap; - QMap menuToDockNameMap; - QList dockWidgets; - QMap > centralWidgetToDockWidgetsMap; - bool isAdvancedMode; ///< If enabled dock widgets can be moved and floated. - bool dockWidgetTitleBarEnabled; ///< If enabled, dock widget titlebars are displayed when NOT in advanced mode. + MenuActionHelper *menuActionHelper; Ui::MainWindow ui; /** @brief Set the appropriate titlebar for a given dock widget. @@ -529,6 +513,7 @@ private: QString getWindowStateKey(); QString getWindowGeometryKey(); + friend class MenuActionHelper; //For VIEW_SECTIONS }; #endif /* _MAINWINDOW_H_ */ diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index d2419ec37a..3cc3603b79 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -576,7 +576,7 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) { if (file.toLower().endsWith(".qgw")) { QWidget* parent = left?ui->generalLeftContents:ui->generalRightContents; - tool = new QGCToolWidget("", parent); + tool = new QGCToolWidget("", "", parent); if (tool->loadSettings(generaldir.absoluteFilePath(file), false)) { toolWidgets.append(tool); @@ -651,7 +651,7 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) foreach (QString file,newdir.entryList(QDir::Files| QDir::NoDotAndDotDot)) { if (file.toLower().endsWith(".qgw")) { - tool = new QGCToolWidget("", tab); + tool = new QGCToolWidget("", "", tab); if (tool->loadSettings(newdir.absoluteFilePath(file), false)) { toolWidgets.append(tool); @@ -698,7 +698,7 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary) foreach (QString file,newdir.entryList(QDir::Files| QDir::NoDotAndDotDot)) { if (file.toLower().endsWith(".qgw")) { - tool = new QGCToolWidget("", tab); + tool = new QGCToolWidget("", "", tab); tool->addUAS(mav); if (tool->loadSettings(newdir.absoluteFilePath(file), false)) { @@ -953,10 +953,8 @@ void QGCPX4VehicleConfig::loadConfig() { parent = ui->generalRightContents; } - tool = new QGCToolWidget("", parent); + tool = new QGCToolWidget(parametersname, parametersname, parent); tool->addUAS(mav); - tool->setTitle(parametersname); - tool->setObjectName(parametersname); tool->setSettings(genset); QList paramlist = tool->getParamList(); for (int i=0;igeneralRightContents; } - tool = new QGCToolWidget("", parent); + tool = new QGCToolWidget(parametersname, parametersname, parent); tool->addUAS(mav); - tool->setTitle(parametersname); - tool->setObjectName(parametersname); tool->setSettings(advset); QList paramlist = tool->getParamList(); for (int i=0;igeneralLeftContents:ui->generalRightContents; - tool = new QGCToolWidget("", parent); + tool = new QGCToolWidget("", "", parent); if (tool->loadSettings(generaldir.absoluteFilePath(file), false)) { toolWidgets.append(tool); @@ -291,7 +291,7 @@ void QGCVehicleConfig::loadQgcConfig(bool primary) { if (file.toLower().endsWith(".qgw")) { QWidget* parent = left?ui->advancedLeftContents:ui->advancedRightContents; - tool = new QGCToolWidget("", parent); + tool = new QGCToolWidget("", "", parent); if (tool->loadSettings(vehicledir.absoluteFilePath(file), false)) { toolWidgets.append(tool); @@ -342,7 +342,7 @@ void QGCVehicleConfig::loadQgcConfig(bool primary) foreach (QString file,newdir.entryList(QDir::Files| QDir::NoDotAndDotDot)) { if (file.toLower().endsWith(".qgw")) { - tool = new QGCToolWidget("", tab); + tool = new QGCToolWidget("", "", tab); if (tool->loadSettings(newdir.absoluteFilePath(file), false)) { toolWidgets.append(tool); @@ -389,7 +389,7 @@ void QGCVehicleConfig::loadQgcConfig(bool primary) foreach (QString file,newdir.entryList(QDir::Files| QDir::NoDotAndDotDot)) { if (file.toLower().endsWith(".qgw")) { - tool = new QGCToolWidget("", tab); + tool = new QGCToolWidget("","", tab); tool->addUAS(mav); if (tool->loadSettings(newdir.absoluteFilePath(file), false)) { @@ -411,7 +411,7 @@ void QGCVehicleConfig::loadQgcConfig(bool primary) // Load general calibration for autopilot //TODO: Handle this more gracefully, maybe have it scan the directory for multiple calibration entries? - tool = new QGCToolWidget("", ui->sensorContents); + tool = new QGCToolWidget("", "", ui->sensorContents); tool->addUAS(mav); if (tool->loadSettings(autopilotdir.absolutePath() + "/general/calibration/calibration.qgw", false)) { @@ -426,7 +426,7 @@ void QGCVehicleConfig::loadQgcConfig(bool primary) } // Load vehicle-specific autopilot configuration - tool = new QGCToolWidget("", ui->sensorContents); + tool = new QGCToolWidget("", "", ui->sensorContents); tool->addUAS(mav); if (tool->loadSettings(autopilotdir.absolutePath() + "/" + mav->getSystemTypeName().toLower() + "/calibration/calibration.qgw", false)) { @@ -681,10 +681,8 @@ void QGCVehicleConfig::loadConfig() { parent = ui->generalRightContents; } - tool = new QGCToolWidget("", parent); + tool = new QGCToolWidget(parametersname, parametersname, parent); tool->addUAS(mav); - tool->setTitle(parametersname); - tool->setObjectName(parametersname); tool->setSettings(genset); QList paramlist = tool->getParamList(); for (int i=0;igeneralRightContents; } - tool = new QGCToolWidget("", parent); + tool = new QGCToolWidget(parametersname, parametersname, parent); tool->addUAS(mav); - tool->setTitle(parametersname); - tool->setObjectName(parametersname); tool->setSettings(advset); QList paramlist = tool->getParamList(); for (int i=0;i 1) { tooltitle = parameterName.split("_")[0] + "_"; } - tool->setTitle(tooltitle); - tool->setObjectName(tooltitle); + QGCToolWidget *tool = new QGCToolWidget(tooltitle, tooltitle, parent); //tool->setSettings(set); libParamToWidgetMap.insert(parameterName,tool); toolWidgets.append(tool); diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index 73eae34c98..6610e03d50 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -16,7 +16,7 @@ #include "QGCCommandButton.h" #include "UASManager.h" -QGCToolWidget::QGCToolWidget(const QString& title, QWidget *parent, QSettings* settings) : +QGCToolWidget::QGCToolWidget(const QString& objectName, const QString& title, QWidget *parent, QSettings* settings) : QWidget(parent), mav(NULL), mainMenuAction(NULL), @@ -50,6 +50,11 @@ QGCToolWidget::QGCToolWidget(const QString& title, QWidget *parent, QSettings* s } connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(addUAS(UASInterface*))); + if(!objectName.isEmpty()) { + instances()->insert(objectName, this); + setObjectName(objectName); + } //Otherwise we must call loadSettings() immediately to set the object name + // Enforce storage if this not loaded from settings // is MUST NOT BE SAVED if it was loaded from settings! //if (!settings) storeWidgetsToSettings(); @@ -58,7 +63,7 @@ QGCToolWidget::QGCToolWidget(const QString& title, QWidget *parent, QSettings* s QGCToolWidget::~QGCToolWidget() { if (mainMenuAction) mainMenuAction->deleteLater(); - if (QGCToolWidget::instances()) QGCToolWidget::instances()->remove(widgetTitle); + if (QGCToolWidget::instances()) QGCToolWidget::instances()->remove(objectName()); delete ui; } @@ -98,11 +103,10 @@ QList QGCToolWidget::createWidgetsFromSettings(QWidget* parent, QString name = settings->value("TITLE", "").toString(); QString objname = settings->value("OBJECT_NAME", "").toString(); - if (!instances()->contains(name) && name.length() != 0) + if (!instances()->contains(objname) && !objname.isEmpty()) { //qDebug() << "CREATED WIDGET:" << name; - QGCToolWidget* tool = new QGCToolWidget(name, parent, settings); - tool->setObjectName(objname); + QGCToolWidget* tool = new QGCToolWidget(objname, name, parent, settings); newWidgets.append(tool); } else if (name.length() == 0) @@ -154,12 +158,13 @@ bool QGCToolWidget::loadSettings(const QString& settings, bool singleinstance) QStringList groups = set.childGroups(); if (groups.length() > 0) { - QString widgetName = groups.first(); - this->setObjectName(widgetName); - if (singleinstance && QGCToolWidget::instances()->keys().contains(widgetName)) return false; + QString objectName = groups.first(); + setObjectName(objectName); + if (singleinstance && QGCToolWidget::instances()->contains(objectName)) return false; + instances()->insert(objectName, this); // Do not use setTitle() here, // interferes with loading settings - widgetTitle = widgetName; + widgetTitle = objectName; //qDebug() << "WIDGET TITLE LOADED: " << widgetName; loadSettings(set); return true; @@ -385,7 +390,7 @@ void QGCToolWidget::storeWidgetsToSettings(QString settingsFile) settings->setArrayIndex(num++); settings->setValue("TITLE", instances()->values().at(i)->getTitle()); settings->setValue("OBJECT_NAME", instances()->values().at(i)->objectName()); - //qDebug() << "WRITING TITLE" << instances()->values().at(i)->getTitle(); + qDebug() << "WRITING TITLE" << instances()->values().at(i)->getTitle() << "object:" << instances()->values().at(i)->objectName(); } } else @@ -640,20 +645,16 @@ void QGCToolWidget::setTitle() void QGCToolWidget::setTitle(const QString& title) { - if (instances()->contains(widgetTitle)) instances()->remove(widgetTitle); - if (!instances()->contains(title)) instances()->insert(title, this); - // Sets title and calls setWindowTitle on QWidget widgetTitle = title; QWidget::setWindowTitle(title); - setObjectName(widgetTitle); QDockWidget* dock = dynamic_cast(this->parentWidget()); - if (dock) { + if (dock) dock->setWindowTitle(widgetTitle); - dock->setObjectName(widgetTitle+"DOCK"); - } emit titleChanged(title); if (mainMenuAction) mainMenuAction->setText(title); + + storeWidgetsToSettings(); } void QGCToolWidget::setMainMenuAction(QAction* action) @@ -667,7 +668,7 @@ void QGCToolWidget::deleteWidget() // Hide this->hide(); - instances()->remove(getTitle()); + instances()->remove(objectName()); QSettings settings; settings.beginGroup("QGC_MAINWINDOW"); diff --git a/src/ui/designer/QGCToolWidget.h b/src/ui/designer/QGCToolWidget.h index 5d1f56d0c9..2e08337c2b 100644 --- a/src/ui/designer/QGCToolWidget.h +++ b/src/ui/designer/QGCToolWidget.h @@ -19,7 +19,7 @@ class QGCToolWidget : public QWidget Q_OBJECT public: - explicit QGCToolWidget(const QString& title=QString("Unnamed Tool"), QWidget *parent = 0, QSettings* settings = 0); + explicit QGCToolWidget(const QString& objectName, const QString& title, QWidget *parent = 0, QSettings* settings = 0); ~QGCToolWidget(); /** @brief Factory method to instantiate all tool widgets */ @@ -85,7 +85,6 @@ protected: QMap dockWidgetArea; ///< Dock widget area desired by this widget QMap viewVisible; ///< Visibility in one view QString widgetTitle; - static int instanceCount; ///< Number of instances around void contextMenuEvent(QContextMenuEvent* event); void createActions(); @@ -104,6 +103,12 @@ protected slots: void setTitle(); private: + /** Do not use this from outside the class to set the object name, + * because we cannot track changes to the object name, and the + * QObject::setObjectName() function is not virtual. Instead only + * pass in the object name to the constructor, or use the , then + * never change it again. */ + void setObjectName(const QString &name) { QWidget::setObjectName(name); } Ui::QGCToolWidget *ui; }; diff --git a/src/ui/dockwidgeteventfilter.cpp b/src/ui/dockwidgeteventfilter.cpp deleted file mode 100644 index 260e3a5466..0000000000 --- a/src/ui/dockwidgeteventfilter.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include - -#include "dockwidgeteventfilter.h" - -DockWidgetEventFilter::DockWidgetEventFilter(QObject *parent) : QObject(parent) {} - -bool DockWidgetEventFilter::eventFilter(QObject *object,QEvent *event) -{ - if (event->type() == QEvent::WindowTitleChange) - { - QDockWidget *dock = dynamic_cast(object); - if(dock) { - QLabel *label = dynamic_cast(dock->titleBarWidget()); - if(label) - label->setText(dock->windowTitle()); - } - } - return QObject::eventFilter(object,event); -} diff --git a/src/ui/dockwidgeteventfilter.h b/src/ui/dockwidgeteventfilter.h deleted file mode 100644 index 60de1e4002..0000000000 --- a/src/ui/dockwidgeteventfilter.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef DOCKWIDGETEVENTFILTER_H -#define DOCKWIDGETEVENTFILTER_H - -#include - -/** Event filter to update a QLabel titleBarWidget if the window's title changes */ -class DockWidgetEventFilter : public QObject -{ - Q_OBJECT -public: - DockWidgetEventFilter(QObject *parent = 0); -protected: - virtual bool eventFilter(QObject *object,QEvent *event) override; -}; - -#endif // DOCKWIDGETEVENTFILTER_H diff --git a/src/ui/dockwidgettitlebareventfilter.cpp b/src/ui/dockwidgettitlebareventfilter.cpp deleted file mode 100644 index 52519215ad..0000000000 --- a/src/ui/dockwidgettitlebareventfilter.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "dockwidgettitlebareventfilter.h" -#include -#include -DockWidgetTitleBarEventFilter::DockWidgetTitleBarEventFilter(QObject *parent) : QObject(parent) -{ -} -bool DockWidgetTitleBarEventFilter::eventFilter(QObject *object,QEvent *event) -{ - if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) - { - return true; - } - return QObject::eventFilter(object,event); -} diff --git a/src/ui/dockwidgettitlebareventfilter.h b/src/ui/dockwidgettitlebareventfilter.h deleted file mode 100644 index d57edef1fb..0000000000 --- a/src/ui/dockwidgettitlebareventfilter.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef DOCKWIDGETTITLEBAREVENTFILTER_H -#define DOCKWIDGETTITLEBAREVENTFILTER_H - -#include - -class DockWidgetTitleBarEventFilter : public QObject -{ - Q_OBJECT -public: - explicit DockWidgetTitleBarEventFilter(QObject *parent = 0); -protected: - bool eventFilter(QObject *object,QEvent *event); -signals: - -public slots: - -}; - -#endif // DOCKWIDGETTITLEBAREVENTFILTER_H diff --git a/src/ui/menuactionhelper.cpp b/src/ui/menuactionhelper.cpp new file mode 100644 index 0000000000..a9b3a8d766 --- /dev/null +++ b/src/ui/menuactionhelper.cpp @@ -0,0 +1,184 @@ +#include "menuactionhelper.h" + +MenuActionHelper::MenuActionHelper(QObject *parent) : QObject(parent), + m_isAdvancedMode(false), + m_dockWidgetTitleBarsEnabled(true), + m_addedCustomSeperator(false) +{ +} + +QAction *MenuActionHelper::createToolAction(const QString &title, const QString &name) +{ + QAction *action = m_menuToDockNameMap.key(name); //For sanity, check that the action is not NULL + if(action) { + qWarning() << "createToolAction was called for action" << name << "which already exists in the menu"; + return action; + } + + action = new QAction(title, NULL); + action->setCheckable(true); + connect(action,SIGNAL(triggered(bool)),this,SLOT(showTool(bool))); + m_menuToDockNameMap[action] = name; + m_menu->addAction(action); + return action; +} + +void MenuActionHelper::removeDockWidget() +{ + QObject *dockWidget = QObject::sender(); //Note that we can't cast to QDockWidget because we are in its destructor + Q_ASSERT(dockWidget); + + qDebug() << "Dockwidget:" << dockWidget->objectName() << "of type" << dockWidget->metaObject()->className(); + + QAction *action = m_menuToDockNameMap.key(dockWidget->objectName()); + if(action) { + m_menuToDockNameMap.remove(action); + action->deleteLater(); + } + QMap >::iterator it; + for (it = m_centralWidgetToDockWidgetsMap.begin(); it != m_centralWidgetToDockWidgetsMap.end(); ++it) { + QMap::iterator it2 = it.value().begin(); + while( it2 != it.value().end()) { + if(it2.value() == dockWidget) + it2 = it.value().erase(it2); + else + ++it2; + } + } + //Don't delete the dockWidget because this could have been called from the dockWidget destructor + m_dockWidgets.removeAll(static_cast(dockWidget)); +} + +QAction *MenuActionHelper::createToolActionForCustomDockWidget(const QString &title, const QString& name, QDockWidget* dockWidget, MainWindow::VIEW_SECTIONS view) { + bool found = false; + QAction *action = NULL; + foreach(QAction *act, m_menuToDockNameMap.keys()) { + if(act->text() == title) { + found = true; + action = act; + } + } + + if(!found) + action = createToolAction(title, name); + else + m_menuToDockNameMap[action] = name; + + m_centralWidgetToDockWidgetsMap[view][name] = dockWidget; + connect(dockWidget, SIGNAL(destroyed()), SLOT(removeDockWidget()),Qt::UniqueConnection); //Use UniqueConnection since we might have already created this connection in createDockWidget + connect(dockWidget, SIGNAL(visibilityChanged(bool)), action, SLOT(setChecked(bool))); + action->setChecked(dockWidget->isVisible()); + return action; +} + +QDockWidget* MenuActionHelper::createDockWidget(const QString& title,const QString& name) +{ + QDockWidget *dockWidget = new QDockWidget(title); + m_dockWidgets.append(dockWidget); + setDockWidgetTitleBar(dockWidget); + dockWidget->setObjectName(name); + connect(dockWidget, SIGNAL(destroyed()), SLOT(removeDockWidget())); + + return dockWidget; +} + +bool MenuActionHelper::containsDockWidget(MainWindow::VIEW_SECTIONS view, const QString &name) const { + + return m_centralWidgetToDockWidgetsMap.contains(view) && m_centralWidgetToDockWidgetsMap[view].contains(name); +} + +QDockWidget *MenuActionHelper::getDockWidget(MainWindow::VIEW_SECTIONS view, const QString &name) const { + if(!m_centralWidgetToDockWidgetsMap.contains(view)) + return NULL; + return m_centralWidgetToDockWidgetsMap[view].value(name); +} + +void MenuActionHelper::showTool(bool show) { + //Called when a menu item is clicked on, regardless of view. + QAction* act = qobject_cast(sender()); + Q_ASSERT(act); + if (m_menuToDockNameMap.contains(act)) { + QString name = m_menuToDockNameMap[act]; + emit needToShowDockWidget(name, show); + } +} + +void MenuActionHelper::setDockWidgetTitleBarsEnabled(bool enabled) +{ + m_dockWidgetTitleBarsEnabled = enabled; + for (int i = 0; i < m_dockWidgets.size(); i++) + setDockWidgetTitleBar(m_dockWidgets[i]); +} + + +void MenuActionHelper::setAdvancedMode(bool advancedMode) +{ + m_isAdvancedMode = advancedMode; + for (int i = 0; i < m_dockWidgets.size(); i++) + setDockWidgetTitleBar(m_dockWidgets[i]); +} + +void MenuActionHelper::setDockWidgetTitleBar(QDockWidget* widget) +{ + Q_ASSERT(widget); + QWidget* oldTitleBar = widget->titleBarWidget(); + + // In advanced mode, we use the default titlebar provided by Qt. + if (m_isAdvancedMode) + { + widget->setTitleBarWidget(0); + } + // Otherwise, if just a textlabel should be shown, make that the titlebar. + else if (m_dockWidgetTitleBarsEnabled) + { + QLabel* label = new QLabel(widget); + label->setText(widget->windowTitle()); + label->installEventFilter(this); //Ignore mouse clicks + widget->installEventFilter(this); //Update label if window title changes. See eventFilter below + widget->setTitleBarWidget(label); + } + // And if nothing should be shown, use an empty widget. + else + { + QWidget* newTitleBar = new QWidget(widget); + widget->setTitleBarWidget(newTitleBar); + } + + // Be sure to clean up the old titlebar. When using QDockWidget::setTitleBarWidget(), + // it doesn't delete the old titlebar object. + delete oldTitleBar; +} + +bool MenuActionHelper::eventFilter(QObject *object,QEvent *event) +{ + if (event->type() == QEvent::WindowTitleChange) + { + QDockWidget *dock = qobject_cast(object); + if(dock) { + // Update the dock title bar label + QLabel *label = dynamic_cast(dock->titleBarWidget()); + if(label) + label->setText(dock->windowTitle()); + // Now update the action label + QString oldObjectName = dock->objectName(); + QAction *action = m_menuToDockNameMap.key(oldObjectName); + if(action) + action->setText(dock->windowTitle()); + //Now modify the object name - it is a strange naming scheme.. +/* QString newObjectName = widgetTitle+"DOCK"; + dock->setObjectName(newObjectName); + m_menuToDockNameMap[action] = newObjectName; + QMap >::iterator it; + for (it = m_centralWidgetToDockWidgetsMap.begin(); it != m_centralWidgetToDockWidgetsMap.end(); ++it) { + QMap &map = it.value(); + map[newObjectName] = map[oldObjectName]; + map.remove(oldObjectName); + }*/ + } + } else if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) + { + if(qobject_cast(object)) + return true; + } + return QObject::eventFilter(object,event); +} diff --git a/src/ui/menuactionhelper.h b/src/ui/menuactionhelper.h new file mode 100644 index 0000000000..cde7883488 --- /dev/null +++ b/src/ui/menuactionhelper.h @@ -0,0 +1,50 @@ +#ifndef MENUACTIONHELPER_H +#define MENUACTIONHELPER_H + +#include "MainWindow.h" + +class MenuActionHelper : public QObject +{ + Q_OBJECT +public: + MenuActionHelper(QObject *parent = NULL); + ~MenuActionHelper() {} + + /** @brief Get title bar mode setting */ + bool dockWidgetTitleBarsEnabled() const { return m_dockWidgetTitleBarsEnabled; } + void setDockWidgetTitleBarsEnabled(bool enabled); + bool isAdvancedMode() const { return m_isAdvancedMode; } + void setAdvancedMode(bool advancedMode); + QAction *createToolAction(const QString &title, const QString &name = QString()); + QAction *createToolActionForCustomDockWidget(const QString& title, const QString& name, QDockWidget* dockWidget, MainWindow::VIEW_SECTIONS view); + QDockWidget *createDockWidget(const QString& title, const QString& name); + bool containsDockWidget(MainWindow::VIEW_SECTIONS view, const QString &name) const; + QDockWidget *getDockWidget(MainWindow::VIEW_SECTIONS view, const QString &name) const; + + /** QMenu to add QActions to */ + void setMenu(QMenu *menu) { m_menu = menu; } + +protected: + virtual bool eventFilter(QObject *object,QEvent *event); + +private slots: + void removeDockWidget(); + /** @brief Shows a Docked Widget based on the action sender */ + void showTool(bool show); + +signals: + void needToShowDockWidget(const QString& name, bool show); +private: + QMap m_menuToDockNameMap; + QList m_dockWidgets; + QMap > m_centralWidgetToDockWidgetsMap; + bool m_isAdvancedMode; ///< If enabled dock widgets can be moved and floated. + bool m_dockWidgetTitleBarsEnabled; ///< If enabled, dock widget titlebars are displayed when NOT in advanced mode. + QMenu *m_menu; ///< \see setMenu() + bool m_addedCustomSeperator; ///< Whether we have added a seperator between the actions and the custom actions + + void setDockWidgetTitleBar(QDockWidget* widget); + +}; + +#endif // MENUACTIONHELPER_H -- GitLab From 98d96af1c7e2240330a9f69ea9adb227e6df4291 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Wed, 16 Oct 2013 23:18:38 +0100 Subject: [PATCH 417/460] Don't translate the object name, otherwise the config will break in non-english languages --- src/ui/MainWindow.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 31662b8ba2..8991ce2409 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -823,7 +823,8 @@ void MainWindow::showHILConfigurationWidget(UASInterface* uas) { QGCHilConfiguration* hconf = new QGCHilConfiguration(mav, this); QString hilDockName = tr("HIL Config %1").arg(uas->getUASName()); - QDockWidget* hilDock = createDockWidget(simView, hconf,hilDockName, hilDockName.toUpper().replace(" ", "_"),VIEW_SIMULATION,Qt::LeftDockWidgetArea); + QString hilDockObjectName = QString("HIL_CONFIG_%1").arg(uas->getUASName().toUpper().replace(' ','_')); + QDockWidget* hilDock = createDockWidget(simView, hconf,hilDockName, hilDockObjectName,VIEW_SIMULATION,Qt::LeftDockWidgetArea); hilDocks.insert(mav->getUASID(), hilDock); } } -- GitLab From a6a5a65b144243c9dde33b0edb83444452cf01b4 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Thu, 17 Oct 2013 17:14:57 +0100 Subject: [PATCH 418/460] Fix warning "Cannot set minimum size to (-1,-1)" --- src/ui/MainWindow.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 8991ce2409..e2081e98e4 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -693,8 +693,10 @@ QDockWidget* MainWindow::createDockWidget(QWidget *subMainWindowParent,QWidget * dockWidget->setWidget(child); //Set child objectName before setting dockwidget, since the dock widget might react to object name changes connect(child, SIGNAL(destroyed()), dockWidget, SLOT(deleteLater())); //Our dockwidget only has only child widget, so kill the dock widget if the child is deleted - if (!minSize.isNull()) - dockWidget->setMinimumSize(minSize); + if (minSize.height() >= 0) + dockWidget->setMinimumHeight(minSize.height()); + if (minSize.width() >= 0) + dockWidget->setMinimumWidth(minSize.width()); addTool(parent,view,dockWidget,title,area); return dockWidget; } -- GitLab From f6ae5ed8fc8b2b6238eefa05401d7e85a93b1bf2 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Thu, 17 Oct 2013 17:43:09 +0100 Subject: [PATCH 419/460] Make sure that our custom widget doesn't reuse an object name --- src/ui/MainWindow.cc | 12 ++++++++++-- src/ui/designer/QGCToolWidget.cc | 6 ------ src/ui/menuactionhelper.cpp | 9 --------- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index e2081e98e4..f38ca9b284 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -860,8 +860,16 @@ void MainWindow::createCustomWidget() // This is the first widget ui.menuTools->addSeparator(); } - QString title = "Unnamed Tool " + QString::number(ui.menuTools->actions().size()); - QString objectName = "UNNAMED_TOOL_" + QString::number(ui.menuTools->actions().size())+"DOCK"; + QString objectName; + int customToolIndex = 0; + //Find the next unique object name that we can use + do { + ++customToolIndex; + objectName = QString("CUSTOM_TOOL_%1").arg(customToolIndex) + "DOCK"; + } while(QGCToolWidget::instances()->contains(objectName)); + + QString title = tr("Custom Tool %1").arg(customToolIndex ); + QGCToolWidget* tool = new QGCToolWidget(objectName, title); createDockWidget(centerStack->currentWidget(),tool,title,objectName,currentView,Qt::BottomDockWidgetArea); diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index 6610e03d50..f394ca1ffa 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -27,12 +27,6 @@ QGCToolWidget::QGCToolWidget(const QString& objectName, const QString& title, QW ui->setupUi(this); if (settings) loadSettings(*settings); - if (title == "Unnamed Tool") - { - widgetTitle = QString("%1 %2").arg(title).arg(QGCToolWidget::instances()->count()); - } - //qDebug() << "WidgetTitle" << widgetTitle; - createActions(); toolLayout = ui->toolLayout; toolLayout->setAlignment(Qt::AlignTop); diff --git a/src/ui/menuactionhelper.cpp b/src/ui/menuactionhelper.cpp index a9b3a8d766..459ebaade3 100644 --- a/src/ui/menuactionhelper.cpp +++ b/src/ui/menuactionhelper.cpp @@ -165,15 +165,6 @@ bool MenuActionHelper::eventFilter(QObject *object,QEvent *event) if(action) action->setText(dock->windowTitle()); //Now modify the object name - it is a strange naming scheme.. -/* QString newObjectName = widgetTitle+"DOCK"; - dock->setObjectName(newObjectName); - m_menuToDockNameMap[action] = newObjectName; - QMap >::iterator it; - for (it = m_centralWidgetToDockWidgetsMap.begin(); it != m_centralWidgetToDockWidgetsMap.end(); ++it) { - QMap &map = it.value(); - map[newObjectName] = map[oldObjectName]; - map.remove(oldObjectName); - }*/ } } else if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) { -- GitLab From 0c5065251d15554244dfb840590d5617443a9dc0 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Thu, 17 Oct 2013 23:33:15 +0100 Subject: [PATCH 420/460] Reduce code duplication --- src/ui/designer/QGCToolWidget.cc | 49 ++++++++------------------------ src/ui/designer/QGCToolWidget.h | 2 ++ 2 files changed, 14 insertions(+), 37 deletions(-) diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index f394ca1ffa..f8ddb6969f 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -51,7 +51,7 @@ QGCToolWidget::QGCToolWidget(const QString& objectName, const QString& title, QW // Enforce storage if this not loaded from settings // is MUST NOT BE SAVED if it was loaded from settings! - //if (!settings) storeWidgetsToSettings(); + if (!settings) storeWidgetsToSettings(); } QGCToolWidget::~QGCToolWidget() @@ -530,60 +530,35 @@ QList* QGCToolWidget::itemList() if (!instances) instances = new QList(); return instances; } + void QGCToolWidget::addParam(int uas,int component,QString paramname,QVariant value) { isFromMetaData = true; QGCParamSlider* slider = new QGCParamSlider(this); - connect(slider, SIGNAL(destroyed()), this, SLOT(storeSettings())); - if (ui->hintLabel) - { - ui->hintLabel->deleteLater(); - ui->hintLabel = NULL; - } - toolLayout->addWidget(slider); + addToolWidget(slider); slider->setActiveUAS(mav); slider->setParameterValue(uas,component,0,-1,paramname,value); - - } void QGCToolWidget::addParam() { - QGCParamSlider* slider = new QGCParamSlider(this); - connect(slider, SIGNAL(destroyed()), this, SLOT(storeSettings())); - if (ui->hintLabel) - { - ui->hintLabel->deleteLater(); - ui->hintLabel = NULL; - } - toolLayout->addWidget(slider); - slider->startEditMode(); + addToolWidgetAndEdit(new QGCParamSlider(this)); } void QGCToolWidget::addCommand() { - QGCCommandButton* button = new QGCCommandButton(this); - connect(button, SIGNAL(destroyed()), this, SLOT(storeSettings())); - if (ui->hintLabel) - { - ui->hintLabel->deleteLater(); - ui->hintLabel = NULL; - } - toolLayout->addWidget(button); - button->startEditMode(); + addToolWidgetAndEdit(new QGCCommandButton(this)); } void QGCToolWidget::addLabel() { - QGCTextLabel* label= new QGCTextLabel(this); - connect(label, SIGNAL(destroyed()), this, SLOT(storeSettings())); - if (ui->hintLabel) - { - ui->hintLabel->deleteLater(); - ui->hintLabel = NULL; - } - toolLayout->addWidget(label); - label->startEditMode(); + addToolWidgetAndEdit(new QGCTextLabel(this)); +} + +void QGCToolWidget::addToolWidgetAndEdit(QGCToolWidgetItem* widget) +{ + addToolWidget(widget); + widget->startEditMode(); } void QGCToolWidget::addToolWidget(QGCToolWidgetItem* widget) diff --git a/src/ui/designer/QGCToolWidget.h b/src/ui/designer/QGCToolWidget.h index 2e08337c2b..9bc17c69d7 100644 --- a/src/ui/designer/QGCToolWidget.h +++ b/src/ui/designer/QGCToolWidget.h @@ -91,6 +91,8 @@ protected: QList* itemList(); /** @brief Add an existing tool widget */ void addToolWidget(QGCToolWidgetItem* widget); + /** @brief Add an existing tool widget and set it to edit mode */ + void addToolWidgetAndEdit(QGCToolWidgetItem* widget); void hideEvent(QHideEvent* event); public slots: -- GitLab From 6c347709a0fa9670411248d8fab6bba187c6895a Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Thu, 17 Oct 2013 23:29:39 +0100 Subject: [PATCH 421/460] Clean up when exactly we should save settings, and add in checks to make sure we do not do it incorrectly --- src/ui/MainWindow.cc | 1 + src/ui/designer/QGCToolWidget.cc | 92 +++++++++------------------- src/ui/designer/QGCToolWidget.h | 20 +++--- src/ui/designer/QGCToolWidgetItem.cc | 5 -- 4 files changed, 40 insertions(+), 78 deletions(-) diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index f38ca9b284..f3b8678c84 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -1035,6 +1035,7 @@ void MainWindow::storeSettings() } settings.setValue("LOW_POWER_MODE", lowPowerMode); settings.setValue("QGC_CUSTOM_MODE", (int)customMode); + QGCToolWidget::storeWidgetsToSettings(settings); settings.sync(); } diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index f8ddb6969f..95167d3bc9 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -48,10 +48,6 @@ QGCToolWidget::QGCToolWidget(const QString& objectName, const QString& title, QW instances()->insert(objectName, this); setObjectName(objectName); } //Otherwise we must call loadSettings() immediately to set the object name - - // Enforce storage if this not loaded from settings - // is MUST NOT BE SAVED if it was loaded from settings! - if (!settings) storeWidgetsToSettings(); } QGCToolWidget::~QGCToolWidget() @@ -353,26 +349,13 @@ void QGCToolWidget::loadSettings(QSettings& settings) settings.endGroup(); } -void QGCToolWidget::storeWidgetsToSettings(QString settingsFile) +void QGCToolWidget::storeWidgetsToSettings(QSettings &settings) //static { - // Store list of widgets - QSettings* settings; - if (!settingsFile.isEmpty()) - { - settings = new QSettings(settingsFile, QSettings::IniFormat); - //qDebug() << "STORING SETTINGS TO" << settings->fileName(); - } - else - { - settings = new QSettings(); - //qDebug() << "STORING SETTINGS TO DEFAULT" << settings->fileName(); - } - - settings->beginGroup("Custom_Tool_Widgets"); - int preArraySize = settings->beginReadArray("QGC_TOOL_WIDGET_NAMES"); - settings->endArray(); + settings.beginGroup("Custom_Tool_Widgets"); + int preArraySize = settings.beginReadArray("QGC_TOOL_WIDGET_NAMES"); + settings.endArray(); - settings->beginWriteArray("QGC_TOOL_WIDGET_NAMES"); + settings.beginWriteArray("QGC_TOOL_WIDGET_NAMES"); int num = 0; for (int i = 0; i < qMax(preArraySize, instances()->size()); ++i) { @@ -381,44 +364,34 @@ void QGCToolWidget::storeWidgetsToSettings(QString settingsFile) // Updating value if (!instances()->values().at(i)->fromMetaData()) { - settings->setArrayIndex(num++); - settings->setValue("TITLE", instances()->values().at(i)->getTitle()); - settings->setValue("OBJECT_NAME", instances()->values().at(i)->objectName()); + settings.setArrayIndex(num++); + settings.setValue("TITLE", instances()->values().at(i)->getTitle()); + settings.setValue("OBJECT_NAME", instances()->values().at(i)->objectName()); qDebug() << "WRITING TITLE" << instances()->values().at(i)->getTitle() << "object:" << instances()->values().at(i)->objectName(); } } else { // Deleting old value - settings->remove("TITLE"); + settings.remove("TITLE"); } } - settings->endArray(); + settings.endArray(); // Store individual widget items for (int i = 0; i < instances()->size(); ++i) { - instances()->values().at(i)->storeSettings(*settings); + instances()->values().at(i)->storeSettings(settings); } - settings->endGroup(); - settings->sync(); - delete settings; -} - -void QGCToolWidget::storeSettings() -{ - QSettings settings; - storeSettings(settings); -} - -void QGCToolWidget::storeSettings(const QString& settingsFile) -{ - QSettings settings(settingsFile, QSettings::IniFormat); - storeSettings(settings); + settings.endGroup(); + settings.sync(); } void QGCToolWidget::storeSettings(QSettings& settings) { + /* This function should be called from storeWidgetsToSettings() which sets up the group etc */ + Q_ASSERT(settings.group() == "Custom_Tool_Widgets"); + if (isFromMetaData) { //Refuse to store if this is loaded from metadata or dynamically generated. @@ -428,17 +401,11 @@ void QGCToolWidget::storeSettings(QSettings& settings) settings.beginGroup(widgetTitle); settings.beginWriteArray("QGC_TOOL_WIDGET_ITEMS"); int k = 0; // QGCToolItem counter - for (int j = 0; j < children().size(); ++j) - { - // Store only QGCToolWidgetItems - QGCToolWidgetItem* item = dynamic_cast(children().at(j)); - if (item) - { - // Only count actual tool widget item children - settings.setArrayIndex(k++); - // Store the ToolWidgetItem - item->writeSettings(settings); - } + foreach(QGCToolWidgetItem *item, toolItemList) { + // Only count actual tool widget item children + settings.setArrayIndex(k++); + // Store the ToolWidgetItem + item->writeSettings(settings); } //qDebug() << "WROTE" << k << "SUB-WIDGETS TO SETTINGS"; settings.endArray(); @@ -524,13 +491,6 @@ QMap* QGCToolWidget::instances() return instances; } -QList* QGCToolWidget::itemList() -{ - static QList* instances; - if (!instances) instances = new QList(); - return instances; -} - void QGCToolWidget::addParam(int uas,int component,QString paramname,QVariant value) { isFromMetaData = true; @@ -568,7 +528,8 @@ void QGCToolWidget::addToolWidget(QGCToolWidgetItem* widget) ui->hintLabel->deleteLater(); ui->hintLabel = NULL; } - connect(widget, SIGNAL(destroyed()), this, SLOT(storeSettings())); + connect(widget, SIGNAL(editingFinished()), this, SLOT(storeWidgetsToSettings())); + connect(widget, SIGNAL(destroyed()), this, SLOT(storeWidgetsToSettings())); toolLayout->addWidget(widget); toolItemList.append(widget); } @@ -581,7 +542,8 @@ void QGCToolWidget::exportWidget() { fileName = fileName.append(widgetFileExtension); } - storeSettings(fileName); + QSettings settings(fileName, QSettings::IniFormat); + storeSettings(settings); } void QGCToolWidget::importWidget() @@ -623,7 +585,9 @@ void QGCToolWidget::setTitle(const QString& title) emit titleChanged(title); if (mainMenuAction) mainMenuAction->setText(title); - storeWidgetsToSettings(); + //Do not save the settings here, because this function might be + //called while loading, and thus saving here could end up clobbering + //all of the other widgets } void QGCToolWidget::setMainMenuAction(QAction* action) diff --git a/src/ui/designer/QGCToolWidget.h b/src/ui/designer/QGCToolWidget.h index 9bc17c69d7..f6d615ac1a 100644 --- a/src/ui/designer/QGCToolWidget.h +++ b/src/ui/designer/QGCToolWidget.h @@ -35,6 +35,9 @@ public: Qt::DockWidgetArea getDockWidgetArea(int view) { return dockWidgetArea.value(view, Qt::BottomDockWidgetArea); } void setParent(QWidget *parent); + /** @brief Store all widgets of this type to QSettings */ + static void storeWidgetsToSettings(QSettings &settingsFile); + public slots: void addUAS(UASInterface* uas); /** @brief Delete this widget */ @@ -44,18 +47,14 @@ public slots: /** @brief Import settings for this widget from a file */ void importWidget(); /** @brief Store all widgets of this type to QSettings */ - static void storeWidgetsToSettings(QString settingsFile=QString()); + void storeWidgetsToSettings() { QSettings settings; QGCToolWidget::storeWidgetsToSettings(settings); } + +public: void loadSettings(QVariantMap& settings); /** @brief Load this widget from a QSettings object */ void loadSettings(QSettings& settings); /** @brief Load this widget from a settings file */ bool loadSettings(const QString& settings, bool singleinstance=false); - /** @brief Store this widget to a QSettings object */ - void storeSettings(QSettings& settings); - /** @brief Store this widget to a settings file */ - void storeSettings(const QString& settingsFile); - /** @brief Store this widget to a settings file */ - void storeSettings(); /** @brief Store the view id and dock widget area */ void setViewVisibilityAndDockWidgetArea(int view, bool visible, Qt::DockWidgetArea area); void setSettings(QVariantMap& settings); @@ -63,8 +62,9 @@ public slots: void setParameterValue(int uas, int component, QString parameterName, const QVariant value); bool fromMetaData() { return isFromMetaData; } void showLabel(QString name,int num); + signals: - void titleChanged(QString); + void titleChanged(const QString &title); protected: bool isFromMetaData; @@ -88,7 +88,6 @@ protected: void contextMenuEvent(QContextMenuEvent* event); void createActions(); - QList* itemList(); /** @brief Add an existing tool widget */ void addToolWidget(QGCToolWidgetItem* widget); /** @brief Add an existing tool widget and set it to edit mode */ @@ -111,6 +110,9 @@ private: * pass in the object name to the constructor, or use the , then * never change it again. */ void setObjectName(const QString &name) { QWidget::setObjectName(name); } + /** Helper for storeWidgetsToSettings() */ + void storeSettings(QSettings& settings); + Ui::QGCToolWidget *ui; }; diff --git a/src/ui/designer/QGCToolWidgetItem.cc b/src/ui/designer/QGCToolWidgetItem.cc index 0d7f95e5cd..d2a8c65905 100644 --- a/src/ui/designer/QGCToolWidgetItem.cc +++ b/src/ui/designer/QGCToolWidgetItem.cc @@ -20,11 +20,6 @@ QGCToolWidgetItem::QGCToolWidgetItem(const QString& name, QWidget *parent) : deleteAction = new QAction(tr("Delete %1").arg(qgcToolWidgetItemName), this); connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteLater())); - QGCToolWidget* tool = dynamic_cast(parent); - if (tool) { - connect(this, SIGNAL(editingFinished()), tool, SLOT(storeWidgetsToSettings())); - } - connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); // Set first UAS if it exists -- GitLab From 98abf5a7ff2047ec65e22a777ed3c8866e3ce710 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Fri, 18 Oct 2013 22:32:15 +0100 Subject: [PATCH 422/460] Fix crash when removing an item from a custom widget --- src/ui/designer/QGCToolWidget.cc | 11 ++++++++++- src/ui/designer/QGCToolWidget.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index 95167d3bc9..eb02a12f37 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -529,11 +529,20 @@ void QGCToolWidget::addToolWidget(QGCToolWidgetItem* widget) ui->hintLabel = NULL; } connect(widget, SIGNAL(editingFinished()), this, SLOT(storeWidgetsToSettings())); - connect(widget, SIGNAL(destroyed()), this, SLOT(storeWidgetsToSettings())); + connect(widget, SIGNAL(destroyed()), this, SLOT(widgetRemoved())); toolLayout->addWidget(widget); toolItemList.append(widget); } +void QGCToolWidget::widgetRemoved() +{ + //Must static cast and not dynamic cast since the object is in the destructor + //and we only want to use it as a pointer value + QGCToolWidgetItem *widget = static_cast(QObject::sender()); + toolItemList.removeAll(widget); + storeWidgetsToSettings(); +} + void QGCToolWidget::exportWidget() { const QString widgetFileExtension(".qgw"); diff --git a/src/ui/designer/QGCToolWidget.h b/src/ui/designer/QGCToolWidget.h index f6d615ac1a..985f8595fe 100644 --- a/src/ui/designer/QGCToolWidget.h +++ b/src/ui/designer/QGCToolWidget.h @@ -102,6 +102,7 @@ protected slots: void addCommand(); void addLabel(); void setTitle(); + void widgetRemoved(); private: /** Do not use this from outside the class to set the object name, -- GitLab From bd3b7ea36de5335f3e2d7b6746d0a57e6a75307b Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Fri, 18 Oct 2013 22:32:40 +0100 Subject: [PATCH 423/460] Merge the startEditMode() and endEditMode() functions into one, and remove code duplication --- src/ui/designer/QGCComboBox.cc | 88 +++++++----------- src/ui/designer/QGCComboBox.h | 4 +- src/ui/designer/QGCCommandButton.cc | 110 ++++++----------------- src/ui/designer/QGCCommandButton.h | 4 +- src/ui/designer/QGCParamSlider.cc | 109 ++++++++++------------ src/ui/designer/QGCParamSlider.h | 4 +- src/ui/designer/QGCRadioChannelDisplay.h | 1 + src/ui/designer/QGCTextLabel.cc | 64 +++---------- src/ui/designer/QGCTextLabel.h | 3 +- src/ui/designer/QGCToolWidgetItem.cc | 25 +++++- src/ui/designer/QGCToolWidgetItem.h | 14 ++- 11 files changed, 153 insertions(+), 273 deletions(-) diff --git a/src/ui/designer/QGCComboBox.cc b/src/ui/designer/QGCComboBox.cc index c5ae6a4b59..1b8345bf22 100644 --- a/src/ui/designer/QGCComboBox.cc +++ b/src/ui/designer/QGCComboBox.cc @@ -167,70 +167,42 @@ void QGCComboBox::selectParameter(int paramIndex) } } -void QGCComboBox::startEditMode() +void QGCComboBox::setEditMode(bool editMode) { - ui->nameLabel->hide(); - ui->writeButton->hide(); - ui->readButton->hide(); - - ui->editInfoCheckBox->show(); - ui->editDoneButton->show(); - ui->editNameLabel->show(); - ui->editRefreshParamsButton->show(); - ui->editSelectParamComboBox->show(); - ui->editSelectComponentComboBox->show(); - ui->editStatusLabel->show(); - ui->writeButton->hide(); - ui->readButton->hide(); - ui->editLine1->show(); - ui->editLine2->show(); - ui->editAddItemButton->show(); - ui->editRemoveItemButton->show(); - ui->editItemValueSpinBox->show(); - ui->editItemNameLabel->show(); - ui->itemValueLabel->show(); - ui->itemNameLabel->show(); - if (isDisabled) - { - ui->editOptionComboBox->setEnabled(true); + if(!editMode) { + // Store component id + selectComponent(ui->editSelectComponentComboBox->currentIndex()); + // Store parameter name and id + selectParameter(ui->editSelectParamComboBox->currentIndex()); } - isInEditMode = true; -} - -void QGCComboBox::endEditMode() -{ - // Store component id - selectComponent(ui->editSelectComponentComboBox->currentIndex()); - // Store parameter name and id - selectParameter(ui->editSelectParamComboBox->currentIndex()); - - // Min/max - - ui->editInfoCheckBox->hide(); - ui->editDoneButton->hide(); - ui->editNameLabel->hide(); - ui->editRefreshParamsButton->hide(); - ui->editSelectParamComboBox->hide(); - ui->editSelectComponentComboBox->hide(); - ui->editStatusLabel->hide(); - ui->editLine1->hide(); - ui->editLine2->hide(); - ui->writeButton->show(); - ui->readButton->show(); - ui->editAddItemButton->hide(); - ui->editRemoveItemButton->hide(); - ui->editItemValueSpinBox->hide(); - ui->editItemNameLabel->hide(); - ui->itemValueLabel->hide(); - ui->itemNameLabel->hide(); - ui->nameLabel->show(); + ui->nameLabel->setVisible(!editMode); + ui->writeButton->setVisible(!editMode); + ui->readButton->setVisible(!editMode); + + ui->editInfoCheckBox->setVisible(editMode); + ui->editDoneButton->setVisible(editMode); + ui->editNameLabel->setVisible(editMode); + ui->editRefreshParamsButton->setVisible(editMode); + ui->editSelectParamComboBox->setVisible(editMode); + ui->editSelectComponentComboBox->setVisible(editMode); + ui->editStatusLabel->setVisible(editMode); + ui->writeButton->setVisible(!editMode); + ui->readButton->setVisible(!editMode); + ui->editLine1->setVisible(editMode); + ui->editLine2->setVisible(editMode); + ui->editAddItemButton->setVisible(editMode); + ui->editRemoveItemButton->setVisible(editMode); + ui->editItemValueSpinBox->setVisible(editMode); + ui->editItemNameLabel->setVisible(editMode); + ui->itemValueLabel->setVisible(editMode); + ui->itemNameLabel->setVisible(editMode); if (isDisabled) { - ui->editOptionComboBox->setEnabled(false); + ui->editOptionComboBox->setEnabled(editMode); } - isInEditMode = false; - emit editingFinished(); + + QGCToolWidgetItem::setEditMode(editMode); } void QGCComboBox::setParamPending() diff --git a/src/ui/designer/QGCComboBox.h b/src/ui/designer/QGCComboBox.h index 9b4b9c68a5..c81a636fee 100644 --- a/src/ui/designer/QGCComboBox.h +++ b/src/ui/designer/QGCComboBox.h @@ -22,9 +22,9 @@ public: explicit QGCComboBox(QWidget *parent = 0); ~QGCComboBox(); + virtual void setEditMode(bool editMode) override; + public slots: - void startEditMode(); - void endEditMode(); /** @brief Queue parameter for sending to the MAV (add to pending list)*/ void setParamPending(); /** @brief Update the UI with the new parameter value */ diff --git a/src/ui/designer/QGCCommandButton.cc b/src/ui/designer/QGCCommandButton.cc index 24bdc7d37e..69efc00607 100644 --- a/src/ui/designer/QGCCommandButton.cc +++ b/src/ui/designer/QGCCommandButton.cc @@ -159,93 +159,33 @@ void QGCCommandButton::setCommandButtonName(QString text) ui->commandButton->setText(text); } -void QGCCommandButton::startEditMode() +void QGCCommandButton::setEditMode(bool editMode) { // Hide elements - ui->commandButton->hide(); - ui->nameLabel->hide(); - - ui->editCommandComboBox->blockSignals(false); - ui->editCommandComboBox->show(); - ui->editFinishButton->show(); - ui->editNameLabel->show(); - ui->editButtonName->show(); - ui->editConfirmationCheckBox->show(); - ui->editComponentSpinBox->show(); - ui->editParamsVisibleCheckBox->show(); - ui->editParam1SpinBox->show(); - ui->editParam2SpinBox->show(); - ui->editParam3SpinBox->show(); - ui->editParam4SpinBox->show(); - ui->editParam5SpinBox->show(); - ui->editParam6SpinBox->show(); - ui->editParam7SpinBox->show(); - ui->editLine1->show(); - ui->editLine2->show(); - - // Attempt to undock the dock widget - QWidget* p = this; - QDockWidget* dock; - - do { - p = p->parentWidget(); - dock = dynamic_cast(p); - - if (dock) - { - dock->setFloating(true); - break; - } - } while (p && !dock); - - isInEditMode = true; -} - -void QGCCommandButton::endEditMode() -{ - ui->editCommandComboBox->blockSignals(true); - ui->editCommandComboBox->hide(); - ui->editFinishButton->hide(); - ui->editNameLabel->hide(); - ui->editButtonName->hide(); - ui->editConfirmationCheckBox->hide(); - ui->editComponentSpinBox->hide(); - ui->editParamsVisibleCheckBox->hide(); - ui->editLine1->hide(); - ui->editLine2->hide(); - if (!ui->editParamsVisibleCheckBox->isChecked()) - { - ui->editParam1SpinBox->hide(); - ui->editParam2SpinBox->hide(); - ui->editParam3SpinBox->hide(); - ui->editParam4SpinBox->hide(); - ui->editParam5SpinBox->hide(); - ui->editParam6SpinBox->hide(); - ui->editParam7SpinBox->hide(); - } - - ui->commandButton->show(); - ui->nameLabel->show(); - - // Write to settings - emit editingFinished(); - - // Attempt to dock the dock widget - QWidget* p = this; - QDockWidget* dock; - - do { - p = p->parentWidget(); - dock = dynamic_cast(p); - - if (dock) - { - dock->setFloating(false); - break; - } - } while (p && !dock); - - isInEditMode = false; + ui->commandButton->setVisible(!editMode); + ui->nameLabel->setVisible(!editMode); + + ui->editCommandComboBox->blockSignals(!editMode); + ui->editCommandComboBox->setVisible(editMode); + ui->editFinishButton->setVisible(editMode); + ui->editNameLabel->setVisible(editMode); + ui->editButtonName->setVisible(editMode); + ui->editConfirmationCheckBox->setVisible(editMode); + ui->editComponentSpinBox->setVisible(editMode); + ui->editParamsVisibleCheckBox->setVisible(editMode); + bool showParams = editMode || ui->editParamsVisibleCheckBox->isChecked(); + ui->editParam1SpinBox->setVisible(showParams); + ui->editParam2SpinBox->setVisible(showParams); + ui->editParam3SpinBox->setVisible(showParams); + ui->editParam4SpinBox->setVisible(showParams); + ui->editParam5SpinBox->setVisible(showParams); + ui->editParam6SpinBox->setVisible(showParams); + ui->editParam7SpinBox->setVisible(showParams); + + ui->editLine1->setVisible(editMode); + ui->editLine2->setVisible(editMode); + + QGCToolWidgetItem::setEditMode(editMode); } void QGCCommandButton::writeSettings(QSettings& settings) diff --git a/src/ui/designer/QGCCommandButton.h b/src/ui/designer/QGCCommandButton.h index 320cc97fba..a1c858a675 100644 --- a/src/ui/designer/QGCCommandButton.h +++ b/src/ui/designer/QGCCommandButton.h @@ -18,11 +18,11 @@ public: explicit QGCCommandButton(QWidget *parent = 0); ~QGCCommandButton(); + virtual void setEditMode(bool editMode) override; + public slots: void sendCommand(); void setCommandButtonName(QString text); - void startEditMode(); - void endEditMode(); void writeSettings(QSettings& settings); void readSettings(const QSettings& settings); void readSettings(const QString& pre,const QVariantMap& settings); diff --git a/src/ui/designer/QGCParamSlider.cc b/src/ui/designer/QGCParamSlider.cc index 6331ac7212..c5f2da52d9 100644 --- a/src/ui/designer/QGCParamSlider.cc +++ b/src/ui/designer/QGCParamSlider.cc @@ -207,74 +207,57 @@ void QGCParamSlider::selectParameter(int paramIndex) } } -void QGCParamSlider::startEditMode() +void QGCParamSlider::setEditMode(bool editMode) { - ui->valueSlider->hide(); - ui->doubleValueSpinBox->hide(); - ui->intValueSpinBox->hide(); - ui->nameLabel->hide(); - ui->writeButton->hide(); - ui->readButton->hide(); - - ui->editInfoCheckBox->show(); - ui->editDoneButton->show(); - ui->editNameLabel->show(); - ui->editRefreshParamsButton->show(); - ui->editSelectParamComboBox->show(); - ui->editSelectComponentComboBox->show(); - ui->editStatusLabel->show(); - ui->editMinSpinBox->show(); - ui->editMaxSpinBox->show(); - ui->writeButton->hide(); - ui->readButton->hide(); - ui->editLine1->show(); - ui->editLine2->show(); - isInEditMode = true; -} + if(!editMode) { + // Store component id + selectComponent(ui->editSelectComponentComboBox->currentIndex()); -void QGCParamSlider::endEditMode() -{ - // Store component id - selectComponent(ui->editSelectComponentComboBox->currentIndex()); + // Store parameter name and id + selectParameter(ui->editSelectParamComboBox->currentIndex()); - // Store parameter name and id - selectParameter(ui->editSelectParamComboBox->currentIndex()); - - // Min/max - parameterMin = ui->editMinSpinBox->value(); - parameterMax = ui->editMaxSpinBox->value(); + // Min/max + parameterMin = ui->editMinSpinBox->value(); + parameterMax = ui->editMaxSpinBox->value(); - ui->editInfoCheckBox->hide(); - ui->editDoneButton->hide(); - ui->editNameLabel->hide(); - ui->editRefreshParamsButton->hide(); - ui->editSelectParamComboBox->hide(); - ui->editSelectComponentComboBox->hide(); - ui->editStatusLabel->hide(); - ui->editMinSpinBox->hide(); - ui->editMaxSpinBox->hide(); - ui->editLine1->hide(); - ui->editLine2->hide(); - ui->writeButton->show(); - ui->readButton->show(); - ui->valueSlider->show(); - switch ((int)parameterValue.type()) - { - case QVariant::Char: - case QVariant::Int: - case QVariant::UInt: - ui->intValueSpinBox->show(); - break; - case QMetaType::Float: - ui->doubleValueSpinBox->show(); - break; - default: - qCritical() << "ERROR: NO VALID PARAM TYPE"; - return; + switch ((int)parameterValue.type()) + { + case QVariant::Char: + case QVariant::Int: + case QVariant::UInt: + ui->intValueSpinBox->show(); + break; + case QMetaType::Float: + ui->doubleValueSpinBox->show(); + break; + default: + qCritical() << "ERROR: NO VALID PARAM TYPE"; + return; + } + } else { + ui->doubleValueSpinBox->hide(); + ui->intValueSpinBox->hide(); } - ui->nameLabel->show(); - isInEditMode = false; - emit editingFinished(); + ui->valueSlider->setVisible(!editMode); + ui->nameLabel->setVisible(!editMode); + ui->writeButton->setVisible(!editMode); + ui->readButton->setVisible(!editMode); + + ui->editInfoCheckBox->setVisible(editMode); + ui->editDoneButton->setVisible(editMode); + ui->editNameLabel->setVisible(editMode); + ui->editRefreshParamsButton->setVisible(editMode); + ui->editSelectParamComboBox->setVisible(editMode); + ui->editSelectComponentComboBox->setVisible(editMode); + ui->editStatusLabel->setVisible(editMode); + ui->editMinSpinBox->setVisible(editMode); + ui->editMaxSpinBox->setVisible(editMode); + ui->writeButton->setVisible(!editMode); + ui->readButton->setVisible(!editMode); + ui->editLine1->setVisible(editMode); + ui->editLine2->setVisible(editMode); + + QGCToolWidgetItem::setEditMode(editMode); } void QGCParamSlider::setParamPending() diff --git a/src/ui/designer/QGCParamSlider.h b/src/ui/designer/QGCParamSlider.h index 74df0db05e..b5b5862d14 100644 --- a/src/ui/designer/QGCParamSlider.h +++ b/src/ui/designer/QGCParamSlider.h @@ -20,9 +20,9 @@ public: explicit QGCParamSlider(QWidget *parent = 0); ~QGCParamSlider(); + virtual void setEditMode(bool editMode) override; + public slots: - void startEditMode(); - void endEditMode(); /** @brief Queue parameter for sending to the MAV (add to pending list)*/ void setParamPending(); /** @brief Set the slider value as parameter value */ diff --git a/src/ui/designer/QGCRadioChannelDisplay.h b/src/ui/designer/QGCRadioChannelDisplay.h index 59bb65438a..2b90a946f5 100644 --- a/src/ui/designer/QGCRadioChannelDisplay.h +++ b/src/ui/designer/QGCRadioChannelDisplay.h @@ -20,6 +20,7 @@ public: int value() { return m_value; } int min() { return m_min; } int max() { return m_max; } + protected: void paintEvent(QPaintEvent *event); private: diff --git a/src/ui/designer/QGCTextLabel.cc b/src/ui/designer/QGCTextLabel.cc index ceb645ffcf..0a74c9d7f4 100644 --- a/src/ui/designer/QGCTextLabel.cc +++ b/src/ui/designer/QGCTextLabel.cc @@ -31,61 +31,17 @@ QGCTextLabel::~QGCTextLabel() delete ui; } -void QGCTextLabel::startEditMode() +void QGCTextLabel::setEditMode(bool editMode) { - // Hide elements - ui->editFinishButton->show(); - ui->editNameLabel->show(); - ui->editLine1->show(); - ui->editLine2->show(); - ui->isMavCommand->show(); - - // Attempt to undock the dock widget - QWidget* p = this; - QDockWidget* dock; - - do { - p = p->parentWidget(); - dock = dynamic_cast(p); - - if (dock) - { - dock->setFloating(true); - break; - } - } while (p && !dock); - - isInEditMode = true; -} - -void QGCTextLabel::endEditMode() -{ - update_isMavCommand(); - ui->editFinishButton->hide(); - ui->editNameLabel->hide(); - ui->editLine1->hide(); - ui->editLine2->hide(); - ui->isMavCommand->hide(); - - // Write to settings - emit editingFinished(); - - // Attempt to dock the dock widget - QWidget* p = this; - QDockWidget* dock; - - do { - p = p->parentWidget(); - dock = dynamic_cast(p); - - if (dock) - { - dock->setFloating(false); - break; - } - } while (p && !dock); - - isInEditMode = false; + if(!editMode) + update_isMavCommand(); + ui->editFinishButton->setVisible(editMode); + ui->editNameLabel->setVisible(editMode); + ui->editLine1->setVisible(editMode); + ui->editLine2->setVisible(editMode); + ui->isMavCommand->setVisible(editMode); + + QGCToolWidgetItem::setEditMode(editMode); } void QGCTextLabel::writeSettings(QSettings& settings) diff --git a/src/ui/designer/QGCTextLabel.h b/src/ui/designer/QGCTextLabel.h index a1c1d1d6cb..bc0a799cc8 100644 --- a/src/ui/designer/QGCTextLabel.h +++ b/src/ui/designer/QGCTextLabel.h @@ -19,9 +19,8 @@ public: ~QGCTextLabel(); void setActiveUAS(UASInterface *uas); void enableText(int num); + virtual void setEditMode(bool editMode) override; public slots: - void startEditMode(); - void endEditMode(); void writeSettings(QSettings& settings); void readSettings(const QSettings& settings); void readSettings(const QString& pre,const QVariantMap& settings); diff --git a/src/ui/designer/QGCToolWidgetItem.cc b/src/ui/designer/QGCToolWidgetItem.cc index d2a8c65905..236ae6e486 100644 --- a/src/ui/designer/QGCToolWidgetItem.cc +++ b/src/ui/designer/QGCToolWidgetItem.cc @@ -5,12 +5,13 @@ #include "QGCToolWidget.h" #include "UASManager.h" +#include QGCToolWidgetItem::QGCToolWidgetItem(const QString& name, QWidget *parent) : QWidget(parent), + uas(NULL), isInEditMode(false), qgcToolWidgetItemName(name), - uas(NULL), _component(-1) { startEditAction = new QAction(tr("Edit %1").arg(qgcToolWidgetItemName), this); @@ -49,3 +50,25 @@ void QGCToolWidgetItem::setActiveUAS(UASInterface *uas) { this->uas = uas; } + +void QGCToolWidgetItem::setEditMode(bool editMode) +{ + isInEditMode = editMode; + + // Attempt to undock the dock widget + QWidget* p = this; + QDockWidget* dock; + + do { + p = p->parentWidget(); + dock = dynamic_cast(p); + + if (dock) + { + dock->setFloating(editMode); + break; + } + } while (p && !dock); + + emit editingFinished(); +} diff --git a/src/ui/designer/QGCToolWidgetItem.h b/src/ui/designer/QGCToolWidgetItem.h index ac09123487..a3b9686109 100644 --- a/src/ui/designer/QGCToolWidgetItem.h +++ b/src/ui/designer/QGCToolWidgetItem.h @@ -18,9 +18,12 @@ public: return _component; } + virtual void setEditMode(bool editMode); + bool isEditMode() const { return isInEditMode; } public slots: - virtual void startEditMode() {} - virtual void endEditMode() {} + void startEditMode() { setEditMode(true); } + void endEditMode() { setEditMode(false); } + virtual void setComponent(int comp) { _component = comp; } @@ -33,15 +36,18 @@ signals: void editingFinished(); protected: + void contextMenuEvent (QContextMenuEvent* event); + UASInterface* uas; + +private: QAction* startEditAction; QAction* stopEditAction; QAction* deleteAction; bool isInEditMode; QString qgcToolWidgetItemName; - UASInterface* uas; int _component; ///< The MAV component (the process or device ID) - void contextMenuEvent (QContextMenuEvent* event); + }; -- GitLab From beb0ecfb98b5761e4857cfa9ee7081c30907475a Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sat, 19 Oct 2013 13:55:02 +0100 Subject: [PATCH 424/460] Fix minor const issues in QGCToolWidget --- src/ui/designer/QGCToolWidget.cc | 2 +- src/ui/designer/QGCToolWidget.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index eb02a12f37..9f8a49e99b 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -562,7 +562,7 @@ void QGCToolWidget::importWidget() loadSettings(fileName); } -const QString QGCToolWidget::getTitle() +QString QGCToolWidget::getTitle() const { return widgetTitle; } diff --git a/src/ui/designer/QGCToolWidget.h b/src/ui/designer/QGCToolWidget.h index 985f8595fe..8b2162003a 100644 --- a/src/ui/designer/QGCToolWidget.h +++ b/src/ui/designer/QGCToolWidget.h @@ -29,9 +29,9 @@ public: /** @brief All instances of this class */ static QMap* instances(); /** @brief Get title of widget */ - const QString getTitle(); + QString getTitle() const; - int isVisible(int view) { return viewVisible.value(view, false); } + int isVisible(int view) const { return viewVisible.value(view, false); } Qt::DockWidgetArea getDockWidgetArea(int view) { return dockWidgetArea.value(view, Qt::BottomDockWidgetArea); } void setParent(QWidget *parent); @@ -60,7 +60,7 @@ public: void setSettings(QVariantMap& settings); QList getParamList(); void setParameterValue(int uas, int component, QString parameterName, const QVariant value); - bool fromMetaData() { return isFromMetaData; } + bool fromMetaData() const { return isFromMetaData; } void showLabel(QString name,int num); signals: -- GitLab From 0e6411c7adc876218155c2e2b0668bc477c4a259 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sat, 19 Oct 2013 16:19:49 +0100 Subject: [PATCH 425/460] Fix setStyleText() to apply to future curves --- src/ui/linechart/IncrementalPlot.cc | 63 ++++++++++++++++------------- src/ui/linechart/IncrementalPlot.h | 6 ++- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/ui/linechart/IncrementalPlot.cc b/src/ui/linechart/IncrementalPlot.cc index 6a5e13f4de..5826d09d39 100644 --- a/src/ui/linechart/IncrementalPlot.cc +++ b/src/ui/linechart/IncrementalPlot.cc @@ -157,36 +157,43 @@ void IncrementalPlot::showLegend(bool show) */ void IncrementalPlot::setStyleText(const QString &style) { + styleText = style.toLower(); foreach (QwtPlotCurve* curve, curves) { - // Style of datapoints - if (style.toLower().contains("circles")) { - curve->setSymbol(QwtSymbol(QwtSymbol::Ellipse, - Qt::NoBrush, QPen(QBrush(curve->symbol().pen().color()), symbolWidth), QSize(6, 6)) ); - } else if (style.toLower().contains("crosses")) { - curve->setSymbol(QwtSymbol(QwtSymbol::XCross, - Qt::NoBrush, QPen(QBrush(curve->symbol().pen().color()), symbolWidth), QSize(5, 5)) ); - } else if (style.toLower().contains("rect")) { - curve->setSymbol(QwtSymbol(QwtSymbol::Rect, - Qt::NoBrush, QPen(QBrush(curve->symbol().pen().color()), symbolWidth), QSize(6, 6)) ); - } else if (style.toLower().contains("line")) { // Show no symbol - curve->setSymbol(QwtSymbol(QwtSymbol::NoSymbol, - Qt::NoBrush, QPen(QBrush(curve->symbol().pen().color()), symbolWidth), QSize(6, 6)) ); - } + updateStyle(curve); + } + replot(); +} - // Style of lines - if (style.toLower().contains("dotted")) { - curve->setPen(QPen(QBrush(curve->symbol().pen().color()), curveWidth, Qt::DotLine)); - } else if (style.toLower().contains("dashed")) { - curve->setPen(QPen(QBrush(curve->symbol().pen().color()), curveWidth, Qt::DashLine)); - } else if (style.toLower().contains("line") || style.toLower().contains("solid")) { - curve->setPen(QPen(QBrush(curve->symbol().pen().color()), curveWidth, Qt::SolidLine)); - } else { - curve->setPen(QPen(QBrush(curve->symbol().pen().color()), curveWidth, Qt::NoPen)); - } - curve->setStyle(QwtPlotCurve::Lines); +void IncrementalPlot::updateStyle(QwtPlotCurve *curve) +{ + if(styleText.isNull()) + return; + // Style of datapoints + if (styleText.contains("circles")) { + curve->setSymbol(QwtSymbol(QwtSymbol::Ellipse, + Qt::NoBrush, QPen(QBrush(curve->symbol().pen().color()), symbolWidth), QSize(6, 6)) ); + } else if (styleText.contains("crosses")) { + curve->setSymbol(QwtSymbol(QwtSymbol::XCross, + Qt::NoBrush, QPen(QBrush(curve->symbol().pen().color()), symbolWidth), QSize(5, 5)) ); + } else if (styleText.contains("rect")) { + curve->setSymbol(QwtSymbol(QwtSymbol::Rect, + Qt::NoBrush, QPen(QBrush(curve->symbol().pen().color()), symbolWidth), QSize(6, 6)) ); + } else if (styleText.contains("line")) { // Show no symbol + curve->setSymbol(QwtSymbol(QwtSymbol::NoSymbol, + Qt::NoBrush, QPen(QBrush(curve->symbol().pen().color()), symbolWidth), QSize(6, 6)) ); + } + // Style of lines + if (styleText.contains("dotted")) { + curve->setPen(QPen(QBrush(curve->symbol().pen().color()), curveWidth, Qt::DotLine)); + } else if (styleText.contains("dashed")) { + curve->setPen(QPen(QBrush(curve->symbol().pen().color()), curveWidth, Qt::DashLine)); + } else if (styleText.contains("line") || styleText.contains("solid")) { + curve->setPen(QPen(QBrush(curve->symbol().pen().color()), curveWidth, Qt::SolidLine)); + } else { + curve->setPen(QPen(QBrush(curve->symbol().pen().color()), curveWidth, Qt::NoPen)); } - replot(); + curve->setStyle(QwtPlotCurve::Lines); } void IncrementalPlot::resetScaling() @@ -275,7 +282,7 @@ void IncrementalPlot::appendData(const QString &key, double *x, double *y, int s const QColor &c = getNextColor(); curve->setSymbol(QwtSymbol(QwtSymbol::XCross, QBrush(c), QPen(c, symbolWidth), QSize(5, 5)) ); - + updateStyle(curve); //Apply any user-set style curve->attach(this); } else { curve = curves.value(key); @@ -374,7 +381,7 @@ void IncrementalPlot::showGrid(bool show) replot(); } -bool IncrementalPlot::gridEnabled() +bool IncrementalPlot::gridEnabled() const { return grid->isVisible(); } diff --git a/src/ui/linechart/IncrementalPlot.h b/src/ui/linechart/IncrementalPlot.h index 0b7f2d3b4f..cb9784ee7d 100644 --- a/src/ui/linechart/IncrementalPlot.h +++ b/src/ui/linechart/IncrementalPlot.h @@ -81,7 +81,7 @@ public: virtual ~IncrementalPlot(); /** @brief Get the state of the grid */ - bool gridEnabled(); + bool gridEnabled() const; /** @brief Read out data from a curve */ int data(const QString &key, double* r_x, double* r_y, int maxSize); @@ -125,10 +125,12 @@ protected: double xmax; ///< Maximum x value seen double ymin; ///< Minimum y value seen double ymax; ///< Maximum y value seen - + QString styleText; ///< Curve style set by setStyleText private: QMap d_data; ///< Data points + /** Helper function to apply styleText style to the given curve */ + void updateStyle(QwtPlotCurve *curve); }; #endif /* INCREMENTALPLOT_H */ -- GitLab From 00a7baae0338035eea22400a41e0eabc347b4361 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sun, 20 Oct 2013 01:27:26 +0100 Subject: [PATCH 426/460] Remove MainWindow styleChanged() signal There's no need to create multiple signals - connect() is fine with connecting styleChanged(MainWindow::QGC_MAINWINDOW_STYLE) to a slot with no parameters. --- src/ui/MainWindow.cc | 1 - src/ui/MainWindow.h | 1 - src/ui/linechart/LinechartWidget.cc | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index f3b8678c84..3eb6b8d8b9 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -1145,7 +1145,6 @@ bool MainWindow::loadStyle(QGC_MAINWINDOW_STYLE style, QString cssFile) // And trigger any changes to other UI elements that are watching for // theme changes. emit styleChanged(style); - emit styleChanged(); // Finally restore the cursor before returning. qApp->restoreOverrideCursor(); diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 9390d6fd2c..9d5cd528f4 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -300,7 +300,6 @@ protected slots: signals: void styleChanged(MainWindow::QGC_MAINWINDOW_STYLE newTheme); - void styleChanged(); void initStatusChanged(const QString& message, int alignment, const QColor &color); #ifdef MOUSE_ENABLED_LINUX /** @brief Forward X11Event to catch 3DMouse inputs */ diff --git a/src/ui/linechart/LinechartWidget.cc b/src/ui/linechart/LinechartWidget.cc index 39f68c8f2e..b6356be1c3 100644 --- a/src/ui/linechart/LinechartWidget.cc +++ b/src/ui/linechart/LinechartWidget.cc @@ -138,7 +138,7 @@ LinechartWidget::LinechartWidget(int systemid, QWidget *parent) : QWidget(parent createLayout(); // And make sure we're listening for future style changes - connect(MainWindow::instance(), SIGNAL(styleChanged()), this, SLOT(recolor())); + connect(MainWindow::instance(), SIGNAL(styleChanged(MainWindow::QGC_MAINWINDOW_STYLE)), this, SLOT(recolor())); updateTimer->setInterval(updateInterval); connect(updateTimer, SIGNAL(timeout()), this, SLOT(refresh())); -- GitLab From 6c59f5f4cb9e459fe05981c1aad017fb0c01b8b0 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sun, 13 Oct 2013 18:20:38 +0100 Subject: [PATCH 427/460] Add an XY plot widget This allows you to add XY graph plots of any data. For example, x,y position data of a servo. --- qgroundcontrol.pro | 5 +- src/ui/MainWindow.cc | 3 + src/ui/MainWindow.h | 3 + src/ui/designer/QGCToolWidget.cc | 21 ++ src/ui/designer/QGCToolWidget.h | 2 + src/ui/designer/QGCXYPlot.cc | 320 +++++++++++++++++++++++++++ src/ui/designer/QGCXYPlot.h | 50 +++++ src/ui/designer/QGCXYPlot.ui | 360 +++++++++++++++++++++++++++++++ 8 files changed, 763 insertions(+), 1 deletion(-) create mode 100644 src/ui/designer/QGCXYPlot.cc create mode 100644 src/ui/designer/QGCXYPlot.h create mode 100644 src/ui/designer/QGCXYPlot.ui diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index bf5ace6e15..e8940419a7 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -301,7 +301,8 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/ApmFirmwareConfig.ui \ src/ui/px4_configuration/QGCPX4AirframeConfig.ui \ src/ui/px4_configuration/QGCPX4MulticopterConfig.ui \ - src/ui/px4_configuration/QGCPX4SensorCalibration.ui + src/ui/px4_configuration/QGCPX4SensorCalibration.ui \ + src/ui/designer/QGCXYPlot.ui INCLUDEPATH += src \ src/ui \ @@ -506,6 +507,7 @@ HEADERS += src/MG.h \ src/ui/QGCBaseParamWidget.h \ src/ui/px4_configuration/QGCPX4MulticopterConfig.h \ src/ui/px4_configuration/QGCPX4SensorCalibration.h \ + src/ui/designer/QGCXYPlot.h \ src/ui/menuactionhelper.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler @@ -728,6 +730,7 @@ SOURCES += src/main.cc \ src/ui/QGCBaseParamWidget.cc \ src/ui/px4_configuration/QGCPX4MulticopterConfig.cc \ src/ui/px4_configuration/QGCPX4SensorCalibration.cc \ + src/ui/designer/QGCXYPlot.cc \ src/ui/menuactionhelper.cpp # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 3eb6b8d8b9..a958dc1ed9 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -480,6 +480,8 @@ void MainWindow::buildCommonWidgets() { // Add generic MAVLink decoder mavlinkDecoder = new MAVLinkDecoder(mavlink, this); + connect(mavlinkDecoder, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), + this, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64))); // Log player logPlayer = new QGCMAVLinkLogPlayer(mavlink, customStatusBar); @@ -1641,6 +1643,7 @@ void MainWindow::UASCreated(UASInterface* uas) connect(uas, SIGNAL(systemSpecsChanged(int)), this, SLOT(UASSpecsChanged(int))); + connect(uas, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), this, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64))); // HIL showHILConfigurationWidget(uas); diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 9d5cd528f4..cc98d0f167 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -301,6 +301,9 @@ protected slots: signals: void styleChanged(MainWindow::QGC_MAINWINDOW_STYLE newTheme); void initStatusChanged(const QString& message, int alignment, const QColor &color); + /** Emitted when any value changes from any source */ + void valueChanged(const int uasId, const QString& name, const QString& unit, const QVariant& value, const quint64 msec); + #ifdef MOUSE_ENABLED_LINUX /** @brief Forward X11Event to catch 3DMouse inputs */ void x11EventOccured(XEvent *event); diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index 9f8a49e99b..2eeae5b26f 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -13,6 +13,7 @@ #include "QGCParamSlider.h" #include "QGCComboBox.h" #include "QGCTextLabel.h" +#include "QGCXYPlot.h" #include "QGCCommandButton.h" #include "UASManager.h" @@ -272,6 +273,11 @@ void QGCToolWidget::loadSettings(QVariantMap& settings) item = new QGCComboBox(this); //qDebug() << "CREATED COMBOBOX"; } + else if (type == "XYPLOT") + { + item = new QGCXYPlot(this); + //qDebug() << "CREATED XYPlot"; + } if (item) { // Configure and add to layout @@ -330,6 +336,11 @@ void QGCToolWidget::loadSettings(QSettings& settings) item->setObjectName(settings.value("QGC_TEXT_ID").toString()); item->setActiveUAS(mav); } + else if (type == "XYPLOT") + { + item = new QGCXYPlot(this); + item->setActiveUAS(mav); + } if (item) { @@ -428,6 +439,7 @@ void QGCToolWidget::contextMenuEvent (QContextMenuEvent* event) menu.addAction(addParamAction); menu.addAction(addCommandAction); menu.addAction(addLabelAction); + menu.addAction(addPlotAction); menu.addSeparator(); menu.addAction(setTitleAction); menu.addAction(exportAction); @@ -467,6 +479,10 @@ void QGCToolWidget::createActions() addLabelAction->setStatusTip(tr("Add a new label to the tool")); connect(addLabelAction, SIGNAL(triggered()), this, SLOT(addLabel())); + addPlotAction = new QAction(tr("New &XY Plot"), this); + addPlotAction->setStatusTip(tr("Add a XY Plot to the tool")); + connect(addPlotAction, SIGNAL(triggered()), this, SLOT(addPlot())); + setTitleAction = new QAction(tr("Set Widget Title"), this); setTitleAction->setStatusTip(tr("Set the title caption of this tool widget")); connect(setTitleAction, SIGNAL(triggered()), this, SLOT(setTitle())); @@ -515,6 +531,11 @@ void QGCToolWidget::addLabel() addToolWidgetAndEdit(new QGCTextLabel(this)); } +void QGCToolWidget::addPlot() +{ + addToolWidgetAndEdit(new QGCXYPlot(this)); +} + void QGCToolWidget::addToolWidgetAndEdit(QGCToolWidgetItem* widget) { addToolWidget(widget); diff --git a/src/ui/designer/QGCToolWidget.h b/src/ui/designer/QGCToolWidget.h index 8b2162003a..7ab9ef679d 100644 --- a/src/ui/designer/QGCToolWidget.h +++ b/src/ui/designer/QGCToolWidget.h @@ -74,6 +74,7 @@ protected: QVariantMap settingsMap; QAction* addParamAction; QAction* addCommandAction; + QAction* addPlotAction; QAction* addLabelAction; QAction* setTitleAction; QAction* deleteAction; @@ -100,6 +101,7 @@ public slots: protected slots: void addParam(); void addCommand(); + void addPlot(); void addLabel(); void setTitle(); void widgetRemoved(); diff --git a/src/ui/designer/QGCXYPlot.cc b/src/ui/designer/QGCXYPlot.cc new file mode 100644 index 0000000000..cf433b00ba --- /dev/null +++ b/src/ui/designer/QGCXYPlot.cc @@ -0,0 +1,320 @@ +#include + +#include "QGCXYPlot.h" +#include "ui_QGCXYPlot.h" + +#include "MAVLinkProtocol.h" +#include "UASManager.h" +#include "IncrementalPlot.h" +#include +#include +#include +#include + +class XYPlotCurve : public QwtPlotItem +{ +public: + XYPlotCurve() { + m_maxPoints = 15; + setItemAttribute(QwtPlotItem::AutoScale); + minMaxSet = false; + m_color = Qt::white; + } + + void setMaxDataPoints(int max) { m_maxPoints = max; } + int maxPoints() const { return m_maxPoints; } + + void appendData(const QPointF &data) { + if(!minMaxSet) { + xmin = xmax = data.x(); + ymin = ymax = data.y(); + minMaxSet = true; + } else if(m_autoScale) { + xmin = qMin(xmin, data.x()); + xmax = qMax(xmax, data.x()); + ymin = qMin(ymin, data.y()); + ymax = qMax(ymax, data.y()); + } + + + m_data.append(data); + while(m_data.size() > m_maxPoints) + m_data.removeFirst(); + itemChanged(); + } + void clear() { + minMaxSet = false; + m_data.clear(); + itemChanged(); + } + void setColor(const QColor &color) { + m_color = color; + } + void unsetMinMax() { + if(m_autoScale) + return; + m_autoScale = true; + clear(); + } + void setMinMax(double xmin, double xmax, double ymin, double ymax ) + { + this->xmin = xmin; + this->xmax = xmax; + this->ymin = ymin; + this->ymax = ymax; + m_autoScale = false; + minMaxSet = true; + itemChanged(); + } + + double xMin() const { return xmin; } + double xMax() const { return xmax; } + double yMin() const { return ymin; } + double yMax() const { return ymax; } + + virtual QwtDoubleRect boundingRect() const { + if(!minMaxSet) + return QwtDoubleRect(1,1,-2,-2); + return QwtDoubleRect(xmin,ymin,xmax-xmin,ymax-ymin); + } + +protected: + /* From QwtPlotItem. Draw the complete series */ + virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRect &canvasRect) const + { + Q_UNUSED(canvasRect); + QPointF lastPoint; + int i = 0; + if(m_data.isEmpty()) + return; + int dataSize = m_data.size(); + + foreach(const QPointF &point, m_data) { + QPointF paintCoord = QPointF(xMap.xTransform(point.x()), yMap.xTransform(point.y())); + m_color.setAlpha((i+m_maxPoints - dataSize)*255/m_maxPoints); + p->setPen(m_color); + if(i++) + p->drawLine(lastPoint, paintCoord); + if(i == dataSize) { + //Draw marker for first point + const int marker_radius = 2; + QRectF marker = QRectF(paintCoord.x()-marker_radius, paintCoord.y()-marker_radius, marker_radius*2+1,marker_radius*2+1); + p->fillRect(marker,QBrush(m_color)); + } + lastPoint = paintCoord; + } + } + +private: + QList< QPointF > m_data; + int m_maxPoints; + mutable QColor m_color; + + double xmin; + double xmax; + double ymin; + double ymax; + bool minMaxSet; + bool m_autoScale; +}; + +QGCXYPlot::QGCXYPlot(QWidget *parent) : + QGCToolWidgetItem("XY Plot", parent), + ui(new Ui::QGCXYPlot), + plot(0), + xycurve(0), + maxElementsToDraw(5), + x(0), + x_timestamp_us(0), + x_valid(false), + y(0), + y_timestamp_us(0), + y_valid(false), + max_timestamp_diff_us(10000) /* Default to 10ms tolerance between x and y values */ + + +{ + uas = 0; + ui->setupUi(this); + plot = new QwtPlot(); + + QHBoxLayout* layout = new QHBoxLayout(ui->xyPlotFrame); + layout->addWidget(plot); + + connect(ui->editFinishButton, SIGNAL(clicked()), this, SLOT(endEditMode())); + + connect(MainWindow::instance(), SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), + this, SLOT(appendData(int,QString,QString,QVariant,quint64))); + + connect(ui->editXParam, SIGNAL(editTextChanged(QString)), this, SLOT(clearPlot())); + connect(ui->editYParam, SIGNAL(editTextChanged(QString)), this, SLOT(clearPlot())); + + plot->plotLayout()->setAlignCanvasToScales(true); + + QwtLinearScaleEngine* yScaleEngine = new QwtLinearScaleEngine(); + plot->setAxisScaleEngine(QwtPlot::yLeft, yScaleEngine); + + plot->setAxisAutoScale(QwtPlot::xBottom); + plot->setAxisAutoScale(QwtPlot::yLeft); + plot->setAutoReplot(); + xycurve = new XYPlotCurve(); + xycurve->attach(plot); + styleChanged(MainWindow::instance()->getStyle()); + connect(MainWindow::instance(), SIGNAL(styleChanged(MainWindow::QGC_MAINWINDOW_STYLE)), + this, SLOT(styleChanged(MainWindow::QGC_MAINWINDOW_STYLE))); + connect(ui->minX, SIGNAL(valueChanged(double)),this, SLOT(updateMinMaxSettings())); + connect(ui->maxX, SIGNAL(valueChanged(double)),this, SLOT(updateMinMaxSettings())); + connect(ui->minY, SIGNAL(valueChanged(double)),this, SLOT(updateMinMaxSettings())); + connect(ui->maxY, SIGNAL(valueChanged(double)),this, SLOT(updateMinMaxSettings())); + connect(ui->automaticAxisRange, SIGNAL(toggled(bool)),this, SLOT(updateMinMaxSettings())); + connect(ui->maxDataSpinBox, SIGNAL(valueChanged(int)),this, SLOT(updateMinMaxSettings())); + setEditMode(false); +} + +QGCXYPlot::~QGCXYPlot() +{ + delete ui; +} + +void QGCXYPlot::clearPlot() +{ + xycurve->clear(); + plot->clear(); +} + +void QGCXYPlot::setEditMode(bool editMode) +{ + ui->lblXParam->setVisible(editMode); + ui->lblYParam->setVisible(editMode); + ui->editXParam->setVisible(editMode); + ui->editYParam->setVisible(editMode); + ui->editFinishButton->setVisible(editMode); + ui->editLine1->setVisible(editMode); + ui->editLine2->setVisible(editMode); + ui->lblMaxData->setVisible(editMode); + ui->lblMaxX->setVisible(editMode); + ui->lblMaxY->setVisible(editMode); + ui->lblMinX->setVisible(editMode); + ui->lblMinY->setVisible(editMode); + ui->maxX->setVisible(editMode); + ui->maxY->setVisible(editMode); + ui->minX->setVisible(editMode); + ui->minY->setVisible(editMode); + ui->maxDataSpinBox->setVisible(editMode); + ui->automaticAxisRange->setVisible(editMode); + + if(!editMode) { + plot->setAxisTitle(QwtPlot::xBottom, ui->editXParam->currentText()); + plot->setAxisTitle(QwtPlot::yLeft, ui->editYParam->currentText()); + } + + QGCToolWidgetItem::setEditMode(editMode); + updateMinMaxSettings(); //Do this after calling the parent +} + +void QGCXYPlot::writeSettings(QSettings& settings) +{ + settings.setValue("TYPE", "XYPLOT"); + settings.setValue("QGC_XYPLOT_X", ui->editXParam->currentText()); + settings.setValue("QGC_XYPLOT_Y", ui->editYParam->currentText()); + settings.setValue("QGC_XYPLOT_MINX", ui->minX->value()); + settings.setValue("QGC_XYPLOT_MAXX", ui->maxX->value()); + settings.setValue("QGC_XYPLOT_MINY", ui->minY->value()); + settings.setValue("QGC_XYPLOT_MAXY", ui->maxY->value()); + settings.setValue("QGC_XYPLOT_MAXDATA", ui->maxDataSpinBox->value()); + settings.setValue("QGC_XYPLOT_AUTO", ui->automaticAxisRange->isChecked()); + + settings.sync(); +} +void QGCXYPlot::readSettings(const QString& pre,const QVariantMap& settings) +{ + ui->editXParam->setEditText(settings.value(pre + "QGC_XYPLOT_X", "").toString()); + ui->editYParam->setEditText(settings.value(pre + "QGC_XYPLOT_Y", "").toString()); + ui->automaticAxisRange->setChecked(settings.value(pre + "QGC_XYPLOT_AUTO", true).toBool()); + ui->minX->setValue(settings.value(pre + "QGC_XYPLOT_MINX", 0).toDouble()); + ui->maxX->setValue(settings.value(pre + "QGC_XYPLOT_MAXX", 0).toDouble()); + ui->minY->setValue(settings.value(pre + "QGC_XYPLOT_MINY", 0).toDouble()); + ui->maxY->setValue(settings.value(pre + "QGC_XYPLOT_MAXY", 0).toDouble()); + ui->maxDataSpinBox->setValue(settings.value(pre + "QGC_XYPLOT_MAXDATA", 15).toInt()); + plot->setAxisTitle(QwtPlot::xBottom, ui->editXParam->currentText()); + plot->setAxisTitle(QwtPlot::yLeft, ui->editYParam->currentText()); + updateMinMaxSettings(); +} + +void QGCXYPlot::readSettings(const QSettings& settings) +{ + ui->editXParam->setEditText(settings.value("QGC_XYPLOT_X", "").toString()); + ui->editYParam->setEditText(settings.value("QGC_XYPLOT_Y", "").toString()); + ui->automaticAxisRange->setChecked(settings.value("QGC_XYPLOT_AUTO", true).toBool()); + ui->minX->setValue(settings.value("QGC_XYPLOT_MINX", 0).toDouble()); + ui->maxX->setValue(settings.value("QGC_XYPLOT_MAXX", 0).toDouble()); + ui->minY->setValue(settings.value("QGC_XYPLOT_MINY", 0).toDouble()); + ui->maxY->setValue(settings.value("QGC_XYPLOT_MAXY", 0).toDouble()); + ui->maxDataSpinBox->setValue(settings.value("QGC_XYPLOT_MAXDATA", 15).toInt()); + plot->setAxisTitle(QwtPlot::xBottom, ui->editXParam->currentText()); + plot->setAxisTitle(QwtPlot::yLeft, ui->editYParam->currentText()); + updateMinMaxSettings(); +} + +void QGCXYPlot::appendData(int uasId, const QString& curve, const QString& unit, const QVariant& variant, quint64 usec) +{ + Q_UNUSED(uasId); + Q_UNUSED(unit); + if(isEditMode()) { + //When in edit mode, add all the items to the combo box + if(ui->editXParam->findText(curve) == -1) { + QString oldX = ui->editXParam->currentText(); + QString oldY = ui->editYParam->currentText(); + ui->editXParam->addItem(curve); //Annoyingly this can wipe out the current text + ui->editYParam->addItem(curve); + ui->editXParam->setEditText(oldX); + ui->editYParam->setEditText(oldY); + } + } + + bool ok; + if(curve == ui->editXParam->currentText()) { + x = variant.toDouble(&ok); + if(!ok) + return; + x_timestamp_us = usec; + x_valid = true; + } else if(curve == ui->editYParam->currentText()) { + y = variant.toDouble(&ok); + if(!ok) + return; + y_timestamp_us = usec; + y_valid = true; + } else + return; + + if(x_valid && y_valid && (int)qAbs(y_timestamp_us - x_timestamp_us) <= max_timestamp_diff_us) { + xycurve->appendData( QPointF(x,y) ); + plot->update(); + x_valid = false; + y_valid = false; + } +} + +void QGCXYPlot::styleChanged(MainWindow::QGC_MAINWINDOW_STYLE style) +{ + if (style == MainWindow::QGC_MAINWINDOW_STYLE_LIGHT) + xycurve->setColor(Qt::black); + else + xycurve->setColor(Qt::white); +} + +void QGCXYPlot::updateMinMaxSettings() +{ + bool automatic = ui->automaticAxisRange->isChecked(); + ui->minX->setEnabled(!automatic); + ui->maxX->setEnabled(!automatic); + ui->minY->setEnabled(!automatic); + ui->maxY->setEnabled(!automatic); + if(automatic) { + xycurve->unsetMinMax(); + } else { + xycurve->setMinMax(ui->minX->value(), ui->maxX->value(), ui->minY->value(), ui->maxY->value()); + } + xycurve->setMaxDataPoints(ui->maxDataSpinBox->value()); +} diff --git a/src/ui/designer/QGCXYPlot.h b/src/ui/designer/QGCXYPlot.h new file mode 100644 index 0000000000..23f7f1ec75 --- /dev/null +++ b/src/ui/designer/QGCXYPlot.h @@ -0,0 +1,50 @@ +#ifndef QGCXYPLOT_H +#define QGCXYPLOT_H + +#include "QGCToolWidgetItem.h" +#include "MainWindow.h" + +namespace Ui +{ +class QGCXYPlot; +} + +class UASInterface; +class QwtPlot; +class XYPlotCurve; + +class QGCXYPlot : public QGCToolWidgetItem +{ + Q_OBJECT + +public: + explicit QGCXYPlot(QWidget *parent = 0); + ~QGCXYPlot(); + virtual void setEditMode(bool editMode); + +public slots: + void writeSettings(QSettings& settings); + void readSettings(const QSettings& settings); + void readSettings(const QString& pre,const QVariantMap& settings); + void appendData(int uasId, const QString& curve, const QString& unit, const QVariant& variant, quint64 usec); + void clearPlot(); + void styleChanged(MainWindow::QGC_MAINWINDOW_STYLE style); + void updateMinMaxSettings(); + +private: + Ui::QGCXYPlot *ui; + QwtPlot *plot; + XYPlotCurve* xycurve; + + int maxElementsToDraw; + + double x; /**< Last unused value for the x-coordinate */ + quint64 x_timestamp_us; /**< Timestamp that we last recieved a value for x */ + bool x_valid; /**< Whether we have recieved an x value but so far no corresponding y value */ + double y; /**< Last unused value for the x-coordinate */ + quint64 y_timestamp_us; /**< Timestamp that we last recieved a value for x */ + bool y_valid; /**< Whether we have recieved an x value but so far no corresponding y value */ + int max_timestamp_diff_us; /**< Only combine x and y to a data point if the timestamp for both doesn't differ by more than this */ +}; + +#endif // QGCXYPLOT_H diff --git a/src/ui/designer/QGCXYPlot.ui b/src/ui/designer/QGCXYPlot.ui new file mode 100644 index 0000000000..3f9fb7fee6 --- /dev/null +++ b/src/ui/designer/QGCXYPlot.ui @@ -0,0 +1,360 @@ + + + QGCXYPlot + + + + 0 + 0 + 771 + 626 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 50 + 0 + + + + X Parameter: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + editXParam + + + + + + + + 0 + 0 + + + + true + + + QComboBox::InsertAlphabetically + + + QComboBox::AdjustToContents + + + 10 + + + + + + + + 50 + 0 + + + + Y Parameter: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + editYParam + + + + + + + + 0 + 0 + + + + true + + + QComboBox::InsertAlphabetically + + + QComboBox::AdjustToContents + + + 10 + + + + + + + + + + + Number of data points to &show: + + + maxDataSpinBox + + + + + + + 2 + + + 999 + + + 15 + + + + + + + Automatic Axis Range + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + &Min X: + + + minX + + + + + + + -999999999.000000000000000 + + + 999999999.000000000000000 + + + + + + + &Max X: + + + maxX + + + + + + + -999999999.000000000000000 + + + 999999999.000000000000000 + + + + + + + Min &Y: + + + minY + + + + + + + -999999999.000000000000000 + + + 999999999.000000000000000 + + + + + + + Ma&x Y: + + + maxY + + + + + + + -999999999.000000000000000 + + + 999999999.000000000000000 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 0 + + + + 0 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Done + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + editXParam + editYParam + maxDataSpinBox + minX + maxX + minY + maxY + editFinishButton + + + + -- GitLab From a40c8870a9789088af50deca162ff1228892ffe8 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sun, 20 Oct 2013 11:23:31 +0100 Subject: [PATCH 428/460] QGCXYPlot: Seperate the number of points shown and number of points store --- src/ui/designer/QGCXYPlot.cc | 58 +++++++++++++++++++++++------------- src/ui/designer/QGCXYPlot.h | 5 ++-- src/ui/designer/QGCXYPlot.ui | 35 ++++++++++++++++++---- 3 files changed, 70 insertions(+), 28 deletions(-) diff --git a/src/ui/designer/QGCXYPlot.cc b/src/ui/designer/QGCXYPlot.cc index cf433b00ba..b3bd9c5c98 100644 --- a/src/ui/designer/QGCXYPlot.cc +++ b/src/ui/designer/QGCXYPlot.cc @@ -15,14 +15,17 @@ class XYPlotCurve : public QwtPlotItem { public: XYPlotCurve() { - m_maxPoints = 15; + m_maxStorePoints = 10000; + m_maxShowPoints = 15; setItemAttribute(QwtPlotItem::AutoScale); minMaxSet = false; m_color = Qt::white; } - void setMaxDataPoints(int max) { m_maxPoints = max; } - int maxPoints() const { return m_maxPoints; } + void setMaxDataStorePoints(int max) { m_maxStorePoints = max; itemChanged(); } + void setMaxDataShowPoints(int max) { m_maxShowPoints = max; itemChanged(); } + int maxDataStorePoints() const { return m_maxStorePoints; } + int maxDataShowPoints() const { return m_maxShowPoints; } void appendData(const QPointF &data) { if(!minMaxSet) { @@ -36,9 +39,8 @@ public: ymax = qMax(ymax, data.y()); } - m_data.append(data); - while(m_data.size() > m_maxPoints) + while(m_data.size() > m_maxStorePoints) m_data.removeFirst(); itemChanged(); } @@ -84,18 +86,18 @@ protected: { Q_UNUSED(canvasRect); QPointF lastPoint; - int i = 0; if(m_data.isEmpty()) return; - int dataSize = m_data.size(); - - foreach(const QPointF &point, m_data) { + int start = qMax(0,m_data.size() - m_maxShowPoints); + int count = qMin(m_data.size()-start, m_maxShowPoints); + for(int i = 0; i < count; ++i) { + const QPointF &point = m_data.at(i+start); QPointF paintCoord = QPointF(xMap.xTransform(point.x()), yMap.xTransform(point.y())); - m_color.setAlpha((i+m_maxPoints - dataSize)*255/m_maxPoints); + m_color.setAlpha((m_maxShowPoints - count + i)*255/m_maxShowPoints); p->setPen(m_color); - if(i++) + if(i != 0) p->drawLine(lastPoint, paintCoord); - if(i == dataSize) { + if(i == count-1) { //Draw marker for first point const int marker_radius = 2; QRectF marker = QRectF(paintCoord.x()-marker_radius, paintCoord.y()-marker_radius, marker_radius*2+1,marker_radius*2+1); @@ -107,7 +109,8 @@ protected: private: QList< QPointF > m_data; - int m_maxPoints; + int m_maxStorePoints; + int m_maxShowPoints; mutable QColor m_color; double xmin; @@ -123,7 +126,6 @@ QGCXYPlot::QGCXYPlot(QWidget *parent) : ui(new Ui::QGCXYPlot), plot(0), xycurve(0), - maxElementsToDraw(5), x(0), x_timestamp_us(0), x_valid(false), @@ -167,7 +169,8 @@ QGCXYPlot::QGCXYPlot(QWidget *parent) : connect(ui->minY, SIGNAL(valueChanged(double)),this, SLOT(updateMinMaxSettings())); connect(ui->maxY, SIGNAL(valueChanged(double)),this, SLOT(updateMinMaxSettings())); connect(ui->automaticAxisRange, SIGNAL(toggled(bool)),this, SLOT(updateMinMaxSettings())); - connect(ui->maxDataSpinBox, SIGNAL(valueChanged(int)),this, SLOT(updateMinMaxSettings())); + connect(ui->maxDataShowSpinBox, SIGNAL(valueChanged(int)),this, SLOT(updateMinMaxSettings())); + connect(ui->maxDataStoreSpinBox, SIGNAL(valueChanged(int)),this, SLOT(updateMinMaxSettings())); setEditMode(false); } @@ -191,7 +194,8 @@ void QGCXYPlot::setEditMode(bool editMode) ui->editFinishButton->setVisible(editMode); ui->editLine1->setVisible(editMode); ui->editLine2->setVisible(editMode); - ui->lblMaxData->setVisible(editMode); + ui->lblMaxDataStore->setVisible(editMode); + ui->lblMaxDataShow->setVisible(editMode); ui->lblMaxX->setVisible(editMode); ui->lblMaxY->setVisible(editMode); ui->lblMinX->setVisible(editMode); @@ -200,7 +204,8 @@ void QGCXYPlot::setEditMode(bool editMode) ui->maxY->setVisible(editMode); ui->minX->setVisible(editMode); ui->minY->setVisible(editMode); - ui->maxDataSpinBox->setVisible(editMode); + ui->maxDataShowSpinBox->setVisible(editMode); + ui->maxDataStoreSpinBox->setVisible(editMode); ui->automaticAxisRange->setVisible(editMode); if(!editMode) { @@ -221,7 +226,8 @@ void QGCXYPlot::writeSettings(QSettings& settings) settings.setValue("QGC_XYPLOT_MAXX", ui->maxX->value()); settings.setValue("QGC_XYPLOT_MINY", ui->minY->value()); settings.setValue("QGC_XYPLOT_MAXY", ui->maxY->value()); - settings.setValue("QGC_XYPLOT_MAXDATA", ui->maxDataSpinBox->value()); + settings.setValue("QGC_XYPLOT_MAXDATA_STORE", ui->maxDataStoreSpinBox->value()); + settings.setValue("QGC_XYPLOT_MAXDATA_SHOW", ui->maxDataShowSpinBox->value()); settings.setValue("QGC_XYPLOT_AUTO", ui->automaticAxisRange->isChecked()); settings.sync(); @@ -235,7 +241,8 @@ void QGCXYPlot::readSettings(const QString& pre,const QVariantMap& settings) ui->maxX->setValue(settings.value(pre + "QGC_XYPLOT_MAXX", 0).toDouble()); ui->minY->setValue(settings.value(pre + "QGC_XYPLOT_MINY", 0).toDouble()); ui->maxY->setValue(settings.value(pre + "QGC_XYPLOT_MAXY", 0).toDouble()); - ui->maxDataSpinBox->setValue(settings.value(pre + "QGC_XYPLOT_MAXDATA", 15).toInt()); + ui->maxDataStoreSpinBox->setValue(settings.value(pre + "QGC_XYPLOT_MAXDATA_STORE", 10000).toInt()); + ui->maxDataShowSpinBox->setValue(settings.value(pre + "QGC_XYPLOT_MAXDATA_SHOW", 15).toInt()); plot->setAxisTitle(QwtPlot::xBottom, ui->editXParam->currentText()); plot->setAxisTitle(QwtPlot::yLeft, ui->editYParam->currentText()); updateMinMaxSettings(); @@ -250,7 +257,8 @@ void QGCXYPlot::readSettings(const QSettings& settings) ui->maxX->setValue(settings.value("QGC_XYPLOT_MAXX", 0).toDouble()); ui->minY->setValue(settings.value("QGC_XYPLOT_MINY", 0).toDouble()); ui->maxY->setValue(settings.value("QGC_XYPLOT_MAXY", 0).toDouble()); - ui->maxDataSpinBox->setValue(settings.value("QGC_XYPLOT_MAXDATA", 15).toInt()); + ui->maxDataStoreSpinBox->setValue(settings.value("QGC_XYPLOT_MAXDATA_STORE", 10000).toInt()); + ui->maxDataShowSpinBox->setValue(settings.value("QGC_XYPLOT_MAXDATA_SHOW", 15).toInt()); plot->setAxisTitle(QwtPlot::xBottom, ui->editXParam->currentText()); plot->setAxisTitle(QwtPlot::yLeft, ui->editYParam->currentText()); updateMinMaxSettings(); @@ -316,5 +324,13 @@ void QGCXYPlot::updateMinMaxSettings() } else { xycurve->setMinMax(ui->minX->value(), ui->maxX->value(), ui->minY->value(), ui->maxY->value()); } - xycurve->setMaxDataPoints(ui->maxDataSpinBox->value()); + xycurve->setMaxDataStorePoints(ui->maxDataStoreSpinBox->value()); + xycurve->setMaxDataShowPoints(ui->maxDataShowSpinBox->value()); +} + +void QGCXYPlot::on_maxDataShowSpinBox_valueChanged(int value) +{ + ui->maxDataStoreSpinBox->setMinimum(value); + if(ui->maxDataStoreSpinBox->value() < value) + ui->maxDataStoreSpinBox->setValue(value); } diff --git a/src/ui/designer/QGCXYPlot.h b/src/ui/designer/QGCXYPlot.h index 23f7f1ec75..8cef9bbd42 100644 --- a/src/ui/designer/QGCXYPlot.h +++ b/src/ui/designer/QGCXYPlot.h @@ -31,13 +31,14 @@ public slots: void styleChanged(MainWindow::QGC_MAINWINDOW_STYLE style); void updateMinMaxSettings(); +private slots: + void on_maxDataShowSpinBox_valueChanged(int value); + private: Ui::QGCXYPlot *ui; QwtPlot *plot; XYPlotCurve* xycurve; - int maxElementsToDraw; - double x; /**< Last unused value for the x-coordinate */ quint64 x_timestamp_us; /**< Timestamp that we last recieved a value for x */ bool x_valid; /**< Whether we have recieved an x value but so far no corresponding y value */ diff --git a/src/ui/designer/QGCXYPlot.ui b/src/ui/designer/QGCXYPlot.ui index 3f9fb7fee6..11d27b5a63 100644 --- a/src/ui/designer/QGCXYPlot.ui +++ b/src/ui/designer/QGCXYPlot.ui @@ -7,7 +7,7 @@ 0 0 771 - 626 + 365 @@ -145,17 +145,17 @@ - + Number of data points to &show: - maxDataSpinBox + maxDataShowSpinBox - + 2 @@ -167,6 +167,29 @@ + + + + To s&tore: + + + maxDataStoreSpinBox + + + + + + + 10 + + + 999999999 + + + 15 + + + @@ -348,7 +371,9 @@ editXParam editYParam - maxDataSpinBox + maxDataShowSpinBox + maxDataStoreSpinBox + automaticAxisRange minX maxX minY -- GitLab From 45c61a29bb7ba71c74ecf148a7b4cf190751ce49 Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Sun, 20 Oct 2013 11:26:45 +0200 Subject: [PATCH 429/460] flightgear hil: correct scaling of pressure for mavlink message and remove indicated airspeed from flightgear protocol, commit requires flightgear protocol update --- .../Protocol/qgroundcontrol-fixed-wing.xml | 8 ----- src/comm/QGCFlightGearLink.cc | 29 ++++++++++++++----- src/uas/UAS.cc | 4 +++ 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/files/flightgear/Protocol/qgroundcontrol-fixed-wing.xml b/files/flightgear/Protocol/qgroundcontrol-fixed-wing.xml index 5fe0ad2b0c..0ecbf20d5d 100644 --- a/files/flightgear/Protocol/qgroundcontrol-fixed-wing.xml +++ b/files/flightgear/Protocol/qgroundcontrol-fixed-wing.xml @@ -142,14 +142,6 @@ 0.514444444444444 - - airspeed-indicated-mps - float - %.8f - /instrumentation/indicated-speed-kt - 0.514444444444444 - - Magnetic Variation (rad) diff --git a/src/comm/QGCFlightGearLink.cc b/src/comm/QGCFlightGearLink.cc index d8bc240ee3..108f8d11ac 100644 --- a/src/comm/QGCFlightGearLink.cc +++ b/src/comm/QGCFlightGearLink.cc @@ -235,9 +235,10 @@ void QGCFlightGearLink::readBytes() QStringList values = state.split("\t"); // Check length - if (values.size() != 22) + const int nValues = 21; + if (values.size() != nValues) { - qDebug() << "RETURN LENGTH MISMATCHING EXPECTED" << 22 << "BUT GOT" << values.size(); + qDebug() << "RETURN LENGTH MISMATCHING EXPECTED" << nValues << "BUT GOT" << values.size(); qDebug() << state; return; } @@ -273,13 +274,12 @@ void QGCFlightGearLink::readBytes() vz = values.at(15).toFloat(); true_airspeed = values.at(16).toFloat(); - ind_airspeed = values.at(17).toFloat(); - mag_variation = values.at(18).toFloat(); - mag_dip = values.at(19).toFloat(); + mag_variation = values.at(17).toFloat(); + mag_dip = values.at(18).toFloat(); - temperature = values.at(20).toFloat(); - abs_pressure = values.at(21).toFloat(); + temperature = values.at(19).toFloat(); + abs_pressure = values.at(20).toFloat()*1e2; //convert to Pa from hPa // Send updated state //qDebug() << "sensorHilEnabled: " << sensorHilEnabled; @@ -292,6 +292,19 @@ void QGCFlightGearLink::readBytes() const float absolute_null_celsius = -273.15f; // °C float density = abs_pressure / (air_gas_constant * (temperature - absolute_null_celsius)); diff_pressure = true_airspeed * true_airspeed * density / 2.0f; + //qDebug() << "diff_pressure: " << diff_pressure << "abs_pressure: " << abs_pressure; + + /* Calculate indicated airspeed */ + const float air_density_sea_level_15C = 1.225f; //kg/m^3 + if (diff_pressure > 0) + { + ind_airspeed = sqrtf((2.0f*diff_pressure) / air_density_sea_level_15C); + } else + { + ind_airspeed = -sqrtf((2.0f*fabsf(diff_pressure)) / air_density_sea_level_15C); + } + + //qDebug() << "ind_airspeed: " << ind_airspeed << "true_airspeed: " << true_airspeed; float pressure_alt = alt; @@ -336,7 +349,7 @@ void QGCFlightGearLink::readBytes() zmag_body = mag_body(2); emit sensorHilRawImuChanged(QGC::groundTimeUsecs(), xacc, yacc, zacc, rollspeed, pitchspeed, yawspeed, - xmag_body, ymag_body, zmag_body, abs_pressure, diff_pressure, pressure_alt, temperature, fields_changed); + xmag_body, ymag_body, zmag_body, abs_pressure*1e-2f, diff_pressure*1e-2f, pressure_alt, temperature, fields_changed); //Pressure in hPa for mavlink // qDebug() << "sensorHilRawImuChanged " << xacc << yacc << zacc << rollspeed << pitchspeed << yawspeed << xmag << ymag << zmag << abs_pressure << diff_pressure << pressure_alt << temperature; int gps_fix_type = 3; diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 94d73f1edc..e50e1dc761 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -3124,6 +3124,10 @@ void UAS::sendHilState(quint64 time_us, float roll, float pitch, float yaw, floa } } +/* +* @param abs_pressure Absolute Pressure (hPa) +* @param diff_pressure Differential Pressure (hPa) +*/ void UAS::sendHilSensors(quint64 time_us, float xacc, float yacc, float zacc, float rollspeed, float pitchspeed, float yawspeed, float xmag, float ymag, float zmag, float abs_pressure, float diff_pressure, float pressure_alt, float temperature, quint32 fields_changed) { -- GitLab From 8966a49f2a060e1803b9d8b529db9acb2e01df78 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sun, 20 Oct 2013 22:12:10 +0100 Subject: [PATCH 430/460] QGCXYPlot: Add smoothing ability to smooth the last N points of data --- src/ui/designer/QGCXYPlot.cc | 28 +++++++++++++++++++++++++++- src/ui/designer/QGCXYPlot.ui | 27 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/ui/designer/QGCXYPlot.cc b/src/ui/designer/QGCXYPlot.cc index b3bd9c5c98..949b00e017 100644 --- a/src/ui/designer/QGCXYPlot.cc +++ b/src/ui/designer/QGCXYPlot.cc @@ -20,12 +20,15 @@ public: setItemAttribute(QwtPlotItem::AutoScale); minMaxSet = false; m_color = Qt::white; + m_smoothPoints = 1; } void setMaxDataStorePoints(int max) { m_maxStorePoints = max; itemChanged(); } void setMaxDataShowPoints(int max) { m_maxShowPoints = max; itemChanged(); } + void setSmoothPoints(int smoothPoints) { m_smoothPoints = smoothPoints; itemChanged(); } int maxDataStorePoints() const { return m_maxStorePoints; } int maxDataShowPoints() const { return m_maxShowPoints; } + int smoothPoints() const { return m_smoothPoints; } void appendData(const QPointF &data) { if(!minMaxSet) { @@ -88,10 +91,25 @@ protected: QPointF lastPoint; if(m_data.isEmpty()) return; + QPointF smoothTotal(0,0); + int smoothCount = 0; int start = qMax(0,m_data.size() - m_maxShowPoints); int count = qMin(m_data.size()-start, m_maxShowPoints); + for(int i = qMax(0,start - m_smoothPoints); i < start; ++i) { + smoothTotal += m_data.at(i); + ++smoothCount; + } for(int i = 0; i < count; ++i) { - const QPointF &point = m_data.at(i+start); + QPointF point = m_data.at(i+start); + if(m_smoothPoints > 1) { + smoothTotal += point; + if(smoothCount >= m_smoothPoints) { + Q_ASSERT(i + start - m_smoothPoints >= 0); + smoothTotal -= m_data.at(i + start - m_smoothPoints); + } else + ++smoothCount; + point = smoothTotal/smoothCount; + } QPointF paintCoord = QPointF(xMap.xTransform(point.x()), yMap.xTransform(point.y())); m_color.setAlpha((m_maxShowPoints - count + i)*255/m_maxShowPoints); p->setPen(m_color); @@ -111,6 +129,7 @@ private: QList< QPointF > m_data; int m_maxStorePoints; int m_maxShowPoints; + int m_smoothPoints; /** Number of points to average across */ mutable QColor m_color; double xmin; @@ -171,6 +190,7 @@ QGCXYPlot::QGCXYPlot(QWidget *parent) : connect(ui->automaticAxisRange, SIGNAL(toggled(bool)),this, SLOT(updateMinMaxSettings())); connect(ui->maxDataShowSpinBox, SIGNAL(valueChanged(int)),this, SLOT(updateMinMaxSettings())); connect(ui->maxDataStoreSpinBox, SIGNAL(valueChanged(int)),this, SLOT(updateMinMaxSettings())); + connect(ui->smoothSpinBox, SIGNAL(valueChanged(int)),this, SLOT(updateMinMaxSettings())); setEditMode(false); } @@ -207,6 +227,8 @@ void QGCXYPlot::setEditMode(bool editMode) ui->maxDataShowSpinBox->setVisible(editMode); ui->maxDataStoreSpinBox->setVisible(editMode); ui->automaticAxisRange->setVisible(editMode); + ui->lblSmooth->setVisible(editMode); + ui->smoothSpinBox->setVisible(editMode); if(!editMode) { plot->setAxisTitle(QwtPlot::xBottom, ui->editXParam->currentText()); @@ -229,6 +251,7 @@ void QGCXYPlot::writeSettings(QSettings& settings) settings.setValue("QGC_XYPLOT_MAXDATA_STORE", ui->maxDataStoreSpinBox->value()); settings.setValue("QGC_XYPLOT_MAXDATA_SHOW", ui->maxDataShowSpinBox->value()); settings.setValue("QGC_XYPLOT_AUTO", ui->automaticAxisRange->isChecked()); + settings.setValue("QGC_XYPLOT_SMOOTH", ui->smoothSpinBox->value()); settings.sync(); } @@ -243,6 +266,7 @@ void QGCXYPlot::readSettings(const QString& pre,const QVariantMap& settings) ui->maxY->setValue(settings.value(pre + "QGC_XYPLOT_MAXY", 0).toDouble()); ui->maxDataStoreSpinBox->setValue(settings.value(pre + "QGC_XYPLOT_MAXDATA_STORE", 10000).toInt()); ui->maxDataShowSpinBox->setValue(settings.value(pre + "QGC_XYPLOT_MAXDATA_SHOW", 15).toInt()); + ui->smoothSpinBox->setValue(settings.value(pre + "QGC_XYPLOT_SMOOTH", 1).toInt()); plot->setAxisTitle(QwtPlot::xBottom, ui->editXParam->currentText()); plot->setAxisTitle(QwtPlot::yLeft, ui->editYParam->currentText()); updateMinMaxSettings(); @@ -259,6 +283,7 @@ void QGCXYPlot::readSettings(const QSettings& settings) ui->maxY->setValue(settings.value("QGC_XYPLOT_MAXY", 0).toDouble()); ui->maxDataStoreSpinBox->setValue(settings.value("QGC_XYPLOT_MAXDATA_STORE", 10000).toInt()); ui->maxDataShowSpinBox->setValue(settings.value("QGC_XYPLOT_MAXDATA_SHOW", 15).toInt()); + ui->smoothSpinBox->setValue(settings.value("QGC_XYPLOT_SMOOTH", 1).toInt()); plot->setAxisTitle(QwtPlot::xBottom, ui->editXParam->currentText()); plot->setAxisTitle(QwtPlot::yLeft, ui->editYParam->currentText()); updateMinMaxSettings(); @@ -326,6 +351,7 @@ void QGCXYPlot::updateMinMaxSettings() } xycurve->setMaxDataStorePoints(ui->maxDataStoreSpinBox->value()); xycurve->setMaxDataShowPoints(ui->maxDataShowSpinBox->value()); + xycurve->setSmoothPoints(ui->smoothSpinBox->value()); } void QGCXYPlot::on_maxDataShowSpinBox_valueChanged(int value) diff --git a/src/ui/designer/QGCXYPlot.ui b/src/ui/designer/QGCXYPlot.ui index 11d27b5a63..a232bd5554 100644 --- a/src/ui/designer/QGCXYPlot.ui +++ b/src/ui/designer/QGCXYPlot.ui @@ -190,6 +190,32 @@ + + + + Number of points to average, to provide a smoothing effect of the plotted values + + + S&mooth: + + + smoothSpinBox + + + + + + + Number of points to average, to provide a smoothing effect of the plotted values + + + 1 + + + 99999 + + + @@ -373,6 +399,7 @@ editYParam maxDataShowSpinBox maxDataStoreSpinBox + smoothSpinBox automaticAxisRange minX maxX -- GitLab From 7f0fa6140099d561eba3932d43273dd418e6f8d6 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Sun, 20 Oct 2013 22:26:30 +0100 Subject: [PATCH 431/460] QGCXYPlot: Clean up layout a bit --- src/ui/designer/QGCXYPlot.cc | 3 +-- src/ui/designer/QGCXYPlot.ui | 30 +++++++++++++++++++++--------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/ui/designer/QGCXYPlot.cc b/src/ui/designer/QGCXYPlot.cc index 949b00e017..db2d47b14f 100644 --- a/src/ui/designer/QGCXYPlot.cc +++ b/src/ui/designer/QGCXYPlot.cc @@ -159,8 +159,7 @@ QGCXYPlot::QGCXYPlot(QWidget *parent) : ui->setupUi(this); plot = new QwtPlot(); - QHBoxLayout* layout = new QHBoxLayout(ui->xyPlotFrame); - layout->addWidget(plot); + ui->xyPlotLayout->addWidget(plot); connect(ui->editFinishButton, SIGNAL(clicked()), this, SLOT(endEditMode())); diff --git a/src/ui/designer/QGCXYPlot.ui b/src/ui/designer/QGCXYPlot.ui index a232bd5554..48f8c5673f 100644 --- a/src/ui/designer/QGCXYPlot.ui +++ b/src/ui/designer/QGCXYPlot.ui @@ -14,6 +14,9 @@ Form + + 0 + 0 @@ -41,6 +44,9 @@ + + 0 + @@ -56,6 +62,9 @@ + + 0 + @@ -343,17 +352,14 @@ - - - - 0 - 0 - - - + + 0 - + + QLayout::SetMinimumSize + + @@ -375,6 +381,12 @@ Done + + false + + + true + -- GitLab From 403104dd016cbc77873ab233aa4726131fa61476 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Mon, 21 Oct 2013 01:51:31 +0100 Subject: [PATCH 432/460] Allow user to stop and start the plot, and scroll back in time --- src/ui/designer/QGCXYPlot.cc | 79 ++++++++++++++++++++++++++++++++---- src/ui/designer/QGCXYPlot.h | 3 ++ src/ui/designer/QGCXYPlot.ui | 55 +++++++++++++++++++++++-- 3 files changed, 127 insertions(+), 10 deletions(-) diff --git a/src/ui/designer/QGCXYPlot.cc b/src/ui/designer/QGCXYPlot.cc index db2d47b14f..58fcb0ea02 100644 --- a/src/ui/designer/QGCXYPlot.cc +++ b/src/ui/designer/QGCXYPlot.cc @@ -21,6 +21,7 @@ public: minMaxSet = false; m_color = Qt::white; m_smoothPoints = 1; + m_startIndex = -1; //Disable } void setMaxDataStorePoints(int max) { m_maxStorePoints = max; itemChanged(); } @@ -30,7 +31,8 @@ public: int maxDataShowPoints() const { return m_maxShowPoints; } int smoothPoints() const { return m_smoothPoints; } - void appendData(const QPointF &data) { + /** Append data, returning the number of removed items */ + int appendData(const QPointF &data) { if(!minMaxSet) { xmin = xmax = data.x(); ymin = ymax = data.y(); @@ -43,9 +45,13 @@ public: } m_data.append(data); - while(m_data.size() > m_maxStorePoints) + int removed = 0; + while(m_data.size() > m_maxStorePoints) { + ++removed; m_data.removeFirst(); + } itemChanged(); + return removed; } void clear() { minMaxSet = false; @@ -59,7 +65,20 @@ public: if(m_autoScale) return; m_autoScale = true; - clear(); + //Recalculate the automatic scale + if(m_data.isEmpty()) + minMaxSet = false; + else { + minMaxSet = true; + xmax = xmin = m_data.at(0).x(); + ymax = ymin = m_data.at(0).y(); + for(int i = 1; i < m_data.size(); i++) { + xmin = qMin(xmin, m_data.at(i).x()); + xmax = qMax(xmax, m_data.at(i).x()); + ymin = qMin(ymin, m_data.at(i).y()); + ymax = qMax(ymax, m_data.at(i).y()); + } + } } void setMinMax(double xmin, double xmax, double ymin, double ymax ) { @@ -71,6 +90,11 @@ public: minMaxSet = true; itemChanged(); } + void setStartIndex(int time) { /** Set to -1 to just use latest */ + m_startIndex = time; + itemChanged(); + } + int dataSize() const { return m_data.size(); } double xMin() const { return xmin; } double xMax() const { return xmax; } @@ -93,8 +117,16 @@ protected: return; QPointF smoothTotal(0,0); int smoothCount = 0; - int start = qMax(0,m_data.size() - m_maxShowPoints); - int count = qMin(m_data.size()-start, m_maxShowPoints); + int start; + int count; + if(m_startIndex >= 0) { + int end = qMin(m_startIndex, m_data.size()-1); + start = qBound(0, end - m_maxShowPoints, m_data.size()-1); + count = end - start; + } else { + start = qMax(0,m_data.size() - m_maxShowPoints); + count = qMin(m_data.size()-start, m_maxShowPoints); + } for(int i = qMax(0,start - m_smoothPoints); i < start; ++i) { smoothTotal += m_data.at(i); ++smoothCount; @@ -138,6 +170,7 @@ private: double ymax; bool minMaxSet; bool m_autoScale; + int m_startIndex; }; QGCXYPlot::QGCXYPlot(QWidget *parent) : @@ -202,6 +235,8 @@ void QGCXYPlot::clearPlot() { xycurve->clear(); plot->clear(); + ui->timeScrollBar->setMaximum(xycurve->dataSize()); + ui->timeScrollBar->setValue(ui->timeScrollBar->maximum()); } void QGCXYPlot::setEditMode(bool editMode) @@ -295,15 +330,22 @@ void QGCXYPlot::appendData(int uasId, const QString& curve, const QString& unit, if(isEditMode()) { //When in edit mode, add all the items to the combo box if(ui->editXParam->findText(curve) == -1) { + ui->editXParam->blockSignals(true); + ui->editYParam->blockSignals(true); QString oldX = ui->editXParam->currentText(); QString oldY = ui->editYParam->currentText(); ui->editXParam->addItem(curve); //Annoyingly this can wipe out the current text ui->editYParam->addItem(curve); ui->editXParam->setEditText(oldX); ui->editYParam->setEditText(oldY); + ui->editXParam->blockSignals(false); + ui->editYParam->blockSignals(false); } } + if(ui->stopStartButton->isChecked()) + return; + bool ok; if(curve == ui->editXParam->currentText()) { x = variant.toDouble(&ok); @@ -321,10 +363,19 @@ void QGCXYPlot::appendData(int uasId, const QString& curve, const QString& unit, return; if(x_valid && y_valid && (int)qAbs(y_timestamp_us - x_timestamp_us) <= max_timestamp_diff_us) { - xycurve->appendData( QPointF(x,y) ); - plot->update(); + int removed = xycurve->appendData( QPointF(x,y) ); x_valid = false; y_valid = false; + bool atMaximum = (ui->timeScrollBar->value() == ui->timeScrollBar->maximum()); + if(ui->timeScrollBar->maximum() != xycurve->dataSize()) { + ui->timeScrollBar->setMaximum(xycurve->dataSize()); + if(atMaximum) + ui->timeScrollBar->setValue(ui->timeScrollBar->maximum()); + } else if(!atMaximum) { //Move the scrollbar to keep current value selected + int value = qMax(ui->timeScrollBar->minimum(), ui->timeScrollBar->value() - removed); + ui->timeScrollBar->setValue(value); + xycurve->setStartIndex(value); + } } } @@ -359,3 +410,17 @@ void QGCXYPlot::on_maxDataShowSpinBox_valueChanged(int value) if(ui->maxDataStoreSpinBox->value() < value) ui->maxDataStoreSpinBox->setValue(value); } + +void QGCXYPlot::on_stopStartButton_toggled(bool checked) +{ + if(!checked) + clearPlot(); +} + +void QGCXYPlot::on_timeScrollBar_valueChanged(int value) +{ + if(value == ui->timeScrollBar->maximum()) + xycurve->setStartIndex(-1); + else + xycurve->setStartIndex(value); +} diff --git a/src/ui/designer/QGCXYPlot.h b/src/ui/designer/QGCXYPlot.h index 8cef9bbd42..77159d6823 100644 --- a/src/ui/designer/QGCXYPlot.h +++ b/src/ui/designer/QGCXYPlot.h @@ -33,6 +33,9 @@ public slots: private slots: void on_maxDataShowSpinBox_valueChanged(int value); + void on_stopStartButton_toggled(bool checked); + + void on_timeScrollBar_valueChanged(int value); private: Ui::QGCXYPlot *ui; diff --git a/src/ui/designer/QGCXYPlot.ui b/src/ui/designer/QGCXYPlot.ui index 48f8c5673f..ab96595175 100644 --- a/src/ui/designer/QGCXYPlot.ui +++ b/src/ui/designer/QGCXYPlot.ui @@ -356,9 +356,56 @@ 0 - - QLayout::SetMinimumSize + + + + + + 6 + + + + + 0 + 0 + + + + 2 + + + true + + + Qt::Horizontal + + + + + + + + :/files/images/actions/media-playback-stop.svg + :/files/images/actions/media-playback-start.svg:/files/images/actions/media-playback-stop.svg + + + + 16 + 16 + + + + true + + + false + + + false + + + @@ -419,6 +466,8 @@ maxY editFinishButton - + + + -- GitLab From 854b9cbdce17ed207a1dae3bbe7c024b89e9b23b Mon Sep 17 00:00:00 2001 From: Anton Babushkin Date: Tue, 22 Oct 2013 15:42:32 +0200 Subject: [PATCH 433/460] Calibration fixes --- .../images/px4/calibration/3dr_gps/gps_05.png | Bin 72523 -> 0 bytes .../images/px4/calibration/3dr_gps/gps_06.png | Bin 61146 -> 72523 bytes .../images/px4/calibration/3dr_gps/gps_07.png | Bin 0 -> 61146 bytes qgroundcontrol.qrc | 2 +- .../QGCPX4SensorCalibration.cc | 139 ++++++------------ .../QGCPX4SensorCalibration.h | 5 - 6 files changed, 42 insertions(+), 104 deletions(-) delete mode 100644 files/images/px4/calibration/3dr_gps/gps_05.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_07.png diff --git a/files/images/px4/calibration/3dr_gps/gps_05.png b/files/images/px4/calibration/3dr_gps/gps_05.png deleted file mode 100644 index f4c909906ed59c37f07c1767dc7694f01113dee0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72523 zcmeAS@N?(olHy`uVBq!ia0y~yV69+aVEMzr#=yW}8T-PQfq{Xg*vT`5gM)*kh9jke zfq{Xuz$3Dl0S4wKsTnaaC@^@sIEGZ*dUJPUk#zXH7Z2?<`r0OBbS|;EFzd=S)->}F z_PQo-rk%}qIfQo}o1DL4W<;>~y0wMt*l+AjOg9hk^R8oJdvPXObywM(1m8$gbGetV*dr%lZd1EohV zFD~DH$)wlBx4r&lxqJNcnGabQ7`pr(urj2@sCPw5L214FSpNY}w<7jvIn;&zt*yi|PO-b3@Rc66l8 zTJ}}v^rG8upUwZT$2M{M;{pZ-23N%oObnMdNj`VE8~pmEo&B!fU}dFQk<+eTHj(Aq zD<~M>eu0~TL8RdTH$%+wa~F?iy50>0`DMWdmNu3UBmuuU{^0I6JU>N}5Z~(o8Loi;X=Wurk

_PkXpSjEWDuu`Ccalsz5#Wu5-#4d+8?faLu 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 z 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 J%Q~loCIFRuGg1Hm diff --git a/files/images/px4/calibration/3dr_gps/gps_06.png b/files/images/px4/calibration/3dr_gps/gps_06.png index 021fcd497b627e85dfe2eef7e1e9a6d7407819e8..f4c909906ed59c37f07c1767dc7694f01113dee0 100644 GIT binary patch literal 72523 zcmeAS@N?(olHy`uVBq!ia0y~yV69+aVEMzr#=yW}8T-PQfq{Xg*vT`5gM)*kh9jke zfq{Xuz$3Dl0S4wKsTnaaC@^@sIEGZ*dUJPUk#zXH7Z2?<`r0OBbS|;EFzd=S)->}F z_PQo-rk%}qIfQo}o1DL4W<;>~y0wMt*l+AjOg9hk^R8oJdvPXObywM(1m8$gbGetV*dr%lZd1EohV zFD~DH$)wlBx4r&lxqJNcnGabQ7`pr(urj2@sCPw5L214FSpNY}w<7jvIn;&zt*yi|PO-b3@Rc66l8 zTJ}}v^rG8upUwZT$2M{M;{pZ-23N%oObnMdNj`VE8~pmEo&B!fU}dFQk<+eTHj(Aq zD<~M>eu0~TL8RdTH$%+wa~F?iy50>0`DMWdmNu3UBmuuU{^0I6JU>N}5Z~(o8Loi;X=Wurk

_PkXpSjEWDuu`Ccalsz5#Wu5-#4d+8?faLu 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 z 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 J%Q~loCIFRuGg1Hm literal 61146 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 diff --git a/files/images/px4/calibration/3dr_gps/gps_07.png b/files/images/px4/calibration/3dr_gps/gps_07.png new file mode 100644 index 0000000000000000000000000000000000000000..021fcd497b627e85dfe2eef7e1e9a6d7407819e8 GIT binary patch literal 61146 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 literal 0 HcmV?d00001 diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index f6e42aa5e5..4ba6ddc2e5 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -190,8 +190,8 @@ files/images/px4/calibration/3dr_gps/gps_18.png files/images/px4/calibration/3dr_gps/gps_17.png files/images/px4/calibration/3dr_gps/gps_16.png + files/images/px4/calibration/3dr_gps/gps_07.png files/images/px4/calibration/3dr_gps/gps_06.png - files/images/px4/calibration/3dr_gps/gps_05.png files/images/px4/calibration/3dr_gps/gps_04.png files/images/px4/calibration/3dr_gps/gps_03.png files/images/px4/calibration/3dr_gps/gps_02.png diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc index dcb4b12d3a..5b64bbaa7c 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc @@ -9,19 +9,8 @@ QGCPX4SensorCalibration::QGCPX4SensorCalibration(QWidget *parent) : QWidget(parent), activeUAS(NULL), clearAction(new QAction(tr("Clear Text"), this)), - accelStarted(false), - gyroStarted(false), - magStarted(false), ui(new Ui::QGCPX4SensorCalibration) { - accelAxes << "x+"; - accelAxes << "x-"; - accelAxes << "y+"; - accelAxes << "y-"; - accelAxes << "z+"; - accelAxes << "z-"; - - ui->setupUi(this); connect(clearAction, SIGNAL(triggered()), ui->textView, SLOT(clear())); @@ -333,10 +322,8 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever text.startsWith("[mavlink pm]")) return; - if (text.contains("progress")) { - qDebug() << "PROGRESS:" << text; + if (text.contains("progress <")) { QString percent = text.split("<").last().split(">").first(); - qDebug() << "PERCENT CANDIDATE" << percent; bool ok; int p = percent.toInt(&ok); if (ok) @@ -346,97 +333,64 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever ui->instructionLabel->setText(QString("%1").arg(text)); - - if (text.contains("accel")) { - qDebug() << "ACCEL" << text; - - if (text.startsWith("accel measurement started: ")) { - QString axis = text.split("measurement started: ").last().left(2); - qDebug() << "AXIS" << axis << "STR" << text; - setInstructionImage(QString(":/files/images/px4/calibration/accel_%1.png").arg(axis)); - - } - } - - if (text.startsWith("directions left")) { - for (int i = 0; i < 6; i++) - { - if (!text.contains(accelAxes[i])) { - qDebug() << "FINISHED" << accelAxes[i]; - accelDone[i] = true; - } - } + if (text.startsWith("accel measurement started: ")) { + QString axis = text.split("measurement started: ").last().left(2); + setInstructionImage(QString(":/files/images/px4/calibration/accel_%1.png").arg(axis)); } - if (text.startsWith("result for")) { - - QString axis = text.split("result for ").last().left(2); - - qDebug() << "ACCELDONE AXIS" << axis << "STR" << text; - - for (int i = 0; i < 6; i++) - { - if (axis == accelAxes[i]) - accelDone[i] = true; - - if (!accelDone[i]) { - qDebug() << "NEW AXIS: " << accelAxes[i]; - setInstructionImage(QString(":/files/images/px4/calibration/accel_%1.png").arg(accelAxes[i])); - ui->instructionLabel->setText(tr("Axis %1 completed. Please rotate like shown here.").arg(axis)); - break; - } - } + if (text.startsWith("directions left: ")) { + QString axis = text.split("directions left: ").last().left(2); + setInstructionImage(QString(":/files/images/px4/calibration/accel_%1.png").arg(axis)); } - if (text.contains("please rotate in a figure 8")) { + if (text == "rotate in a figure 8") { setInstructionImage(":/files/images/px4/calibration/mag_calibration_figure8.png"); } - if (text.contains("accel calibration done")) { - accelStarted = false; + if (text.endsWith(" calibration: done") || text.endsWith(" calibration: failed")) { // XXX use a confirmation image or something setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); - if (activeUAS) { - activeUAS->requestParameter(0, "SENS_ACC_XOFF"); - activeUAS->requestParameter(0, "SENS_BOARD_ROT"); + if (text.endsWith(" calibration: done")) { + ui->progressBar->setValue(100); + } else { + ui->progressBar->setValue(0); } - } - - if (text.contains("gyro calibration done")) { - gyroStarted = false; - // XXX use a confirmation image or something - setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); - if (activeUAS) - activeUAS->requestParameter(0, "SENS_GYRO_XOFF"); - } - if (text.contains("mag calibration done") - || text.contains("magnetometer calibration completed")) { - magStarted = false; - // XXX use a confirmation image or something - setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); if (activeUAS) { - activeUAS->requestParameter(0, "SENS_MAG_XOFF"); - activeUAS->requestParameter(0, "SENS_EXT_MAG_ROT"); + if (text.startsWith("accel ")) { + activeUAS->requestParameter(0, "SENS_ACC_XOFF"); + activeUAS->requestParameter(0, "SENS_ACC_YOFF"); + activeUAS->requestParameter(0, "SENS_ACC_ZOFF"); + activeUAS->requestParameter(0, "SENS_ACC_XSCALE"); + activeUAS->requestParameter(0, "SENS_ACC_YSCALE"); + activeUAS->requestParameter(0, "SENS_ACC_ZSCALE"); + activeUAS->requestParameter(0, "SENS_BOARD_ROT"); + } + if (text.startsWith("gyro ")) { + activeUAS->requestParameter(0, "SENS_GYRO_XOFF"); + activeUAS->requestParameter(0, "SENS_GYRO_YOFF"); + activeUAS->requestParameter(0, "SENS_GYRO_ZOFF"); + activeUAS->requestParameter(0, "SENS_GYRO_XSCALE"); + activeUAS->requestParameter(0, "SENS_GYRO_YSCALE"); + activeUAS->requestParameter(0, "SENS_GYRO_ZSCALE"); + activeUAS->requestParameter(0, "SENS_BOARD_ROT"); + } + if (text.startsWith("mag ")) { + activeUAS->requestParameter(0, "SENS_MAG_XOFF"); + activeUAS->requestParameter(0, "SENS_MAG_YOFF"); + activeUAS->requestParameter(0, "SENS_MAG_ZOFF"); + activeUAS->requestParameter(0, "SENS_MAG_XSCALE"); + activeUAS->requestParameter(0, "SENS_MAG_YSCALE"); + activeUAS->requestParameter(0, "SENS_MAG_ZSCALE"); + activeUAS->requestParameter(0, "SENS_EXT_MAG_ROT"); + } } } - if (text.contains("accel calibration started")) { - accelStarted = true; - setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); - } - - if (text.contains("gyro calibration started")) { - gyroStarted = true; + if (text.endsWith(" calibration: started")) { setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); } - if (text.contains("mag calibration started")) { - magStarted = false; - setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); - } - - // XXX color messages according to severity QPlainTextEdit *msgWidget = ui->textView; @@ -457,7 +411,6 @@ void QGCPX4SensorCalibration::gyroButtonClicked() setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); activeUAS->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); ui->progressBar->setValue(0); - ui->instructionLabel->setText(tr("Please do not move the system at all.")); } void QGCPX4SensorCalibration::magButtonClicked() @@ -465,7 +418,6 @@ void QGCPX4SensorCalibration::magButtonClicked() setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); activeUAS->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); ui->progressBar->setValue(0); - ui->instructionLabel->setText(tr("Please put the system in a rest position.")); } void QGCPX4SensorCalibration::accelButtonClicked() @@ -473,15 +425,6 @@ void QGCPX4SensorCalibration::accelButtonClicked() setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); activeUAS->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0); ui->progressBar->setValue(0); - accelStarted = true; - accelDone[0] = false; - accelDone[1] = false; - accelDone[2] = false; - accelDone[3] = false; - accelDone[4] = false; - accelDone[5] = false; - - ui->instructionLabel->setText(tr("Please hold the system very still in the shown orientations.")); } void QGCPX4SensorCalibration::contextMenuEvent(QContextMenuEvent* event) diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.h b/src/ui/px4_configuration/QGCPX4SensorCalibration.h index 35d0dc2fd8..fecb8b8b27 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.h +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.h @@ -64,11 +64,6 @@ protected: QPixmap instructionIcon; QPixmap autopilotIcon; QPixmap gpsIcon; - bool accelStarted; - bool accelDone[6]; - bool gyroStarted; - bool magStarted; - QStringList accelAxes; virtual void resizeEvent(QResizeEvent* event); -- GitLab From b28c86af155a309d896107060c6ea80aa612a0da Mon Sep 17 00:00:00 2001 From: Anton Babushkin Date: Tue, 22 Oct 2013 22:36:35 +0200 Subject: [PATCH 434/460] Mag calibration message parsing fix --- src/ui/px4_configuration/QGCPX4SensorCalibration.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc index 5b64bbaa7c..c479d55251 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc @@ -343,7 +343,7 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever setInstructionImage(QString(":/files/images/px4/calibration/accel_%1.png").arg(axis)); } - if (text == "rotate in a figure 8") { + if (text == "rotate in a figure 8 around all axis") { setInstructionImage(":/files/images/px4/calibration/mag_calibration_figure8.png"); } -- GitLab From 126b51bed5765279b0743a82a9add69658dcfae7 Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Wed, 23 Oct 2013 11:45:43 +0200 Subject: [PATCH 435/460] fw hil: fixed indentation --- src/comm/QGCFlightGearLink.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/comm/QGCFlightGearLink.cc b/src/comm/QGCFlightGearLink.cc index 108f8d11ac..7926fa28c2 100644 --- a/src/comm/QGCFlightGearLink.cc +++ b/src/comm/QGCFlightGearLink.cc @@ -298,11 +298,11 @@ void QGCFlightGearLink::readBytes() const float air_density_sea_level_15C = 1.225f; //kg/m^3 if (diff_pressure > 0) { - ind_airspeed = sqrtf((2.0f*diff_pressure) / air_density_sea_level_15C); - } else - { - ind_airspeed = -sqrtf((2.0f*fabsf(diff_pressure)) / air_density_sea_level_15C); - } + ind_airspeed = sqrtf((2.0f*diff_pressure) / air_density_sea_level_15C); + } else + { + ind_airspeed = -sqrtf((2.0f*fabsf(diff_pressure)) / air_density_sea_level_15C); + } //qDebug() << "ind_airspeed: " << ind_airspeed << "true_airspeed: " << true_airspeed; -- GitLab From 8e3f46f6984b28a7544fddcc3828f12f85d62efe Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Wed, 23 Oct 2013 13:44:23 +0200 Subject: [PATCH 436/460] add textbox for filtering --- src/ui/Linechart.ui | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/ui/Linechart.ui b/src/ui/Linechart.ui index 4a6a23e5ce..944063ae30 100644 --- a/src/ui/Linechart.ui +++ b/src/ui/Linechart.ui @@ -47,7 +47,7 @@ 10 - + 6 @@ -103,14 +103,14 @@ 0 0 - 884 - 491 + 948 + 454 - + 2 @@ -218,6 +218,9 @@ + + + -- GitLab From bd9e85c9d69a81263667bc215c3c97def3432595 Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Wed, 23 Oct 2013 20:43:41 +0200 Subject: [PATCH 437/460] basic filter functionality --- src/ui/linechart/LinechartWidget.cc | 46 ++++++++++++++++++++++++++++- src/ui/linechart/LinechartWidget.h | 8 ++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/ui/linechart/LinechartWidget.cc b/src/ui/linechart/LinechartWidget.cc index 39f68c8f2e..fd38214221 100644 --- a/src/ui/linechart/LinechartWidget.cc +++ b/src/ui/linechart/LinechartWidget.cc @@ -26,7 +26,7 @@ This file is part of the PIXHAWK project * @brief Line chart plot widget * * @author Lorenz Meier - * + * @author Thomas Gubler */ #include @@ -105,6 +105,7 @@ LinechartWidget::LinechartWidget(int systemid, QWidget *parent) : QWidget(parent connect(ui.recolorButton, SIGNAL(clicked()), this, SLOT(recolor())); connect(ui.shortNameCheckBox, SIGNAL(clicked(bool)), this, SLOT(setShortNames(bool))); + connect(ui.plotFilterLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(filterCurves(const QString&))); int labelRow = curvesWidgetLayout->rowCount(); @@ -564,6 +565,7 @@ void LinechartWidget::addCurve(const QString& curve, const QString& unit) checkBox->setObjectName(curve+unit); checkBox->setToolTip(tr("Enable the curve in the graph window")); checkBox->setWhatsThis(tr("Enable the curve in the graph window")); + checkBoxes.insert(curve+unit, checkBox); curvesWidgetLayout->addWidget(checkBox, labelRow, 0); // Icon @@ -593,6 +595,7 @@ void LinechartWidget::addCurve(const QString& curve, const QString& unit) unitLabel->setText(unit); unitLabel->setToolTip(tr("Unit of ") + curve); unitLabel->setWhatsThis(tr("Unit of ") + curve); + curveUnits.insert(curve+unit, unitLabel); curvesWidgetLayout->addWidget(unitLabel, labelRow, 4); unitLabel->setVisible(ui.showUnitsCheckBox->isChecked()); connect(ui.showUnitsCheckBox, SIGNAL(clicked(bool)), unitLabel, SLOT(setVisible(bool))); @@ -691,6 +694,47 @@ void LinechartWidget::recolor() } } +void LinechartWidget::filterCurve(const QString &key, bool match) +{ + colorIcons[key]->setVisible(match); + curveNameLabels[key]->setVisible(match); + (*curveLabels)[key]->setVisible(match); + (*curveMeans)[key]->setVisible(match); + (*curveVariances)[key]->setVisible(match); + curveUnits[key]->setVisible(match); + checkBoxes[key]->setVisible(match); +} + +void LinechartWidget::filterCurves(const QString &filter) +{ + //qDebug() << "filterCurves: filter: " << filter; + + if (filter != "") + { + /* Hide Elements which do not match the filter pattern */ + QStringMatcher stringMatcher(filter, Qt::CaseInsensitive); + foreach (QString key, colorIcons.keys()) + { + if (stringMatcher.indexIn(key) < 0) + { + filterCurve(key, false); + } + else + { + filterCurve(key, true); + } + } + } + else + { + /* Show all Elements */ + foreach (QString key, colorIcons.keys()) + { + filterCurve(key, true); + } + } +} + QString LinechartWidget::getCurveName(const QString& key, bool shortEnabled) { if (shortEnabled) diff --git a/src/ui/linechart/LinechartWidget.h b/src/ui/linechart/LinechartWidget.h index 4640f2c191..e7fcf7048d 100644 --- a/src/ui/linechart/LinechartWidget.h +++ b/src/ui/linechart/LinechartWidget.h @@ -26,7 +26,7 @@ This file is part of the PIXHAWK project * @brief Definition of Line chart plot widget * * @author Lorenz Meier - * + * @author Thomas Gubler */ #ifndef LINECHARTWIDGET_H #define LINECHARTWIDGET_H @@ -79,6 +79,8 @@ public slots: void setShortNames(bool enable); /** @brief Append data to the given curve. */ void appendData(int uasId, const QString& curve, const QString& unit, const QVariant& value, quint64 usec); + /** @brief Hide curves which do not match the filter pattern */ + void filterCurves(const QString &filter); void toggleLogarithmicScaling(bool toggled); void takeButtonClick(bool checked); @@ -110,6 +112,8 @@ public slots: private slots: /** Called when the user changes the time scale combobox. */ void timeScaleChanged(int index); + /** @brief Applies action on curve corresponding to key based on the bool match. I used to filter curves */ + void filterCurve(const QString &key, bool match); protected: void addCurveToList(QString curve); @@ -132,9 +136,11 @@ protected: QMap curveNames; ///< Full curve names QMap* curveMeans; ///< References to the curve means QMap* curveMedians; ///< References to the curve medians + QMap curveUnits; ///< References to the curve units QMap* curveVariances; ///< References to the curve variances QMap intData; ///< Current values for integer-valued curves QMap colorIcons; ///< Reference to color icons + QMap checkBoxes; ///< Reference to checkboxes QWidget* curvesWidget; ///< The QWidget containing the curve selection button QGridLayout* curvesWidgetLayout; ///< The layout for the curvesWidget QWidget -- GitLab From 6e882d9570838c2ecf38a1c2119b96b574c246b4 Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Wed, 23 Oct 2013 20:58:08 +0200 Subject: [PATCH 438/460] set placeholderText plotFilterLineEdit --- src/ui/Linechart.ui | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ui/Linechart.ui b/src/ui/Linechart.ui index 944063ae30..794c32a3a0 100644 --- a/src/ui/Linechart.ui +++ b/src/ui/Linechart.ui @@ -219,7 +219,11 @@ - + + + Filter... + + -- GitLab From 878ba466e5b63c47113980f3f24c433bdf8658f9 Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Wed, 23 Oct 2013 21:46:16 +0200 Subject: [PATCH 439/460] add keyboard shortcut for plot filtering --- src/ui/Linechart.ui | 2 +- src/ui/linechart/LinechartWidget.cc | 6 ++++++ src/ui/linechart/LinechartWidget.h | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ui/Linechart.ui b/src/ui/Linechart.ui index 794c32a3a0..382720d5ff 100644 --- a/src/ui/Linechart.ui +++ b/src/ui/Linechart.ui @@ -221,7 +221,7 @@ - Filter... + Filter... (Ctrl+F) diff --git a/src/ui/linechart/LinechartWidget.cc b/src/ui/linechart/LinechartWidget.cc index fd38214221..00750f9171 100644 --- a/src/ui/linechart/LinechartWidget.cc +++ b/src/ui/linechart/LinechartWidget.cc @@ -106,6 +106,7 @@ LinechartWidget::LinechartWidget(int systemid, QWidget *parent) : QWidget(parent connect(ui.recolorButton, SIGNAL(clicked()), this, SLOT(recolor())); connect(ui.shortNameCheckBox, SIGNAL(clicked(bool)), this, SLOT(setShortNames(bool))); connect(ui.plotFilterLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(filterCurves(const QString&))); + new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F), this, SLOT(setPlotFilterLineEditFocus())); int labelRow = curvesWidgetLayout->rowCount(); @@ -694,6 +695,11 @@ void LinechartWidget::recolor() } } +void LinechartWidget::setPlotFilterLineEditFocus() +{ + ui.plotFilterLineEdit->setFocus(Qt::ShortcutFocusReason); +} + void LinechartWidget::filterCurve(const QString &key, bool match) { colorIcons[key]->setVisible(match); diff --git a/src/ui/linechart/LinechartWidget.h b/src/ui/linechart/LinechartWidget.h index e7fcf7048d..12fe58494e 100644 --- a/src/ui/linechart/LinechartWidget.h +++ b/src/ui/linechart/LinechartWidget.h @@ -108,6 +108,8 @@ public slots: void readSettings(); /** @brief Select all curves */ void selectAllCurves(bool all); + /** @brief Sets the focus to the LineEdit for plot-filtering */ + void setPlotFilterLineEditFocus(); private slots: /** Called when the user changes the time scale combobox. */ -- GitLab From 52d4181c1433dd6dbeca4d77a95228a60cb50ed1 Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Wed, 23 Oct 2013 21:58:49 +0200 Subject: [PATCH 440/460] better placement of filtering LineEdit --- src/ui/Linechart.ui | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ui/Linechart.ui b/src/ui/Linechart.ui index 382720d5ff..a46a506911 100644 --- a/src/ui/Linechart.ui +++ b/src/ui/Linechart.ui @@ -47,7 +47,7 @@ 10 - + 6 @@ -103,18 +103,25 @@ 0 0 - 948 - 454 + 884 + 491 - + 2 + + + + Filter... (Ctrl+F) + + + @@ -218,13 +225,6 @@ - - - - Filter... (Ctrl+F) - - - -- GitLab From ee32097e0b66e13e5537392c452bdbe0b38e099b Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Fri, 25 Oct 2013 12:11:24 +0200 Subject: [PATCH 441/460] LinechartWidget: fix removal of curves --- src/ui/linechart/LinechartWidget.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ui/linechart/LinechartWidget.cc b/src/ui/linechart/LinechartWidget.cc index 00750f9171..7017a5c542 100644 --- a/src/ui/linechart/LinechartWidget.cc +++ b/src/ui/linechart/LinechartWidget.cc @@ -673,9 +673,19 @@ void LinechartWidget::removeCurve(QString curve) widget = curveVariances->take(curve); curvesWidgetLayout->removeWidget(widget); widget->deleteLater(); -// widget = colorIcons->take(curve); -// curvesWidgetLayout->removeWidget(colorIcons->take(curve)); + widget = colorIcons.take(curve); + curvesWidgetLayout->removeWidget(widget); + widget->deleteLater(); + widget = curveNameLabels.take(curve); + curvesWidgetLayout->removeWidget(widget); + widget->deleteLater(); + widget = curveUnits.take(curve); + curvesWidgetLayout->removeWidget(widget); widget->deleteLater(); + QCheckBox* checkbox; + checkbox = checkBoxes.take(curve); + curvesWidgetLayout->removeWidget(checkbox); + checkbox->deleteLater(); // intData->remove(curve); } -- GitLab From 942a02c96b2e4b15dd80f6a27779f59bdafe01d5 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 28 Oct 2013 14:32:48 +0100 Subject: [PATCH 442/460] Added code style tool --- tools/fix_code_style.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100755 tools/fix_code_style.sh diff --git a/tools/fix_code_style.sh b/tools/fix_code_style.sh new file mode 100755 index 0000000000..a654399886 --- /dev/null +++ b/tools/fix_code_style.sh @@ -0,0 +1,19 @@ +#!/bin/sh +astyle \ + --style=allman \ + --indent=spaces=4 \ + --indent-cases \ + --indent-preprocessor \ + --break-blocks=all \ + --pad-oper \ + --pad-header \ + --unpad-paren \ + --keep-one-line-blocks \ + --keep-one-line-statements \ + --align-pointer=name \ + --align-reference=name \ + --suffix=none \ + --ignore-exclude-errors-x \ + --lineend=linux \ + --exclude=EASTL \ + $* -- GitLab From 0700a1e7d64f83fc214537dcd6dacc23c60f7b4b Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 31 Oct 2013 14:58:45 +0100 Subject: [PATCH 443/460] Audio for Windows --- src/GAudioOutput.cc | 747 +++++++++++++++++++++++--------------------- src/GAudioOutput.h | 34 +- 2 files changed, 420 insertions(+), 361 deletions(-) diff --git a/src/GAudioOutput.cc b/src/GAudioOutput.cc index 364ca018c5..b9d451929b 100644 --- a/src/GAudioOutput.cc +++ b/src/GAudioOutput.cc @@ -1,352 +1,395 @@ -/*===================================================================== - -QGroundControl Open Source Ground Control Station - -(c) 2009, 2010 QGROUNDCONTROL PROJECT - -This file is part of the QGROUNDCONTROL project - - QGROUNDCONTROL is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - QGROUNDCONTROL is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with QGROUNDCONTROL. If not, see . - -======================================================================*/ - -/** - * @file - * @brief Implementation of audio output - * - * @author Lorenz Meier - * - */ - -#include -#include -#include -#include "GAudioOutput.h" -#include "MG.h" - -#include - -#ifdef Q_OS_MAC -#include -#endif - -// Speech synthesis is only supported with MSVC compiler -#if _MSC_VER2 -// Documentation: http://msdn.microsoft.com/en-us/library/ee125082%28v=VS.85%29.aspx -#define _ATL_APARTMENT_THREADED - -#include -//You may derive a class from CComModule and use it if you want to override something, -//but do not change the name of _Module -extern CComModule _Module; -#include - -#include - -//using System; -//using System.Speech.Synthesis; -#endif - -#ifdef Q_OS_LINUX -extern "C" { -#include - cst_voice* register_cmu_us_kal(const char* voxdir); -}; -#endif - - - -/** - * This class follows the singleton design pattern - * @see http://en.wikipedia.org/wiki/Singleton_pattern - * A call to this function thus returns the only instance of this object - * the call can occur at any place in the code, no reference to the - * GAudioOutput object has to be passed. - */ -GAudioOutput* GAudioOutput::instance() -{ - static GAudioOutput* _instance = 0; - if(_instance == 0) - { - _instance = new GAudioOutput(); - // Set the application as parent to ensure that this object - // will be destroyed when the main application exits - _instance->setParent(qApp); - } - return _instance; -} - -#define QGC_GAUDIOOUTPUT_KEY QString("QGC_AUDIOOUTPUT_") - -GAudioOutput::GAudioOutput(QObject* parent) : QObject(parent), - voiceIndex(0), - emergency(false), - muted(false) -{ - // Load settings - QSettings settings; - settings.sync(); - muted = settings.value(QGC_GAUDIOOUTPUT_KEY+"muted", muted).toBool(); - - -#ifdef Q_OS_LINUX - flite_init(); -#endif - -#if _MSC_VER2 - - ISpVoice * pVoice = NULL; - if (FAILED(::CoInitialize(NULL))) - { - qDebug("Creating COM object for audio output failed!"); - } - else - { - - HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice;); - if( SUCCEEDED( hr ) ) - { - hr = pVoice->Speak(L"Hello world", 0, NULL); - pVoice->Release(); - pVoice = NULL; - } - } -#endif - // Initialize audio output - //m_media = new Phonon::MediaObject(this); - //Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this); - //createPath(m_media, audioOutput); - - // Prepare regular emergency signal, will be fired off on calling startEmergency() - emergencyTimer = new QTimer(); - connect(emergencyTimer, SIGNAL(timeout()), this, SLOT(beep())); - - switch (voiceIndex) { - case 0: - selectFemaleVoice(); - break; - default: - selectMaleVoice(); - break; - } -} - -//GAudioOutput::~GAudioOutput() -//{ -//#ifdef _MSC_VER2 -// ::CoUninitialize(); -//#endif -//} - -void GAudioOutput::mute(bool mute) -{ - if (mute != muted) - { - this->muted = mute; - QSettings settings; - settings.setValue(QGC_GAUDIOOUTPUT_KEY+"muted", this->muted); - settings.sync(); - emit mutedChanged(muted); - } -} - -bool GAudioOutput::isMuted() -{ - return this->muted; -} - -bool GAudioOutput::say(QString text, int severity) -{ - if (!muted) - { - // TODO Add severity filter - Q_UNUSED(severity); - bool res = false; - if (!emergency) - { - - // Speech synthesis is only supported with MSVC compiler -#ifdef _MSC_VER2 - SpeechSynthesizer synth = new SpeechSynthesizer(); - synth.SelectVoice("Microsoft Anna"); - synth.SpeakText(text.toStdString().c_str()); - res = true; -#endif - -#ifdef Q_OS_LINUX - QTemporaryFile file; - file.setFileTemplate("XXXXXX.wav"); - if (file.open()) { - cst_voice* v = register_cmu_us_kal(NULL); - cst_wave* wav = flite_text_to_wave(text.toStdString().c_str(), v); - // file.fileName() returns the unique file name - cst_wave_save(wav, file.fileName().toStdString().c_str(), "riff"); - //m_media->setCurrentSource(Phonon::MediaSource(file.fileName().toStdString().c_str())); - //m_media->play(); - res = true; - } -#endif - -#ifdef Q_OS_MAC - // Slashes necessary to have the right start to the sentence - // copying data prevents SpeakString from reading additional chars - text = "\\" + text; - QStdWString str = text.toStdWString(); - unsigned char str2[1024] = {}; - memcpy(str2, text.toAscii().data(), str.length()); - SpeakString(str2); - res = true; -#endif - } - return res; - } - else - { - return false; - } -} - -/** - * @param text This message will be played after the alert beep - */ -bool GAudioOutput::alert(QString text) -{ - if (!emergency || !muted) - { - // Play alert sound - beep(); - // Say alert message - say(text, 2); - return true; - } - else - { - return false; - } -} - -void GAudioOutput::notifyPositive() -{ - if (!muted) - { - // Use QFile to transform path for all OS - QFile f(QCoreApplication::applicationDirPath()+QString("/files/audio/double_notify.wav")); - //m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str())); - //m_media->play(); - } -} - -void GAudioOutput::notifyNegative() -{ - if (!muted) - { - // Use QFile to transform path for all OS - QFile f(QCoreApplication::applicationDirPath()+QString("/files/audio/flat_notify.wav")); - //m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str())); - //m_media->play(); - } -} - -/** - * The emergency sound will be played continously during the emergency. - * call stopEmergency() to disable it again. No speech synthesis or other - * audio output is available during the emergency. - * - * @return true if the emergency could be started, false else - */ -bool GAudioOutput::startEmergency() -{ - if (!emergency) - { - emergency = true; - // Beep immediately and then start timer - if (!muted) beep(); - emergencyTimer->start(1500); - QTimer::singleShot(5000, this, SLOT(stopEmergency())); - } - return true; -} - -/** - * Stops the continous emergency sound. Use startEmergency() to start - * the emergency sound. - * - * @return true if the emergency could be stopped, false else - */ -bool GAudioOutput::stopEmergency() -{ - if (emergency) { - emergency = false; - emergencyTimer->stop(); - } - return true; -} - -void GAudioOutput::beep() -{ - if (!muted) - { - // Use QFile to transform path for all OS - QFile f(QCoreApplication::applicationDirPath()+QString("/files/audio/alert.wav")); - qDebug() << "FILE:" << f.fileName(); - //m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str())); - //m_media->play(); - } -} - -void GAudioOutput::selectFemaleVoice() -{ -#ifdef Q_OS_LINUX - //this->voice = register_cmu_us_slt(NULL); -#endif -} - -void GAudioOutput::selectMaleVoice() -{ -#ifdef Q_OS_LINUX - //this->voice = register_cmu_us_rms(NULL); -#endif -} - -/* -void GAudioOutput::selectNeutralVoice() -{ -#ifdef Q_OS_LINUX - this->voice = register_cmu_us_awb(NULL); -#endif -}*/ - -QStringList GAudioOutput::listVoices(void) -{ - QStringList l; -#ifdef Q_OS_LINUX2 - cst_voice *voice; - const cst_val *v; - - - - printf("Voices available: "); - for (v=flite_voice_list; v; v=val_cdr(v)) { - voice = val_voice(val_car(v)); - QString s; - s.sprintf("%s",voice->name); - printf("%s",voice->name); - l.append(s); - } - printf("\n"); - -#endif - return l; - -} +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2009, 2010 QGROUNDCONTROL PROJECT + +This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Implementation of audio output + * + * @author Lorenz Meier + * + */ + +#include +#include +#include +#include "GAudioOutput.h" +#include "MG.h" + +#include + +#ifdef Q_OS_MAC +#include +#endif + +// Speech synthesis is only supported with MSVC compiler +#if _MSC_VER +// Documentation: http://msdn.microsoft.com/en-us/library/ee125082%28v=VS.85%29.aspx +#define _ATL_APARTMENT_THREADED + +#include +//You may derive a class from CComModule and use it if you want to override something, +//but do not change the name of _Module +extern CComModule _Module; +#include + +#include + +//using System; +//using System.Speech.Synthesis; +#endif + +#ifdef Q_OS_LINUX +extern "C" { +#include + cst_voice *register_cmu_us_kal(const char *voxdir); +}; +#endif + +#ifdef _MSC_VER +ISpVoice *GAudioOutput::pVoice = NULL; +#endif + +/** + * This class follows the singleton design pattern + * @see http://en.wikipedia.org/wiki/Singleton_pattern + * A call to this function thus returns the only instance of this object + * the call can occur at any place in the code, no reference to the + * GAudioOutput object has to be passed. + */ +GAudioOutput *GAudioOutput::instance() +{ + static GAudioOutput *_instance = 0; + + if (_instance == 0) + { + _instance = new GAudioOutput(); + // Set the application as parent to ensure that this object + // will be destroyed when the main application exits + _instance->setParent(qApp); + } + + return _instance; +} + +#define QGC_GAUDIOOUTPUT_KEY QString("QGC_AUDIOOUTPUT_") + +GAudioOutput::GAudioOutput(QObject *parent) : QObject(parent), + voiceIndex(0), + emergency(false), + muted(false) +{ + // Load settings + QSettings settings; + settings.sync(); + muted = settings.value(QGC_GAUDIOOUTPUT_KEY + "muted", muted).toBool(); + + +#ifdef Q_OS_LINUX + flite_init(); +#endif + +#if _MSC_VER + pVoice = NULL; + + if (FAILED(::CoInitialize(NULL))) + { + qDebug("Creating COM object for audio output failed!"); + } + + else + { + + HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice); + + if (SUCCEEDED(hr)) + { + hr = pVoice->Speak(L"QGC audio output active!", 0, NULL); + //pVoice->Release(); + //pVoice = NULL; + } + } + +#endif + // Initialize audio output + //m_media = new Phonon::MediaObject(this); + //Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this); + //createPath(m_media, audioOutput); + + // Prepare regular emergency signal, will be fired off on calling startEmergency() + emergencyTimer = new QTimer(); + connect(emergencyTimer, SIGNAL(timeout()), this, SLOT(beep())); + + switch (voiceIndex) + { + case 0: + selectFemaleVoice(); + break; + + default: + selectMaleVoice(); + break; + } +} + +GAudioOutput::~GAudioOutput() +{ +#ifdef _MSC_VER + pVoice->Release(); + pVoice = NULL; + ::CoUninitialize(); +#endif +} + + +void GAudioOutput::mute(bool mute) +{ + if (mute != muted) + { + this->muted = mute; + QSettings settings; + settings.setValue(QGC_GAUDIOOUTPUT_KEY + "muted", this->muted); + settings.sync(); + emit mutedChanged(muted); + } +} + +bool GAudioOutput::isMuted() +{ + return this->muted; +} + +bool GAudioOutput::say(QString text, int severity) +{ + if (!muted) + { + // TODO Add severity filter + Q_UNUSED(severity); + bool res = false; + + if (!emergency) + { + + // Speech synthesis is only supported with MSVC compiler +#ifdef _MSC_VER + /*SpeechSynthesizer synth = new SpeechSynthesizer(); + synth.SelectVoice("Microsoft Anna"); + synth.SpeakText(text.toStdString().c_str()); + res = true;*/ + /*ISpVoice * pVoice = NULL; + if (FAILED(::CoInitialize(NULL))) + { + qDebug("Creating COM object for audio output failed!"); + } + else + { + HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice); + if( SUCCEEDED( hr ) ) + { + hr = */pVoice->Speak(text.toStdWString().c_str(), SPF_ASYNC, NULL); + /*pVoice->WaitUntilDone(5000); + pVoice->Release(); + pVoice = NULL; + } + }*/ +#endif + +#ifdef Q_OS_LINUX + QTemporaryFile file; + file.setFileTemplate("XXXXXX.wav"); + + if (file.open()) + { + cst_voice *v = register_cmu_us_kal(NULL); + cst_wave *wav = flite_text_to_wave(text.toStdString().c_str(), v); + // file.fileName() returns the unique file name + cst_wave_save(wav, file.fileName().toStdString().c_str(), "riff"); + //m_media->setCurrentSource(Phonon::MediaSource(file.fileName().toStdString().c_str())); + //m_media->play(); + res = true; + } + +#endif + +#ifdef Q_OS_MAC + // Slashes necessary to have the right start to the sentence + // copying data prevents SpeakString from reading additional chars + text = "\\" + text; + QStdWString str = text.toStdWString(); + unsigned char str2[1024] = {}; + memcpy(str2, text.toAscii().data(), str.length()); + SpeakString(str2); + res = true; +#endif + } + + return res; + } + + else + { + return false; + } +} + +/** + * @param text This message will be played after the alert beep + */ +bool GAudioOutput::alert(QString text) +{ + if (!emergency || !muted) + { + // Play alert sound + beep(); + // Say alert message + say(text, 2); + return true; + } + + else + { + return false; + } +} + +void GAudioOutput::notifyPositive() +{ + if (!muted) + { + // Use QFile to transform path for all OS + QFile f(QCoreApplication::applicationDirPath() + QString("/files/audio/double_notify.wav")); + //m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str())); + //m_media->play(); + } +} + +void GAudioOutput::notifyNegative() +{ + if (!muted) + { + // Use QFile to transform path for all OS + QFile f(QCoreApplication::applicationDirPath() + QString("/files/audio/flat_notify.wav")); + //m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str())); + //m_media->play(); + } +} + +/** + * The emergency sound will be played continously during the emergency. + * call stopEmergency() to disable it again. No speech synthesis or other + * audio output is available during the emergency. + * + * @return true if the emergency could be started, false else + */ +bool GAudioOutput::startEmergency() +{ + if (!emergency) + { + emergency = true; + + // Beep immediately and then start timer + if (!muted) beep(); + + emergencyTimer->start(1500); + QTimer::singleShot(5000, this, SLOT(stopEmergency())); + } + + return true; +} + +/** + * Stops the continous emergency sound. Use startEmergency() to start + * the emergency sound. + * + * @return true if the emergency could be stopped, false else + */ +bool GAudioOutput::stopEmergency() +{ + if (emergency) + { + emergency = false; + emergencyTimer->stop(); + } + + return true; +} + +void GAudioOutput::beep() +{ + if (!muted) + { + // Use QFile to transform path for all OS + QFile f(QCoreApplication::applicationDirPath() + QString("/files/audio/alert.wav")); + qDebug() << "FILE:" << f.fileName(); + //m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str())); + //m_media->play(); + } +} + +void GAudioOutput::selectFemaleVoice() +{ +#ifdef Q_OS_LINUX + //this->voice = register_cmu_us_slt(NULL); +#endif +} + +void GAudioOutput::selectMaleVoice() +{ +#ifdef Q_OS_LINUX + //this->voice = register_cmu_us_rms(NULL); +#endif +} + +/* +void GAudioOutput::selectNeutralVoice() +{ +#ifdef Q_OS_LINUX + this->voice = register_cmu_us_awb(NULL); +#endif +}*/ + +QStringList GAudioOutput::listVoices(void) +{ + QStringList l; +#ifdef Q_OS_LINUX2 + cst_voice *voice; + const cst_val *v; + + + + printf("Voices available: "); + + for (v = flite_voice_list; v; v = val_cdr(v)) + { + voice = val_voice(val_car(v)); + QString s; + s.sprintf("%s", voice->name); + printf("%s", voice->name); + l.append(s); + } + + printf("\n"); + +#endif + return l; + +} diff --git a/src/GAudioOutput.h b/src/GAudioOutput.h index 78667290a0..faef16f5e4 100644 --- a/src/GAudioOutput.h +++ b/src/GAudioOutput.h @@ -59,10 +59,21 @@ This file is part of the PIXHAWK project extern "C" { cst_voice *REGISTER_VOX(const char *voxdir); void UNREGISTER_VOX(cst_voice *vox); - cst_voice* register_cmu_us_kal16(const char *voxdir); + cst_voice *register_cmu_us_kal16(const char *voxdir); } #endif +#if _MSC_VER +// Documentation: http://msdn.microsoft.com/en-us/library/ee125082%28v=VS.85%29.aspx +#define _ATL_APARTMENT_THREADED +#include +//You may derive a class from CComModule and use it if you want to override something, +//but do not change the name of _Module +extern CComModule _Module; +#include +#include +#endif + /** * @brief Audio Output (speech synthesizer and "beep" output) * This class follows the singleton design pattern @@ -73,10 +84,11 @@ class GAudioOutput : public QObject Q_OBJECT public: /** @brief Get the singleton instance */ - static GAudioOutput* instance(); + static GAudioOutput *instance(); /** @brief List available voices */ QStringList listVoices(void); - enum { + enum + { VOICE_MALE = 0, VOICE_FEMALE } QGVoice; @@ -86,7 +98,7 @@ public: public slots: /** @brief Say this text if current output priority matches */ - bool say(QString text, int severity=1); + bool say(QString text, int severity = 1); /** @brief Play alert sound and say notification message */ bool alert(QString text); /** @brief Start emergency sound */ @@ -115,16 +127,20 @@ protected: #endif #ifdef Q_OS_LINUX //cst_voice* voice; ///< The flite voice object +#endif +#ifdef _MSC_VER + static ISpVoice *pVoice; #endif int voiceIndex; ///< The index of the flite voice to use (awb, slt, rms) - Phonon::MediaObject* m_media; ///< The output object for audio - Phonon::AudioOutput* m_audioOutput; + Phonon::MediaObject *m_media; ///< The output object for audio + Phonon::AudioOutput *m_audioOutput; bool emergency; ///< Emergency status flag - QTimer* emergencyTimer; + QTimer *emergencyTimer; bool muted; private: - GAudioOutput(QObject* parent=NULL); -// ~GAudioOutput(); + GAudioOutput(QObject *parent = NULL); + ~GAudioOutput(); }; #endif // AUDIOOUTPUT_H + -- GitLab From 9cd72124d6c0a2d13b9f59267dc0b5c9b4938d90 Mon Sep 17 00:00:00 2001 From: Geoff Fink Date: Thu, 31 Oct 2013 15:43:39 -0600 Subject: [PATCH 444/460] override is not available in gcc 4.6 (only 4.7). Removed for compatability --- src/ui/designer/QGCComboBox.h | 2 +- src/ui/designer/QGCCommandButton.h | 2 +- src/ui/designer/QGCParamSlider.h | 2 +- src/ui/designer/QGCTextLabel.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/designer/QGCComboBox.h b/src/ui/designer/QGCComboBox.h index c81a636fee..2e606a559c 100644 --- a/src/ui/designer/QGCComboBox.h +++ b/src/ui/designer/QGCComboBox.h @@ -22,7 +22,7 @@ public: explicit QGCComboBox(QWidget *parent = 0); ~QGCComboBox(); - virtual void setEditMode(bool editMode) override; + virtual void setEditMode(bool editMode); public slots: /** @brief Queue parameter for sending to the MAV (add to pending list)*/ diff --git a/src/ui/designer/QGCCommandButton.h b/src/ui/designer/QGCCommandButton.h index a1c858a675..da47e6082c 100644 --- a/src/ui/designer/QGCCommandButton.h +++ b/src/ui/designer/QGCCommandButton.h @@ -18,7 +18,7 @@ public: explicit QGCCommandButton(QWidget *parent = 0); ~QGCCommandButton(); - virtual void setEditMode(bool editMode) override; + virtual void setEditMode(bool editMode); public slots: void sendCommand(); diff --git a/src/ui/designer/QGCParamSlider.h b/src/ui/designer/QGCParamSlider.h index b5b5862d14..9ca92423bf 100644 --- a/src/ui/designer/QGCParamSlider.h +++ b/src/ui/designer/QGCParamSlider.h @@ -20,7 +20,7 @@ public: explicit QGCParamSlider(QWidget *parent = 0); ~QGCParamSlider(); - virtual void setEditMode(bool editMode) override; + virtual void setEditMode(bool editMode); public slots: /** @brief Queue parameter for sending to the MAV (add to pending list)*/ diff --git a/src/ui/designer/QGCTextLabel.h b/src/ui/designer/QGCTextLabel.h index bc0a799cc8..8e8cd509ea 100644 --- a/src/ui/designer/QGCTextLabel.h +++ b/src/ui/designer/QGCTextLabel.h @@ -19,7 +19,7 @@ public: ~QGCTextLabel(); void setActiveUAS(UASInterface *uas); void enableText(int num); - virtual void setEditMode(bool editMode) override; + virtual void setEditMode(bool editMode); public slots: void writeSettings(QSettings& settings); void readSettings(const QSettings& settings); -- GitLab From d36eca90e9500d4250ca66e0f461ce8f2ed8679f Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Tue, 5 Nov 2013 08:31:07 +0100 Subject: [PATCH 445/460] Added ping reply patch by Paul Chavent --- src/comm/MAVLinkProtocol.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/comm/MAVLinkProtocol.cc b/src/comm/MAVLinkProtocol.cc index d78cdac774..66f0280d8d 100644 --- a/src/comm/MAVLinkProtocol.cc +++ b/src/comm/MAVLinkProtocol.cc @@ -268,6 +268,20 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b) if (decodeState == 1) { decodedFirstPacket = true; + + if(message.msgid == MAVLINK_MSG_ID_PING) + { + // process ping requests (tgt_system and tgt_comp must be zero) + mavlink_ping_t ping; + mavlink_msg_ping_decode(&message, &ping); + if(!ping.target_system && !ping.target_component) + { + mavlink_message_t msg; + mavlink_msg_ping_pack(getSystemId(), getComponentId(), &msg, ping.time_usec, ping.seq, message.sysid, message.compid); + sendMessage(msg); + } + } + #if defined(QGC_PROTOBUF_ENABLED) if (message.msgid == MAVLINK_MSG_ID_EXTENDED_MESSAGE) -- GitLab From 74ee8c7cb6f6bd44271fcc31646db5c4c384d6cc Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Tue, 5 Nov 2013 15:01:19 +0100 Subject: [PATCH 446/460] Fixed scaling of differential pressure for XPlane link --- src/comm/QGCXPlaneLink.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/comm/QGCXPlaneLink.cc b/src/comm/QGCXPlaneLink.cc index c1286235b1..89cf722a54 100644 --- a/src/comm/QGCXPlaneLink.cc +++ b/src/comm/QGCXPlaneLink.cc @@ -709,7 +709,7 @@ void QGCXPlaneLink::readBytes() fields_changed |= (1 << 11); emit sensorHilRawImuChanged(QGC::groundTimeUsecs(), xacc, yacc, zacc, rollspeed, pitchspeed, yawspeed, - xmag, ymag, zmag, abs_pressure, diff_pressure, pressure_alt, temperature, fields_changed); + xmag, ymag, zmag, abs_pressure, diff_pressure / 100.0, pressure_alt, temperature, fields_changed); // XXX make these GUI-configurable and add randomness int gps_fix_type = 3; -- GitLab From e2089acc0e4196aebc60c47b2c8d0c0b599d5d24 Mon Sep 17 00:00:00 2001 From: Anton Babushkin Date: Thu, 7 Nov 2013 20:09:59 +0400 Subject: [PATCH 447/460] Use onboard remaining battery estimate by default --- src/uas/UAS.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index e50e1dc761..45a25b4fba 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -85,7 +85,7 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), currentVoltage(12.6f), lpVoltage(12.0f), currentCurrent(0.4f), - batteryRemainingEstimateEnabled(true), + batteryRemainingEstimateEnabled(false), // chargeLevel not initialized // timeRemaining not initialized lowBattAlarm(false), @@ -211,7 +211,7 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), actions.append(newAction); color = UASInterface::getNextColor(); - setBatterySpecs(QString("9V,9.5V,12.6V")); + setBatterySpecs(QString("")); connect(statusTimeout, SIGNAL(timeout()), this, SLOT(updateState())); connect(this, SIGNAL(systemSpecsChanged(int)), this, SLOT(writeSettings())); statusTimeout->start(500); -- GitLab From c086bcbb31d236027ac48364ad8d1f52a0472b0b Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Sun, 10 Nov 2013 19:28:13 +0100 Subject: [PATCH 448/460] differential pressure/airspeed calibration ui --- .../QGCPX4SensorCalibration.cc | 39 +++++++++++++++++++ .../QGCPX4SensorCalibration.h | 2 + .../QGCPX4SensorCalibration.ui | 23 ++++++++++- 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc index c479d55251..a4ec8a356a 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc @@ -17,6 +17,7 @@ QGCPX4SensorCalibration::QGCPX4SensorCalibration(QWidget *parent) : connect(ui->gyroButton, SIGNAL(clicked()), this, SLOT(gyroButtonClicked())); connect(ui->magButton, SIGNAL(clicked()), this, SLOT(magButtonClicked())); connect(ui->accelButton, SIGNAL(clicked()), this, SLOT(accelButtonClicked())); + connect(ui->diffPressureButton, SIGNAL(clicked()), this, SLOT(diffPressureButtonClicked())); ui->gyroButton->setEnabled(false); ui->magButton->setEnabled(false); @@ -168,6 +169,17 @@ void QGCPX4SensorCalibration::parameterChanged(int uas, int component, QString p setAccelCalibrated(true); } } + + // Check differential pressure calibration naively + if (parameterName.contains("SENS_DPRES_OFF")) { + float offset = value.toFloat(); + if (offset < 0.000001f && offset > -0.000001f) { + // Must be zero, not good + setDiffPressureCalibrated(false); + } else { + setDiffPressureCalibrated(true); + } + } } void QGCPX4SensorCalibration::setMagCalibrated(bool calibrated) @@ -215,6 +227,21 @@ void QGCPX4SensorCalibration::setAccelCalibrated(bool calibrated) } } +void QGCPX4SensorCalibration::setDiffPressureCalibrated(bool calibrated) +{ + if (calibrated) { + ui->diffPressureLabel->setText(tr("DIFF. PRESSURE CALIBRATED")); + ui->diffPressureLabel->setStyleSheet("QLabel { color: #FFFFFF;" + "background-color: #20AA20;" + "}"); + } else { + ui->diffPressureLabel->setText(tr("DIFF. PRESSURE UNCALIBRATED")); + ui->diffPressureLabel->setStyleSheet("QLabel { color: #FFFFFF;" + "background-color: #FF0037;" + "}"); + } +} + void QGCPX4SensorCalibration::setInstructionImage(const QString &path) { instructionIcon.load(path); @@ -384,6 +411,11 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever activeUAS->requestParameter(0, "SENS_MAG_ZSCALE"); activeUAS->requestParameter(0, "SENS_EXT_MAG_ROT"); } + + if (text.startsWith("dpress ")) { + activeUAS->requestParameter(0, "SENS_DPRES_OFF"); + activeUAS->requestParameter(0, "SENS_DPRES_ANA"); + } } } @@ -427,6 +459,13 @@ void QGCPX4SensorCalibration::accelButtonClicked() ui->progressBar->setValue(0); } +void QGCPX4SensorCalibration::diffPressureButtonClicked() +{ + setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); + activeUAS->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0); + ui->progressBar->setValue(0); +} + void QGCPX4SensorCalibration::contextMenuEvent(QContextMenuEvent* event) { QMenu menu(this); diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.h b/src/ui/px4_configuration/QGCPX4SensorCalibration.h index fecb8b8b27..1bddf458f0 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.h +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.h @@ -35,6 +35,7 @@ public slots: void gyroButtonClicked(); void magButtonClicked(); void accelButtonClicked(); + void diffPressureButtonClicked(); /** * @brief Hand context menu event @@ -70,6 +71,7 @@ protected: void setMagCalibrated(bool calibrated); void setGyroCalibrated(bool calibrated); void setAccelCalibrated(bool calibrated); + void setDiffPressureCalibrated(bool calibrated); void updateIcons(); diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui index e954372126..b1fd81425e 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui @@ -25,7 +25,7 @@ border: 2px solid #465158; } -QPushButton#gyroButton, QPushButton#accelButton { +QPushButton#gyroButton, QPushButton#accelButton, QPushButton#diffPressureButton { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #D3795D, stop: 1 #A81154); border-radius: 8px; min-height: 25px; @@ -121,6 +121,27 @@ QPushButton#gyroButton, QPushButton#accelButton { + + + + Diff. pressure + + + + :/files/images/px4/calibration/arrows.png:/files/images/px4/calibration/arrows.png + + + + + + + + + + Qt::AlignCenter + + + -- GitLab From d2e513c558a66c5efd4da11a972759a2ed3fdc11 Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Sun, 10 Nov 2013 21:19:13 +0100 Subject: [PATCH 449/460] Do not filter/hide line in linechartwidget when checkbox of the line is checked --- src/ui/linechart/LinechartWidget.cc | 17 ++++++++++------- src/ui/linechart/LinechartWidget.h | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/ui/linechart/LinechartWidget.cc b/src/ui/linechart/LinechartWidget.cc index f4badd7a5e..c8652ddecc 100644 --- a/src/ui/linechart/LinechartWidget.cc +++ b/src/ui/linechart/LinechartWidget.cc @@ -712,13 +712,16 @@ void LinechartWidget::setPlotFilterLineEditFocus() void LinechartWidget::filterCurve(const QString &key, bool match) { - colorIcons[key]->setVisible(match); - curveNameLabels[key]->setVisible(match); - (*curveLabels)[key]->setVisible(match); - (*curveMeans)[key]->setVisible(match); - (*curveVariances)[key]->setVisible(match); - curveUnits[key]->setVisible(match); - checkBoxes[key]->setVisible(match); + if (!checkBoxes[key]->isChecked()) + { + colorIcons[key]->setVisible(match); + curveNameLabels[key]->setVisible(match); + (*curveLabels)[key]->setVisible(match); + (*curveMeans)[key]->setVisible(match); + (*curveVariances)[key]->setVisible(match); + curveUnits[key]->setVisible(match); + checkBoxes[key]->setVisible(match); + } } void LinechartWidget::filterCurves(const QString &filter) diff --git a/src/ui/linechart/LinechartWidget.h b/src/ui/linechart/LinechartWidget.h index 12fe58494e..4c9fb20b62 100644 --- a/src/ui/linechart/LinechartWidget.h +++ b/src/ui/linechart/LinechartWidget.h @@ -114,7 +114,7 @@ public slots: private slots: /** Called when the user changes the time scale combobox. */ void timeScaleChanged(int index); - /** @brief Applies action on curve corresponding to key based on the bool match. I used to filter curves */ + /** @brief Toggles visibility of curve based on bool match if corresponding checkbox is not checked */ void filterCurve(const QString &key, bool match); protected: -- GitLab From 0d445a4d71398873488dd35b87a57365ee6016ed Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Tue, 26 Nov 2013 16:32:07 +0100 Subject: [PATCH 450/460] re-enable linux text to speech and fix use of deprecated function --- src/GAudioOutput.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/GAudioOutput.cc b/src/GAudioOutput.cc index b9d451929b..b3eb0e533e 100644 --- a/src/GAudioOutput.cc +++ b/src/GAudioOutput.cc @@ -131,9 +131,9 @@ GAudioOutput::GAudioOutput(QObject *parent) : QObject(parent), #endif // Initialize audio output - //m_media = new Phonon::MediaObject(this); - //Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this); - //createPath(m_media, audioOutput); + m_media = new Phonon::MediaObject(this); + Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this); + createPath(m_media, audioOutput); // Prepare regular emergency signal, will be fired off on calling startEmergency() emergencyTimer = new QTimer(); @@ -223,8 +223,8 @@ bool GAudioOutput::say(QString text, int severity) cst_wave *wav = flite_text_to_wave(text.toStdString().c_str(), v); // file.fileName() returns the unique file name cst_wave_save(wav, file.fileName().toStdString().c_str(), "riff"); - //m_media->setCurrentSource(Phonon::MediaSource(file.fileName().toStdString().c_str())); - //m_media->play(); + m_media->setCurrentSource(Phonon::MediaSource(QUrl::fromLocalFile(file.fileName().toStdString().c_str()))); + m_media->play(); res = true; } -- GitLab From d9fe006905bda92591b0ab5ad540fb81ef9ff23e Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Thu, 28 Nov 2013 14:43:07 -0800 Subject: [PATCH 451/460] Initial TCP support --- qgroundcontrol.pro | 2 + src/comm/TCPLink.cc | 323 ++++++++++++++++++++++++++++++ src/comm/TCPLink.h | 121 +++++++++++ src/ui/CommConfigurationWindow.cc | 17 +- src/ui/CommConfigurationWindow.h | 1 + 5 files changed, 463 insertions(+), 1 deletion(-) create mode 100644 src/comm/TCPLink.cc create mode 100644 src/comm/TCPLink.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index e8940419a7..b34aefbb2e 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -352,6 +352,7 @@ HEADERS += src/MG.h \ src/ui/CameraView.h \ src/comm/MAVLinkSimulationLink.h \ src/comm/UDPLink.h \ + src/comm/TCPLink.h \ src/ui/ParameterInterface.h \ src/ui/WaypointList.h \ src/Waypoint.h \ @@ -578,6 +579,7 @@ SOURCES += src/main.cc \ src/ui/CameraView.cc \ src/comm/MAVLinkSimulationLink.cc \ src/comm/UDPLink.cc \ + src/comm/TCPLink.cc \ src/ui/ParameterInterface.cc \ src/ui/WaypointList.cc \ src/Waypoint.cc \ diff --git a/src/comm/TCPLink.cc b/src/comm/TCPLink.cc new file mode 100644 index 0000000000..c1c2d01ade --- /dev/null +++ b/src/comm/TCPLink.cc @@ -0,0 +1,323 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2011 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/** + * @file + * @brief Definition of TCP connection (server) for unmanned vehicles + * @author Lorenz Meier + * + */ + +#include +#include +#include +#include +#include +#include "TCPLink.h" +#include "LinkManager.h" +#include "QGC.h" +#include +//#include + +TCPLink::TCPLink(QHostAddress host, quint16 port) +: socket(NULL) +{ + // FIXFIX: host and port and hard-wired + this->host = "127.0.0.1"; + this->port = 5760; + + this->socketIsConnected = false; + + // Set unique ID and add link to the list of links + this->id = getNextLinkId(); + // FIXFIX: What about host name? + this->name = tr("TCP Link (port:%1)").arg(this->port); + emit nameChanged(this->name); + + qDebug() << "TCP Created " << name; +} + +TCPLink::~TCPLink() +{ + disconnect(); + this->deleteLater(); +} + +/** + * @brief Runs the thread + * + **/ +void TCPLink::run() +{ + exec(); +} + +void TCPLink::setAddress(QHostAddress host) +{ + bool reconnect(false); + if(this->isConnected()) + { + disconnect(); + reconnect = true; + } + this->host = host; + if(reconnect) + { + connect(); + } +} + +void TCPLink::setPort(int port) +{ + bool reconnect(false); + if(this->isConnected()) + { + disconnect(); + reconnect = true; + } + this->port = port; + this->name = tr("TCP Link (port:%1)").arg(this->port); + emit nameChanged(this->name); + if(reconnect) + { + connect(); + } +} + +void TCPLink::writeBytes(const char* data, qint64 size) +{ + //#define TCPLINK_DEBUG +#ifdef TCPLINK_DEBUG + QString bytes; + QString ascii; + for (int i=0; i 31 && data[i] < 127) + { + ascii.append(data[i]); + } + else + { + ascii.append(219); + } + } + qDebug() << "Sent" << size << "bytes to" << currentHost.toString() << ":" << currentPort << "data:"; + qDebug() << bytes; + qDebug() << "ASCII:" << ascii; +#endif + socket->write(data, size); +} + +/** + * @brief Read a number of bytes from the interface. + * + * @param data Pointer to the data byte array to write the bytes to + * @param maxLength The maximum number of bytes to write + **/ +void TCPLink::readBytes() +{ + qint64 byteCount = socket->bytesAvailable(); + + if (byteCount) + { + QByteArray buffer; + buffer.resize(byteCount); + + socket->read(buffer.data(), buffer.size()); + + emit bytesReceived(this, buffer); + + // // Echo data for debugging purposes + // std::cerr << __FILE__ << __LINE__ << "Received datagram:" << std::endl; + // int i; + // for (i=0; ibytesAvailable(); +} + +/** + * @brief Disconnect the connection. + * + * @return True if connection has been disconnected, false if connection couldn't be disconnected. + **/ +bool TCPLink::disconnect() +{ + this->quit(); + this->wait(); + + if (socket) + { + if (socketIsConnected) { + socket->disconnect(); + socketIsConnected = false; + } + delete socket; + socket = NULL; + } + + return true; +} + +/** + * @brief Connect the connection. + * + * @return True if connection has been established, false if connection couldn't be established. + **/ +bool TCPLink::connect() +{ + if(this->isRunning()) + { + this->quit(); + this->wait(); + } + bool connected = this->hardwareConnect(); + start(HighPriority); + return connected; +} + +bool TCPLink::hardwareConnect(void) +{ + socket = new QTcpSocket(); + + socket->connectToHost(host, port); + + QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(readBytes())); + //QObject::connect(socket, SIGNAL(connected()), this, SLOT(socketConnected())); + socketIsConnected = true; + + connectionStartTime = QGC::groundTimeUsecs()/1000; + + return true; +} + +void TCPLink::socketConnected() +{ + socketIsConnected = true; +} + +/** + * @brief Check if connection is active. + * + * @return True if link is connected, false otherwise. + **/ +bool TCPLink::isConnected() const +{ + return socketIsConnected; +} + +int TCPLink::getId() const +{ + return id; +} + +QString TCPLink::getName() const +{ + return name; +} + +void TCPLink::setName(QString name) +{ + this->name = name; + emit nameChanged(this->name); +} + + +qint64 TCPLink::getNominalDataRate() const +{ + return 54000000; // 54 Mbit +} + +qint64 TCPLink::getTotalUpstream() +{ + statisticsMutex.lock(); + qint64 totalUpstream = bitsSentTotal / ((QGC::groundTimeUsecs()/1000 - connectionStartTime) / 1000); + statisticsMutex.unlock(); + return totalUpstream; +} + +qint64 TCPLink::getCurrentUpstream() +{ + return 0; // TODO +} + +qint64 TCPLink::getMaxUpstream() +{ + return 0; // TODO +} + +qint64 TCPLink::getBitsSent() const +{ + return bitsSentTotal; +} + +qint64 TCPLink::getBitsReceived() const +{ + return bitsReceivedTotal; +} + +qint64 TCPLink::getTotalDownstream() +{ + statisticsMutex.lock(); + qint64 totalDownstream = bitsReceivedTotal / ((QGC::groundTimeUsecs()/1000 - connectionStartTime) / 1000); + statisticsMutex.unlock(); + return totalDownstream; +} + +qint64 TCPLink::getCurrentDownstream() +{ + return 0; // TODO +} + +qint64 TCPLink::getMaxDownstream() +{ + return 0; // TODO +} + +bool TCPLink::isFullDuplex() const +{ + return true; +} + +int TCPLink::getLinkQuality() const +{ + /* This feature is not supported with this interface */ + return -1; +} diff --git a/src/comm/TCPLink.h b/src/comm/TCPLink.h new file mode 100644 index 0000000000..c2d639fb91 --- /dev/null +++ b/src/comm/TCPLink.h @@ -0,0 +1,121 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2011 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/** + * @file + * @brief TCP connection (server) for unmanned vehicles + * @author Lorenz Meier + * + */ + +#ifndef TCPLINK_H +#define TCPLINK_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class TCPLink : public LinkInterface +{ + Q_OBJECT + +public: + TCPLink(QHostAddress host = QHostAddress::Any, quint16 port = 14550); + ~TCPLink(); + + void requestReset() { } + + bool isConnected() const; + qint64 bytesAvailable(); + int getPort() const { + return port; + } + + QString getName() const; + int getBaudRate() const; + int getBaudRateType() const; + int getFlowType() const; + int getParityType() const; + int getDataBitsType() const; + int getStopBitsType() const; + + /* Extensive statistics for scientific purposes */ + qint64 getNominalDataRate() const; + qint64 getTotalUpstream(); + qint64 getCurrentUpstream(); + qint64 getMaxUpstream(); + qint64 getTotalDownstream(); + qint64 getCurrentDownstream(); + qint64 getMaxDownstream(); + qint64 getBitsSent() const; + qint64 getBitsReceived() const; + + void run(); + + int getLinkQuality() const; + bool isFullDuplex() const; + int getId() const; + +public slots: + void setAddress(QHostAddress host); + void setPort(int port); + void readBytes(); + void writeBytes(const char* data, qint64 length); + bool connect(); + bool disconnect(); + void socketConnected(); + +protected: + QString name; + QHostAddress host; + quint16 port; + int id; + QTcpSocket* socket; + bool socketIsConnected; + + quint64 bitsSentTotal; + quint64 bitsSentCurrent; + quint64 bitsSentMax; + quint64 bitsReceivedTotal; + quint64 bitsReceivedCurrent; + quint64 bitsReceivedMax; + quint64 connectionStartTime; + QMutex statisticsMutex; + QMutex dataMutex; + + void setName(QString name); + +private: + bool hardwareConnect(void); + +signals: + //Signals are defined by LinkInterface + +}; + +#endif // TCPLINK_H diff --git a/src/ui/CommConfigurationWindow.cc b/src/ui/CommConfigurationWindow.cc index 462f1c42cb..96894ed1d2 100644 --- a/src/ui/CommConfigurationWindow.cc +++ b/src/ui/CommConfigurationWindow.cc @@ -40,6 +40,7 @@ This file is part of the QGROUNDCONTROL project #include "SerialConfigurationWindow.h" #include "SerialLink.h" #include "UDPLink.h" +#include "TCPLink.h" #include "MAVLinkSimulationLink.h" #ifdef XBEELINK #include "XbeeLink.h" @@ -82,6 +83,7 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn // add link types ui.linkType->addItem(tr("Serial"), QGC_LINK_SERIAL); ui.linkType->addItem(tr("UDP"), QGC_LINK_UDP); + ui.linkType->addItem(tr("TCP"), QGC_LINK_TCP); if(dynamic_cast(link)) { //Only show simulation option if already setup elsewhere as a simulation ui.linkType->addItem(tr("Simulation"), QGC_LINK_SIMULATION); @@ -148,6 +150,11 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn ui.linkGroupBox->setTitle(tr("UDP Link")); ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_UDP)); } + TCPLink* tcp = dynamic_cast(link); + if (tcp != 0) { + ui.linkGroupBox->setTitle(tr("TCP Link")); + ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_TCP)); + } MAVLinkSimulationLink* sim = dynamic_cast(link); if (sim != 0) { ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_SIMULATION)); @@ -177,7 +184,7 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn connect(xbee,SIGNAL(tryConnectEnd(bool)),ui.actionConnect,SLOT(setEnabled(bool))); } #endif // XBEELINK - if (serial == 0 && udp == 0 && sim == 0 + if (serial == 0 && udp == 0 && sim == 0 && tcp == 0 #ifdef OPAL_RT && opal == 0 #endif @@ -256,6 +263,14 @@ void CommConfigurationWindow::setLinkType(qgc_link_t linktype) break; } + case QGC_LINK_TCP: + { + TCPLink *tcp = new TCPLink(); + tmpLink = tcp; + MainWindow::instance()->addLink(tmpLink); + break; + } + #ifdef OPAL_RT case QGC_LINK_OPAL: { diff --git a/src/ui/CommConfigurationWindow.h b/src/ui/CommConfigurationWindow.h index 47e2b4c8ff..406331604c 100644 --- a/src/ui/CommConfigurationWindow.h +++ b/src/ui/CommConfigurationWindow.h @@ -42,6 +42,7 @@ This file is part of the QGROUNDCONTROL project enum qgc_link_t { QGC_LINK_SERIAL, QGC_LINK_UDP, + QGC_LINK_TCP, QGC_LINK_SIMULATION, QGC_LINK_FORWARDING, #ifdef XBEELINK -- GitLab From db465d5a2c46fad3360a46f8791df70fa141c27a Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Thu, 28 Nov 2013 18:30:47 -0800 Subject: [PATCH 452/460] Final TCP link support --- qgcunittest.pro | 3 ++ qgroundcontrol.pro | 3 ++ src/comm/TCPLink.cc | 84 ++++++++++++++++--------------- src/comm/TCPLink.h | 14 +++++- src/ui/CommConfigurationWindow.cc | 7 ++- src/ui/QGCTCPLinkConfiguration.cc | 35 +++++++++++++ src/ui/QGCTCPLinkConfiguration.h | 32 ++++++++++++ src/ui/QGCTCPLinkConfiguration.ui | 51 +++++++++++++++++++ 8 files changed, 184 insertions(+), 45 deletions(-) create mode 100644 src/ui/QGCTCPLinkConfiguration.cc create mode 100644 src/ui/QGCTCPLinkConfiguration.h create mode 100644 src/ui/QGCTCPLinkConfiguration.ui diff --git a/qgcunittest.pro b/qgcunittest.pro index 308ce32dc8..b8b8a5d564 100644 --- a/qgcunittest.pro +++ b/qgcunittest.pro @@ -200,6 +200,7 @@ FORMS += src/ui/MainWindow.ui \ src/ui/QGCMAVLinkLogPlayer.ui \ src/ui/QGCWaypointListMulti.ui \ src/ui/QGCUDPLinkConfiguration.ui \ + src/ui/QGCTCPLinkConfiguration.ui \ src/ui/QGCSettingsWidget.ui \ src/ui/UASControlParameters.ui \ src/ui/map/QGCMapTool.ui \ @@ -323,6 +324,7 @@ HEADERS += src/MG.h \ src/uas/QGCMAVLinkUASFactory.h \ src/ui/QGCWaypointListMulti.h \ src/ui/QGCUDPLinkConfiguration.h \ + src/ui/QGCTCPLinkConfiguration.h \ src/ui/QGCSettingsWidget.h \ src/ui/uas/UASControlParameters.h \ src/uas/QGCUASParamManager.h \ @@ -490,6 +492,7 @@ SOURCES += src/QGCCore.cc \ src/uas/QGCMAVLinkUASFactory.cc \ src/ui/QGCWaypointListMulti.cc \ src/ui/QGCUDPLinkConfiguration.cc \ + src/ui/QGCTCPLinkConfiguration.cc \ src/ui/QGCSettingsWidget.cc \ src/ui/uas/UASControlParameters.cpp \ src/uas/QGCUASParamManager.cc \ diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index b34aefbb2e..3f48dc0f24 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -227,6 +227,7 @@ FORMS += src/ui/MainWindow.ui \ src/ui/QGCMAVLinkLogPlayer.ui \ src/ui/QGCWaypointListMulti.ui \ src/ui/QGCUDPLinkConfiguration.ui \ + src/ui/QGCTCPLinkConfiguration.ui \ src/ui/QGCSettingsWidget.ui \ src/ui/UASControlParameters.ui \ src/ui/map/QGCMapTool.ui \ @@ -408,6 +409,7 @@ HEADERS += src/MG.h \ src/uas/QGCMAVLinkUASFactory.h \ src/ui/QGCWaypointListMulti.h \ src/ui/QGCUDPLinkConfiguration.h \ + src/ui/QGCTCPLinkConfiguration.h \ src/ui/QGCSettingsWidget.h \ src/ui/uas/UASControlParameters.h \ src/uas/QGCUASParamManager.h \ @@ -634,6 +636,7 @@ SOURCES += src/main.cc \ src/uas/QGCMAVLinkUASFactory.cc \ src/ui/QGCWaypointListMulti.cc \ src/ui/QGCUDPLinkConfiguration.cc \ + src/ui/QGCTCPLinkConfiguration.cc \ src/ui/QGCSettingsWidget.cc \ src/ui/uas/UASControlParameters.cpp \ src/uas/QGCUASParamManager.cc \ diff --git a/src/comm/TCPLink.cc b/src/comm/TCPLink.cc index c1c2d01ade..f56ef84d38 100644 --- a/src/comm/TCPLink.cc +++ b/src/comm/TCPLink.cc @@ -37,24 +37,20 @@ #include "LinkManager.h" #include "QGC.h" #include -//#include -TCPLink::TCPLink(QHostAddress host, quint16 port) -: socket(NULL) +TCPLink::TCPLink(QHostAddress hostAddress, quint16 socketPort) : + host(hostAddress), + port(socketPort), + socket(NULL), + socketIsConnected(false) + { - // FIXFIX: host and port and hard-wired - this->host = "127.0.0.1"; - this->port = 5760; - - this->socketIsConnected = false; - // Set unique ID and add link to the list of links this->id = getNextLinkId(); - // FIXFIX: What about host name? this->name = tr("TCP Link (port:%1)").arg(this->port); emit nameChanged(this->name); - qDebug() << "TCP Created " << name; + qDebug() << "TCP Created " << this->name; } TCPLink::~TCPLink() @@ -63,25 +59,26 @@ TCPLink::~TCPLink() this->deleteLater(); } -/** - * @brief Runs the thread - * - **/ void TCPLink::run() { exec(); } +void TCPLink::setAddress(const QString &text) +{ + setAddress(QHostAddress(text)); +} + void TCPLink::setAddress(QHostAddress host) { bool reconnect(false); - if(this->isConnected()) + if (this->isConnected()) { disconnect(); reconnect = true; } this->host = host; - if(reconnect) + if (reconnect) { connect(); } @@ -104,10 +101,9 @@ void TCPLink::setPort(int port) } } -void TCPLink::writeBytes(const char* data, qint64 size) +#ifdef TCPLINK_READWRITE_DEBUG +void TCPLink::writeDebugBytes(const char *data, qint16 size) { - //#define TCPLINK_DEBUG -#ifdef TCPLINK_DEBUG QString bytes; QString ascii; for (int i=0; iwrite(data, size); } @@ -148,17 +151,10 @@ void TCPLink::readBytes() socket->read(buffer.data(), buffer.size()); emit bytesReceived(this, buffer); - - // // Echo data for debugging purposes - // std::cerr << __FILE__ << __LINE__ << "Received datagram:" << std::endl; - // int i; - // for (i=0; idisconnect(); - socketIsConnected = false; - } + socket->disconnect(); + socketIsConnected = false; delete socket; socket = NULL; } @@ -220,17 +214,25 @@ bool TCPLink::hardwareConnect(void) socket->connectToHost(host, port); QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(readBytes())); - //QObject::connect(socket, SIGNAL(connected()), this, SLOT(socketConnected())); - socketIsConnected = true; + QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); + + // Give the socket a second to connect to the other side otherwise error out + if (!socket->waitForConnected(1000)) + { + emit communicationError(getName(), "connection failed"); + return false; + } + socketIsConnected = true; connectionStartTime = QGC::groundTimeUsecs()/1000; - + emit connected(true); + return true; } -void TCPLink::socketConnected() +void TCPLink::socketError(QAbstractSocket::SocketError socketError) { - socketIsConnected = true; + emit communicationError(getName(), "Error on socket: " + socket->errorString()); } /** diff --git a/src/comm/TCPLink.h b/src/comm/TCPLink.h index c2d639fb91..6c6131d6f4 100644 --- a/src/comm/TCPLink.h +++ b/src/comm/TCPLink.h @@ -40,12 +40,14 @@ #include #include +//#define TCPLINK_READWRITE_DEBUG // Use to debug data reads/writes + class TCPLink : public LinkInterface { Q_OBJECT public: - TCPLink(QHostAddress host = QHostAddress::Any, quint16 port = 14550); + TCPLink(QHostAddress hostAddress = QHostAddress::LocalHost, quint16 socketPort = 5760); ~TCPLink(); void requestReset() { } @@ -55,6 +57,9 @@ public: int getPort() const { return port; } + QHostAddress getHostAddress() const { + return host; + } QString getName() const; int getBaudRate() const; @@ -88,7 +93,9 @@ public slots: void writeBytes(const char* data, qint64 length); bool connect(); bool disconnect(); - void socketConnected(); + void socketError(QAbstractSocket::SocketError socketError); + void setAddress(const QString &text); + protected: QString name; @@ -112,6 +119,9 @@ protected: private: bool hardwareConnect(void); +#ifdef TCPLINK_READWRITE_DEBUG + void writeDebugBytes(const char *data, qint16 size); +#endif signals: //Signals are defined by LinkInterface diff --git a/src/ui/CommConfigurationWindow.cc b/src/ui/CommConfigurationWindow.cc index 96894ed1d2..5da0323569 100644 --- a/src/ui/CommConfigurationWindow.cc +++ b/src/ui/CommConfigurationWindow.cc @@ -53,6 +53,7 @@ This file is part of the QGROUNDCONTROL project #include "MAVLinkProtocol.h" #include "MAVLinkSettingsWidget.h" #include "QGCUDPLinkConfiguration.h" +#include "QGCTCPLinkConfiguration.h" #include "LinkManager.h" #include "MainWindow.h" @@ -152,6 +153,8 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn } TCPLink* tcp = dynamic_cast(link); if (tcp != 0) { + QWidget* conf = new QGCTCPLinkConfiguration(tcp, this); + ui.linkScrollArea->setWidget(conf); ui.linkGroupBox->setTitle(tr("TCP Link")); ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_TCP)); } @@ -264,12 +267,12 @@ void CommConfigurationWindow::setLinkType(qgc_link_t linktype) } case QGC_LINK_TCP: - { + { TCPLink *tcp = new TCPLink(); tmpLink = tcp; MainWindow::instance()->addLink(tmpLink); break; - } + } #ifdef OPAL_RT case QGC_LINK_OPAL: diff --git a/src/ui/QGCTCPLinkConfiguration.cc b/src/ui/QGCTCPLinkConfiguration.cc new file mode 100644 index 0000000000..364631ad3d --- /dev/null +++ b/src/ui/QGCTCPLinkConfiguration.cc @@ -0,0 +1,35 @@ +#include + +#include "QGCTCPLinkConfiguration.h" +#include "ui_QGCTCPLinkConfiguration.h" + +QGCTCPLinkConfiguration::QGCTCPLinkConfiguration(TCPLink* link, QWidget *parent) : + QWidget(parent), + link(link), + ui(new Ui::QGCTCPLinkConfiguration) +{ + ui->setupUi(this); + uint16_t port = link->getPort(); + ui->portSpinBox->setValue(port); + QString addr = link->getHostAddress().toString(); + ui->hostAddressLineEdit->setText(addr); + connect(ui->portSpinBox, SIGNAL(valueChanged(int)), link, SLOT(setPort(int))); + connect(ui->hostAddressLineEdit, SIGNAL(textChanged (const QString &)), link, SLOT(setAddress(const QString &))); +} + +QGCTCPLinkConfiguration::~QGCTCPLinkConfiguration() +{ + delete ui; +} + +void QGCTCPLinkConfiguration::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} \ No newline at end of file diff --git a/src/ui/QGCTCPLinkConfiguration.h b/src/ui/QGCTCPLinkConfiguration.h new file mode 100644 index 0000000000..0d8eb33ad7 --- /dev/null +++ b/src/ui/QGCTCPLinkConfiguration.h @@ -0,0 +1,32 @@ +#ifndef QGCTCPLINKCONFIGURATION_H +#define QGCTCPLINKCONFIGURATION_H + +#include + +#include "TCPLink.h" + +namespace Ui +{ +class QGCTCPLinkConfiguration; +} + +class QGCTCPLinkConfiguration : public QWidget +{ + Q_OBJECT + +public: + explicit QGCTCPLinkConfiguration(TCPLink* link, QWidget *parent = 0); + ~QGCTCPLinkConfiguration(); + +public slots: + +protected: + void changeEvent(QEvent *e); + + TCPLink* link; ///< TCP link instance this widget configures + +private: + Ui::QGCTCPLinkConfiguration *ui; +}; + +#endif // QGCTCPLINKCONFIGURATION_H diff --git a/src/ui/QGCTCPLinkConfiguration.ui b/src/ui/QGCTCPLinkConfiguration.ui new file mode 100644 index 0000000000..416e587970 --- /dev/null +++ b/src/ui/QGCTCPLinkConfiguration.ui @@ -0,0 +1,51 @@ + + + QGCTCPLinkConfiguration + + + + 0 + 0 + 400 + 300 + + + + Form + + + + QFormLayout::FieldsStayAtSizeHint + + + + + TCP Port + + + + + + + 3000 + + + 100000 + + + + + + + Host Address + + + + + + + + + + + -- GitLab From feda356f723227433d24ea2763856e2d37fc2f22 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Thu, 28 Nov 2013 21:57:08 -0800 Subject: [PATCH 453/460] Mavericks fix to APM_Toolbar QTBUG 34300 causes relative path references to qml file loading to fail. --- src/ui/apmtoolbar.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/ui/apmtoolbar.cpp b/src/ui/apmtoolbar.cpp index 6899f88d70..7b82aa8641 100644 --- a/src/ui/apmtoolbar.cpp +++ b/src/ui/apmtoolbar.cpp @@ -10,7 +10,16 @@ APMToolBar::APMToolBar(QWidget *parent): QDeclarativeView(parent), m_uas(0) { // Configure our QML object + + // Hack to fix QTBUG 34300 on OSX where QDir::currentPath has changed behavior. This causes + // relative paths to inside the .app package to fail. +#ifdef Q_OS_MAC + QString qmlFile = QApplication::applicationDirPath(); + qmlFile.append("/qml/ApmToolBar.qml"); + setSource(QUrl::fromLocalFile(qmlFile)); +#else setSource(QUrl::fromLocalFile("qml/ApmToolBar.qml")); +#endif setResizeMode(QDeclarativeView::SizeRootObjectToView); this->rootContext()->setContextProperty("globalObj", this); connect(LinkManager::instance(),SIGNAL(newLink(LinkInterface*)), -- GitLab From aa9dfa2333880457094fc90f96a2c165959011d9 Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Wed, 4 Dec 2013 23:56:40 +0100 Subject: [PATCH 454/460] fix handling of setmode when base_mode was not yet updated, also fix some wrong bitmask handling --- src/uas/UAS.cc | 135 +++++++++++++++++++++++++++++++------------------ src/uas/UAS.h | 6 ++- 2 files changed, 92 insertions(+), 49 deletions(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index e50e1dc761..64bb2d8a28 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -143,7 +143,8 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), sensorHil(false), lastSendTimeGPS(0), lastSendTimeSensors(0), - blockHomePositionChanges(false) + blockHomePositionChanges(false), + receivedMode(false) { for (unsigned int i = 0; i<255;++i) { @@ -309,6 +310,7 @@ void UAS::updateState() if (!connectionLost && (heartbeatInterval > timeoutIntervalHeartbeat)) { connectionLost = true; + receivedMode = false; QString audiostring = QString("Link lost to system %1").arg(this->getUASID()); GAudioOutput::instance()->say(audiostring.toLower()); } @@ -572,6 +574,7 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message) if (this->base_mode != state.base_mode || this->custom_mode != state.custom_mode) { modechanged = true; + receivedMode = true; this->base_mode = state.base_mode; this->custom_mode = state.custom_mode; shortModeText = getShortModeTextFor(this->base_mode, this->custom_mode, this->autopilot); @@ -1821,26 +1824,51 @@ QList UAS::getComponentIds() } /** -* @param mode that UAS is to be set to. +* @param newBaseMode that UAS is to be set to. +* @param newCustomMode that UAS is to be set to. */ void UAS::setMode(uint8_t newBaseMode, uint32_t newCustomMode) { - //this->mode = mode; //no call assignament, update receive message from UAS + if (receivedMode) + { + //this->mode = mode; //no call assignament, update receive message from UAS - // Strip armed / disarmed call, this is not relevant for setting the mode - newBaseMode &= ~MAV_MODE_FLAG_SAFETY_ARMED; - // Now set current state (request no change) - newBaseMode |= this->base_mode & MAV_MODE_FLAG_SAFETY_ARMED; + // Strip armed / disarmed call for safety reasons, this is not relevant for setting the mode + newBaseMode &= ~MAV_MODE_FLAG_SAFETY_ARMED; + // Now set current state (request no change) + newBaseMode |= this->base_mode & MAV_MODE_FLAG_SAFETY_ARMED; - // Strip HIL part, replace it with current system state - newBaseMode &= (~MAV_MODE_FLAG_HIL_ENABLED); - // Now set current state (request no change) - newBaseMode |= this->base_mode & MAV_MODE_FLAG_HIL_ENABLED; +// // Strip HIL part, replace it with current system state +// newBaseMode &= (~MAV_MODE_FLAG_HIL_ENABLED); +// // Now set current state (request no change) +// newBaseMode |= this->base_mode & MAV_MODE_FLAG_HIL_ENABLED; - mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, (uint8_t)uasId, newBaseMode, newCustomMode); - sendMessage(msg); - qDebug() << "SENDING REQUEST TO SET MODE TO SYSTEM" << uasId << ", MODE " << newBaseMode << " " << newCustomMode; + setModeArm(newBaseMode, newCustomMode); + } + else + { + qDebug() << "WARNING: setMode called before base_mode bitmask was received from UAS"; + } +} + +/** +* @param newBaseMode that UAS is to be set to. +* @param newCustomMode that UAS is to be set to. +*/ +void UAS::setModeArm(uint8_t newBaseMode, uint32_t newCustomMode) +{ + if (receivedMode) + { + mavlink_message_t msg; + mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, (uint8_t)uasId, newBaseMode, newCustomMode); + qDebug() << "mavlink_msg_set_mode_pack 1"; + sendMessage(msg); + qDebug() << "SENDING REQUEST TO SET MODE TO SYSTEM" << uasId << ", MODE " << newBaseMode << " " << newCustomMode; + } + else + { + qDebug() << "WARNING: setModeArm called before base_mode bitmask was received from UAS"; + } } /** @@ -2716,9 +2744,10 @@ void UAS::launch() */ void UAS::armSystem() { - mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); - sendMessage(msg); +// mavlink_message_t msg; + setModeArm(base_mode | MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); +// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); +// sendMessage(msg); } /** @@ -2727,37 +2756,42 @@ void UAS::armSystem() */ void UAS::disarmSystem() { - mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode & ~MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); - sendMessage(msg); +// mavlink_message_t msg; + setModeArm(base_mode & ~MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); +// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode & ~MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); +// sendMessage(msg); } void UAS::toggleArmedState() { - mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode ^ MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); - sendMessage(msg); +// mavlink_message_t msg; + setModeArm(base_mode ^ MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); +// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode ^ MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); +// sendMessage(msg); } void UAS::goAutonomous() { - mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_MODE_FLAG_AUTO_ENABLED, 0); - sendMessage(msg); +// mavlink_message_t msg; + setMode(base_mode | MAV_MODE_FLAG_AUTO_ENABLED, custom_mode); +// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_MODE_FLAG_AUTO_ENABLED, 0); +// sendMessage(msg); } void UAS::goManual() { - mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, 0); - sendMessage(msg); +// mavlink_message_t msg; + setMode(base_mode | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, custom_mode); +// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, 0); +// sendMessage(msg); } void UAS::toggleAutonomy() { - mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode ^ MAV_MODE_FLAG_AUTO_ENABLED ^ MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, 0); - sendMessage(msg); +// mavlink_message_t msg; + setMode(base_mode ^ MAV_MODE_FLAG_AUTO_ENABLED ^ MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, custom_mode); +// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode ^ MAV_MODE_FLAG_AUTO_ENABLED ^ MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, 0); +// sendMessage(msg); } /** @@ -3117,9 +3151,10 @@ void UAS::sendHilState(quint64 time_us, float roll, float pitch, float yaw, floa else { // Attempt to set HIL mode - mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); - sendMessage(msg); +// mavlink_message_t msg; + setMode(base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); +// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); +// sendMessage(msg); qDebug() << __FILE__ << __LINE__ << "HIL is onboard not enabled, trying to enable."; } } @@ -3144,9 +3179,10 @@ void UAS::sendHilSensors(quint64 time_us, float xacc, float yacc, float zacc, fl else { // Attempt to set HIL mode - mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); - sendMessage(msg); +// mavlink_message_t msg; + setMode(base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); +// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); +// sendMessage(msg); qDebug() << __FILE__ << __LINE__ << "HIL is onboard not enabled, trying to enable."; } } @@ -3175,9 +3211,10 @@ void UAS::sendHilGps(quint64 time_us, double lat, double lon, double alt, int fi else { // Attempt to set HIL mode - mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); - sendMessage(msg); +// mavlink_message_t msg; + setMode(base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); +// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); +// sendMessage(msg); qDebug() << __FILE__ << __LINE__ << "HIL is onboard not enabled, trying to enable."; } } @@ -3191,9 +3228,10 @@ void UAS::startHil() if (hilEnabled) return; hilEnabled = true; sensorHil = false; - mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); - sendMessage(msg); +// mavlink_message_t msg; + setMode(base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); +// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); +// sendMessage(msg); // Connect HIL simulation link simulation->connectSimulation(); } @@ -3204,9 +3242,10 @@ void UAS::startHil() void UAS::stopHil() { if (simulation) simulation->disconnectSimulation(); - mavlink_message_t msg; - mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode & !MAV_MODE_FLAG_HIL_ENABLED, custom_mode); - sendMessage(msg); +// mavlink_message_t msg; +// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode & ~MAV_MODE_FLAG_HIL_ENABLED, custom_mode); + setMode(base_mode & ~MAV_MODE_FLAG_HIL_ENABLED, custom_mode); +// sendMessage(msg); hilEnabled = false; sensorHil = false; } diff --git a/src/uas/UAS.h b/src/uas/UAS.h index e30946a67c..25b8ffc944 100644 --- a/src/uas/UAS.h +++ b/src/uas/UAS.h @@ -465,6 +465,7 @@ protected: //COMMENTS FOR TEST UNIT QImage image; ///< Image data of last completely transmitted image quint64 imageStart; bool blockHomePositionChanges; ///< Block changes to the home position + bool receivedMode; ///< True if mode was retrieved from current conenction to UAS #if defined(QGC_PROTOBUF_ENABLED) && defined(QGC_USE_PIXHAWK_MESSAGES) px::GLOverlay overlay; @@ -833,9 +834,12 @@ public slots: /** @brief Set this UAS as the system currently in focus, e.g. in the main display widgets */ void setSelected(); - /** @brief Set current mode of operation, e.g. auto or manual */ + /** @brief Set current mode of operation, e.g. auto or manual, always uses the current arming status for safety reason */ void setMode(uint8_t newBaseMode, uint32_t newCustomMode); + /** @brief Set current mode of operation, e.g. auto or manual, does not check the arming status, for anything else than arming/disarming operations use setMode instead */ + void setModeArm(uint8_t newBaseMode, uint32_t newCustomMode); + /** @brief Request all parameters */ void requestParameters(); -- GitLab From f50c15f16b0e2f96a0dada8210c263ee1be30987 Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Thu, 5 Dec 2013 16:21:50 +0100 Subject: [PATCH 455/460] set_mode fix: cleanup --- src/uas/UAS.cc | 37 ++----------------------------------- 1 file changed, 2 insertions(+), 35 deletions(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 64bb2d8a28..434111f162 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -1847,7 +1847,7 @@ void UAS::setMode(uint8_t newBaseMode, uint32_t newCustomMode) } else { - qDebug() << "WARNING: setMode called before base_mode bitmask was received from UAS"; + qDebug() << "WARNING: setMode called before base_mode bitmask was received from UAS, new mode was not sent to system"; } } @@ -1867,7 +1867,7 @@ void UAS::setModeArm(uint8_t newBaseMode, uint32_t newCustomMode) } else { - qDebug() << "WARNING: setModeArm called before base_mode bitmask was received from UAS"; + qDebug() << "WARNING: setModeArm called before base_mode bitmask was received from UAS, new mode was not sent to system"; } } @@ -2744,10 +2744,7 @@ void UAS::launch() */ void UAS::armSystem() { -// mavlink_message_t msg; setModeArm(base_mode | MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); -// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); -// sendMessage(msg); } /** @@ -2756,42 +2753,27 @@ void UAS::armSystem() */ void UAS::disarmSystem() { -// mavlink_message_t msg; setModeArm(base_mode & ~MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); -// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode & ~MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); -// sendMessage(msg); } void UAS::toggleArmedState() { -// mavlink_message_t msg; setModeArm(base_mode ^ MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); -// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode ^ MAV_MODE_FLAG_SAFETY_ARMED, custom_mode); -// sendMessage(msg); } void UAS::goAutonomous() { -// mavlink_message_t msg; setMode(base_mode | MAV_MODE_FLAG_AUTO_ENABLED, custom_mode); -// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_MODE_FLAG_AUTO_ENABLED, 0); -// sendMessage(msg); } void UAS::goManual() { -// mavlink_message_t msg; setMode(base_mode | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, custom_mode); -// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, 0); -// sendMessage(msg); } void UAS::toggleAutonomy() { -// mavlink_message_t msg; setMode(base_mode ^ MAV_MODE_FLAG_AUTO_ENABLED ^ MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, custom_mode); -// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode ^ MAV_MODE_FLAG_AUTO_ENABLED ^ MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, 0); -// sendMessage(msg); } /** @@ -3151,10 +3133,7 @@ void UAS::sendHilState(quint64 time_us, float roll, float pitch, float yaw, floa else { // Attempt to set HIL mode -// mavlink_message_t msg; setMode(base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); -// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); -// sendMessage(msg); qDebug() << __FILE__ << __LINE__ << "HIL is onboard not enabled, trying to enable."; } } @@ -3179,10 +3158,7 @@ void UAS::sendHilSensors(quint64 time_us, float xacc, float yacc, float zacc, fl else { // Attempt to set HIL mode -// mavlink_message_t msg; setMode(base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); -// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); -// sendMessage(msg); qDebug() << __FILE__ << __LINE__ << "HIL is onboard not enabled, trying to enable."; } } @@ -3211,10 +3187,7 @@ void UAS::sendHilGps(quint64 time_us, double lat, double lon, double alt, int fi else { // Attempt to set HIL mode -// mavlink_message_t msg; setMode(base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); -// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); -// sendMessage(msg); qDebug() << __FILE__ << __LINE__ << "HIL is onboard not enabled, trying to enable."; } } @@ -3228,10 +3201,7 @@ void UAS::startHil() if (hilEnabled) return; hilEnabled = true; sensorHil = false; -// mavlink_message_t msg; setMode(base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); -// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode | MAV_MODE_FLAG_HIL_ENABLED, custom_mode); -// sendMessage(msg); // Connect HIL simulation link simulation->connectSimulation(); } @@ -3242,10 +3212,7 @@ void UAS::startHil() void UAS::stopHil() { if (simulation) simulation->disconnectSimulation(); -// mavlink_message_t msg; -// mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), base_mode & ~MAV_MODE_FLAG_HIL_ENABLED, custom_mode); setMode(base_mode & ~MAV_MODE_FLAG_HIL_ENABLED, custom_mode); -// sendMessage(msg); hilEnabled = false; sensorHil = false; } -- GitLab From d7ae91c59433f32c0cb4fec5ab24638758eb8473 Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Fri, 6 Dec 2013 11:38:34 +0100 Subject: [PATCH 456/460] updated goAutonomous, goManual and toggleAutonomy --- src/uas/UAS.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 434111f162..5538435886 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -2763,17 +2763,17 @@ void UAS::toggleArmedState() void UAS::goAutonomous() { - setMode(base_mode | MAV_MODE_FLAG_AUTO_ENABLED, custom_mode); + setMode((base_mode & ~MAV_MODE_FLAG_MANUAL_INPUT_ENABLED) | (MAV_MODE_FLAG_AUTO_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED | MAV_MODE_FLAG_GUIDED_ENABLED), 0); } void UAS::goManual() { - setMode(base_mode | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, custom_mode); + setMode((base_mode & ~(MAV_MODE_FLAG_AUTO_ENABLED | MAV_MODE_FLAG_STABILIZE_ENABLED | MAV_MODE_FLAG_GUIDED_ENABLED)) | MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, 0); } void UAS::toggleAutonomy() { - setMode(base_mode ^ MAV_MODE_FLAG_AUTO_ENABLED ^ MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, custom_mode); + setMode(base_mode ^ MAV_MODE_FLAG_AUTO_ENABLED ^ MAV_MODE_FLAG_MANUAL_INPUT_ENABLED ^ MAV_MODE_FLAG_GUIDED_ENABLED ^ MAV_MODE_FLAG_STABILIZE_ENABLED, 0); } /** -- GitLab From ff5a3fe3d12e8fd5e356e7726ce2048345db6203 Mon Sep 17 00:00:00 2001 From: Anton Babushkin Date: Sun, 8 Dec 2013 13:23:11 +0400 Subject: [PATCH 457/460] Fix crash when acceptance in pixels == 0 --- src/ui/map/Waypoint2DIcon.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ui/map/Waypoint2DIcon.cc b/src/ui/map/Waypoint2DIcon.cc index 3bf54232f5..83aad5b51f 100644 --- a/src/ui/map/Waypoint2DIcon.cc +++ b/src/ui/map/Waypoint2DIcon.cc @@ -291,10 +291,12 @@ void Waypoint2DIcon::paint(QPainter *painter, const QStyleOptionGraphicsItem *op redPen.setWidth(1); painter->setPen(redPen); const int acceptance = map->metersToPixels(waypoint->getAcceptanceRadius(), Coord()); - painter->setPen(penBlack); - painter->drawEllipse(QPointF(0, 0), acceptance, acceptance); - painter->setPen(redPen); - painter->drawEllipse(QPointF(0, 0), acceptance, acceptance); + if (acceptance > 0) { + painter->setPen(penBlack); + painter->drawEllipse(QPointF(0, 0), acceptance, acceptance); + painter->setPen(redPen); + painter->drawEllipse(QPointF(0, 0), acceptance, acceptance); + } } if ((waypoint) && ((waypoint->getAction() == (int)MAV_CMD_NAV_LOITER_UNLIM) || (waypoint->getAction() == (int)MAV_CMD_NAV_LOITER_TIME) || (waypoint->getAction() == (int)MAV_CMD_NAV_LOITER_TURNS))) { -- GitLab From c014645853c710f64450c568042be911579ed6f2 Mon Sep 17 00:00:00 2001 From: Thomas Gubler Date: Sun, 8 Dec 2013 20:54:22 +0100 Subject: [PATCH 458/460] change type of port from uint16_t to quint16 --- src/ui/QGCTCPLinkConfiguration.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/QGCTCPLinkConfiguration.cc b/src/ui/QGCTCPLinkConfiguration.cc index 364631ad3d..7eb0f661ca 100644 --- a/src/ui/QGCTCPLinkConfiguration.cc +++ b/src/ui/QGCTCPLinkConfiguration.cc @@ -9,7 +9,7 @@ QGCTCPLinkConfiguration::QGCTCPLinkConfiguration(TCPLink* link, QWidget *parent) ui(new Ui::QGCTCPLinkConfiguration) { ui->setupUi(this); - uint16_t port = link->getPort(); + quint16 port = link->getPort(); ui->portSpinBox->setValue(port); QString addr = link->getHostAddress().toString(); ui->hostAddressLineEdit->setText(addr); @@ -32,4 +32,4 @@ void QGCTCPLinkConfiguration::changeEvent(QEvent *e) default: break; } -} \ No newline at end of file +} -- GitLab From 44cb715f84885b9efb08c67dc727e8feb28bc89b Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Tue, 10 Dec 2013 12:59:36 -0800 Subject: [PATCH 459/460] Use same resource file list between builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Linux build was broken due to the fact that it wasn’t copying qml files. With each build flavor having it’s own seperate copy code it was easy for these to get out of sync. Centralized the copy list so that it remains in sync across flavors. --- qgroundcontrol.pri | 49 ++++++++++++++++------------------------------ 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/qgroundcontrol.pri b/qgroundcontrol.pri index cff2724729..aeabbef310 100644 --- a/qgroundcontrol.pri +++ b/qgroundcontrol.pri @@ -28,6 +28,14 @@ win32-msvc2008|win32-msvc2010|win32-msvc2012 { # Turn off serial port warnings DEFINES += _TTY_NOWARN_ +// This is the list of application resources which must be copied to the build target location +// We create one list and use it in each build type so that the various build flavors don't +// get out of sync. +COPY_RESOURCE_LIST = \ + $$BASEDIR/files \ + $$BASEDIR/qml \ + $$BASEDIR/data + # MAC OS X macx|macx-g++42|macx-g++|macx-llvm: { @@ -47,15 +55,9 @@ macx|macx-g++42|macx-g++|macx-llvm: { ICON = $$BASEDIR/files/images/icons/macx.icns - # Copy contributed files - QMAKE_POST_LINK += && cp -rf $$BASEDIR/files $$TARGETDIR/qgroundcontrol.app/Contents/MacOS - # Copy google earth starter file - QMAKE_POST_LINK += && cp -f $$BASEDIR/files/images/earth.html $$TARGETDIR/qgroundcontrol.app/Contents/MacOS - # Copy CSS stylesheets - QMAKE_POST_LINK += && cp -f $$BASEDIR/files/styles/style-dark.css $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/style-dark.css - QMAKE_POST_LINK += && cp -f $$BASEDIR/files/styles/style-light.css $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/style-light.css - # Copy support files - QMAKE_POST_LINK += && cp -rf $$BASEDIR/files $$TARGETDIR/qgroundcontrol.app/Contents/MacOS + # Copy application resources + for(COPY_DIR, COPY_RESOURCE_LIST):QMAKE_POST_LINK += && cp -rf $${COPY_DIR} $$TARGETDIR/qgroundcontrol.app/Contents/MacOS + # Copy MAVLink QMAKE_POST_LINK += && cp -rf $$BASEDIR/libs/mavlink $$TARGETDIR/qgroundcontrol.app/Contents/MacOS # Copy libraries @@ -65,19 +67,6 @@ macx|macx-g++42|macx-g++|macx-llvm: { QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/Frameworks QMAKE_POST_LINK += && cp -rf $$BASEDIR/libs/lib/Frameworks/* $$TARGETDIR/qgroundcontrol.app/Contents/Frameworks - # Copy QML stuff - message(BASEDIR $$BASEDIR) - QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml - QMAKE_POST_LINK += && cp -rf $$BASEDIR/qml/*.qml $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml - - QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/components/ - QMAKE_POST_LINK += && cp -rf $$BASEDIR/qml/components/*.qml $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/components - - QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/resources - QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/resources/qgroundcontrol - QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/resources/qgroundcontrol/toolbar - QMAKE_POST_LINK += && cp -rf $$BASEDIR/qml/resources/qgroundcontrol/toolbar/*.png $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qml/resources/qgroundcontrol/toolbar - # Fix library paths inside executable QMAKE_POST_LINK += && install_name_tool -change libOpenThreads.dylib "@executable_path/../libs/libOpenThreads.dylib" $$TARGETDIR/qgroundcontrol.app/Contents/MacOS/qgroundcontrol @@ -256,10 +245,9 @@ linux-g++|linux-g++-64{ QMAKE_POST_LINK += && mkdir -p $$TARGETDIR } DESTDIR = $$TARGETDIR - QMAKE_POST_LINK += && cp -rf $$BASEDIR/files $$TARGETDIR - QMAKE_POST_LINK += && cp -rf $$BASEDIR/data $$TARGETDIR - QMAKE_POST_LINK += && mkdir -p $$TARGETDIR/files/images - QMAKE_POST_LINK += && cp -rf $$BASEDIR/files/styles/Vera.ttf $$TARGETDIR/files/styles/Vera.ttf + + # Copy application resources + for(COPY_DIR, COPY_RESOURCE_LIST):QMAKE_POST_LINK += && cp -rf $${COPY_DIR} $$TARGETDIR # osg/osgEarth dynamic casts might fail without this compiler option. # see http://osgearth.org/wiki/FAQ for details. @@ -346,6 +334,7 @@ win32-msvc2008|win32-msvc2010|win32-msvc2012 { # Copy dependencies BASEDIR_WIN = $$replace(BASEDIR,"/","\\") TARGETDIR_WIN = $$replace(TARGETDIR,"/","\\") + COPY_RESOURCE_LIST_WIN = $$replace(COPY_RESOURCE_LIST, "/","\\") CONFIG(debug, debug|release) { # Copy supporting library DLLs @@ -354,9 +343,7 @@ win32-msvc2008|win32-msvc2010|win32-msvc2012 { QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\libs\\thirdParty\\libxbee\\lib\\libxbee.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n)) # Copy application resources - QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\files" "$$TARGETDIR_WIN\\debug\\files" /E /I $$escape_expand(\\n)) - QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\models" "$$TARGETDIR_WIN\\debug\\models" /E /I $$escape_expand(\\n)) - QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\qml" "$$TARGETDIR_WIN\\debug\\qml" /E /I $$escape_expand(\\n)) + for(COPY_DIR, COPY_RESOURCE_LIST):QMAKE_POST_LINK += $$quote(xcopy /D /Y "$${COPY_DIR}" "$$TARGETDIR_WIN\\debug" /E /I $$escape_expand(\\n)) # Copy Qt DLLs QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\plugins" "$$TARGETDIR_WIN\\debug" /E /I $$escape_expand(\\n)) @@ -388,9 +375,7 @@ win32-msvc2008|win32-msvc2010|win32-msvc2012 { QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\libs\\thirdParty\\libxbee\\lib\\libxbee.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n)) # Copy application resources - QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\files" "$$TARGETDIR_WIN\\release\\files" /E /I $$escape_expand(\\n)) - QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\models" "$$TARGETDIR_WIN\\release\\models" /E /I $$escape_expand(\\n)) - QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\qml" "$$TARGETDIR_WIN\\release\\qml" /E /I $$escape_expand(\\n)) + for(COPY_DIR, COPY_RESOURCE_LIST_WIN):QMAKE_POST_LIST += $$quote(xcopy /D /Y "$${COPY_DIR}" "$$TARGETDIR_WIN\\release" /E /I $$escape_expand(\\n)) # Copy Qt DLLs QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\plugins" "$$TARGETDIR_WIN\\release" /E /I $$escape_expand(\\n)) -- GitLab From 4a91f435f4fca7f53e64dcfae887781330a3734a Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Wed, 11 Dec 2013 17:08:07 -0800 Subject: [PATCH 460/460] Windows build required atlbase.h While testing the previous commit on Windows I found that I could not compile windows due to include of atlbase.h. This file is no longer available in SDKs. It is only available in for money versions of VIsual Studio. Luckily this include was not needed. So I just removed it and Windows now builds again with just VS Express. Tested all changes on OSX, Linux and Windows (including speech on windows, which still works). --- qgroundcontrol.pri | 6 +++--- src/GAudioOutput.cc | 8 -------- src/GAudioOutput.h | 6 ------ 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/qgroundcontrol.pri b/qgroundcontrol.pri index aeabbef310..a7599d7c51 100644 --- a/qgroundcontrol.pri +++ b/qgroundcontrol.pri @@ -28,9 +28,9 @@ win32-msvc2008|win32-msvc2010|win32-msvc2012 { # Turn off serial port warnings DEFINES += _TTY_NOWARN_ -// This is the list of application resources which must be copied to the build target location -// We create one list and use it in each build type so that the various build flavors don't -// get out of sync. +# This is the list of application resources which must be copied to the build target location +# We create one list and use it in each build type so that the various build flavors don't +# get out of sync. COPY_RESOURCE_LIST = \ $$BASEDIR/files \ $$BASEDIR/qml \ diff --git a/src/GAudioOutput.cc b/src/GAudioOutput.cc index b3eb0e533e..e4f158d5ef 100644 --- a/src/GAudioOutput.cc +++ b/src/GAudioOutput.cc @@ -44,14 +44,6 @@ This file is part of the QGROUNDCONTROL project // Speech synthesis is only supported with MSVC compiler #if _MSC_VER // Documentation: http://msdn.microsoft.com/en-us/library/ee125082%28v=VS.85%29.aspx -#define _ATL_APARTMENT_THREADED - -#include -//You may derive a class from CComModule and use it if you want to override something, -//but do not change the name of _Module -extern CComModule _Module; -#include - #include //using System; diff --git a/src/GAudioOutput.h b/src/GAudioOutput.h index faef16f5e4..2f7ecdf948 100644 --- a/src/GAudioOutput.h +++ b/src/GAudioOutput.h @@ -65,12 +65,6 @@ extern "C" { #if _MSC_VER // Documentation: http://msdn.microsoft.com/en-us/library/ee125082%28v=VS.85%29.aspx -#define _ATL_APARTMENT_THREADED -#include -//You may derive a class from CComModule and use it if you want to override something, -//but do not change the name of _Module -extern CComModule _Module; -#include #include #endif -- GitLab

`NW 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 H;aLO*C<-Lm0Sb7ARKF2jZ;ChtuDZ;-tF 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 literal 0 HcmV?d00001 diff --git a/files/images/px4/rc/cessna_side.png b/files/images/px4/rc/cessna_side.png new file mode 100644 index 0000000000000000000000000000000000000000..5fc19e68ba5ceb47e23f6ec36961fc0038898633 GIT binary patch literal 74727 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 literal 0 HcmV?d00001 diff --git a/files/images/px4/rc/rc_backgrounds.graffle b/files/images/px4/rc/rc_backgrounds.graffle new file mode 100644 index 0000000000..a3b5c1703a --- /dev/null +++ b/files/images/px4/rc/rc_backgrounds.graffle @@ -0,0 +1,674 @@ + + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGraffle + 139.18.0.187838 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {559.28001499176025, 782.8900146484375}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2013-08-23 20:20:16 +0000 + Creator + Lorenz + DisplayScale + 1 0/72 in = 1 0/72 in + GraphDocumentVersion + 8 + GraphicsList + + + Bounds + {{188.3818359375, 271.5}, {29, 16}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + b + 0.379293 + g + 0.379287 + r + 0.379298 + + Font + Helvetica-Bold + Size + 13 + + ID + 38 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + RTFD + + BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0 + ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp + bmcBlIQBKwVyaWdodIaEAmlJAQWShISEDE5TRGljdGlv + bmFyeQCUhAFpA5KElpYHTlNDb2xvcoaShISEB05TQ29s + b3IAlIQBYwKEBGZmZmaD6ujoPoPq6Og+g+ro6D4BhpKE + lpYQTlNQYXJhZ3JhcGhTdHlsZYaShISEEE5TUGFyYWdy + YXBoU3R5bGUAlIQEQ0NAUwIAhISEB05TQXJyYXkAlJkM + koSEhAlOU1RleHRUYWIAlIQCQ2YAHIaShKKhADiGkoSi + oQBUhpKEoqEAcIaShKKhAIGMAIaShKKhAIGoAIaShKKh + AIHEAIaShKKhAIHgAIaShKKhAIH8AIaShKKhAIEYAYaS + hKKhAIE0AYaShKKhAIFQAYaGgQAIhARbMWZdg83MTD2G + koSWlgZOU0ZvbnSGkoSEhAZOU0ZvbnQelJkohAVbNDBj + XQYAAAAeAAAA//5IAGUAbAB2AGUAdABpAGMAYQAtAEIA + bwBsAGQAAACEAWYNmwCbAZsAmwCGhoY= + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red97\green97\blue97;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\b\fs26 \cf2 right} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{153, 271.5}, {20, 16}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + b + 0.379293 + g + 0.379287 + r + 0.379298 + + Font + Helvetica-Bold + Size + 13 + + ID + 36 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + RTFD + + BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0 + ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp + bmcBlIQBKwRsZWZ0hoQCaUkBBJKEhIQMTlNEaWN0aW9u + YXJ5AJSEAWkEkoSWlg5OU09yaWdpbmFsRm9udIaShISE + Bk5TRm9udB6UmRyEBVsyOGNdBgAAABQAAAD//kgAZQBs + AHYAZQB0AGkAYwBhAIQBZgyEAWMAnQGdAJ0AhpKElpYQ + TlNQYXJhZ3JhcGhTdHlsZYaShISEF05TTXV0YWJsZVBh + cmFncmFwaFN0eWxlAISEEE5TUGFyYWdyYXBoU3R5bGUA + lIQEQ0NAUwIAhYEACIQEWzFmXYPNzEw9hpKElpYGTlNG + b250hpKEm5kohAVbNDBjXQYAAAAeAAAA//5IAGUAbAB2 + AGUAdABpAGMAYQAtAEIAbwBsAGQAAACcDZ0AnQGdAJ0A + hpKElpYHTlNDb2xvcoaShISEB05TQ29sb3IAlJ0ChARm + ZmZmg+ro6D6D6ujoPoPq6Og+AYaGhg== + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red97\green97\blue97;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\b\fs26 \cf2 left} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{124, 268}, {23, 23}} + Class + ShapedGraphic + ID + 35 + Rotation + 180 + Shape + HorizontalTriangle + Style + + fill + + Color + + b + 0.380387 + g + 0.380387 + r + 0.380387 + + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{224, 268}, {23, 23}} + Class + ShapedGraphic + ID + 34 + Shape + HorizontalTriangle + Style + + fill + + Color + + b + 0.380387 + g + 0.380387 + r + 0.380387 + + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{251.99999284744263, 106}, {23, 23}} + Class + ShapedGraphic + ID + 33 + Rotation + 270 + Shape + HorizontalTriangle + Style + + fill + + Color + + b + 0.380387 + g + 0.380387 + r + 0.380387 + + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{167.80909729003906, 160}, {42.381816864013672, 42}} + Class + ShapedGraphic + ID + 32 + Shape + Circle + Style + + fill + + Color + + b + 0.379293 + g + 0.379287 + r + 0.379298 + + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{252, 205}, {23, 23}} + Class + ShapedGraphic + ID + 13 + Rotation + 90 + Shape + HorizontalTriangle + Style + + fill + + Color + + b + 0.380387 + g + 0.380387 + r + 0.380387 + + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{171.5, 147.5}, {128, 23}} + Class + ShapedGraphic + ID + 30 + Rotation + 90 + Shape + Rectangle + Style + + fill + + Color + + b + 0.409312 + g + 0.828576 + r + 0.468975 + + + shadow + + Draws + NO + + + + + Bounds + {{119, 237}, {128, 23}} + Class + ShapedGraphic + ID + 29 + Shape + Rectangle + Style + + fill + + Color + + b + 0.409312 + g + 0.828576 + r + 0.468975 + + + shadow + + Draws + NO + + + + + Bounds + {{78, 71}, {222, 220}} + Class + ShapedGraphic + ID + 28 + Shape + Circle + Style + + fill + + Color + + b + 0.877468 + g + 0.877468 + r + 0.877468 + + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + VerticalPad + 0 + + + + GridInfo + + GuidesLocked + NO + GuidesVisible + YES + HPages + 1 + ImageCounter + 1 + KeepToScale + + Layers + + + Lock + NO + Name + Ebene 1 + Print + YES + View + YES + + + LayoutInfo + + Animate + NO + circoMinDist + 18 + circoSeparation + 0.0 + layoutEngine + dot + neatoSeparation + 0.0 + twopiSeparation + 0.0 + + LinksVisible + NO + MagnetsVisible + NO + MasterSheets + + ModificationDate + 2013-08-26 18:20:11 +0000 + Modifier + Lorenz + NotesVisible + NO + Orientation + 2 + OriginVisible + NO + PageBreaks + YES + PrintInfo + + NSBottomMargin + + float + 41 + + NSHorizonalPagination + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSLeftMargin + + float + 18 + + NSPaperSize + + size + {595.28001499176025, 841.8900146484375} + + NSPrintReverseOrientation + + int + 0 + + NSRightMargin + + float + 18 + + NSTopMargin + + float + 18 + + + PrintOnePage + + ReadOnly + NO + RowAlign + 1 + RowSpacing + 36 + SheetTitle + Arbeitsfläche 1 + SmartAlignmentGuidesActive + YES + SmartDistanceGuidesActive + YES + UniqueID + 1 + UseEntirePage + + VPages + 1 + WindowInfo + + CurrentSheet + 0 + ExpandedCanvases + + Frame + {{76, 4}, {918, 774}} + ListView + + OutlineWidth + 142 + RightSidebar + + ShowRuler + + Sidebar + + SidebarWidth + 120 + VisibleRegion + {{-112, 0}, {783, 635}} + Zoom + 1 + ZoomValues + + + Arbeitsfläche 1 + 1 + 1 + + + + + diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 0e5a041496..d9bd57f2f6 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -180,6 +180,8 @@ files/images/px4/menu/plane.png files/images/px4/menu/remote.png files/images/px4/menu/cogwheels.png + files/images/px4/rc/cessna_back.png + files/images/px4/rc/cessna_side.png files/styles/Vera.ttf diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index c7b882a21f..cb1675fd32 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -60,6 +60,8 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : #ifdef QUPGRADE_SUPPORT firmwareDialog(NULL), #endif + planeBack(":/files/images/px4/rc/cessna_back.png"), + planeSide(":/files/images/px4/rc/cessna_side.png"), ui(new Ui::QGCPX4VehicleConfig) { doneLoadingConfig = false; @@ -142,6 +144,15 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(ui->advancedCheckBox, SIGNAL(clicked(bool)), ui->advancedGroupBox, SLOT(setVisible(bool))); ui->advancedGroupBox->setVisible(false); + connect(ui->advancedCheckBox, SIGNAL(clicked(bool)), ui->graphicsView, SLOT(setHidden(bool))); + ui->graphicsView->setScene(&scene); + + scene.addPixmap(planeBack); + scene.addPixmap(planeSide); + + // XXX hide while WIP + ui->graphicsView->hide(); + ui->rcCalibrationButton->setCheckable(true); connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool))); @@ -209,6 +220,7 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : rcMappedMin[i] = 1000; rcMappedMax[i] = 2000; rcMappedValue[i] = UINT16_MAX; + rcMappedValueRev[i] = UINT16_MAX; rcMappedNormalizedValue[i] = 0.0f; } @@ -217,6 +229,7 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : rcMappedMin[i] = 1000; rcMappedMax[i] = 2000; rcMappedValue[i] = UINT16_MAX; + rcMappedValueRev[i] = UINT16_MAX; rcMappedNormalizedValue[i] = 0.0f; } @@ -1184,13 +1197,12 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float fval) } // Raw value - float mappedVal = rcMappedValue[rcToFunctionMapping[chan]]; float deltaRaw = fabsf(fval - rcValue[chan]); - float delta = fabsf(fval - mappedVal); + float delta = fabsf(fval - rcMappedValue[rcToFunctionMapping[chan]]); if (!configEnabled && !calibrationEnabled && (deltaRaw < 12.0f && delta < 12.0f && rcValue[chan] > 800 && rcValue[chan] < 2200)) { - //ignore tiny jitter values + // ignore tiny jitter values return; } else { @@ -1281,17 +1293,13 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float fval) normalized = (rcRev[chan]) ? -1.0f*normalized : normalized; // Find correct mapped channel - for (unsigned int i = 0; i < chanCount; i++) { - if (chan == rcMapping[i]) { - rcMappedValue[i] = (rcRev[chan]) ? rcMax[chan] - (fval - rcMin[chan]) : fval; + rcMappedValueRev[rcToFunctionMapping[chan]] = (rcRev[chan]) ? rcMax[chan] - (fval - rcMin[chan]) : fval; + rcMappedValue[rcToFunctionMapping[chan]] = fval; - // Copy min / max - rcMappedMin[i] = rcMin[chan]; - rcMappedMax[i] = rcMax[chan]; - - rcMappedNormalizedValue[i] = normalized; - } - } + // Copy min / max + rcMappedMin[rcToFunctionMapping[chan]] = rcMin[chan]; + rcMappedMax[rcToFunctionMapping[chan]] = rcMax[chan]; + rcMappedNormalizedValue[rcToFunctionMapping[chan]] = normalized; if (chan == rcMapping[0]) { rcRoll = normalized; diff --git a/src/ui/QGCPX4VehicleConfig.h b/src/ui/QGCPX4VehicleConfig.h index 1be13079cb..62d11c0143 100644 --- a/src/ui/QGCPX4VehicleConfig.h +++ b/src/ui/QGCPX4VehicleConfig.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "QGCToolWidget.h" #include "UASInterface.h" @@ -285,10 +286,11 @@ protected: float rcScaling[chanMax]; ///< Scaling of channel input to control commands bool rcRev[chanMax]; ///< Channel reverse int rcValue[chanMax]; ///< Last values, RAW - float rcValueReversed[chanMax]; ///< Last values, accounted for reverse - float rcMappedMin[chanMappedMax]; ///< Mapped channels in default order - float rcMappedMax[chanMappedMax]; ///< Mapped channels in default order - float rcMappedValue[chanMappedMax]; ///< Mapped channels in default order + int rcValueReversed[chanMax]; ///< Last values, accounted for reverse + int rcMappedMin[chanMappedMax]; ///< Mapped channels in default order + int rcMappedMax[chanMappedMax]; ///< Mapped channels in default order + int rcMappedValue[chanMappedMax]; ///< Mapped channels in default order + int rcMappedValueRev[chanMappedMax]; float rcMappedNormalizedValue[chanMappedMax]; ///< Mapped channels in default order int channelWanted; ///< During channel assignment search the requested default index int channelReverseStateWanted; @@ -323,8 +325,11 @@ protected: QGCPX4AirframeConfig* px4AirframeConfig; DialogBare* firmwareDialog; + QPixmap planeBack; + QPixmap planeSide; QGCPX4SensorCalibration* px4SensorCalibration; QMessageBox msgBox; + QGraphicsScene scene; QPushButton* skipActionButton; private: diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index f23424e64e..c9d9fb63b7 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -42,7 +42,7 @@ - 0 + 1 @@ -205,6 +205,9 @@ + + + @@ -819,8 +822,8 @@ 0 0 - 98 - 28 + 21 + 16 @@ -856,8 +859,8 @@ 0 0 - 98 - 28 + 21 + 16 @@ -907,8 +910,8 @@ 0 0 - 98 - 28 + 16 + 16 -- GitLab From de5fc6a5bd58688335a28a6ccbe238776f3672dc Mon Sep 17 00:00:00 2001 From: tstellanova Date: Mon, 26 Aug 2013 23:11:41 -0700 Subject: [PATCH 336/460] Reimplement write and read timeout retransmission Also move default component ID into data model --- src/uas/QGCUASParamManager.cc | 25 +- src/uas/QGCUASParamManager.h | 1 - src/uas/UASParameterCommsMgr.cc | 447 ++++++++++++------------------- src/uas/UASParameterCommsMgr.h | 45 ++-- src/uas/UASParameterDataModel.cc | 23 +- src/uas/UASParameterDataModel.h | 5 + 6 files changed, 230 insertions(+), 316 deletions(-) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 38450eb81a..90991f899d 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -11,8 +11,7 @@ QGCUASParamManager::QGCUASParamManager(QObject *parent) : QObject(parent), mav(NULL), paramDataModel(this), - paramCommsMgr(NULL), - defaultComponentId(-1) + paramCommsMgr(NULL) { @@ -63,22 +62,7 @@ void QGCUASParamManager::clearAllPendingParams() int QGCUASParamManager::getDefaultComponentId() { - int result = 0; - - if (-1 != defaultComponentId) - return defaultComponentId; - - QList components = getComponentForParam("SYS_AUTOSTART");//TODO is this the best way to find the right component? - - // Guard against multiple components responding - this will never show in practice - if (1 == components.count()) { - result = components.first(); - defaultComponentId = result; - } - - qDebug() << "Default compId: " << result; - - return result; + return paramDataModel.getDefaultComponentId(); } QList QGCUASParamManager::getComponentForParam(const QString& parameter) const @@ -119,7 +103,6 @@ void QGCUASParamManager::requestParameterListIfEmpty() if (mav) { int totalOnboard = paramDataModel.countOnboardParams(); if (totalOnboard < 2) { //TODO arbitrary constant, maybe 0 is OK? - defaultComponentId = -1; //reset this ...we have no idea what the default component ID is requestParameterList(); } } @@ -135,7 +118,7 @@ void QGCUASParamManager::setParameter(int compId, QString paramName, QVariant va { if ((0 == compId) || (-1 == compId)) { //attempt to get an actual component ID - compId = getDefaultComponentId(); + compId = paramDataModel.getDefaultComponentId(); } paramDataModel.updatePendingParamWithValue(compId,paramName,value); } @@ -152,7 +135,7 @@ void QGCUASParamManager::setPendingParam(int compId, const QString& paramName, { if ((0 == compId) || (-1 == compId)) { //attempt to get an actual component ID - compId = getDefaultComponentId(); + compId = paramDataModel.getDefaultComponentId(); } paramDataModel.updatePendingParamWithValue(compId,paramName,value); } diff --git a/src/uas/QGCUASParamManager.h b/src/uas/QGCUASParamManager.h index 2c31136e26..84efadfeed 100644 --- a/src/uas/QGCUASParamManager.h +++ b/src/uas/QGCUASParamManager.h @@ -125,7 +125,6 @@ protected: UASInterface* mav; ///< The MAV this manager is controlling UASParameterDataModel paramDataModel;///< Shared data model of parameters UASParameterCommsMgr* paramCommsMgr; ///< Shared comms mgr for parameters - int defaultComponentId; ///< Cached default component ID }; diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index a62ab19c5d..a176114e92 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -5,18 +5,18 @@ #include "QGCUASParamManager.h" #include "UASInterface.h" + + #define RC_CAL_CHAN_MAX 8 UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent) : QObject(parent), mav(NULL), + maxSilenceTimeout(30000), paramDataModel(NULL), - transmissionListMode(false), - transmissionActive(false), - transmissionTimeout(0), - retransmissionTimeout(1000), - rewriteTimeout(1000), - retransmissionBurstRequestSize(5) + retransmitBurstLimit(5), + silenceTimeout(1000), + transmissionListMode(false) { @@ -40,29 +40,27 @@ UASParameterCommsMgr* UASParameterCommsMgr::initWithUAS(UASInterface* uas) connect(mav, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(receivedParameterUpdate(int,int,int,int,QString,QVariant))); - //connect to retransmissionTimer - connect(&retransmissionTimer, SIGNAL(timeout()), - this, SLOT(retransmissionGuardTick())); + connect(&silenceTimer, SIGNAL(timeout()), + this,SLOT(silenceTimerExpired())); return this; } + void UASParameterCommsMgr::loadParamCommsSettings() { QSettings settings; + //TODO these are duplicates of MAVLinkProtocol settings...seems wrong to use them in two places settings.beginGroup("QGC_MAVLINK_PROTOCOL"); bool ok; - int val = settings.value("PARAMETER_RETRANSMISSION_TIMEOUT", retransmissionTimeout).toInt(&ok); - if (ok) { - retransmissionTimeout = val; - qDebug() << "retransmissionTimeout" << retransmissionTimeout; - } - val = settings.value("PARAMETER_REWRITE_TIMEOUT", rewriteTimeout).toInt(&ok); + int val = settings.value("PARAMETER_RETRANSMISSION_TIMEOUT", 1000).toInt(&ok); if (ok) { - rewriteTimeout = val; + silenceTimeout = val; + qDebug() << "silenceTimeout" << silenceTimeout; } + settings.endGroup(); } @@ -79,20 +77,11 @@ void UASParameterCommsMgr::requestParameterList() } if (!transmissionListMode) { - // Clear transmission state - receivedParamsList.clear(); - transmissionListSizeKnown.clear(); - - transmissionListMode = true; - foreach (int key, missingReadPackets.keys()) { - missingReadPackets.value(key)->clear(); - } - transmissionActive = true; - - setParameterStatusMsg(tr("Requested param list.. waiting")); - listRecvTimeout = QGC::groundTimeMilliseconds() + 10000; + transmissionListMode = true;//TODO eliminate? + //we use (compId 0, paramId 0) as indicating all params for the system + markReadParamWaiting(0,0); mav->requestParameters(); - setRetransmissionGuardEnabled(true); + updateSilenceTimer(); } else { qDebug() << __FILE__ << __LINE__ << "Ignoring requestParameterList because we're receiving params list"; @@ -101,6 +90,26 @@ void UASParameterCommsMgr::requestParameterList() } +void UASParameterCommsMgr::markReadParamWaiting(int compId, int paramId) +{ + if (!readsWaiting.contains(compId)) { + readsWaiting.insert(compId, new QSet()); + } + + readsWaiting.value(compId)->insert(paramId); +} + +void UASParameterCommsMgr::markWriteParamWaiting(int compId, QString paramName, QVariant value) +{ + //ensure we have a map for this compId + if (!writesWaiting.contains(compId)) { + writesWaiting.insert(compId, new QMap()); + } + + // Insert it in missing write ACK list + writesWaiting.value(compId)->insert(paramName, value); +} + /* Empty read retransmission list Empty write retransmission list @@ -110,17 +119,17 @@ void UASParameterCommsMgr::clearRetransmissionLists(int& missingReadCount, int& qDebug() << __FILE__ << __LINE__ << "clearRetransmissionLists"; missingReadCount = 0; - QList readKeys = missingReadPackets.keys(); - foreach (int compId, readKeys) { - missingReadCount += missingReadPackets.value(compId)->count(); - missingReadPackets.value(compId)->clear(); + QList compIds = readsWaiting.keys(); + foreach (int compId, compIds) { + missingReadCount += readsWaiting.value(compId)->count(); + readsWaiting.value(compId)->clear(); } missingWriteCount = 0; - QList writeKeys = missingWriteAckPackets.keys(); - foreach (int compId, writeKeys) { - missingWriteCount += missingWriteAckPackets.value(compId)->count(); - missingWriteAckPackets.value(compId)->clear(); + compIds = writesWaiting.keys(); + foreach (int compId, compIds) { + missingWriteCount += writesWaiting.value(compId)->count(); + writesWaiting.value(compId)->clear(); } } @@ -170,16 +179,21 @@ void UASParameterCommsMgr::resendReadWriteRequests() int compId; QList compIds; - // Re-request at maximum retransmissionBurstRequestSize parameters at once + // Re-request at maximum retransmitBurstLimit parameters at once // to prevent link flooding' int requestedReadCount = 0; - compIds = missingReadPackets.keys(); + compIds = readsWaiting.keys(); foreach (compId, compIds) { // Request n parameters from this component (at maximum) - QList* missingReadParams = missingReadPackets.value(compId, NULL); - qDebug() << "missingReadParams:" << missingReadParams->count(); + QSet* missingReadParams = readsWaiting.value(compId, NULL); + qDebug() << "compId " << compId << "readsWaiting:" << missingReadParams->count(); foreach (int paramId, *missingReadParams) { - if (requestedReadCount < retransmissionBurstRequestSize) { + if (0 == paramId && 0 == compId) { + mav->requestParameters(); + //don't request any other params individually for this component + break; + } + if (requestedReadCount < retransmitBurstLimit) { //qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD REQUESTS RETRANSMISSION OF PARAM #" << paramId << "FROM COMPONENT #" << compId; emit parameterUpdateRequestedById(compId, paramId); setParameterStatusMsg(tr("Requested retransmission of #%1").arg(paramId+1)); @@ -192,16 +206,16 @@ void UASParameterCommsMgr::resendReadWriteRequests() } } - // Re-request at maximum retransmissionBurstRequestSize parameters at once + // Re-request at maximum retransmitBurstLimit parameters at once // to prevent write-request link flooding int requestedWriteCount = 0; - compIds = missingWriteAckPackets.keys(); + compIds = writesWaiting.keys(); foreach (compId, compIds) { - QMap * missingParams = missingWriteAckPackets.value(compId); - foreach (QString key, missingParams->keys()) { - if (requestedWriteCount < retransmissionBurstRequestSize) { + QMap * missingWriteParams = writesWaiting.value(compId); + foreach (QString key, missingWriteParams->keys()) { + if (requestedWriteCount < retransmitBurstLimit) { // Re-request write operation - QVariant value = missingParams->value(key); + QVariant value = missingWriteParams->value(key); emitPendingParameterCommit(compId, key, value); requestedWriteCount++; } @@ -212,106 +226,47 @@ void UASParameterCommsMgr::resendReadWriteRequests() } } - if ((0 == requestedWriteCount) && (0 == requestedReadCount) ) { - qDebug() << __FILE__ << __LINE__ << "No pending re-read or rewrite requests"; - if (!transmissionListMode) { - setRetransmissionGuardEnabled(false); - transmissionActive = false; - } - } - else { - //restart the timer now that we've sent - setRetransmissionGuardEnabled(true); - } + updateSilenceTimer(); + } void UASParameterCommsMgr::resetAfterListReceive() { transmissionListMode = false; - transmissionListSizeKnown.clear(); - - //We shouldn't clear missingPackets because other transactions might be using them? - + knownParamListSize.clear(); } -void UASParameterCommsMgr::retransmissionGuardTick() +void UASParameterCommsMgr::silenceTimerExpired() { quint64 curTime = QGC::groundTimeMilliseconds(); + int elapsed = (int)(curTime - lastSilenceTimerReset); + qDebug() << "silenceTimerExpired elapsed:" << elapsed; - //Workaround for an apparent Qt bug that causes retransmission guard timer to fire prematurely (350ms) - int elapsed = (int)(curTime - lastTimerReset); - if (elapsed < retransmissionTimeout) { - qDebug() << "retransmissionGuardTick elapsed:" << (curTime - lastTimerReset); + if (elapsed < silenceTimeout) { //reset the guard timer: it fired prematurely - setRetransmissionGuardEnabled(true); + updateSilenceTimer(); return; } - qDebug() << __FILE__ << __LINE__ << "RETRANSMISSION GUARD ACTIVE after" << elapsed; - - - if (transmissionActive) { - - if (transmissionListMode && transmissionListSizeKnown.isEmpty() ) { - //we are still waitin for the first parameter list response - if (curTime > this->listRecvTimeout) { - //re-request parameters - setParameterStatusMsg(tr("TIMEOUT: Re-requesting param list"),ParamCommsStatusLevel_Warning); - listRecvTimeout = curTime + 10000; - mav->requestParameters(); - //reset the timer - setRetransmissionGuardEnabled(true); - } - return; - } - // Check for timeout - // stop retransmission attempts on timeout - if (curTime > transmissionTimeout) { - setRetransmissionGuardEnabled(false); - resetAfterListReceive(); - - int missingReadCount, missingWriteCount; - clearRetransmissionLists(missingReadCount,missingWriteCount); - if ((missingReadCount > 0) || (missingWriteCount > 0)) { - setParameterStatusMsg(tr("TIMEOUT! MISSING: %1 read, %2 write.").arg(missingReadCount).arg(missingWriteCount), - ParamCommsStatusLevel_Warning); - } - - return; - } - - resendReadWriteRequests(); + int totalElapsed = (int)(curTime - lastReceiveTime); + if (totalElapsed > maxSilenceTimeout) { + qDebug() << "Max silence time exceeded: " + totalElapsed; + int missingReads, missingWrites; + clearRetransmissionLists(missingReads,missingWrites); + //TODO notify user! } else { - qDebug() << __FILE__ << __LINE__ << "STOPPING RETRANSMISSION GUARD GRACEFULLY"; - setRetransmissionGuardEnabled(false); + resendReadWriteRequests(); } } - -/** - * Enabling the retransmission guard enables the parameter widget to track - * dropped parameters and to re-request them. This works for both individual - * parameter reads as well for whole list requests. - * - * @param enabled True if retransmission checking should be enabled, false else - */ - -void UASParameterCommsMgr::setRetransmissionGuardEnabled(bool enabled) -{ - if (enabled) { - retransmissionTimer.start(retransmissionTimeout); - lastTimerReset = QGC::groundTimeMilliseconds() ; - } else { - retransmissionTimer.stop(); - } -} - -void UASParameterCommsMgr::requestParameterUpdate(int component, const QString& parameter) +void UASParameterCommsMgr::requestParameterUpdate(int compId, const QString& paramName) { if (mav) { - mav->requestParameter(component, parameter); + mav->requestParameter(compId, paramName); + //TODO track these read requests with a paramName but no param ID : use index in getOnboardParamsForComponent? + //ensure we keep track of every single read request } } @@ -326,15 +281,14 @@ void UASParameterCommsMgr::requestRcCalibrationParamsUpdate() // Do not request the RC type, as these values depend on this // active onboard parameter + + int defCompId = paramDataModel->getDefaultComponentId(); for (unsigned int i = 1; i < (RC_CAL_CHAN_MAX+1); ++i) { qDebug() << "Request RC " << i; - mav->requestParameter(0, minTpl.arg(i)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, trimTpl.arg(i)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, maxTpl.arg(i)); - QGC::SLEEP::usleep(5000); - mav->requestParameter(0, revTpl.arg(i)); + requestParameterUpdate(defCompId, minTpl.arg(i)); + requestParameterUpdate(defCompId, trimTpl.arg(i)); + requestParameterUpdate(defCompId, maxTpl.arg(i)); + requestParameterUpdate(defCompId, revTpl.arg(i)); QGC::SLEEP::usleep(5000); } } @@ -349,158 +303,152 @@ void UASParameterCommsMgr::requestRcCalibrationParamsUpdate() * @param parameterName name of the parameter, as delivered by the system * @param value value of the parameter */ -void UASParameterCommsMgr::setParameter(int component, QString parameterName, QVariant value) +void UASParameterCommsMgr::setParameter(int compId, QString paramName, QVariant value) { - if (parameterName.isEmpty()) { + if (paramName.isEmpty()) { return; } double dblValue = value.toDouble(); - if (paramDataModel->isValueLessThanParamMin(parameterName,dblValue)) { - setParameterStatusMsg(tr("REJ. %1, %2 < min").arg(parameterName).arg(dblValue), + if (paramDataModel->isValueLessThanParamMin(paramName,dblValue)) { + setParameterStatusMsg(tr("REJ. %1, %2 < min").arg(paramName).arg(dblValue), ParamCommsStatusLevel_Error ); return; } - if (paramDataModel->isValueGreaterThanParamMax(parameterName,dblValue)) { - setParameterStatusMsg(tr("REJ. %1, %2 > max").arg(parameterName).arg(dblValue), + if (paramDataModel->isValueGreaterThanParamMax(paramName,dblValue)) { + setParameterStatusMsg(tr("REJ. %1, %2 > max").arg(paramName).arg(dblValue), ParamCommsStatusLevel_Error ); return; } QVariant onboardVal; - paramDataModel->getOnboardParamValue(component,parameterName,onboardVal); + paramDataModel->getOnboardParamValue(compId,paramName,onboardVal); if (onboardVal == value) { - setParameterStatusMsg(tr("REJ. %1 already %2").arg(parameterName).arg(dblValue), + setParameterStatusMsg(tr("REJ. %1 already %2").arg(paramName).arg(dblValue), ParamCommsStatusLevel_Warning ); return; } - emitPendingParameterCommit(component, parameterName, value); + emitPendingParameterCommit(compId, paramName, value); + + //Add this request to list of writes not yet ack'd - // Wait for parameter to be written back - // mark it therefore as missing - if (!missingWriteAckPackets.contains(component)) { - missingWriteAckPackets.insert(component, new QMap()); + markWriteParamWaiting( compId, paramName, value); + updateSilenceTimer(); + + +} + +void UASParameterCommsMgr::updateSilenceTimer() +{ + //if there are pending reads or writes, ensure we timeout in a little while + //if we hear nothing but silence from our partner + + int missReadCount = 0; + foreach (int key, readsWaiting.keys()) { + missReadCount += readsWaiting.value(key)->count(); + } + + int missWriteCount = 0; + foreach (int key, writesWaiting.keys()) { + missWriteCount += writesWaiting.value(key)->count(); } - // Insert it in missing write ACK list - missingWriteAckPackets.value(component)->insert(parameterName, value); - // Set timeouts - if (transmissionActive) { - transmissionTimeout += rewriteTimeout; + if (missReadCount > 0 || missWriteCount > 0) { + silenceTimer.start(silenceTimeout); //TODO configurable silence timeout + lastSilenceTimerReset = QGC::groundTimeMilliseconds(); } else { - quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + rewriteTimeout; - if (newTransmissionTimeout > transmissionTimeout) { - transmissionTimeout = newTransmissionTimeout; - } - transmissionActive = true; + //all parameters have been received, broadcast to UI + emit parameterListUpToDate(); + resetAfterListReceive(); + silenceTimer.stop(); } - // Enable guard / reset timeouts - setRetransmissionGuardEnabled(true); + + } + void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg, ParamCommsStatusLevel_t level) { qDebug() << "parameterStatusMsg: " << msg; - parameterStatusMsg = msg; - emit parameterStatusMsgUpdated(msg,level); } - -/** - * @param uas System which has the component - * @param component id of the component - * @param parameterName human friendly name of the parameter - */ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value) { Q_UNUSED(uas); //this object is assigned to one UAS only - + lastReceiveTime = QGC::groundTimeMilliseconds(); qDebug() << "compId" << compId << "receivedParameterUpdate:" << paramName; //notify the data model that we have an updated param paramDataModel->handleParamUpdate(compId,paramName,value); - // Missing packets list has to be instantiated for all components - if (!missingReadPackets.contains(compId)) { - missingReadPackets.insert(compId, new QList()); - } - QList* compMissReadPackets = missingReadPackets.value(compId); + // Ensure we have missing read/write lists for this compId + if (!readsWaiting.contains(compId)) { + readsWaiting.insert(compId, new QSet()); + } + if (!writesWaiting.contains(compId) ) { + writesWaiting.insert(compId,new QMap()); + } + QSet* compMissingReads = readsWaiting.value(compId); // List mode is different from single parameter transfers if (transmissionListMode) { - // Only accept the list size once on the first packet from - // each component - if (!transmissionListSizeKnown.contains(compId)) { + // Only accept the list size once on the first packet from each component + if (!knownParamListSize.contains(compId)) { // Mark list size as known - transmissionListSizeKnown.insert(compId, true); + knownParamListSize.insert(compId,paramCount); - qDebug() << "Mark all parameters as missing: " << paramCount; - for (int i = 1; i < paramCount; ++i) { //TODO check: param Id 0 is "all parameters" and not valid ? - if (!compMissReadPackets->contains(i)) { - compMissReadPackets->append(i); - } - } + //remove our placeholder read request for all params + readsWaiting.value(0)->remove(0); - // There is only one transmission timeout for all components - // since components do not manage their transmission, - // the longest timeout is safe for all components. - quint64 thisTransmissionTimeout = QGC::groundTimeMilliseconds() + (paramCount*retransmissionTimeout); - if (thisTransmissionTimeout > transmissionTimeout) { - transmissionTimeout = thisTransmissionTimeout; + qDebug() << "Mark all parameters as missing: " << paramCount; + for (int i = 1; i < paramCount; ++i) { //param Id 0 is "all parameters" and not valid + compMissingReads->insert(i); } } - } + // Mark this parameter as received in read list - int index = compMissReadPackets->indexOf(paramId); - if (index != -1) { - compMissReadPackets->removeAt(index); - } + compMissingReads->remove(paramId); + bool justWritten = false; bool writeMismatch = false; // Mark this parameter as received in write ACK list - QMap* compMissWritePackets = missingWriteAckPackets.value(compId); - if (!compMissWritePackets) { + QMap* compMissingWrites = writesWaiting.value(compId); + if (!compMissingWrites) { //we sometimes send a write request on compId 0 and get a response on a nonzero compId eg 50 - compMissWritePackets = missingWriteAckPackets.value(0); + compMissingWrites = writesWaiting.value(0); } - if (compMissWritePackets && compMissWritePackets->contains(paramName)) { + if (compMissingWrites && compMissingWrites->contains(paramName)) { justWritten = true; - if (compMissWritePackets->value(paramName) != value) { + if (compMissingWrites->value(paramName) != value) { writeMismatch = true; } - compMissWritePackets->remove(paramName); + compMissingWrites->remove(paramName); } - int missReadCount = 0; - foreach (int key, missingReadPackets.keys()) { - missReadCount += missingReadPackets.value(key)->count(); - } - - int missWriteCount = 0; - foreach (int key, missingWriteAckPackets.keys()) { - missWriteCount += missingWriteAckPackets.value(key)->count(); - } - //TODO simplify this if-else tree if (justWritten) { + int waitingWritesCount = compMissingWrites->count(); if (!writeMismatch) { - setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1/%4): %3 [%5]").arg(paramId+1).arg(paramName).arg(value.toDouble()).arg(paramCount).arg(missWriteCount)); - if (0 == missWriteCount) { - setParameterStatusMsg(tr("SUCCESS: WROTE ALL PARAMETERS")); + setParameterStatusMsg(tr("SUCCESS: Wrote %2 (#%1): %3").arg(paramId+1).arg(paramName).arg(value.toDouble())); + } + + if (!writeMismatch) { + if (0 == waitingWritesCount) { + setParameterStatusMsg(tr("SUCCESS: Wrote all params for component %1").arg(compId)); if (persistParamsAfterSend) { writeParamsToPersistentStorage(); persistParamsAfterSend = false; @@ -509,60 +457,30 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para } else { // Mismatch, tell user - setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(compMissWritePackets->value(paramName).toDouble()).arg(value.toDouble()), + setParameterStatusMsg(tr("FAILURE: Wrote %1: sent %2 != onboard %3").arg(paramName).arg(compMissingWrites->value(paramName).toDouble()).arg(value.toDouble()), ParamCommsStatusLevel_Warning); } } else { - if (missReadCount == 0) { + int waitingReadsCount = compMissingReads->count(); + + if (0 == waitingReadsCount) { // Transmission done QTime time = QTime::currentTime(); QString timeString = time.toString(); setParameterStatusMsg(tr("All received. (updated at %1)").arg(timeString)); } else { - // Transmission in progress + // Waiting to receive more QString val = QString("%1").arg(value.toFloat(), 5, 'f', 1, QChar(' ')); - setParameterStatusMsg(tr("OK: %1 %2 (%3/%4)").arg(paramName).arg(val).arg(paramCount-missReadCount).arg(paramCount), - ParamCommsStatusLevel_Warning); - //transmissionMissingPackets + setParameterStatusMsg(tr("OK: %1 %2 (%3/%4)").arg(paramName).arg(val).arg(paramCount-waitingReadsCount).arg(paramCount), + ParamCommsStatusLevel_OK); } } - // Check if last parameter was received - if (missReadCount == 0 && missWriteCount == 0) { - resetAfterListReceive(); - setRetransmissionGuardEnabled(false); - //all parameters have been received, broadcast to UI - emit parameterListUpToDate(); - } - else { - //reset the timeout timer since we received one - setRetransmissionGuardEnabled(true); - - //qDebug() << "missCount:" << missCount << "missWriteCount:" << missWriteCount; - //if (missCount < 4) { - // foreach (int key, transmissionMissingPackets.keys()) { - // QList* list = transmissionMissingPackets.value(key); - - // if (list && list->count()) { - // QString yazza = QString().sprintf("Component %d missing %d: ",key,list->count()); - - // for (int i = 0; i < list->count(); i++) { - // int val = list->at(i); - // yazza.append( QString().sprintf("%d,",val) ); - // } - - // qDebug() << yazza; - // } - // else { - // //very suspicious...no actual missing items?? - // transmissionMissingPackets.remove(key); - // break; - // } - // } - //} - } + updateSilenceTimer(); + + } @@ -591,42 +509,27 @@ void UASParameterCommsMgr::sendPendingParameters(bool copyToPersistent) setParameterStatusMsg(tr("%1 pending params for component %2").arg(paramList->count()).arg(compId)); for (j = paramList->begin(); j != paramList->end(); ++j) { - //TODO mavlink command for "set parameter list" ? setParameter(compId, j.key(), j.value()); parametersSent++; } } // Change transmission status if necessary - if (parametersSent == 0) { + if (0 == parametersSent) { setParameterStatusMsg(tr("No transmission: No changed values."),ParamCommsStatusLevel_Warning); - if (persistParamsAfterSend) { - writeParamsToPersistentStorage(); - } } else { setParameterStatusMsg(tr("Transmitting %1 parameters.").arg(parametersSent)); - // Set timeouts - if (transmissionActive) { - transmissionTimeout += parametersSent*rewriteTimeout; - } - else { - transmissionActive = true; - quint64 newTransmissionTimeout = QGC::groundTimeMilliseconds() + parametersSent*rewriteTimeout; - if (newTransmissionTimeout > transmissionTimeout) { - transmissionTimeout = newTransmissionTimeout; - } - } - // Enable guard - setRetransmissionGuardEnabled(true); - qDebug() << "Pending parameters now:" << paramDataModel->countPendingParams(); } + + + updateSilenceTimer(); } UASParameterCommsMgr::~UASParameterCommsMgr() { - setRetransmissionGuardEnabled(false); + silenceTimer.stop(); QString ptrStr; ptrStr.sprintf("%8p", this); diff --git a/src/uas/UASParameterCommsMgr.h b/src/uas/UASParameterCommsMgr.h index 958fa42114..0f240c5e17 100644 --- a/src/uas/UASParameterCommsMgr.h +++ b/src/uas/UASParameterCommsMgr.h @@ -32,8 +32,9 @@ public: protected: - /** @brief Activate / deactivate parameter retransmission */ - virtual void setRetransmissionGuardEnabled(bool enabled); + + /** @brief activate the silence timer if there are unack'd reads or writes */ + virtual void updateSilenceTimer(); virtual void setParameterStatusMsg(const QString& msg, ParamCommsStatusLevel_t level=ParamCommsStatusLevel_OK); @@ -43,6 +44,12 @@ protected: /** @brief clear transmissionMissingPackets and transmissionMissingWriteAckPackets */ void clearRetransmissionLists(int& missingReadCount, int& missingWriteCount ); + /** @brief we are waiting for a response to this read param request */ + virtual void markReadParamWaiting(int compId, int paramId); + + /** @brief we are waiting for a response to this write param request */ + void markWriteParamWaiting(int compId, QString paramName, QVariant value); + void resendReadWriteRequests(); void resetAfterListReceive(); @@ -75,8 +82,8 @@ public slots: /** @brief Request list of parameters from MAV */ virtual void requestParameterList(); - /** @brief Check for missing parameters */ - virtual void retransmissionGuardTick(); + /** @brief The max silence time expired */ + virtual void silenceTimerExpired(); /** @brief Request a single parameter update by name */ virtual void requestParameterUpdate(int component, const QString& parameter); @@ -88,28 +95,24 @@ public slots: protected: + + QMap knownParamListSize;///< The known param list size for each component, by component ID + quint64 lastReceiveTime; ///< The last time we received anything from our partner + quint64 lastSilenceTimerReset; UASInterface* mav; ///< The MAV we're talking to + int maxSilenceTimeout; ///< If nothing received within this period of time, abandon resends + UASParameterDataModel* paramDataModel; - // Communications management - QVector receivedParamsList; ///< Successfully received parameters - QMap* > missingReadPackets; ///< Missing packets - QMap* > missingWriteAckPackets; ///< Missing write ACK packets - bool transmissionListMode; ///< Currently requesting list - QMap transmissionListSizeKnown; ///< List size initialized? - bool transmissionActive; ///< Missing packets, working on list? bool persistParamsAfterSend; ///< Copy all parameters to persistent storage after sending - quint64 transmissionTimeout; ///< Timeout - QTimer retransmissionTimer; ///< Timer handling parameter retransmission - quint64 lastTimerReset; ///< Last time the guard timer was reset, to prevent premature firing - int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds - int rewriteTimeout; ///< Write request timeout, in milliseconds - int retransmissionBurstRequestSize; ///< Number of packets requested for retransmission per burst - quint64 listRecvTimeout; ///< How long to wait for first parameter list response before re-requesting - - // Status - QString parameterStatusMsg; + QMap*> readsWaiting; ///< All reads that have not yet been received, by component ID + int retransmitBurstLimit; ///< Number of packets requested for retransmission per burst + int silenceTimeout; ///< If nothing received within this period of time, start resends + QTimer silenceTimer; ///< Timer handling parameter retransmission + bool transmissionListMode; ///< Currently requesting list + QMap* > writesWaiting; ///< All writes that have not yet been ack'd, by component ID + }; diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 4493758a30..0a16a3ad65 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -9,7 +9,8 @@ #include "QGCMAVLink.h" UASParameterDataModel::UASParameterDataModel(QObject *parent) : - QObject(parent) + QObject(parent), + defaultComponentId(-1) { onboardParameters.clear(); pendingParameters.clear(); @@ -199,6 +200,26 @@ bool UASParameterDataModel::getOnboardParamValue(int componentId, const QString& return false; } +int UASParameterDataModel::getDefaultComponentId() +{ + int result = 0; + + if (-1 != defaultComponentId) + return defaultComponentId; + + QList components = getComponentForOnboardParam("SYS_AUTOSTART");//TODO is this the best way to find the right component? + + // Guard against multiple components responding - this will never show in practice + if (1 == components.count()) { + result = components.first(); + defaultComponentId = result; + } + + qDebug() << "Default compId: " << result; + + return result; +} + QList UASParameterDataModel::getComponentForOnboardParam(const QString& parameter) const { QList components; diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index 84761a9680..501f488e85 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -28,6 +28,9 @@ public: virtual QString getParamDescription(const QString& param) { return paramDescriptions.value(param, ""); } virtual void setParamDescriptions(const QMap& paramInfo); + /** @brief Get the default component ID for the UAS */ + virtual int getDefaultComponentId(); + //TODO make this method protected? /** @brief Ensure that the data model is aware of this component * @param compId Id of the component @@ -113,6 +116,8 @@ public slots: virtual void clearAllPendingParams(); protected: + int defaultComponentId; ///< Cached default component ID + int uasId; ///< The UAS / MAV to which this data model pertains QMap* > pendingParameters; ///< Changed values that have not yet been transmitted to the UAS, by component ID QMap* > onboardParameters; ///< All parameters confirmed to be stored onboard the UAS, by component ID -- GitLab From c07de6faac74fbbb6d14790f961e285c2a4783d3 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Tue, 27 Aug 2013 08:51:08 +0200 Subject: [PATCH 337/460] Guarding against zero RC channels --- src/ui/QGCPX4VehicleConfig.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index cb1675fd32..09b3e17e37 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -421,6 +421,11 @@ void QGCPX4VehicleConfig::detectChannelInversion(int aert_index) void QGCPX4VehicleConfig::startCalibrationRC() { + if (chanCount < 5) { + QMessageBox::warning(0,tr("Warning! Not enough RC channels"), tr("Detected %1 radio channels. To operate PX4, you need at least 5 channels. Is the radio control connected?").arg(chanCount)); + return; + } + configEnabled = true; QMessageBox::warning(0,"Warning!","You are about to start radio calibration.\nPlease ensure all motor power is disconnected AND all props are removed from the vehicle.\nAlso ensure transmitter and receiver are powered and connected.\nRESET ALL TRIMS TO CENTER!\n\nDo not move the RC sticks, then click OK to confirm"); -- GitLab From 85e653eeb65a5c05637ba33bba99679470d57edd Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Tue, 27 Aug 2013 10:37:53 +0200 Subject: [PATCH 338/460] Cleanup of calibration UI --- .../QGCPX4SensorCalibration.cc | 58 ++++++++++++++----- .../QGCPX4SensorCalibration.ui | 49 +++++++--------- 2 files changed, 64 insertions(+), 43 deletions(-) diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc index 1fbea1f62d..aeaf072d50 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc @@ -90,6 +90,10 @@ void QGCPX4SensorCalibration::setActiveUAS(UASInterface* uas) void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int severity, QString text) { + Q_UNUSED(uasid); + Q_UNUSED(compId); + Q_UNUSED(severity); + if (text.startsWith("[cmd]") || text.startsWith("[mavlink pm]")) return; @@ -105,38 +109,51 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever return; } + ui->instructionLabel->setText(QString("%1").arg(text)); + if (text.contains("accel")) { qDebug() << "ACCEL" << text; - if (text.startsWith("accel meas started: ")) { - QString axis = text.split("meas started: ").last().right(2); + if (text.startsWith("accel measurement started: ")) { + QString axis = text.split("measurement started: ").last().left(2); qDebug() << "AXIS" << axis << "STR" << text; setInstructionImage(QString(":/files/images/px4/calibration/accel_%1.png").arg(axis)); } } - if (text.startsWith("meas result for")) { + if (text.startsWith("directions left")) { + for (int i = 0; i < 6; i++) + { + if (!text.contains(accelAxes[i])) { + qDebug() << "FINISHED" << accelAxes[i]; + accelDone[i] = true; + } + } + } + + if (text.startsWith("result for")) { - QString axis = text.split("meas result for ").last().left(2); + QString axis = text.split("result for ").last().left(2); qDebug() << "ACCELDONE AXIS" << axis << "STR" << text; for (int i = 0; i < 6; i++) { - if (accelAxes[i] == axis) + if (axis == accelAxes[i]) accelDone[i] = true; if (!accelDone[i]) { + qDebug() << "NEW AXIS: " << accelAxes[i]; setInstructionImage(QString(":/files/images/px4/calibration/accel_%1.png").arg(accelAxes[i])); - ui->calibrationExplanationLabel->setText(tr("Axis %1 completed. Please rotate to a different axis, e.g. the one shown here.").arg(axis)); + ui->instructionLabel->setText(tr("Axis %1 completed. Please rotate like shown here.").arg(axis)); + break; } } } if (text.contains("please rotate in a figure 8")) { - ui->calibrationExplanationLabel->setText(tr("Rotate the system around all its axes, e.g. in a figure eight.")); setInstructionImage(":/files/images/px4/calibration/mag_calibration_figure8.png"); } @@ -144,24 +161,35 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever accelStarted = false; // XXX use a confirmation image or something setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); - ui->calibrationExplanationLabel->setText(tr("Accelerometer calibration completed. Parameters permanently stored.")); } if (text.contains("gyro calibration done")) { gyroStarted = false; // XXX use a confirmation image or something setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); - ui->calibrationExplanationLabel->setText(tr("Gyroscope calibration completed. Parameters permanently stored.")); } - if (text.contains("mag calibration done")) { + if (text.contains("mag calibration done") + || text.contains("magnetometer calibration completed")) { magStarted = false; // XXX use a confirmation image or something setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); - ui->calibrationExplanationLabel->setText(tr("Magnetometer calibration completed. Parameters permanently stored.")); } - ui->instructionLabel->setText(QString("%1").arg(text)); + if (text.contains("accel calibration started")) { + accelStarted = true; + setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); + } + + if (text.contains("gyro calibration started")) { + gyroStarted = true; + setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); + } + + if (text.contains("mag calibration started")) { + magStarted = false; + setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); + } // XXX color messages according to severity @@ -184,7 +212,7 @@ void QGCPX4SensorCalibration::gyroButtonClicked() setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); activeUAS->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); ui->progressBar->setValue(0); - ui->calibrationExplanationLabel->setText(tr("Please do not move the system at all and wait for calibration to complete.")); + ui->instructionLabel->setText(tr("Please do not move the system at all.")); } void QGCPX4SensorCalibration::magButtonClicked() @@ -192,7 +220,7 @@ void QGCPX4SensorCalibration::magButtonClicked() setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); activeUAS->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); ui->progressBar->setValue(0); - ui->calibrationExplanationLabel->setText(tr("Please put the system in a rest position and wait for instructions.")); + ui->instructionLabel->setText(tr("Please put the system in a rest position.")); } void QGCPX4SensorCalibration::accelButtonClicked() @@ -208,7 +236,7 @@ void QGCPX4SensorCalibration::accelButtonClicked() accelDone[4] = false; accelDone[5] = false; - ui->calibrationExplanationLabel->setText(tr("Please hold the system very still in the shown orientations. Start with the one shown.")); + ui->instructionLabel->setText(tr("Please hold the system very still in the shown orientations.")); } void QGCPX4SensorCalibration::contextMenuEvent(QContextMenuEvent* event) diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui index 5e5de8479b..7f6b0b8213 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui @@ -36,29 +36,29 @@ QPushButton#gyroButton, QPushButton#accelButton { border: 2px solid #465158; } - - - + + + - Qt::Horizontal + Qt::Vertical - 40 - 20 + 498 + 21 - - + + - Qt::Vertical + Qt::Horizontal - 498 - 21 + 40 + 20 @@ -70,16 +70,6 @@ QPushButton#gyroButton, QPushButton#accelButton { - - - - 24 - - - - - - @@ -117,13 +107,6 @@ QPushButton#gyroButton, QPushButton#accelButton { - - - - To calibrate the system, execute the three calibration steps below. - - - @@ -134,6 +117,16 @@ QPushButton#gyroButton, QPushButton#accelButton { + + + + 24 + + + + + + -- GitLab From 1b4ac63a8b3a0bdcf38db4fe9f3aafc70d2a678f Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 27 Aug 2013 16:11:35 -0700 Subject: [PATCH 339/460] fix sense of RC pitch calibration; notify user when we abandon reads/writes after timeout --- src/uas/UASParameterCommsMgr.cc | 6 +++--- src/ui/QGCPX4VehicleConfig.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index a176114e92..d33eed747a 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -250,10 +250,10 @@ void UASParameterCommsMgr::silenceTimerExpired() int totalElapsed = (int)(curTime - lastReceiveTime); if (totalElapsed > maxSilenceTimeout) { - qDebug() << "Max silence time exceeded: " + totalElapsed; + qDebug() << "maxSilenceTimeout exceeded: " << totalElapsed; int missingReads, missingWrites; clearRetransmissionLists(missingReads,missingWrites); - //TODO notify user! + setParameterStatusMsg(tr("TIMEOUT: Abandoning %1 reads %2 writes after %3 seconds").arg(missingReads).arg(missingWrites).arg(totalElapsed/1000)); } else { resendReadWriteRequests(); @@ -360,7 +360,7 @@ void UASParameterCommsMgr::updateSilenceTimer() if (missReadCount > 0 || missWriteCount > 0) { - silenceTimer.start(silenceTimeout); //TODO configurable silence timeout + silenceTimer.start(silenceTimeout); lastSilenceTimerReset = QGC::groundTimeMilliseconds(); } else { diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 09b3e17e37..30dd3e036b 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -393,7 +393,7 @@ void QGCPX4VehicleConfig::detectChannelInversion(int aert_index) QStringList instructions; instructions << "ROLL: Move stick left"; - instructions << "PITCH: Move stick up"; + instructions << "PITCH: Move stick down";//matches the other sticks: should cause DECREASE in raw rc channel value when not reversed instructions << "YAW: Move stick left"; instructions << "THROTTLE: Move stick down"; instructions << "MODE SWITCH: Push down / towards you"; -- GitLab From 34d6ef6022a1a2cd17a9a605aa508ce7921e149b Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Wed, 28 Aug 2013 09:22:04 +0200 Subject: [PATCH 340/460] Small warning fix --- src/ui/QGCPX4VehicleConfig.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 30dd3e036b..4f44812d71 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -56,12 +56,12 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : calibrationEnabled(false), configEnabled(false), px4AirframeConfig(NULL), - px4SensorCalibration(NULL), #ifdef QUPGRADE_SUPPORT firmwareDialog(NULL), #endif planeBack(":/files/images/px4/rc/cessna_back.png"), planeSide(":/files/images/px4/rc/cessna_side.png"), + px4SensorCalibration(NULL), ui(new Ui::QGCPX4VehicleConfig) { doneLoadingConfig = false; @@ -1383,7 +1383,7 @@ void QGCPX4VehicleConfig::updateAllInvertedCheckboxes() int rc_input_index = rcMapping[function_index]; - if (rc_input_index < 0 || rc_input_index > chanMax) + if (rc_input_index < 0 || rc_input_index > (int)chanMax) continue; // Map index to checkbox. -- GitLab From cb76cc555d85270fc57418b2384001ef57dbcaee Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Wed, 28 Aug 2013 15:50:45 +0200 Subject: [PATCH 341/460] Updated airframe config --- src/ui/px4_configuration/QGCPX4AirframeConfig.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc index e4de511d49..f550417240 100644 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc @@ -30,6 +30,7 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : connect(ui->planePushButton, SIGNAL(clicked()), this, SLOT(planeSelected())); connect(ui->planeComboBox, SIGNAL(activated(int)), this, SLOT(planeSelected(int))); + ui->planePushButton->setEnabled(ui->planeComboBox->count() > 0); ui->flyingWingComboBox->addItem(tr("Bormatec Camflyer Q"), 30); ui->flyingWingComboBox->addItem(tr("Phantom FPV"), 31); @@ -37,9 +38,11 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : connect(ui->flyingWingPushButton, SIGNAL(clicked()), this, SLOT(flyingWingSelected())); connect(ui->flyingWingComboBox, SIGNAL(activated(int)), this, SLOT(flyingWingSelected(int))); - ui->quadXComboBox->addItem(tr("Standard 10\" Quad"), 1); ui->quadXComboBox->addItem(tr("DJI F330 8\" Quad"), 10); + ui->quadXComboBox->addItem(tr("DJI F450 10\" Quad"), 11); ui->quadXComboBox->addItem(tr("Turnigy Talon v2 X550 Quad"), 666); + ui->quadXComboBox->addItem(tr("AR.Drone Frame Quad"), 8); + ui->quadXComboBox->addItem(tr("AR.Drone Quad (w. PX4FLOW)"), 9); connect(ui->quadXPushButton, SIGNAL(clicked()), this, SLOT(quadXSelected())); connect(ui->quadXComboBox, SIGNAL(activated(int)), this, SLOT(quadXSelected(int))); @@ -64,8 +67,8 @@ QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : connect(ui->octoPlusComboBox, SIGNAL(activated(int)), this, SLOT(octoPlusSelected(int))); ui->octoPlusPushButton->setEnabled(ui->octoPlusComboBox->count() > 0); + ui->hComboBox->addItem(tr("3DR Iris"), 16); ui->hComboBox->addItem(tr("TBS Discovery"), 15); - ui->hComboBox->addItem(tr("H Custom"), 16); connect(ui->hPushButton, SIGNAL(clicked()), this, SLOT(hSelected())); connect(ui->hComboBox, SIGNAL(activated(int)), this, SLOT(hSelected(int))); -- GitLab From 980ec0542cec55ddab4a6a3398eb33f29dab9eb2 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 28 Aug 2013 18:23:03 -0700 Subject: [PATCH 342/460] ensure data model knows the mav's ID --- src/uas/QGCUASParamManager.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/uas/QGCUASParamManager.cc b/src/uas/QGCUASParamManager.cc index 90991f899d..c4d81c7761 100644 --- a/src/uas/QGCUASParamManager.cc +++ b/src/uas/QGCUASParamManager.cc @@ -24,6 +24,7 @@ QGCUASParamManager* QGCUASParamManager::initWithUAS(UASInterface* uas) // Load default values and tooltips for data model loadParamMetaInfoCSV(); + paramDataModel.setUASID(mav->getUASID()); paramCommsMgr = new UASParameterCommsMgr(this); paramCommsMgr->initWithUAS(uas); -- GitLab From 30be74b224f69df508ae5dca6bc36bae127303de Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 28 Aug 2013 18:23:25 -0700 Subject: [PATCH 343/460] ensure that delta files with new params are loaded --- src/uas/UASParameterDataModel.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index 0a16a3ad65..80b7f70a7c 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -264,13 +264,13 @@ void UASParameterDataModel::readUpdateParamsFromStream( QTextStream& stream) if (wpParams.size() == 5) { // Only load parameters for right mav if (!userWarned && (uasId != lineMavId)) { - //TODO warn the user somehow ?? + //TODO warn the user somehow ?? Appears these are saved currently with mav ID 0 but mav ID is often nonzero? QString msg = tr("The parameters in the stream have been saved from system %1, but the currently selected system has the ID %2.").arg(lineMavId).arg(uasId); -// MainWindow::instance()->showCriticalMessage( -// tr("Parameter loading warning"), -// tr("The parameters from the file %1 have been saved from system %2, but the currently selected system has the ID %3. If this is unintentional, please click on to revert to the parameters that are currently onboard").arg(fileName).arg(wpParams.at(0).toInt()).arg(mav->getUASID())); + qWarning() << msg ; + //MainWindow::instance()->showCriticalMessage( + // tr("Parameter loading warning"), + // tr("The parameters from the file %1 have been saved from system %2, but the currently selected system has the ID %3. If this is unintentional, please click on to revert to the parameters that are currently onboard").arg(fileName).arg(wpParams.at(0).toInt()).arg(mav->getUASID())); userWarned = true; - return; } bool changed = false; @@ -286,8 +286,9 @@ void UASParameterDataModel::readUpdateParamsFromStream( QTextStream& stream) changed = true; } else { - if (fabs((static_cast(onboardParameters.value(componentId)->value(key, dblVal).toDouble())) - (dblVal)) > - 2.0f * FLT_EPSILON) { + QMap* compParams = onboardParameters.value(componentId); + if (!compParams->contains(key) || + (fabs((static_cast(compParams->value(key).toDouble())) - (dblVal)) > 2.0f * FLT_EPSILON)) { changed = true; qDebug() << "Changed" << key << "VAL" << dblVal; } -- GitLab From 6623bd765120292f0e15f097f23326a0bc93bde1 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Wed, 28 Aug 2013 18:23:56 -0700 Subject: [PATCH 344/460] stop timer when maxSilenceTimeout is exceeded to avoid infinite loop --- src/uas/UASParameterCommsMgr.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index d33eed747a..126a6910fc 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -253,6 +253,8 @@ void UASParameterCommsMgr::silenceTimerExpired() qDebug() << "maxSilenceTimeout exceeded: " << totalElapsed; int missingReads, missingWrites; clearRetransmissionLists(missingReads,missingWrites); + silenceTimer.stop(); + lastSilenceTimerReset = curTime; setParameterStatusMsg(tr("TIMEOUT: Abandoning %1 reads %2 writes after %3 seconds").arg(missingReads).arg(missingWrites).arg(totalElapsed/1000)); } else { -- GitLab From d52ac62aedf9be7be75f1e867ae7443ed4c6af0b Mon Sep 17 00:00:00 2001 From: Kai Date: Thu, 29 Aug 2013 13:12:25 +1000 Subject: [PATCH 345/460] Update Readme for MAC Clang compiler --- README | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/README b/README index 1d08b8244e..1952d7d2bd 100644 --- a/README +++ b/README @@ -15,6 +15,19 @@ Documentation ============= For generating documentation, refer to README in the doc directory. +Notes: +===== +Please make sure to delete your build folder before re-building. Independent of which +build system you use (this is not related to Qt or your OS) the dependency checking and +cleaning is based on the current project revision. So if you change the project and not +doing a clean build before you do, incremental building can leave you with stale +object files. + +For the current config branch 'qupgrade' has to be installed (subject to change): + +cd qgroundcontrol +git clone https://github.com/LorenzMeier/qupgrade.git + Mac OS X ======== @@ -33,13 +46,13 @@ Install QT 2) Double click the package installer -Build QGroundControl --------------------- +Build QGroundControl (use clang compiler - not gcc) +------------------------------------- 1) From the terminal go to the `groundcontrol` directory -2) Run `qmake -spec macx-g++` +2) Run `qmake qgroundcontrol.pro -r -spec unsupported/macx-clang CONFIG+=x86_64` -3) Run `make -j8` +3) Run `make -j4` Linux -- GitLab From 17fc6302a6af77f11310cdfcd4babd1c2ae8e263 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 29 Aug 2013 16:30:57 +0200 Subject: [PATCH 346/460] Improved calibration screen a lot, gives now much better feedback what to do --- files/styles/style-dark.css | 30 ++- .../QGCPX4SensorCalibration.cc | 232 +++++++++++++++++- .../QGCPX4SensorCalibration.h | 20 ++ .../QGCPX4SensorCalibration.ui | 115 ++++++--- 4 files changed, 359 insertions(+), 38 deletions(-) diff --git a/files/styles/style-dark.css b/files/styles/style-dark.css index 26b68253b6..136c7bc328 100644 --- a/files/styles/style-dark.css +++ b/files/styles/style-dark.css @@ -208,6 +208,27 @@ QGCToolBar .QWidget { background-color: transparent; } +QGCPX4SensorCalibration QLabel#magLabel { + font-size: 15pt; + font-weight: bold; + border-radius: 4px; + min-height: 25px; +} + +QGCPX4SensorCalibration QLabel#gyroLabel { + font-size: 15pt; + font-weight: bold; + border-radius: 4px; + min-height: 25px; +} + +QGCPX4SensorCalibration QLabel#accelLabel { + font-size: 15pt; + font-weight: bold; + border-radius: 4px; + min-height: 25px; +} + QGCToolWidgetItem { border: 1px solid #666; border-radius: 3px; @@ -409,12 +430,9 @@ QPushButton#viewModeGeneric, QPushButton#viewModePX4, QPushButton#viewModeAPM, Q } QPushButton#magButton, QPushButton#gyroButton, QPushButton#accelButton { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #73D95D, stop: 1 #18A154); - border-radius: 8px; - min-height: 30px; - max-height: 50px; - min-width: 60px; - border: 3px solid #465158; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #757575, stop: 1 #333); + border-radius: 5px; + border: 1px solid #000000; } QWidget#containerWidget { diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc index aeaf072d50..e9c1fb72c0 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.cc +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.cc @@ -33,7 +33,67 @@ QGCPX4SensorCalibration::QGCPX4SensorCalibration(QWidget *parent) : ui->magButton->setEnabled(false); ui->accelButton->setEnabled(false); + ui->autopilotComboBox->setEnabled(false); + ui->magComboBox->setEnabled(false); + setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); + setAutopilotImage(":/files/images/px4/calibration/accel_z-.png"); + setGpsImage(":/files/images/px4/calibration/accel_z-.png"); + + // Fill combo boxes + ui->autopilotComboBox->addItem(tr("Default Orientation"), 0); + ui->autopilotComboBox->addItem(tr("ROTATION_YAW_45"), 1); + ui->autopilotComboBox->addItem(tr("ROTATION_YAW_90"), 2); + ui->autopilotComboBox->addItem(tr("ROTATION_YAW_135"), 3); + ui->autopilotComboBox->addItem(tr("ROTATION_YAW_180"), 4); + ui->autopilotComboBox->addItem(tr("ROTATION_YAW_225"), 5); + ui->autopilotComboBox->addItem(tr("ROTATION_YAW_270"), 6); + ui->autopilotComboBox->addItem(tr("ROTATION_YAW_315"), 7); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_180"), 8); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_180_YAW_45"), 9); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_180_YAW_90"), 10); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_180_YAW_135"), 11); + ui->autopilotComboBox->addItem(tr("ROTATION_PITCH_180"), 12); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_180_YAW_225"), 13); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_180_YAW_270"), 14); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_180_YAW_315"), 15); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_90"), 16); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_90_YAW_45"), 17); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_90_YAW_90"), 18); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_90_YAW_135"), 19); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_270"), 20); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_270_YAW_45"), 21); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_270_YAW_90"), 22); + ui->autopilotComboBox->addItem(tr("ROTATION_ROLL_270_YAW_135"), 23); + ui->autopilotComboBox->addItem(tr("ROTATION_PITCH_90"), 24); + ui->autopilotComboBox->addItem(tr("ROTATION_PITCH_270"), 25); + + ui->magComboBox->addItem(tr("Default Orientation"), 0); + ui->magComboBox->addItem(tr("ROTATION_YAW_45"), 1); + ui->magComboBox->addItem(tr("ROTATION_YAW_90"), 2); + ui->magComboBox->addItem(tr("ROTATION_YAW_135"), 3); + ui->magComboBox->addItem(tr("ROTATION_YAW_180"), 4); + ui->magComboBox->addItem(tr("ROTATION_YAW_225"), 5); + ui->magComboBox->addItem(tr("ROTATION_YAW_270"), 6); + ui->magComboBox->addItem(tr("ROTATION_YAW_315"), 7); + ui->magComboBox->addItem(tr("ROTATION_ROLL_180"), 8); + ui->magComboBox->addItem(tr("ROTATION_ROLL_180_YAW_45"), 9); + ui->magComboBox->addItem(tr("ROTATION_ROLL_180_YAW_90"), 10); + ui->magComboBox->addItem(tr("ROTATION_ROLL_180_YAW_135"), 11); + ui->magComboBox->addItem(tr("ROTATION_PITCH_180"), 12); + ui->magComboBox->addItem(tr("ROTATION_ROLL_180_YAW_225"), 13); + ui->magComboBox->addItem(tr("ROTATION_ROLL_180_YAW_270"), 14); + ui->magComboBox->addItem(tr("ROTATION_ROLL_180_YAW_315"), 15); + ui->magComboBox->addItem(tr("ROTATION_ROLL_90"), 16); + ui->magComboBox->addItem(tr("ROTATION_ROLL_90_YAW_45"), 17); + ui->magComboBox->addItem(tr("ROTATION_ROLL_90_YAW_90"), 18); + ui->magComboBox->addItem(tr("ROTATION_ROLL_90_YAW_135"), 19); + ui->magComboBox->addItem(tr("ROTATION_ROLL_270"), 20); + ui->magComboBox->addItem(tr("ROTATION_ROLL_270_YAW_45"), 21); + ui->magComboBox->addItem(tr("ROTATION_ROLL_270_YAW_90"), 22); + ui->magComboBox->addItem(tr("ROTATION_ROLL_270_YAW_135"), 23); + ui->magComboBox->addItem(tr("ROTATION_PITCH_90"), 24); + ui->magComboBox->addItem(tr("ROTATION_PITCH_270"), 25); setObjectName("PX4_SENSOR_CALIBRATION"); @@ -42,6 +102,11 @@ QGCPX4SensorCalibration::QGCPX4SensorCalibration(QWidget *parent) : setActiveUAS(UASManager::instance()->getActiveUAS()); connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); ui->progressBar->setValue(0); + + connect(ui->autopilotComboBox, SIGNAL(activated(int)), this, SLOT(setAutopilotOrientation(int))); + connect(ui->magComboBox, SIGNAL(activated(int)), this, SLOT(setGpsOrientation(int))); + + // XXX ask for params (if not loaded) } QGCPX4SensorCalibration::~QGCPX4SensorCalibration() @@ -49,6 +114,106 @@ QGCPX4SensorCalibration::~QGCPX4SensorCalibration() delete ui; } +void QGCPX4SensorCalibration::parameterChanged(int uas, int component, QString parameterName, QVariant value) +{ + Q_UNUSED(uas); + Q_UNUSED(component); + + int index = (int)value.toFloat(); + + if (parameterName.contains("SENS_BOARD_ROT")) + { + ui->autopilotComboBox->setCurrentIndex(index); + setAutopilotImage(index); + ui->autopilotComboBox->setEnabled(true); + } + + if (parameterName.contains("SENS_EXT_MAG_ROT")) + { + ui->magComboBox->setCurrentIndex(index); + setGpsImage(index); + ui->magComboBox->setEnabled(true); + } + + // Check mag calibration naively + if (parameterName.contains("SENS_MAG_XOFF")) { + float offset = value.toFloat(); + if (offset < 0.000001f && offset > -0.000001f) { + // Must be zero, not good + setMagCalibrated(false); + } else { + setMagCalibrated(true); + } + } + + // Check gyro calibration naively + if (parameterName.contains("SENS_GYRO_XOFF")) { + float offset = value.toFloat(); + if (offset < 0.000001f && offset > -0.000001f) { + // Must be zero, not good + setGyroCalibrated(false); + } else { + setGyroCalibrated(true); + } + } + + // Check accel calibration naively + if (parameterName.contains("SENS_ACC_XOFF")) { + float offset = value.toFloat(); + if (offset < 0.000001f && offset > -0.000001f) { + // Must be zero, not good + setAccelCalibrated(false); + } else { + setAccelCalibrated(true); + } + } +} + +void QGCPX4SensorCalibration::setMagCalibrated(bool calibrated) +{ + if (calibrated) { + ui->magLabel->setText(tr("MAG CALIBRATED")); + ui->magLabel->setStyleSheet("QLabel { color: #FFFFFF;" + "background-color: #20AA20;" + "}"); + } else { + ui->magLabel->setText(tr("MAG UNCALIBRATED")); + ui->magLabel->setStyleSheet("QLabel { color: #FFFFFF;" + "background-color: #FF0037;" + "}"); + } +} + +void QGCPX4SensorCalibration::setGyroCalibrated(bool calibrated) +{ + if (calibrated) { + ui->gyroLabel->setText(tr("GYRO CALIBRATED")); + ui->gyroLabel->setStyleSheet("QLabel { color: #FFFFFF;" + "background-color: #20AA20;" + "}"); + } else { + ui->gyroLabel->setText(tr("GYRO UNCALIBRATED")); + ui->gyroLabel->setStyleSheet("QLabel { color: #FFFFFF;" + "background-color: #FF0037;" + "}"); + } +} + +void QGCPX4SensorCalibration::setAccelCalibrated(bool calibrated) +{ + if (calibrated) { + ui->accelLabel->setText(tr("ACCEL CALIBRATED")); + ui->accelLabel->setStyleSheet("QLabel { color: #FFFFFF;" + "background-color: #20AA20;" + "}"); + } else { + ui->accelLabel->setText(tr("ACCEL UNCALIBRATED")); + ui->accelLabel->setStyleSheet("QLabel { color: #FFFFFF;" + "background-color: #FF0037;" + "}"); + } +} + void QGCPX4SensorCalibration::setInstructionImage(const QString &path) { instructionIcon.load(path); @@ -56,7 +221,53 @@ void QGCPX4SensorCalibration::setInstructionImage(const QString &path) int w = ui->iconLabel->width(); int h = ui->iconLabel->height(); - ui->iconLabel->setPixmap(instructionIcon.scaled(w, h, Qt::KeepAspectRatio)); + ui->iconLabel->setPixmap(instructionIcon.scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation)); +} + +void QGCPX4SensorCalibration::setAutopilotImage(int index) +{ + setAutopilotImage(QString(":/files/images/px4/calibration/pixhawk_%1.png").arg(index)); +} + +void QGCPX4SensorCalibration::setGpsImage(int index) +{ + setGpsImage(QString(":/files/images/px4/calibration/gps_%1.png").arg(index)); +} + +void QGCPX4SensorCalibration::setAutopilotOrientation(int index) +{ + if (activeUAS) { + activeUAS->getParamManager()->setPendingParam(0, "SENS_BOARD_ROT", (int)index); + activeUAS->getParamManager()->sendPendingParameters(true); + } +} + +void QGCPX4SensorCalibration::setGpsOrientation(int index) +{ + if (activeUAS) { + activeUAS->getParamManager()->setPendingParam(0, "SENS_EXT_MAG_ROT", (int)index); + activeUAS->getParamManager()->sendPendingParameters(true); + } +} + +void QGCPX4SensorCalibration::setAutopilotImage(const QString &path) +{ + autopilotIcon.load(path); + + int w = ui->autopilotLabel->width(); + int h = ui->autopilotLabel->height(); + + ui->autopilotLabel->setPixmap(autopilotIcon.scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation)); +} + +void QGCPX4SensorCalibration::setGpsImage(const QString &path) +{ + gpsIcon.load(path); + + int w = ui->gpsLabel->width(); + int h = ui->gpsLabel->height(); + + ui->gpsLabel->setPixmap(gpsIcon.scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation)); } void QGCPX4SensorCalibration::resizeEvent(QResizeEvent* event) @@ -64,8 +275,15 @@ void QGCPX4SensorCalibration::resizeEvent(QResizeEvent* event) int w = ui->iconLabel->width(); int h = ui->iconLabel->height(); + ui->iconLabel->setPixmap(instructionIcon.scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + + int wa = ui->autopilotLabel->width(); + int ha = ui->autopilotLabel->height(); + ui->autopilotLabel->setPixmap(autopilotIcon.scaled(wa, ha, Qt::KeepAspectRatio, Qt::SmoothTransformation)); - ui->iconLabel->setPixmap(instructionIcon.scaled(w, h, Qt::KeepAspectRatio)); + int wg = ui->gpsLabel->width(); + int hg = ui->gpsLabel->height(); + ui->gpsLabel->setPixmap(gpsIcon.scaled(wg, hg, Qt::KeepAspectRatio, Qt::SmoothTransformation)); QWidget::resizeEvent(event); } @@ -76,7 +294,8 @@ void QGCPX4SensorCalibration::setActiveUAS(UASInterface* uas) return; if (activeUAS) { - disconnect(uas, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(handleTextMessage(int,int,int,QString))); + disconnect(activeUAS, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(handleTextMessage(int,int,int,QString))); + disconnect(activeUAS, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); ui->textView->clear(); } @@ -85,6 +304,7 @@ void QGCPX4SensorCalibration::setActiveUAS(UASInterface* uas) ui->accelButton->setEnabled(true); connect(uas, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(handleTextMessage(int,int,int,QString))); + connect(uas, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); activeUAS = uas; } @@ -161,12 +381,16 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever accelStarted = false; // XXX use a confirmation image or something setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); + if (activeUAS) + activeUAS->requestParameter(0, "SENS_ACC_XOFF"); } if (text.contains("gyro calibration done")) { gyroStarted = false; // XXX use a confirmation image or something setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); + if (activeUAS) + activeUAS->requestParameter(0, "SENS_GYRO_XOFF"); } if (text.contains("mag calibration done") @@ -174,6 +398,8 @@ void QGCPX4SensorCalibration::handleTextMessage(int uasid, int compId, int sever magStarted = false; // XXX use a confirmation image or something setInstructionImage(":/files/images/px4/calibration/accel_z-.png"); + if (activeUAS) + activeUAS->requestParameter(0, "SENS_MAG_XOFF"); } if (text.contains("accel calibration started")) { diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.h b/src/ui/px4_configuration/QGCPX4SensorCalibration.h index b6cfd1bd22..50500a83c5 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.h +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.h @@ -42,12 +42,28 @@ public slots: */ virtual void contextMenuEvent(QContextMenuEvent* event); + void setAutopilotOrientation(int index); + void setGpsOrientation(int index); + void parameterChanged(int uas, int component, QString parameterName, QVariant value); + +protected slots: + void setInstructionImage(const QString &path); + void setAutopilotImage(const QString &path); + + void setGpsImage(const int index); + + void setAutopilotImage(const int index); + + void setGpsImage(const QString &path); + protected: UASInterface* activeUAS; QAction* clearAction; QPixmap instructionIcon; + QPixmap autopilotIcon; + QPixmap gpsIcon; bool accelStarted; bool accelDone[6]; bool gyroStarted; @@ -55,6 +71,10 @@ protected: QStringList accelAxes; virtual void resizeEvent(QResizeEvent* event); + + void setMagCalibrated(bool calibrated); + void setGyroCalibrated(bool calibrated); + void setAccelCalibrated(bool calibrated); private: Ui::QGCPX4SensorCalibration *ui; diff --git a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui index 7f6b0b8213..0533f386bb 100644 --- a/src/ui/px4_configuration/QGCPX4SensorCalibration.ui +++ b/src/ui/px4_configuration/QGCPX4SensorCalibration.ui @@ -6,8 +6,8 @@ 0 0 - 531 - 448 + 657 + 598 @@ -36,8 +36,29 @@ QPushButton#gyroButton, QPushButton#accelButton { border: 2px solid #465158; } - - + + + + + Autopilot and GPS / Compass Orientation + + + + + + + + + + + + + + 24 + + + + Qt::Vertical @@ -45,12 +66,12 @@ QPushButton#gyroButton, QPushButton#accelButton { 498 - 21 + 5 - + Qt::Horizontal @@ -63,19 +84,51 @@ QPushButton#gyroButton, QPushButton#accelButton { - - + + + + + + + + + + + + + true + - - - - + + + + - Magnetometer + + + + Qt::AlignCenter + + + + + + + + + + Qt::AlignCenter + + + + + + + Gyroscope @@ -83,10 +136,10 @@ QPushButton#gyroButton, QPushButton#accelButton { - - + + - Gyroscope + Magnetometer @@ -94,7 +147,7 @@ QPushButton#gyroButton, QPushButton#accelButton { - + Accelerometer @@ -105,28 +158,32 @@ QPushButton#gyroButton, QPushButton#accelButton { + + + + + + + Qt::AlignCenter + + + - - + + - - true - - - - - 24 + + + + - - - -- GitLab From af4b8ccea1ad91e6657a56e001f2d0f3a6d08a04 Mon Sep 17 00:00:00 2001 From: David Goodman Date: Thu, 29 Aug 2013 16:22:31 -0700 Subject: [PATCH 347/460] Default map type checked and defined in QGCMapWidget.h. --- src/ui/map/QGCMapToolBar.cc | 11 ++++++++++- src/ui/map/QGCMapWidget.cc | 6 ++++++ src/ui/map/QGCMapWidget.h | 5 +++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/ui/map/QGCMapToolBar.cc b/src/ui/map/QGCMapToolBar.cc index 067544bcd2..c9596efafa 100644 --- a/src/ui/map/QGCMapToolBar.cc +++ b/src/ui/map/QGCMapToolBar.cc @@ -60,18 +60,27 @@ void QGCMapToolBar::setMap(QGCMapWidget* map) action = mapTypesMenu.addAction(tr("Bing Hybrid"),this,SLOT(setMapType())); action->setData(MapType::BingHybrid); action->setCheckable(true); +#ifdef MAP_DEFAULT_TYPE_BING + action->setChecked(true); +#endif mapTypesGroup->addAction(action); action = mapTypesMenu.addAction(tr("Google Hybrid"),this,SLOT(setMapType())); action->setData(MapType::GoogleHybrid); action->setCheckable(true); +#ifdef MAP_DEFAULT_TYPE_GOOGLE + action->setChecked(true); +#endif mapTypesGroup->addAction(action); action = mapTypesMenu.addAction(tr("OpenStreetMap"),this,SLOT(setMapType())); action->setData(MapType::OpenStreetMap); action->setCheckable(true); +#ifdef MAP_DEFAULT_TYPE_OSM + action->setChecked(true); +#endif mapTypesGroup->addAction(action); - //TODO check current item + optionsMenu.addMenu(&mapTypesMenu); diff --git a/src/ui/map/QGCMapWidget.cc b/src/ui/map/QGCMapWidget.cc index 748d1c2dfb..8e2e82165e 100644 --- a/src/ui/map/QGCMapWidget.cc +++ b/src/ui/map/QGCMapWidget.cc @@ -34,7 +34,13 @@ QGCMapWidget::QGCMapWidget(QWidget *parent) : //this->SetShowTileGridLines(true); //default appears to be Google Hybrid, and is broken currently +#if defined MAP_DEFAULT_TYPE_BING this->SetMapType(MapType::BingHybrid); +#elif defined MAP_DEFAULT_TYPE_GOOGLE + this->SetMapType(MapType::GoogleHybrid); +#else + this->SetMapType(MapType::OpenStreetMap); +#endif this->setContextMenuPolicy(Qt::ActionsContextMenu); diff --git a/src/ui/map/QGCMapWidget.h b/src/ui/map/QGCMapWidget.h index 8657ede17a..2f169a9ef4 100644 --- a/src/ui/map/QGCMapWidget.h +++ b/src/ui/map/QGCMapWidget.h @@ -5,6 +5,11 @@ #include #include "../../../libs/opmapcontrol/opmapcontrol.h" +// Choose one default map type +#define MAP_DEFAULT_TYPE_BING +//#define MAP_DEFAULT_TYPE_GOOGLE +//#define MAP_DEFAULT_TYPE_OSM + class UASInterface; class UASWaypointManager; class Waypoint; -- GitLab From d916bfdda446fe47f6bef1baf234336a05320d3b Mon Sep 17 00:00:00 2001 From: David Goodman Date: Thu, 29 Aug 2013 16:24:28 -0700 Subject: [PATCH 348/460] Removed commented out code. --- src/ui/map/QGCMapWidget.cc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/ui/map/QGCMapWidget.cc b/src/ui/map/QGCMapWidget.cc index 8e2e82165e..6fbc618109 100644 --- a/src/ui/map/QGCMapWidget.cc +++ b/src/ui/map/QGCMapWidget.cc @@ -171,15 +171,6 @@ void QGCMapWidget::mouseReleaseEvent(QMouseEvent *event) mapcontrol::OPMapWidget::mouseReleaseEvent(event); } -/* -void QGCMapWidget::contextMenuEvent(QContextMenuEvent *event) -{ - // TODO Remove this method - qDebug() << "Context menu event triggered."; - mapcontrol::OPMapWidget::contextMenuEvent(event); -} -*/ - QGCMapWidget::~QGCMapWidget() { SetShowHome(false); // doing this appears to stop the map lib crashing on exit -- GitLab From 948e9d063bf90ac2fb2baaba6ca69cc9279d4099 Mon Sep 17 00:00:00 2001 From: David Goodman Date: Thu, 29 Aug 2013 16:32:55 -0700 Subject: [PATCH 349/460] Fixed "Go To Here" and "Point Camera Here" map context actions to use correct mouse coordinates. --- src/ui/map/QGCMapWidget.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/map/QGCMapWidget.cc b/src/ui/map/QGCMapWidget.cc index 6fbc618109..db76a20a2a 100644 --- a/src/ui/map/QGCMapWidget.cc +++ b/src/ui/map/QGCMapWidget.cc @@ -81,7 +81,7 @@ void QGCMapWidget::guidedActionTriggered() } } // Create new waypoint and send it to the WPManager to send out. - internals::PointLatLng pos = map->FromLocalToLatLng(mousePressPos.x(), mousePressPos.y()); + internals::PointLatLng pos = map->FromLocalToLatLng(contextMousePressPos.x(), contextMousePressPos.y()); qDebug() << "Guided action requested. Lat:" << pos.Lat() << "Lon:" << pos.Lng(); Waypoint wp; wp.setLatitude(pos.Lat()); @@ -119,7 +119,7 @@ void QGCMapWidget::cameraActionTriggered() if (newmav) { newmav->setMountConfigure(4,true,true,true); - internals::PointLatLng pos = map->FromLocalToLatLng(mousePressPos.x(), mousePressPos.y()); + internals::PointLatLng pos = map->FromLocalToLatLng(contextMousePressPos.x(), contextMousePressPos.y()); newmav->setMountControl(pos.Lat(),pos.Lng(),100,true); } } -- GitLab From 3cf08f4c48c98a20bcfe4e67ec760976ca0577c7 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Fri, 30 Aug 2013 12:47:16 -0700 Subject: [PATCH 350/460] don't even attempt to send message if link is down --- src/uas/UAS.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 3ba41583fd..75da0e1d2e 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -1862,7 +1862,8 @@ void UAS::sendMessage(mavlink_message_t message) { if (LinkManager::instance()->getLinks().contains(link)) { - sendMessage(link, message); + if (link->isConnected()) + sendMessage(link, message); qDebug() << "SENT MESSAGE id" << message.msgid << "component" << message.compid; } else -- GitLab From 8afe3e6b863f946353cf33decefa5af920177a3e Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sat, 31 Aug 2013 08:52:16 -0700 Subject: [PATCH 351/460] Remove OK button on RC cal steps where it doesn't make sense Cleanup some RC calibration text as well --- src/ui/QGCPX4VehicleConfig.cc | 45 ++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index 4f44812d71..e20d0b2e63 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -300,11 +300,10 @@ void QGCPX4VehicleConfig::identifyChannelMapping(int aert_index) } } - msgBox.setText(tr("Identifying %1 channel").arg(channelNames[channelWanted])); - msgBox.setInformativeText(tr("Please move stick, switch or potentiometer for the %1 channel\n all the way up/down or left/right.").arg(channelNames[channelWanted])); - msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("Detecting %1 ...\t\t").arg(channelNames[channelWanted])); + msgBox.setInformativeText(tr("Please move stick, switch or potentiometer for this channel all the way up/down or left/right.")); + msgBox.setStandardButtons(QMessageBox::NoButton); skipActionButton = msgBox.addButton(tr("Skip"),QMessageBox::RejectRole); - msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); skipActionButton->hide(); msgBox.removeButton(skipActionButton); @@ -404,11 +403,10 @@ void QGCPX4VehicleConfig::detectChannelInversion(int aert_index) instructions << "AUX1: Push down / towards you or turn dial to the leftmost position"; instructions << "AUX2: Push down / towards you or turn dial to the leftmost position"; - msgBox.setText(tr("Identifying DIRECTION of %1 channel").arg(channelNames[channelReverseStateWanted])); + msgBox.setText(tr("%1 Direction").arg(channelNames[channelReverseStateWanted])); msgBox.setInformativeText(tr("%2").arg((aert_index < instructions.length()) ? instructions[aert_index] : "")); - msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setStandardButtons(QMessageBox::NoButton); skipActionButton = msgBox.addButton(tr("Skip"),QMessageBox::RejectRole); - msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); skipActionButton->hide(); msgBox.removeButton(skipActionButton); @@ -422,12 +420,16 @@ void QGCPX4VehicleConfig::detectChannelInversion(int aert_index) void QGCPX4VehicleConfig::startCalibrationRC() { if (chanCount < 5) { - QMessageBox::warning(0,tr("Warning! Not enough RC channels"), tr("Detected %1 radio channels. To operate PX4, you need at least 5 channels. Is the radio control connected?").arg(chanCount)); + QMessageBox::warning(0, + tr("RC not Connected"), + tr("Is the RC receiver connected and transmitter turned on? Detected %1 radio channels. To operate PX4, you need at least 5 channels. ").arg(chanCount)); return; } configEnabled = true; - QMessageBox::warning(0,"Warning!","You are about to start radio calibration.\nPlease ensure all motor power is disconnected AND all props are removed from the vehicle.\nAlso ensure transmitter and receiver are powered and connected.\nRESET ALL TRIMS TO CENTER!\n\nDo not move the RC sticks, then click OK to confirm"); + + QMessageBox::warning(0,tr("Safety Warning"), + tr("Starting RC calibration.\n Ensure that motor power is disconnected, all props are removed, RC transmitter and receiver are powered and connected.\n\nRESET ALL TRIMS TO CENTER! Do not move the RC controls, then click OK to continue")); //go ahead and try to map first 8 channels, now that user can skip channels for (int i = 0; i < 8; i++) { @@ -457,7 +459,7 @@ void QGCPX4VehicleConfig::startCalibrationRC() void QGCPX4VehicleConfig::stopCalibrationRC() { - QMessageBox::information(0,"Trims","Ensure all sticks are centeres and throttle is in the downmost position, click OK to continue"); + QMessageBox::information(0,"Trims","Ensure all controls are centered and throttle is in the lowest position. Click OK to continue"); calibrationEnabled = false; configEnabled = false; @@ -486,10 +488,10 @@ void QGCPX4VehicleConfig::stopCalibrationRC() setTrimPositions(); QString statusstr; - statusstr = "Below you will find the detected radio calibration information that will be sent to the autopilot\n"; - statusstr += "Normal values are around 1100 to 1900, with disconnected channels reading 1000, 1500, 2000\n\n"; - statusstr += "Channel\tMin\tCenter\tMax\n"; - statusstr += "--------------------\n"; + statusstr = tr("This is the RC calibration information that will be sent to the autopilot if you click OK. To prevent transmission, click Cancel."); + statusstr += tr("Normal values range from 1000 to 2000, with disconnected channels reading 1000, 1500, 2000\n\n"); + statusstr += tr("Channel\tMin\tCenter\tMax\n"); + statusstr += "-------\t---\t------\t---\n"; for (unsigned int i=0; i < chanCount; i++) { statusstr += QString::number(i) +"\t"+ QString::number(rcMin[i]) +"\t"+ QString::number(rcValue[i]) +"\t"+ QString::number(rcMax[i]) +"\n"; } @@ -1235,10 +1237,13 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float fval) channelWanted = -1; // Confirm found channel - msgBox.setText(tr("%1 Channel found.").arg(channelNames[chanFound])); - msgBox.setInformativeText(tr("Found %1 to be on the raw RC channel %2").arg(channelNames[chanFound]).arg(chan + 1)); + msgBox.setText(tr("Found %1 \t\t").arg(channelNames[chanFound])); + msgBox.setInformativeText(tr("Assigned raw RC channel %2").arg(chan + 1)); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); + skipActionButton->hide(); + msgBox.removeButton(skipActionButton); + (void)msgBox.exec(); // XXX fuse with parameter update handling @@ -1364,17 +1369,19 @@ void QGCPX4VehicleConfig::remoteControlChannelRawChanged(int chan, float fval) channelReverseStateWanted = -1; // Confirm found channel - msgBox.setText(tr("Direction of %1 Channel assigned").arg(channelNames[currRevFunc])); - msgBox.setInformativeText(tr("%1").arg((rcRev[rcMapping[currRevFunc]]) ? "Reversed channel." : "Did not reverse channel.")); + msgBox.setText(tr("%1 direction assigned").arg(channelNames[currRevFunc])); + msgBox.setInformativeText(tr("%1").arg((rcRev[rcMapping[currRevFunc]]) ? tr("Reversed channel.") : tr("Did not reverse channel.") )); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); + skipActionButton->hide(); + msgBox.removeButton(skipActionButton); (void)msgBox.exec(); } } dataModelChanged = true; - qDebug() << "RC CHAN:" << chan << "PPM:" << fval << "NORMALIZED:" << normalized; + //qDebug() << "RC CHAN:" << chan << "PPM:" << fval << "NORMALIZED:" << normalized; } void QGCPX4VehicleConfig::updateAllInvertedCheckboxes() -- GitLab From 9d6c1ddcba8785d208cf8c8477e99d6e24eacc4a Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sat, 31 Aug 2013 09:01:30 -0700 Subject: [PATCH 352/460] small RC calibration text tweaks --- src/ui/QGCPX4VehicleConfig.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index e20d0b2e63..dc0e7b5fed 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -429,7 +429,7 @@ void QGCPX4VehicleConfig::startCalibrationRC() configEnabled = true; QMessageBox::warning(0,tr("Safety Warning"), - tr("Starting RC calibration.\n Ensure that motor power is disconnected, all props are removed, RC transmitter and receiver are powered and connected.\n\nRESET ALL TRIMS TO CENTER! Do not move the RC controls, then click OK to continue")); + tr("Starting RC calibration.\n\nEnsure that motor power is disconnected, all props are removed, RC transmitter and receiver are powered and connected.\n\nReset transmitter trims to center, then click OK to continue")); //go ahead and try to map first 8 channels, now that user can skip channels for (int i = 0; i < 8; i++) { @@ -489,7 +489,7 @@ void QGCPX4VehicleConfig::stopCalibrationRC() QString statusstr; statusstr = tr("This is the RC calibration information that will be sent to the autopilot if you click OK. To prevent transmission, click Cancel."); - statusstr += tr("Normal values range from 1000 to 2000, with disconnected channels reading 1000, 1500, 2000\n\n"); + statusstr += tr(" Normal values range from 1000 to 2000, with disconnected channels reading 1000, 1500, 2000\n\n"); statusstr += tr("Channel\tMin\tCenter\tMax\n"); statusstr += "-------\t---\t------\t---\n"; for (unsigned int i=0; i < chanCount; i++) { -- GitLab From b66ee7e9177d50f9089133ff4154d9634ae723d5 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sat, 31 Aug 2013 15:29:43 -0700 Subject: [PATCH 353/460] reset lastReceiveTime --- src/uas/UASParameterCommsMgr.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/uas/UASParameterCommsMgr.cc b/src/uas/UASParameterCommsMgr.cc index 126a6910fc..8110651a8b 100644 --- a/src/uas/UASParameterCommsMgr.cc +++ b/src/uas/UASParameterCommsMgr.cc @@ -11,6 +11,7 @@ UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent) : QObject(parent), + lastReceiveTime(0), mav(NULL), maxSilenceTimeout(30000), paramDataModel(NULL), @@ -254,6 +255,7 @@ void UASParameterCommsMgr::silenceTimerExpired() int missingReads, missingWrites; clearRetransmissionLists(missingReads,missingWrites); silenceTimer.stop(); + lastReceiveTime = 0; lastSilenceTimerReset = curTime; setParameterStatusMsg(tr("TIMEOUT: Abandoning %1 reads %2 writes after %3 seconds").arg(missingReads).arg(missingWrites).arg(totalElapsed/1000)); } @@ -362,14 +364,18 @@ void UASParameterCommsMgr::updateSilenceTimer() if (missReadCount > 0 || missWriteCount > 0) { - silenceTimer.start(silenceTimeout); lastSilenceTimerReset = QGC::groundTimeMilliseconds(); + if (0 == lastReceiveTime) { + lastReceiveTime = lastSilenceTimerReset; + } + silenceTimer.start(silenceTimeout); } else { //all parameters have been received, broadcast to UI emit parameterListUpToDate(); resetAfterListReceive(); silenceTimer.stop(); + lastReceiveTime = 0; } -- GitLab From 3f606af54ac5320b4dde1fc1cafc765addb1a5f4 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Sat, 31 Aug 2013 15:30:08 -0700 Subject: [PATCH 354/460] clear channel mappings for > Ch 5 when starting rc cal --- src/ui/QGCPX4VehicleConfig.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index dc0e7b5fed..ceb17af298 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -426,6 +426,11 @@ void QGCPX4VehicleConfig::startCalibrationRC() return; } + // reset all channel mappings above Ch 5 to invalid/unused value before starting calibration + for (unsigned int j= 5; j < chanMappedMax; j++) { + rcMapping[j] = -1; + } + configEnabled = true; QMessageBox::warning(0,tr("Safety Warning"), -- GitLab From 3f88380f27a2f4653dfd0e7d834217c9fdfce82c Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 1 Sep 2013 13:51:50 +0200 Subject: [PATCH 355/460] Fixed RC cal --- files/styles/style-dark.css | 5 +++++ src/ui/QGCPX4VehicleConfig.cc | 9 +++++++++ src/ui/QGCPX4VehicleConfig.ui | 21 ++++++++++++++------- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/files/styles/style-dark.css b/files/styles/style-dark.css index 136c7bc328..75656465c5 100644 --- a/files/styles/style-dark.css +++ b/files/styles/style-dark.css @@ -229,6 +229,11 @@ QGCPX4SensorCalibration QLabel#accelLabel { min-height: 25px; } +QGCPX4VehicleConfig QLabel#rcLabel { + color: #FEC654; + font-size: 18pt; +} + QGCToolWidgetItem { border: 1px solid #666; border-radius: 3px; diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index ceb17af298..9ab20d3241 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -239,6 +239,8 @@ QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) : connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateView())); updateTimer.start(); + ui->rcLabel->setText(tr("NO RADIO CONTROL INPUT DETECTED. PLEASE ENSURE THE TRANSMITTER IS ON.")); + } QGCPX4VehicleConfig::~QGCPX4VehicleConfig() @@ -423,6 +425,7 @@ void QGCPX4VehicleConfig::startCalibrationRC() QMessageBox::warning(0, tr("RC not Connected"), tr("Is the RC receiver connected and transmitter turned on? Detected %1 radio channels. To operate PX4, you need at least 5 channels. ").arg(chanCount)); + ui->rcCalibrationButton->setChecked(false); return; } @@ -464,6 +467,9 @@ void QGCPX4VehicleConfig::startCalibrationRC() void QGCPX4VehicleConfig::stopCalibrationRC() { + if (!calibrationEnabled) + return; + QMessageBox::information(0,"Trims","Ensure all controls are centered and throttle is in the lowest position. Click OK to continue"); calibrationEnabled = false; @@ -1808,5 +1814,8 @@ void QGCPX4VehicleConfig::updateView() updateRcWidgetValues(); updateRcChanLabels(); + if (chanCount > 0) + ui->rcLabel->setText(tr("Radio control detected with %1 channels.").arg(chanCount)); } + } diff --git a/src/ui/QGCPX4VehicleConfig.ui b/src/ui/QGCPX4VehicleConfig.ui index c9d9fb63b7..858e409363 100644 --- a/src/ui/QGCPX4VehicleConfig.ui +++ b/src/ui/QGCPX4VehicleConfig.ui @@ -7,7 +7,7 @@ 0 0 1256 - 918 + 985 @@ -198,6 +198,13 @@ + + + + Waiting for RC channel data.. + + + @@ -822,8 +829,8 @@ 0 0 - 21 - 16 + 98 + 28 @@ -859,8 +866,8 @@ 0 0 - 21 - 16 + 98 + 28 @@ -910,8 +917,8 @@ 0 0 - 16 - 16 + 98 + 28 -- GitLab From 46ca0abac14a9198d6a20c92c45835501eb8c3d4 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 1 Sep 2013 16:39:56 +0200 Subject: [PATCH 356/460] Loading the correct mag icons for a few rotations now --- files/images/px4/calibration/3dr_gps/gps_01.png | Bin 0 -> 77187 bytes files/images/px4/calibration/3dr_gps/gps_02.png | Bin 0 -> 58288 bytes files/images/px4/calibration/3dr_gps/gps_03.png | Bin 0 -> 73246 bytes files/images/px4/calibration/3dr_gps/gps_04.png | Bin 0 -> 59034 bytes files/images/px4/calibration/3dr_gps/gps_05.png | Bin 0 -> 73697 bytes files/images/px4/calibration/3dr_gps/gps_06.png | Bin 0 -> 72523 bytes files/images/px4/calibration/3dr_gps/gps_07.png | Bin 0 -> 61146 bytes files/images/px4/calibration/3dr_gps/gps_12.png | Bin 0 -> 81113 bytes files/images/px4/calibration/3dr_gps/gps_13.png | Bin 0 -> 82220 bytes files/images/px4/calibration/3dr_gps/gps_14.png | Bin 0 -> 86632 bytes files/images/px4/calibration/3dr_gps/gps_15.png | Bin 0 -> 94474 bytes files/images/px4/calibration/3dr_gps/gps_16.png | Bin 0 -> 91147 bytes files/images/px4/calibration/3dr_gps/gps_17.png | Bin 0 -> 86136 bytes files/images/px4/calibration/3dr_gps/gps_18.png | Bin 0 -> 83111 bytes files/images/px4/calibration/3dr_gps/gps_19.png | Bin 0 -> 80885 bytes files/images/px4/calibration/3dr_gps/gps_24.png | Bin 0 -> 56471 bytes qgroundcontrol.qrc | 16 ++++++++++++++++ .../QGCPX4SensorCalibration.cc | 4 ++-- 18 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 files/images/px4/calibration/3dr_gps/gps_01.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_02.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_03.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_04.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_05.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_06.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_07.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_12.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_13.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_14.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_15.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_16.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_17.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_18.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_19.png create mode 100644 files/images/px4/calibration/3dr_gps/gps_24.png diff --git a/files/images/px4/calibration/3dr_gps/gps_01.png b/files/images/px4/calibration/3dr_gps/gps_01.png new file mode 100644 index 0000000000000000000000000000000000000000..483c45ca09b5590ade075a30b3481c2d98ebb945 GIT binary patch literal 77187 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 Mp00i_>zopr06_~lK>z>% literal 0 HcmV?d00001 diff --git a/files/images/px4/calibration/3dr_gps/gps_02.png b/files/images/px4/calibration/3dr_gps/gps_02.png new file mode 100644 index 0000000000000000000000000000000000000000..2bb8670270bb1d9d23e826b87c6640210aee1c50 GIT binary patch literal 58288 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

˸C!GNJwB~kw +>>"u{ZԜd&HLʸ,w=EnnG OA (ݷsJ)$6(ll+NZlw# -muA y_[RW#tU(ě@/`^ۇ[ד{~vdv{-A‘h;m8-I=wy 62XZzfg1!Q)W׋3XY+\W_8} p 7|( +-cݎl>5x#QT?%FyfI*=oę.%Z]ٕs spKb,:!7.Rܠ-6e_ڙz"`xN;PDC /2Oǜ'h8ޠX 2;#ͱ)M)%$".W Jz$=Nm{QGk/cinZEo /SO LP/%ۿ-фRZԮ}ǢJf += H9C 5w';$̑=or&UҵGR-(wi3ӟ&~*l߷5(iz148ZkQ_UkqLtNt|<n+Y%wPHf ^ͳdCՍ8ʫ8 G*)a=ܟԍ'Z|T%T Ra ?>_Pʥ"g`i:Qa&}N n3SVG %YSd7G@;'m-?ūsqF! W^Ć\-2^\ NSwwK±Gsk}9j6UnHz9ljdhخɓ_痆GM2r{MpO4"~aäoSS +|(PgG\:l3Y~ 5= +9~4+XUtHolԚFS,eSLu7c}ey^. I +^^"[dVuȊȣ]45Ӛ2YZoH7d9vEZN$s{S~E2w5\Z( D}.97p[r0GWu[ñU}H. GنfiT'S'Ά!]K߉ZϞ}V-Us S_z$S?Z!F%<٦&[Nw܇(('bOlv%xM`➬3.YtsSяݜ'dдd2e:4iaϋKa3?3m RF 9^Ỳ269C+ҝhRU~TpX 8V{-]&Kk*\ݪbǦAUn 6g*BO1{jt Ҍk}R9v?fcs:67]/D[cBFS +*)|-Ѵ 13ޘL&z3:#_DD `~?+|O2 0#K>.D/ +2c7\H9rxyk +;"]7ն%Q̰;*ef"flԓfMY;v6|S7 cYnૹ,7͹y7''*-n_+wʢFu v͚쐩+Y$irzDSaiYGǕ񁝎A~=D/˘!=KoJ]Cڊz; +~9v. eiLKJdtx>&[dw2Vl'% &_'$833<\hyFNjpiVr!i^DJs0xߌ$m_Dqdt*G }x<:YT 7*ZX9ᦩ/@i@Y!=R[["߮ +`'Agr#WTG٭j+"2o[$חvkZXN3DmH}iZ4+BȒr]#KBHdfpRi/1FQ]sܥɻk6@TMEDMﲷ0¤9aIWaif:uJs<ÛаQuIuD3ܥ!\ˇGNYQ'`0Vm +ʑFDw#)IRz*_q#i-EUM-ԵC)wJ>q3; +;tiFyd - 5kuvP=y7}G?Nn .m`z$alfN Pd=rfH6K3[]>"JBIůG_cbm"IL^Zi` gqA|{~zwKh/n)l_Rhh}JC;{ُ1PeYZ=B9`yJ wCZnjAІXt]J+J. 5lۍ^!T]kqS28*'?'e5=XMM{JO9!A7iHL9_Uu#"F$G FXDJ#_֭*Cz]~eddRz$2#^3߮Foij]-\U?F#4֢wQ*W תJuՉRXUA TG[Pi.|6y8IlK:!h6)ȍ4M%( +Q"{qYphw.+wBm +L4 ?zzp(QM=<0q":pi'F hT#N8e^~y?η+- k"jz Ѻ2 uva9 (%sc U&pO-"IH +g?j*j@ˉXD\YhqL:)eiw`G@䟈dm{ ,y21lZx7*ȧ"vSL1ŌfyWkI,Jf=U:@n\gU6Q8o<=h$xG6#ovW83rc.?@+WQ>(KE]\?U};1dbG"t_\5`/gRl_nX1m" sR98/\+/+C֨Oˇ9H 0*fUJǚ޳~%bw*Zl@#\uPՔLݎRb:4!*flk?LDa :Wro>i P(H-eJHxϛ t8j)l7`FӃ7GDP'^#=toܭ(p-Y]6כg.I +g9qoV89̘nFBqB5ny@PpӃ,6cz!Y~@WVN^ sWl3sTj0n̬UO[ hU~d(ݑZϵT-STϛ캮o`u]N433u/[b\,̝yJn类[] +d&js뿧\սEu]% [_4yzqa Zu݈LDb%oc}!iۑU1M?]$%Rn>H?](_fjX03~l)1t>Nv.oso{%=ӲϡP8ehıؘW]6uB|7='kJk"t@,DJD(8Mk|?[`\5sL/8_N=:L)8*?@h ü@^kqU +a`U%VpR<6rW`O deVҰaj7'G3˷6ޞǤp%'_6-6JaX8٠Sqg[' j錈ʴaL2#( GmdC4)ve`$&a!X.?ѯV~ChuqW^L`.V#@n ~|U>3]yL=QTs&4޶_ʟRM#:hsEz~A.p kF5X@HQ|Bӧ $ m; 0GIDLf69x8;mlHcuNHS~g$\ˠؚ M:MaVZ T +EY8MZx?ӬYw$rDM|RoN+ǔʯ%1&f>Y˻%lW+g )|8~Xt";G}g-&eʨanx0J /D6=J '`f%v(X#%A]sû%,9h={̸[l;8\5a5vL}Riv2v_Fx뀝K,%8 +_sBvBiPyfޝBklntx bX+[H)SuDC5%!nЁ8Dh5Uڥ7&S(vH/V >WqTW Ķ3ɏj3csY|R6Pd`,Y*`MZ oC(#jPҖy6 3Ś @Z +P"M@#a:tk4n]3fE1nj(`ސ ҂r5gaxZ9h޶AK9PBAIۇQf4?8eI]5`QZ 54O|1oZm#?iIeD|0˹rRXV5R;2#;>kjyUIYd:f2 b wJoNqXU7Z)^+%Օ`MQKy9ǙWrOcA%+Nzy`cDV|47Cm7:Qa|K'Nz ǹI`;D}y~^zݬoKz➷3Wpζ[_oha*]_%zaB6Z0:+`sI2ex<([nN\ĂZmquHX~\tk HcxXPP}e!)*da]*e.H巗h- c1>Rc//F&oNs.T,%)]~5ZZٮ)\֎IEEX[,һ׏\md3e {Tȼ,K>B<'Hp0WDBǒ|m[,  +$RzҴlniW4ߞgTkH-گx%|K[ ^NGޕƝ:8LJFbqٽD8 =jLv #t4Q6q땫gZfk u%|OSii +9DT4{K+|$5y޾e:(*YȥJk'1 +8 ->-![g- H:KysƠb#{JCM`EjZ:#*T<\B-${~R{a7"hdZ,8,S?ɴP ek&]\hx6lJBpg]/&$feϗ%dZcLz&ٟOqatkAPH\ۛˑ'.#XQ+Bl +48oSpeeNXCvB(1!^_JH-VqUǝZ467elDb4~a;4N۲,Lq~x%+rlXSr`^i|h vG|xW$Ip`2.˒i֥'x͢:̞-EOqwT>cHJ~ag &H`:W֙z3i`Lf k}#ͣ~%t_tբ!X3m(" *Q 3]HÛ XvfPhMq˿/X2pMMEvKzƒxolPxJQ󏽂Vj~ﶬ+4sqwbÊ >)̚!g库bT.4"=k!M3Ѡ\cHJ~Q(F$>3cVJue}><Ƈ*\(AƧ;fV;er#|6;n 9f{zw }lI2(  f]j*"C+u3@}k&WT.2(^ 4C@JU +G>݈GL]zMl:|{أgD5]>롫+B8s$EHj@:_1z:q=PgPk"ͣ}?WooN Fy Sv(٠#}db8ǟuP)KM `_ +U{k-aYi?Q`U8 d׻}{Io`z +Ū0Ă.珑4]#4!ek/V??J,eնmz#uWͮW<.PV` REZDwXk<%&p,Tp !Z>"1W?Tam*G/(yl%Թ(ݰD%gŴ!']U\f|XZ?q@gALhD,ע@T0>&Ao=Z_w1f_{v<,k?H,%gY; +$= !N3ۺj?N~Ѻ=7늨nҙeN4rV.F@A.$L ݔB1GS\4T &~YY_L:;W>̥Eo\X=hte}EOлKt27X3)~k׀W&Qj-[JkS=bj.\ +bf15'Nt8'Y()𲮀+uҋoH\K<7*֠osx7Gۿ*qednT`psў67QZgtaڏ(FǿawYoTjU5`3'f[?Ԛf +i3L:glcFeNeTAʹVkUXFP҄Z+w!f꜏6 +D,0n:m<:Bfkwc]߻ k[ID}6741c|~Rt]v=DK"$ s&0>і2_D]qِm ߓ01/JdjGb.& 1˭s7MwӢf߃hҖpz< }if}ƚ,OP[7px!#8}/Wٛ{Bgכ.#Q$io 7Ag;;#-:J3\B%שC7W += DZܓspl\oj\sN O9V'-4/^5xlܤxJLi='-7B+ܝ +,wb]˗ 36BۑL' +(A")>ͼu{:,Ahptce -x4޴nV9ma+ݏj}.|s|FmÉ-=-[*G<1:ޞAa<YYb% +!!fcolkT؏+r{Sf@9*@D\leG3)@dR{:jVz8q`ӛ'QdfWb +,\m@ 0B5RB +tIa+b>tսNK(pֆ_$G\sȂf=9󐊬a"啕Ò~G7"Qh/́L92fʩd VI:Qĥ"_Άz#'J–B+J swv^]װIRz52uMfK 1 ߵc/J>:o= (]6M蚑QxJrfxͶӹi( q dW/U^Yi9kQ')|^vJp&ROZH!19էmDCeYR4q<܌̋+i~"K z~8~@RqÇ-,4tN(,Sw8t` WݦFbTK-UɄ>>%ݽ=+i#Ѱs3$]MY4HR/S3ցuhJB[p o?kC3ԧO!ႯEhņzF-Sg#E5q_l>8$1agZ9sdN? icB-429&^Ifڔk> + Ld9 Ҟg(e~ ++t+Hn7v0 WۖFBܚd +b-(#Z-{u 62{8Xp%:!j; \Kt20<ѴIAq/Hժ av?n;Z׬4M'N*?b-+ێNȊxbW8E9.+.Gcs9-"i(Lgt52rO!"ؽy;tdfCx .SFT2]. $:9W}R{о' s3k%DQ♤$9O̯:zf,@y;vmQY/5ͪ\K]'>c_!t8z[$y?/n\$~O6 lQP4? +0@uH-x5:j4"MAs;i:v_l$z)Gz5Xh.oƩxutFmt1ԒŧU,l,s[W^!C!c^,z4/!!BP|(hditbq9(q +(௦VNʡ-%J*M`vb8K7πZuj++~:KB$]c Xc|8An-FWQZz 0mYj ~gz8-Cw Һ3hY1oP7qBk'NG-C qbud?$o@ 3=~w::Tv/$IzX`_WX\Uhߏa:mǣu,ؖ 8𸯹UjGeiPL?a7T9R/ۻ`̓fwp wB8vP0Or92P,K|ӷ"xh%{lMZO`eJM .b;z3Nl +4'z>X#2X5i>^VA|qIИIB D!M)Ҋ{I3[2mEġUSk%*DU)QF/خLb1u 6\>٧o_ġ*jHJC n,HlmgZGj@ .ܚ ƛۖ?ou1̖ﰁQk+ŏ8 /hgTVid^!mmf ʛm3gܽb3 n!X}I.'_7̽|BH}'$OG5gK\{] ą{#jLS4S6=d90'lx{1 gb-1lK< u3!%hOe{bC8b}8CJs90Ί`:j8@j3Bp='%c ֫W0U?@BI8uR*ġauɛ+>6u;Z`uk!Co@>3| !{OCE$?ebYrZEn eh d,T DCgŻS ӈ&Fc?`mLf2l|ާǚz+UCbXn]*ukLHlմ F8 +J)uYɄ?c'k` +m Wcyᣱ_YKEm ׹!sy-$O"Juw&ȓ '1-Gl%,*:Zq?<-\I)2N^47I=q8dy+8 .Rz|ݎM 0ҿ3gp?D5rz婼(} @L ʩC- _xRa'" {5IfnփX$\l,Nq4¦yٙ֞JG/seA=bwJDB9 -wL^>N&7jx܁bJb(AMlm$3ht}U*3(,3VꝢJ"*⏨?q9;4H?D{ןϯɥl,>?/Ӱi͡uDhjqu_Yh]SsM05ڢ(ͣ$ӗ6[ n#PapMK@đ !h̖߱kTEXB + m[b9i'@wz 4cY`E a|uXTywMoĶ!PCBZnbґŁ{̒rOO3m%BA虫b=\B~ z%2lўQþ厚aرLRQ'Ð0,3I:R-J +t*uYk ꇤYPiRc>RyOKϊ3ֱ +ʶ6" q\&(ZhZ5RuoD-wc 8j3q-*aZ/a 48jQAz\Tr<̵#$v)[c\Gd@TR:}+2i&+ǓةYdLchv=RLtٜ.4ɨA:B0Q =N1x'|QJCWʦv^C0 W{e3"$a䞛I-Gy07hp +t8 mYTB83Qaӥepٴ- Zw^\bTfQEv[c1%rd n )r%HAlp8F'eBm 3&˼} +*Y,b_kor#OB r̄ubLZ:zUI$)3ckL6?AϢLPBubOtBs0Q&,?NC8_|t61#nz^[E: +_מT9 5&JVѽǦJP [2B 9pQwꔸMZ-5 gSW:g`nc[I:*'=rkH&Y_նy!1`KY9iGU2 %6 b-h#ou [i"Ŭ&>cp&/׉kTd< QPq1ބ325i Nfgk ĥN۝#[I9!NP1Ѵ~4%pnL[+Nj-hyL*'tH$5F`}NjqymWrlvG>*zA-Af8v"t ^аiXv[\lk8Z|! +I$u'p!4A$e g(ͩM56 Ko_UR\\4&xiل +uw +r]Y1rimt(60Ҝ,yz9-tzď +BZHT EYԄP_Ы+9_ +ad t^DlϦUgDn>Q! ]ikOb$K[mzL&8o2/aU7"1Sj瘖#t<SbRO|( {fv F ~Nmg}SX'$JӶuYi&{*jtXwº5Z]s:(lk)ы!&eO~z_CHLfc6ēXXYtu$v5D@B* =vy`_=$fuH;6AN(}(WGƛ^(BK\pJXga]#9u?~S.u,N.=Voб\ݎ˧PkԒjq;8N3+2<*×,;Xͅgw;Z_0S)k']e,gj]^S^p|y_ưZbn}Ksb hcm^ޏ$!ӉT=.C; +z!c柢%/|voh.dksC0Ŷ0L-*L{ Vj舞_ś╓6Go! ;Wbp\c_ΚL . "%yE>jE>6KT~нM(քvB_7]OI.Lt +nNkf*EPaubؾ2OC!T+&d s݂68NM-2:i+ *>5%pD `DAAwt/TmÐp1l+Qtr&Iچ@7pq+7}BPZci-Fx8d7!nU@zcdPpRa]Tݽ&#١%տ ၎C +H5x*sqÔ@0&'-+g,GG!;=OZ5j+[?ŽҚ+o9dn޺-U4rY !U-@-`)'q9۬' x'2z )3p\xf_Vy0E}"l^Y(2(SOݼO('k1fs e+HCT#JvUaL~)/41WkW?3H֑Ԣ,cY) *~-;᠕×8zmNGXF,A#lGTKe&آuj>4G%i< +"׊*$;%=(4ZPjJ lz!L)MΕjMji~r>v$+5>\)$G;&l0M1A^@7U*#D)8mC@Y?4zXt;!E4-vZϫ QlGYټmפmBhheDf7태6U7րp=QyY~zk%2oj_^$:uh^Y|dR^y2}uPP'g%bDá1-SqU=.ocab\>*4udP?-ElUX8 Gşٝ0(f?aɩB'0~JԹ + 7gf~7‚øby2C\U·rB w:VzDh Xbx9lJPr h]I^XFOr`.ߐ}wʷ׬?/i,u +endstream endobj 82 0 obj <> endobj 95 0 obj [/ICCBased 49 0 R] endobj 10 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 11 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 12 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 13 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 14 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 104 0 obj <>stream +HMn6:/4"v:AV "0xU%3= KpYM籾/W܇nG/o˛ Tg-29-]tѥ>qf(Cw/r/ܥPޔ+eXZ|n]Cj;W:E| zH>|O1r;X#9X|,4Է>y8bM(9}f*u-szյ-w`z=RHn#l}=| +hA2j"*iy>1dbkmQP4MC8gm |!:1"U'[{DdS{5,G:'tL}Mw|&ΕĄ]ǹOf-2MpnTvȠׂcA!/8@ҹ!xvM&I +f/Fk ,|$BI%a=i4'f5c1JHy +VnBKQIii${>s蟫lfh40JklMi3+Q͗6`KXnޚֶbS.,^瞯?{ZiŞ?X_3LjVδIvT"f'8rJ<zsp:flWLW]bh.'= ¢J_e׈&q13 f2h6 ȗ9s$耄 c>J:+MO'/8ⷖøG_/ tJ_Yxԡck z<>uJ@*˫?^. 0<\ +endstream endobj 105 0 obj <> endobj 106 0 obj [/ICCBased 49 0 R] endobj 102 0 obj <>stream +Hˎ\5~lW VY#.g:(VN\ǗukI|{MZd [{K#>Ͽ}O +X=Ҍjz/}爴+Jha52Q riF^rFnޝ|g<Ւ%$5 HF6ÖS]:Ǩj#J6.=! S[fsG=nTg3? k<-^-WhoͲ7Xq~lq@R' ",YӄkҘ\)X1 viu& :N@k*[6DSq409-H5kk Yk{5{p W-pqnֹg_ymn3wxwQ6r'#J3hyK,0}k$]9hjnOH>qi+^8\0Cĝc[/]x)ٞON'ٹ1.X;"X=zg`cЖlZ[^C6!qd*g_' &S\NAsrE pGᩣO'!6]km08J +&0QP Ҕy/^~ȫLd7Cpa=y)Dl&d$ەl͋`:R…u!` +M ! +'CԞea'#Q"vfdd݈N + }5sHtXFS/gD)cWqP$ {C6ԘE* Dg|30Z,9-yd 샄CeAATeHkUu~5y\,hqQd+>z >Yv6ԴL%1zt\a/lwf'RxH&qTI D.d?F19ݰ?Տcj{C0Iz:mk׿cs$[$q4!}=:b&t+YP0S;h W439Keg@zD:nBA씝GSeaHïu2 x,O؟mW=k z6,\^3 Uƻjڳi}k]Kq@R X2%f @JNmEMKr7r5-)! Oʠ&^ +|BܑF=OuvLOkc_C!DJxĮ%3 nv؞:6n+Z[E+-7 ;C j0ʾ-gh~ony$m;ħ\dɊ0}ڎ^FvNYOl\q.OoXz&Eʷ7ygh6nw~g9p"+kF0ߊ]h8H:F?9Ɏ ԞQ.;̺uV>D3nܹإ#ơ |ʱةڮˉl0]Y5|N#_}w\_Ƶ뻷ׄ`~ +endstream endobj 103 0 obj <> endobj 107 0 obj [/ICCBased 49 0 R] endobj 100 0 obj <>stream +HɎ6 ~ +": I!Pr`҇~~RRUs2]hY"?񧥧N)ߝe +NB__$(ν4w4O}ʌ۹Hy|sn.*zOs /Ր|Jx#;bK1C\QPKf/)B\ ![YZԅŀY' >K-tnshS +e}wm/.unqo XjStnآkgiBDi6,ԝ, +w +z`yJ[4e##b!-ԥMԶv)U]^Y6bЗ[荧, %aڇ-FbaQG3ȷFȖvIȂ3 -ْQi@h%ymkRiŭ%Yٍi\YkF_鉮g-EOo-6u5 . Х,PحfBݖm. zwߦ{9={>xԖ-1=l0$iCEbJ+n>< +M[r@(!p7eQ4kxANjjxN kAq\FK./YKH0ߕ w K ;@ZXG/.ڥW.?___Y@wݮO И7VPt%6jczvJCm-|)&:ƊMnэR>Pjj㡶<ԦUb롨xoP!&Sؒaw{=1,q6!{i\YPuk(d_ژ0`F#,cePM>6Y@/d`@&l[5˜1īNHrә`܇#IDS}Ńn58lqa;R.7ZԮkZsECQQ*r`SWC+2% L q<q~hg߰êR[ XrWӑŐ`А#:e^J[0v{L:X`)YWeKeov 7Y4ilҤoMMWf_ìgOT +endstream endobj 101 0 obj <> endobj 108 0 obj [/ICCBased 49 0 R] endobj 98 0 obj <>stream +HۊdE+VB)`SbnޡGnBG׸XӟR1˷bi?[O·ӧ??$$'X:Z8I|9˗b$~ )uoN &9ދ3ψ ư9N +ȥ;gwEiXԄk4wv6߳b3"}xeF`Mi{H r#G}}Fڤԃ@i +׋q1>w0.^ +ʎSҙHf{>ޱYU+ 2`6s"ݸ·D6s6=) -^N8p`Kf#h(EQ(Zm4{ DLF:Ah.;zc v$y L4v^WP +_CCO+`@Ak!DDMʬr{17cזF˛~e; Yw u wwuGī4Ak/fhH5^\}TT22|cE {: Y2<1JNDBwOڣ0 &(-4ku`!n89dP겁6Phd + xpaS}K1x 'ͻ˔C PA8b϶jF Ķ"^]'J0nT->VC-q&\e&6Kr&ndunϙgwJ2bJnٺQ ]GMS.XYP;#la-.IGa+x^ > >eUd>Cvw<@-`z]@|AA[ЁtޡJ;<ȯz}Z[࠵p`y9"ҁ`a\PV.;֬P +mB ʂbޱ/80-LPV&G&ho1A1A#AE܁Z7 Pz=x5eHmčr~m8@ G #z;D h+0Cn`,@%; [;$tlx O=@,,ӕB56.l(-gbCu[Ӡ]iLM#>@Mm+*޼,:X*SNH [@gd?$-`S/ł09Yn"*2'39i]z;t|ei̺e'[i!s(>)XEB#vmZ^:y@ mVG 7f1jXѐoy$V{Cp=لvvÀ6Rp4e\Hl  :-M498@l+49 T=k65<8:1A>aƼ.1-i.:8.P<ҙĵꝒ{5/H)E +u +Ú#I3QWL[OM>Jfca:CgrY]=,pl[V62a&يM}:SyF58M2NJ31k PFtƙ'nSLh{pd=`3\r63#T( FpW<[|mACz Ui$ 4inq:kB amNj)TyrINVbFI3&IGNCmV_Ԅ'J~Rxb^hpm6c-;.oÒxқV"xb(c0~&tBs"HouRb?WlV|iYf#> endobj 109 0 obj [/ICCBased 49 0 R] endobj 96 0 obj <>stream +HU[j1 *J7P(!܏.`B+؞K $1>d~BpeퟷOi9 L%\eUWug`  VԊY($c-V炱 Q`u"Vy^*&3hu&q'|~]r6:|w/7:*}G JH؞)j8,RNK(i> ғo[3aG}%o$p:9*nEHZqϩaV``y3|efhFaz@!5;ݡnHڎӠ[})[XHmOc.hG +0X;w{@.&VXza1Ku#} tE_Ճ/`Hd +endstream endobj 97 0 obj <> endobj 110 0 obj [/ICCBased 49 0 R] endobj 6 0 obj [5 0 R] endobj 111 0 obj <> endobj xref +0 112 +0000000000 65535 f +0000000016 00000 n +0000000144 00000 n +0000040248 00000 n +0000000000 00000 f +0000047778 00000 n +0000351863 00000 n +0000040312 00000 n +0000040405 00000 n +0000040498 00000 n +0000340635 00000 n +0000340997 00000 n +0000341359 00000 n +0000341724 00000 n +0000342089 00000 n +0000272326 00000 n +0000272683 00000 n +0000273040 00000 n +0000273399 00000 n +0000273762 00000 n +0000040598 00000 n +0000040961 00000 n +0000041324 00000 n +0000041687 00000 n +0000042084 00000 n +0000042480 00000 n +0000270117 00000 n +0000272229 00000 n +0000048957 00000 n +0000044891 00000 n +0000048079 00000 n +0000267636 00000 n +0000270020 00000 n +0000266186 00000 n +0000267539 00000 n +0000263973 00000 n +0000265181 00000 n +0000265590 00000 n +0000265243 00000 n +0000260465 00000 n +0000262970 00000 n +0000263377 00000 n +0000263032 00000 n +0000042877 00000 n +0000044686 00000 n +0000047964 00000 n +0000044748 00000 n +0000260430 00000 n +0000044926 00000 n +0000045129 00000 n +0000045021 00000 n +0000047848 00000 n +0000047879 00000 n +0000048192 00000 n +0000048245 00000 n +0000048561 00000 n +0000048638 00000 n +0000048785 00000 n +0000048880 00000 n +0000049031 00000 n +0000049271 00000 n +0000050351 00000 n +0000054914 00000 n +0000120503 00000 n +0000186092 00000 n +0000251681 00000 n +0000263938 00000 n +0000263175 00000 n +0000263270 00000 n +0000263492 00000 n +0000263545 00000 n +0000263861 00000 n +0000266151 00000 n +0000265386 00000 n +0000265481 00000 n +0000265705 00000 n +0000265758 00000 n +0000266074 00000 n +0000267601 00000 n +0000270082 00000 n +0000272291 00000 n +0000304468 00000 n +0000340538 00000 n +0000280322 00000 n +0000304371 00000 n +0000278888 00000 n +0000280225 00000 n +0000276537 00000 n +0000278791 00000 n +0000274124 00000 n +0000276440 00000 n +0000276502 00000 n +0000278853 00000 n +0000280287 00000 n +0000304433 00000 n +0000340600 00000 n +0000351265 00000 n +0000351764 00000 n +0000347535 00000 n +0000351166 00000 n +0000346036 00000 n +0000347435 00000 n +0000344070 00000 n +0000345936 00000 n +0000342454 00000 n +0000343970 00000 n +0000344034 00000 n +0000346000 00000 n +0000347499 00000 n +0000351229 00000 n +0000351827 00000 n +0000351886 00000 n +trailer +<<7D5557C01281CD4D9D99656AB0619DA4>]>> +startxref +352083 +%%EOF diff --git a/files/images/firmware/Tir_off.png b/files/images/firmware/Tir_off.png new file mode 100644 index 0000000000000000000000000000000000000000..94af2e23abfb6c4ab19ef60e75fc4937d54ed9e4 GIT binary patch literal 30545 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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 K&t;ucLK6TZuxnEQ literal 0 HcmV?d00001 diff --git a/files/images/firmware/Tir_on.png b/files/images/firmware/Tir_on.png new file mode 100644 index 0000000000000000000000000000000000000000..884e4a59af7bcc6217e7d306d343bcc21f968767 GIT binary patch literal 55407 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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 literal 0 HcmV?d00001 diff --git a/files/images/firmware/X8.png b/files/images/firmware/X8.png new file mode 100644 index 0000000000000000000000000000000000000000..5ad68cf0e4321bd72fea016866ac16c069dbae9f GIT binary patch literal 42226 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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 a1OJk=nIHb`GG$<3VDNPHb6Mw<&;$VN|I;!6 literal 0 HcmV?d00001 diff --git a/files/images/firmware/X8_on.png b/files/images/firmware/X8_on.png new file mode 100644 index 0000000000000000000000000000000000000000..3ef05efce8f151f0b6798302ca84fadd8268cfd3 GIT binary patch literal 97409 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&0X7B(2F(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D 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%0Ai0@0FH>_1AY# z&Rv%ia1UO*GVsFom$$#a_<&fLTy0cqk7k&Pvo2q_f@5SU#EFUI(2=5D8^;nuW zY~rV{wvA35txetD-481M#GR|QTp$zUHlJU2}ko7IR9N$y-^9auUitnfw`2By zm2y7g$l@H{!13$T>0fWVIkx>?9{;%J;?)pO0iUgxmVD%xq8-#~$M~$Oaxx_eerljEZ7rzMXK*ZiLPJ4?c8 z*V~0w3@eSYCvFi|k$*muX{T|eb`4vEf%{gq1?si$tJ@Vq4gZcr{ydmF;q_EcZ{em7tM58^C$D{&H>2eL*MI+QSi0h^X6<5@ zJPU#o_FbJkeIl>f+4sK}Fi*M>_IK-pm1dziHZ5P2PER{xG2`~qc_HFUW(A*JnRY|s zro>H&M)BQoZ>lzO&kMC%T@%KsFSmaMcZ);z=exiCEK_*J<$f<-o$yI3_|@M0eKwP1 zKQ^5Rji@j%w5wp67hXHbzKnH>oa*rswl}`t)T)Im%Bst%%bN2KZhsKnz+>xt{=&h9 zmL~0NUJjfZj2<#RGCndb0r4yJudwTHici^pqU|~ReEFI>0jBiuW#OkBq)%7OdETm1 zpZKSrufa0@^G)u3jnmFR))UM9JYgNg>7QN~^!@v9$9K!G&8YqQ(|8Myu5#5cW=6M!(cPQ#%)WaynHCIo2xk*~g-jv?OcC_^MoC$jE%N)OZEI%vN;@w+xn$_T0 zZ`>`HpEWO!p1AX>oj>8;|HCKub2**6HfOD6^uiZG7nd&bp0F@QLz2tm`O?pqeunS= z{<7jrz^z)2(<`-~HRt`-h6+>pUX|}_Xu)+s{PsT6Dsig z^pASaJB+_8FTefqUs9(&?`QGp`ONYk80Gi;s{Fa7Cd!UCs6jHBf$4wlMZ@j9KK5mQ z=bNo%tUt7WYS9r^wLhN}48PX@oxQfa_~4J-NA~yq$yYdi!e|rEiGTAq|9}4GzvPwk zS5!Z9cYIy{)qb*r9MAlkIM#{(n{9u-`!61L=494v-bwr=t3T!+{1<;Fvr0eX|Fuu) zui~5UZjdfxmWh^)mW_7&9q_w8qn=gpe%8;;N)dOy7k=aa|9*k{$;tIR+v=x2JLki2 zHR#oAiQP-@`De!au+JEoo{betRDgKi$`(OM+=+9L( zp%Z>L-;sav@4?l3>HFk=)xG$wXd%?sqRe>8@#%shfh9^SJ+zoqSGi2pi1^?9)jr}s zv&FxykK?WXnOgim@>BhsJ!AIXuk~B!HQv}C^}qS4Rm7TqKjQnYIsd7bKil)i^oG;B z9q;=c{vFuj`SH)UQ;Dk84-b8j{n4S``Ty5-fs~8CKh|xKyRvJ`f8`(ldf(sw@sD@U z=GSv$-@j>!DPCuJooD9HeeL_AI<`mprCvL9xqkkQxBtWi0>27vmS3Ul^DO)6-}5T# zA2ojX{;2Dt<%}f}&$4t={-r+qZ~XcH`Fr<|ADNoQdGEpdx+A^s6*!t0l6@wrcm{5n zy)cviZCXX8WQyUM)JQR>xYM7MT69tr`;Trqk*%ojB<6G?DUv&KTKws3#kiD8N&e