1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-29 14:52:12 +01:00

Merge branch 'next' into corvuscorax/OP-1161_magnetometer-alarm

This commit is contained in:
Corvus Corax 2014-05-08 21:16:21 +02:00
commit ce8e9db362
12 changed files with 497 additions and 484 deletions

View File

@ -743,26 +743,15 @@ void MainWindow::registerDefaultActions()
tmpaction->setEnabled(true); tmpaction->setEnabled(true);
connect(tmpaction, SIGNAL(triggered()), this, SLOT(showHelp())); connect(tmpaction, SIGNAL(triggered()), this, SLOT(showHelp()));
// About sep // About GCS Action
#ifndef Q_WS_MAC // doesn't have the "About" actions in the Help menu // Mac doesn't have the "About" actions in the Help menu
#ifndef Q_WS_MAC
tmpaction = new QAction(this); tmpaction = new QAction(this);
tmpaction->setSeparator(true); tmpaction->setSeparator(true);
cmd = am->registerAction(tmpaction, QLatin1String("QtCreator.Help.Sep.About"), m_globalContext); cmd = am->registerAction(tmpaction, QLatin1String("QtCreator.Help.Sep.About"), m_globalContext);
mhelp->addAction(cmd, Constants::G_HELP_ABOUT); mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
#endif #endif
// About GCS Action
#ifdef Q_WS_MAC
#else
#endif
#ifdef Q_WS_MAC
#endif
connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutOpenPilotGCS()));
// About Plugins Action // About Plugins Action
tmpaction = new QAction(QIcon(Constants::ICON_PLUGIN), tr("About &Plugins..."), this); tmpaction = new QAction(QIcon(Constants::ICON_PLUGIN), tr("About &Plugins..."), this);
cmd = am->registerAction(tmpaction, Constants::ABOUT_PLUGINS, m_globalContext); cmd = am->registerAction(tmpaction, Constants::ABOUT_PLUGINS, m_globalContext);

View File

@ -37,47 +37,64 @@ void AutoUpdatePage::enableButtons(bool enable = false)
void AutoUpdatePage::updateStatus(uploader::AutoUpdateStep status, QVariant value) void AutoUpdatePage::updateStatus(uploader::AutoUpdateStep status, QVariant value)
{ {
QString msg;
switch (status) { switch (status) {
case uploader::WAITING_DISCONNECT: case uploader::WAITING_DISCONNECT:
getWizard()->setWindowFlags(getWizard()->windowFlags() & ~Qt::WindowStaysOnTopHint);
disableButtons(); disableButtons();
ui->statusLabel->setText("Waiting for all OP boards to be disconnected"); ui->statusLabel->setText(tr("Waiting for all OP boards to be disconnected."));
// TODO get rid of magic number 20s (should use UploaderGadgetWidget::BOARD_EVENT_TIMEOUT)
ui->levellinProgressBar->setMaximum(20);
ui->levellinProgressBar->setValue(value.toInt());
break; break;
case uploader::WAITING_CONNECT: case uploader::WAITING_CONNECT:
getWizard()->setWindowFlags(getWizard()->windowFlags() | Qt::WindowStaysOnTopHint); // Note:
getWizard()->setWindowIcon(qApp->windowIcon()); // the following commented out lines were probably added to fix an issue when uploader opened a popup requesting
// user to disconnect all boards
// Side effect is that the wizard dialog flickers
// the uploader was changed to avoid popups alltogether and that fix is not need anymore
// same commented fix can be found in FAILURE case and they are kept for future ref.
// getWizard()->setWindowFlags(getWizard()->windowFlags() | Qt::WindowStaysOnTopHint);
// getWizard()->setWindowIcon(qApp->windowIcon());
// getWizard()->show();
// End of Note
disableButtons(); disableButtons();
getWizard()->show(); ui->statusLabel->setText(tr("Please connect the board to the USB port (don't use external supply)."));
ui->statusLabel->setText("Please connect the board to the USB port (don't use external supply)"); // TODO get rid of magic number 20s (should use UploaderGadgetWidget::BOARD_EVENT_TIMEOUT)
ui->levellinProgressBar->setMaximum(20);
ui->levellinProgressBar->setValue(value.toInt()); ui->levellinProgressBar->setValue(value.toInt());
break; break;
case uploader::JUMP_TO_BL: case uploader::JUMP_TO_BL:
ui->levellinProgressBar->setValue(0); ui->levellinProgressBar->setValue(0);
ui->statusLabel->setText("Board going into bootloader mode"); ui->statusLabel->setText(tr("Board going into bootloader mode."));
break; break;
case uploader::LOADING_FW: case uploader::LOADING_FW:
ui->statusLabel->setText("Loading firmware"); ui->statusLabel->setText(tr("Loading firmware."));
break; break;
case uploader::UPLOADING_FW: case uploader::UPLOADING_FW:
ui->statusLabel->setText("Uploading firmware"); ui->statusLabel->setText(tr("Uploading firmware."));
ui->levellinProgressBar->setMaximum(100);
ui->levellinProgressBar->setValue(value.toInt()); ui->levellinProgressBar->setValue(value.toInt());
break; break;
case uploader::UPLOADING_DESC: case uploader::UPLOADING_DESC:
ui->statusLabel->setText("Uploading description"); ui->statusLabel->setText(tr("Uploading description."));
break; break;
case uploader::BOOTING: case uploader::BOOTING:
ui->statusLabel->setText("Booting the board"); ui->statusLabel->setText(tr("Booting the board."));
break; break;
case uploader::SUCCESS: case uploader::SUCCESS:
enableButtons(true); enableButtons(true);
ui->statusLabel->setText("Board updated, please press 'Next' to continue"); ui->statusLabel->setText(tr("Board updated, please press 'Next' to continue."));
break; break;
case uploader::FAILURE: case uploader::FAILURE:
getWizard()->setWindowFlags(getWizard()->windowFlags() | Qt::WindowStaysOnTopHint); // getWizard()->setWindowFlags(getWizard()->windowFlags() | Qt::WindowStaysOnTopHint);
getWizard()->setWindowIcon(qApp->windowIcon()); // getWizard()->setWindowIcon(qApp->windowIcon());
enableButtons(true); enableButtons(true);
getWizard()->show(); QString msg = value.toString();
ui->statusLabel->setText("Something went wrong, you will have to manually upgrade the board using the uploader plugin"); if (msg.isEmpty()) {
msg = tr("Something went wrong, you will have to manually upgrade the board using the uploader plugin.");
}
ui->statusLabel->setText(QString("<font color='red'>%1</font>").arg(msg));
break; break;
} }
} }

View File

@ -5,6 +5,7 @@ QT += svg
include(../../openpilotgcsplugin.pri) include(../../openpilotgcsplugin.pri)
include(../../plugins/coreplugin/coreplugin.pri) include(../../plugins/coreplugin/coreplugin.pri)
include(../../libs/version_info/version_info.pri)
include(telemetry_dependencies.pri) include(telemetry_dependencies.pri)
HEADERS += telemetry_global.h \ HEADERS += telemetry_global.h \

View File

@ -1,3 +1,4 @@
include(../../plugins/uavtalk/uavtalk.pri)
include(../../plugins/uavobjects/uavobjects.pri) include(../../plugins/uavobjects/uavobjects.pri)
include(../../plugins/uavobjectutil/uavobjectutil.pri)
include(../../plugins/uavtalk/uavtalk.pri)

View File

@ -28,21 +28,26 @@
#include "telemetryplugin.h" #include "telemetryplugin.h"
#include "monitorgadgetfactory.h" #include "monitorgadgetfactory.h"
#include "extensionsystem/pluginmanager.h" #include "version_info/version_info.h"
#include "uavobjectmanager.h" #include "uavobjectmanager.h"
#include "uavobject.h" #include "uavobject.h"
#include "coreplugin/icore.h" #include "uavobjectutilmanager.h"
#include "coreplugin/connectionmanager.h"
#include <QDebug>
#include <QtPlugin>
#include <QStringList>
#include <extensionsystem/pluginmanager.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/iuavgadget.h> #include <coreplugin/iuavgadget.h>
#include <coreplugin/connectionmanager.h>
#include <uavtalk/telemetrymanager.h>
TelemetryPlugin::TelemetryPlugin() #include <QDebug>
#include <QStringList>
#include <QWidget>
#include <QMainWindow>
#include <QMessageBox>
#include <QCheckBox>
TelemetryPlugin::TelemetryPlugin() : firmwareWarningMessageBox(0)
{} {}
TelemetryPlugin::~TelemetryPlugin() TelemetryPlugin::~TelemetryPlugin()
@ -81,166 +86,83 @@ bool TelemetryPlugin::initialize(const QStringList & args, QString *errMsg)
// add monitor widget to connection manager // add monitor widget to connection manager
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
// connect(cm, SIGNAL(deviceConnected(QIODevice *)), w, SLOT(telemetryConnected()));
// connect(cm, SIGNAL(deviceDisconnected()), w, SLOT(telemetryDisconnected()));
cm->addWidget(w); cm->addWidget(w);
// Listen to autopilot connection events
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
TelemetryManager *telMngr = pm->getObject<TelemetryManager>();
connect(telMngr, SIGNAL(connected()), this, SLOT(versionMatchCheck()));
return true; return true;
} }
void TelemetryPlugin::extensionsInitialized() void TelemetryPlugin::extensionsInitialized()
{
// Core::ICore::instance()->readSettings(this);
// ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
// connect(pm, SIGNAL(objectAdded(QObject *)), this, SLOT(onTelemetryManagerAdded(QObject *)));
// _toRemoveNotifications.clear();
// connectNotifications();
}
// void TelemetryPlugin::saveConfig(QSettings *settings, UAVConfigInfo *configInfo)
// {
// configInfo->setVersion(VERSION);
//
// settings->beginWriteArray("Current");
// settings->setArrayIndex(0);
// currentNotification.saveState(settings);
// settings->endArray();
//
// settings->beginGroup("listNotifies");
// settings->remove("");
// settings->endGroup();
//
// settings->beginWriteArray("listNotifies");
// for (int i = 0; i < _notificationList.size(); i++) {
// settings->setArrayIndex(i);
// _notificationList.at(i)->saveState(settings);
// }
// settings->endArray();
// settings->setValue(QLatin1String("Enable"), enable);
// }
// void TelemetryPlugin::readConfig(QSettings *settings, UAVConfigInfo * /* configInfo */)
// {
//// Just for migration to the new format.
//// Q_ASSERT(configInfo->version() == UAVConfigVersion());
//
// settings->beginReadArray("Current");
// settings->setArrayIndex(0);
// currentNotification.restoreState(settings);
// settings->endArray();
//
//// read list of notifications from settings
// int size = settings->beginReadArray("listNotifies");
// for (int i = 0; i < size; ++i) {
// settings->setArrayIndex(i);
// NotificationItem *notification = new NotificationItem;
// notification->restoreState(settings);
// _notificationList.append(notification);
// }
// settings->endArray();
// setEnable(settings->value(QLatin1String("Enable"), 0).toBool());
// }
// void TelemetryPlugin::onTelemetryManagerAdded(QObject *obj)
// {
// telMngr = qobject_cast<TelemetryManager *>(obj);
// if (telMngr) {
// connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
// }
// }
void TelemetryPlugin::shutdown()
{ {
// Do nothing // Do nothing
} }
// void TelemetryPlugin::onAutopilotDisconnect() void TelemetryPlugin::shutdown()
// { {
// connectNotifications(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
// } TelemetryManager *telMngr = pm->getObject<TelemetryManager>();
///*! disconnect(telMngr, SIGNAL(connected()), this, SLOT(versionMatchCheck()));
// clear any telemetry timers from previous flight;
// reset will be perform on start of option page
// */
// void TelemetryPlugin::resetNotification(void)
// {
//// first, reject empty args and unknown fields.
// foreach(NotificationItem * ntf, _notificationList) {
// ntf->disposeTimer();
// disconnect(ntf->getTimer(), SIGNAL(timeout()), this, SLOT(on_timerRepeated_Notification()));
// ntf->disposeExpireTimer();
// disconnect(ntf->getExpireTimer(), SIGNAL(timeout()), this, SLOT(on_timerRepeated_Notification()));
// }
// }
// void TelemetryPlugin::connectNotifications() if (firmwareWarningMessageBox) {
// { delete firmwareWarningMessageBox;
// foreach(UAVDataObject * obj, lstNotifiedUAVObjects) { }
// if (obj != NULL) { }
// disconnect(obj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(on_arrived_Notification(UAVObject *)));
// } void TelemetryPlugin::versionMatchCheck()
// } {
// if (phonon.mo != NULL) { ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
// delete phonon.mo; UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
// phonon.mo = NULL; deviceDescriptorStruct boardDescription = utilMngr->getBoardDescriptionStruct();
// }
// QString uavoHash = VersionInfo::uavoHashArray();
// if (!enable) {
// return; uavoHash.chop(2);
// } uavoHash.remove(0, 2);
// uavoHash = uavoHash.trimmed();
// ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
// UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); QByteArray uavoHashArray;
// bool ok;
// lstNotifiedUAVObjects.clear(); foreach(QString str, uavoHash.split(",")) {
// _pendingNotifications.clear(); uavoHashArray.append(str.toInt(&ok, 16));
// _notificationList.append(_toRemoveNotifications); }
// _toRemoveNotifications.clear();
// QByteArray fwVersion = boardDescription.uavoHash;
//// first, reject empty args and unknown fields. if (fwVersion != uavoHashArray) {
// foreach(NotificationItem * telemetry, _notificationList) { QString gcsDescription = VersionInfo::revision();
// telemetry->_isPlayed = false; QString gcsGitHash = gcsDescription.mid(gcsDescription.indexOf(":") + 1, 8);
// telemetry->isNowPlaying = false; gcsGitHash.remove(QRegExp("^[0]*"));
// QString gcsGitDate = gcsDescription.mid(gcsDescription.indexOf(" ") + 1, 14);
// if (telemetry->mute()) {
// continue; QString gcsUavoHashStr;
// } QString fwUavoHashStr;
//// check is all sounds presented for notification, foreach(char i, fwVersion) {
//// if not - we must not subscribe to it at all fwUavoHashStr.append(QString::number(i, 16).right(2));
// if (telemetry->toList().isEmpty()) { }
// continue; foreach(char i, uavoHashArray) {
// } gcsUavoHashStr.append(QString::number(i, 16).right(2));
// }
// UAVDataObject *obj = dynamic_cast<UAVDataObject *>(objManager->getObject(telemetry->getDataObject())); QString versionFormat = "%1 (%2-%3)";
// if (obj != NULL) { QString gcsVersion = versionFormat.arg(gcsGitDate, gcsGitHash, gcsUavoHashStr.left(8));
// if (!lstNotifiedUAVObjects.contains(obj)) { QString fwVersion = versionFormat.arg(boardDescription.gitDate, boardDescription.gitHash, fwUavoHashStr.left(8));
// lstNotifiedUAVObjects.append(obj);
// if (!firmwareWarningMessageBox) {
// connect(obj, SIGNAL(objectUpdated(UAVObject *)), firmwareWarningMessageBox = new QMessageBox(Core::ICore::instance()->mainWindow());
// this, SLOT(on_arrived_Notification(UAVObject *)), firmwareWarningMessageBox->setWindowModality(Qt::NonModal);
// Qt::QueuedConnection); firmwareWarningMessageBox->setWindowTitle(tr("Firmware Version Mismatch!"));
// } firmwareWarningMessageBox->setIcon(QMessageBox::Warning);
// } else { firmwareWarningMessageBox->setStandardButtons(QMessageBox::Ok);
// qTelemetryDebug() << "Error: Object is unknown (" << telemetry->getDataObject() << ")."; firmwareWarningMessageBox->setText(tr("GCS and firmware versions of the UAV objects set do not match which can cause configuration problems."));
// } // should we want to re-introduce the checkbox
// } // firmwareWarningMessageBox->setCheckBox(new QCheckBox(tr("&Don't show this message again.")));
// }
// if (_notificationList.isEmpty()) { QString detailTxt = tr("GCS version: %1").arg(gcsVersion) + "\n" + tr("Firmware version: %1").arg(fwVersion);
// return; firmwareWarningMessageBox->setDetailedText(detailTxt);
// } firmwareWarningMessageBox->show();
//// set notification message to current event }
// phonon.mo = Phonon::createPlayer(Phonon::NotificationCategory); }
// phonon.mo->clearQueue();
// phonon.firstPlay = true;
// QList<Phonon::AudioOutputDevice> audioOutputDevices =
// Phonon::BackendCapabilities::availableAudioOutputDevices();
// foreach(Phonon::AudioOutputDevice dev, audioOutputDevices) {
// qTelemetryDebug() << "Telemetry: Audio Output device: " << dev.name() << " - " << dev.description();
// }
// connect(phonon.mo, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
// this, SLOT(stateChanged(Phonon::State, Phonon::State)));
// }

View File

@ -29,6 +29,7 @@
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
class QMessageBox;
class MonitorGadgetFactory; class MonitorGadgetFactory;
class TelemetryPlugin : public ExtensionSystem::IPlugin { class TelemetryPlugin : public ExtensionSystem::IPlugin {
@ -44,8 +45,12 @@ public:
bool initialize(const QStringList &arguments, QString *errorString); bool initialize(const QStringList &arguments, QString *errorString);
void shutdown(); void shutdown();
private slots:
void versionMatchCheck();
private: private:
MonitorGadgetFactory *mf; MonitorGadgetFactory *mf;
QMessageBox *firmwareWarningMessageBox;
}; };
#endif // TELEMETRYPLUGIN_H #endif // TELEMETRYPLUGIN_H

View File

@ -47,7 +47,16 @@
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -88,10 +97,10 @@ menu on the right.</string>
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reboot the board and clear its settings memory.&lt;/p&gt;&lt;p&gt; Useful if the board cannot boot properly.&lt;/p&gt;&lt;p&gt; Blue led starts blinking quick for 20-30 seconds than the board will start normally&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If telemetry is not running, select the link using the dropdown&lt;/p&gt;&lt;p&gt;menu on the right.&lt;/p&gt;&lt;p&gt;PLEASE NOTE: Supported with bootloader versions 4.0 and earlier&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reboot the board and clear its settings memory.&lt;/p&gt;&lt;p&gt; Useful if the board cannot boot properly.&lt;/p&gt;&lt;p&gt; Blue led starts blinking quick for 20-30 seconds than the board will start normally&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If telemetry is not running, select the link using the dropdown&lt;/p&gt;&lt;p&gt;menu on the right.&lt;/p&gt;&lt;p&gt;PLEASE NOTE: Supported with bootloader versions 4.0 and later&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Erase settings</string> <string>Erase Settings</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -192,6 +201,12 @@ through serial or USB)</string>
</item> </item>
<item row="0" column="11"> <item row="0" column="11">
<widget class="QLabel" name="boardStatus"> <widget class="QLabel" name="boardStatus">
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
@ -277,7 +292,7 @@ Rescue is possible in USB mode only.</string>
<number>0</number> <number>0</number>
</property> </property>
<property name="textVisible"> <property name="textVisible">
<bool>false</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -1,6 +1,6 @@
include(../../openpilotgcsplugin.pri) include(../../openpilotgcsplugin.pri)
include(../../plugins/coreplugin/coreplugin.pri) include(../../plugins/coreplugin/coreplugin.pri)
include(../../plugins/uavobjects/uavobjects.pri) include(../../plugins/uavobjects/uavobjects.pri)
include(../../plugins/uavobjectutil/uavobjectutil.pri)
include(../../plugins/uavtalk/uavtalk.pri) include(../../plugins/uavtalk/uavtalk.pri)
include(../../plugins/ophid/ophid.pri) include(../../plugins/ophid/ophid.pri)
include(../../plugins/uavobjectutil/uavobjectutil.pri)

View File

@ -25,18 +25,111 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "uploadergadgetwidget.h" #include "uploadergadgetwidget.h"
#include "version_info/version_info.h"
#include "flightstatus.h"
#include "flightstatus.h"
#include "delay.h"
#include "devicewidget.h"
#include "runningdevicewidget.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/connectionmanager.h>
#include <uavtalk/telemetrymanager.h> #include <uavtalk/telemetrymanager.h>
#include <QDesktopServices>
#include <QMessageBox>
#include <QProgressBar>
#include <QDebug> #include <QDebug>
#define DFU_DEBUG true #define DFU_DEBUG true
const int UploaderGadgetWidget::BOARD_EVENT_TIMEOUT = 20000;
const int UploaderGadgetWidget::AUTOUPDATE_CLOSE_TIMEOUT = 7000; const int UploaderGadgetWidget::AUTOUPDATE_CLOSE_TIMEOUT = 7000;
TimedDialog::TimedDialog(const QString &title, const QString &labelText, int timeout, QWidget *parent, Qt::WindowFlags flags) :
QProgressDialog(labelText, tr("Cancel"), 0, timeout, parent, flags), bar(new QProgressBar(this))
{
setWindowTitle(title);
setAutoReset(false);
// open immediately...
setMinimumDuration(0);
// setup progress bar
bar->setRange(0, timeout);
bar->setFormat(tr("Timing out in %1 seconds").arg(timeout));
setBar(bar);
}
void TimedDialog::perform()
{
setValue(value() + 1);
int remaining = bar->maximum() - bar->value();
if (remaining > 0) {
bar->setFormat(tr("Timing out in %1 seconds").arg(remaining));
} else {
bar->setFormat(tr("Timed out after %1 seconds").arg(bar->maximum()));
}
}
ConnectionWaiter::ConnectionWaiter(int targetDeviceCount, int timeout, QWidget *parent) : QObject(parent), eventLoop(this), timer(this), timeout(timeout), elapsed(0), targetDeviceCount(targetDeviceCount), result(ConnectionWaiter::Ok)
{}
int ConnectionWaiter::exec()
{
connect(USBMonitor::instance(), SIGNAL(deviceDiscovered(USBPortInfo)), this, SLOT(deviceEvent()));
connect(USBMonitor::instance(), SIGNAL(deviceRemoved(USBPortInfo)), this, SLOT(deviceEvent()));
connect(&timer, SIGNAL(timeout()), this, SLOT(perform()));
timer.start(1000);
emit timeChanged(0);
eventLoop.exec();
return result;
}
void ConnectionWaiter::cancel()
{
quit();
result = ConnectionWaiter::Canceled;
}
void ConnectionWaiter::quit()
{
disconnect(USBMonitor::instance(), SIGNAL(deviceDiscovered(USBPortInfo)), this, SLOT(deviceEvent()));
disconnect(USBMonitor::instance(), SIGNAL(deviceRemoved(USBPortInfo)), this, SLOT(deviceEvent()));
timer.stop();
eventLoop.exit();
}
void ConnectionWaiter::perform()
{
++elapsed;
emit timeChanged(elapsed);
int remaining = timeout - elapsed * 1000;
if (remaining <= 0) {
result = ConnectionWaiter::TimedOut;
quit();
}
}
void ConnectionWaiter::deviceEvent()
{
if (USBMonitor::instance()->availableDevices(0x20a0, -1, -1, -1).length() == targetDeviceCount) {
quit();
}
}
int ConnectionWaiter::openDialog(const QString &title, const QString &labelText, int targetDeviceCount, int timeout, QWidget *parent, Qt::WindowFlags flags)
{
TimedDialog dlg(title, labelText, timeout / 1000, parent, flags);
ConnectionWaiter waiter(targetDeviceCount, timeout, parent);
connect(&dlg, SIGNAL(canceled()), &waiter, SLOT(cancel()));
connect(&waiter, SIGNAL(timeChanged(int)), &dlg, SLOT(perform()));
return waiter.exec();
}
UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent) UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent)
{ {
m_config = new Ui_UploaderWidget(); m_config = new Ui_UploaderWidget();
@ -44,35 +137,31 @@ UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent)
currentStep = IAP_STATE_READY; currentStep = IAP_STATE_READY;
resetOnly = false; resetOnly = false;
dfu = NULL; dfu = NULL;
m_timer = 0;
m_progress = 0;
msg = new QErrorMessage(this);
// Listen to autopilot connection events // Listen to autopilot connection events
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
TelemetryManager *telMngr = pm->getObject<TelemetryManager>(); TelemetryManager *telMngr = pm->getObject<TelemetryManager>();
connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect())); connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
connect(telMngr, SIGNAL(connected()), this, SLOT(versionMatchCheck()));
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect())); connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
connect(cm, SIGNAL(deviceConnected(QIODevice *)), this, SLOT(onPhysicalHWConnect()));
connect(m_config->haltButton, SIGNAL(clicked()), this, SLOT(systemHalt())); connect(m_config->haltButton, SIGNAL(clicked()), this, SLOT(systemHalt()));
connect(m_config->resetButton, SIGNAL(clicked()), this, SLOT(systemReset())); connect(m_config->resetButton, SIGNAL(clicked()), this, SLOT(systemReset()));
connect(m_config->bootButton, SIGNAL(clicked()), this, SLOT(systemBoot())); connect(m_config->bootButton, SIGNAL(clicked()), this, SLOT(systemBoot()));
connect(m_config->safeBootButton, SIGNAL(clicked()), this, SLOT(systemSafeBoot())); connect(m_config->safeBootButton, SIGNAL(clicked()), this, SLOT(systemSafeBoot()));
connect(m_config->eraseBootButton, SIGNAL(clicked()), this, SLOT(systemEraseBoot())); connect(m_config->eraseBootButton, SIGNAL(clicked()), this, SLOT(systemEraseBoot()));
connect(m_config->rescueButton, SIGNAL(clicked()), this, SLOT(systemRescue())); connect(m_config->rescueButton, SIGNAL(clicked()), this, SLOT(systemRescue()));
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
connect(cm, SIGNAL(deviceConnected(QIODevice *)), this, SLOT(onPhisicalHWConnect()));
getSerialPorts(); getSerialPorts();
m_config->autoUpdateButton->setEnabled(autoUpdateCapable());
connect(m_config->autoUpdateButton, SIGNAL(clicked()), this, SLOT(startAutoUpdate())); connect(m_config->autoUpdateButton, SIGNAL(clicked()), this, SLOT(startAutoUpdate()));
connect(m_config->autoUpdateOkButton, SIGNAL(clicked()), this, SLOT(closeAutoUpdate())); connect(m_config->autoUpdateOkButton, SIGNAL(clicked()), this, SLOT(closeAutoUpdate()));
m_config->autoUpdateButton->setEnabled(autoUpdateCapable());
m_config->autoUpdateGroupBox->setVisible(false); m_config->autoUpdateGroupBox->setVisible(false);
QIcon rbi; m_config->refreshPorts->setIcon(QIcon(":uploader/images/view-refresh.svg"));
rbi.addFile(QString(":uploader/images/view-refresh.svg"));
m_config->refreshPorts->setIcon(rbi);
bootButtonsSetEnable(false); bootButtonsSetEnable(false);
@ -82,11 +171,9 @@ UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent)
// And check whether by any chance we are not already connected // And check whether by any chance we are not already connected
if (telMngr->isConnected()) { if (telMngr->isConnected()) {
onAutopilotConnect(); onAutopilotConnect();
versionMatchCheck();
} }
} }
bool sortPorts(const QSerialPortInfo &s1, const QSerialPortInfo &s2) bool sortPorts(const QSerialPortInfo &s1, const QSerialPortInfo &s2)
{ {
return s1.portName() < s2.portName(); return s1.portName() < s2.portName();
@ -141,7 +228,7 @@ FlightStatus *UploaderGadgetWidget::getFlightStatus()
Q_ASSERT(pm); Q_ASSERT(pm);
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
Q_ASSERT(objManager); Q_ASSERT(objManager);
FlightStatus *status = dynamic_cast<FlightStatus *>(objManager->getObject(QString("FlightStatus"))); FlightStatus *status = dynamic_cast<FlightStatus *>(objManager->getObject("FlightStatus"));
Q_ASSERT(status); Q_ASSERT(status);
return status; return status;
} }
@ -151,14 +238,12 @@ void UploaderGadgetWidget::bootButtonsSetEnable(bool enabled)
m_config->bootButton->setEnabled(enabled); m_config->bootButton->setEnabled(enabled);
m_config->safeBootButton->setEnabled(enabled); m_config->safeBootButton->setEnabled(enabled);
m_config->eraseBootButton->setEnabled(
enabled &&
// this feature is supported only on BL revision >= 4 // this feature is supported only on BL revision >= 4
((dfu != NULL) && (dfu->devices[0].BL_Version >= 4))); bool isBL4 = ((dfu != NULL) && (dfu->devices[0].BL_Version >= 4));
m_config->eraseBootButton->setEnabled(isBL4 && enabled);
} }
void UploaderGadgetWidget::onPhisicalHWConnect() void UploaderGadgetWidget::onPhysicalHWConnect()
{ {
bootButtonsSetEnable(false); bootButtonsSetEnable(false);
m_config->rescueButton->setEnabled(false); m_config->rescueButton->setEnabled(false);
@ -190,7 +275,7 @@ void UploaderGadgetWidget::populate()
} }
RunningDeviceWidget *dw = new RunningDeviceWidget(this); RunningDeviceWidget *dw = new RunningDeviceWidget(this);
dw->populate(); dw->populate();
m_config->systemElements->addTab(dw, QString("Connected Device")); m_config->systemElements->addTab(dw, tr("Connected Device"));
} }
/** /**
@ -210,6 +295,14 @@ void UploaderGadgetWidget::onAutopilotDisconnect()
} }
} }
static void sleep(int ms)
{
QEventLoop eventLoop;
QTimer::singleShot(ms, &eventLoop, SLOT(quit()));
eventLoop.exec();
}
/** /**
Tell the mainboard to go to bootloader: Tell the mainboard to go to bootloader:
- Send the relevant IAP commands - Send the relevant IAP commands
@ -221,7 +314,7 @@ void UploaderGadgetWidget::goToBootloader(UAVObject *callerObj, bool success)
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVObject *fwIAP = dynamic_cast<UAVDataObject *>(objManager->getObject(QString("FirmwareIAPObj"))); UAVObject *fwIAP = dynamic_cast<UAVDataObject *>(objManager->getObject("FirmwareIAPObj"));
switch (currentStep) { switch (currentStep) {
case IAP_STATE_READY: case IAP_STATE_READY:
@ -235,39 +328,37 @@ void UploaderGadgetWidget::goToBootloader(UAVObject *callerObj, bool success)
connect(fwIAP, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(goToBootloader(UAVObject *, bool))); connect(fwIAP, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(goToBootloader(UAVObject *, bool)));
currentStep = IAP_STATE_STEP_1; currentStep = IAP_STATE_STEP_1;
clearLog(); clearLog();
log(QString("IAP Step 1")); log("IAP Step 1");
fwIAP->updated(); fwIAP->updated();
break; break;
case IAP_STATE_STEP_1: case IAP_STATE_STEP_1:
if (!success) { if (!success) {
log(QString("Oops, failure step 1")); log("Oops, failure step 1");
log("Reset did NOT happen"); log("Reset did NOT happen");
currentStep = IAP_STATE_READY; currentStep = IAP_STATE_READY;
disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(goToBootloader(UAVObject *, bool))); disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(goToBootloader(UAVObject *, bool)));
m_config->haltButton->setEnabled(true); m_config->haltButton->setEnabled(true);
break; break;
} }
QTimer::singleShot(600, &m_eventloop, SLOT(quit())); sleep(600);
m_eventloop.exec();
fwIAP->getField("Command")->setValue("2233"); fwIAP->getField("Command")->setValue("2233");
currentStep = IAP_STATE_STEP_2; currentStep = IAP_STATE_STEP_2;
log(QString("IAP Step 2")); log("IAP Step 2");
fwIAP->updated(); fwIAP->updated();
break; break;
case IAP_STATE_STEP_2: case IAP_STATE_STEP_2:
if (!success) { if (!success) {
log(QString("Oops, failure step 2")); log("Oops, failure step 2");
log("Reset did NOT happen"); log("Reset did NOT happen");
currentStep = IAP_STATE_READY; currentStep = IAP_STATE_READY;
disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(goToBootloader(UAVObject *, bool))); disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(goToBootloader(UAVObject *, bool)));
m_config->haltButton->setEnabled(true); m_config->haltButton->setEnabled(true);
break; break;
} }
QTimer::singleShot(600, &m_eventloop, SLOT(quit())); sleep(600);
m_eventloop.exec();
fwIAP->getField("Command")->setValue("3344"); fwIAP->getField("Command")->setValue("3344");
currentStep = IAP_STEP_RESET; currentStep = IAP_STEP_RESET;
log(QString("IAP Step 3")); log("IAP Step 3");
fwIAP->updated(); fwIAP->updated();
break; break;
case IAP_STEP_RESET: case IAP_STEP_RESET:
@ -286,14 +377,12 @@ void UploaderGadgetWidget::goToBootloader(UAVObject *callerObj, bool success)
QString dli = cm->getCurrentDevice().getConName(); QString dli = cm->getCurrentDevice().getConName();
QString dlj = cm->getCurrentDevice().getConName(); QString dlj = cm->getCurrentDevice().getConName();
cm->disconnectDevice(); cm->disconnectDevice();
QTimer::singleShot(200, &m_eventloop, SLOT(quit())); sleep(200);
m_eventloop.exec();
// Tell connections to stop their polling threads: otherwise it will mess up DFU // Tell connections to stop their polling threads: otherwise it will mess up DFU
cm->suspendPolling(); cm->suspendPolling();
QTimer::singleShot(200, &m_eventloop, SLOT(quit())); sleep(200);
m_eventloop.exec();
log("Board Halt"); log("Board Halt");
m_config->boardStatus->setText("Bootloader"); m_config->boardStatus->setText(tr("Bootloader"));
if (dlj.startsWith("USB")) { if (dlj.startsWith("USB")) {
m_config->telemetryLink->setCurrentIndex(m_config->telemetryLink->findText("USB")); m_config->telemetryLink->setCurrentIndex(m_config->telemetryLink->findText("USB"));
} else { } else {
@ -319,7 +408,7 @@ void UploaderGadgetWidget::goToBootloader(UAVObject *callerObj, bool success)
dfu = NULL; dfu = NULL;
cm->resumePolling(); cm->resumePolling();
currentStep = IAP_STATE_READY; currentStep = IAP_STATE_READY;
m_config->boardStatus->setText("Bootloader?"); m_config->boardStatus->setText(tr("Bootloader?"));
m_config->haltButton->setEnabled(true); m_config->haltButton->setEnabled(true);
return; return;
} }
@ -330,15 +419,14 @@ void UploaderGadgetWidget::goToBootloader(UAVObject *callerObj, bool success)
dfu = NULL; dfu = NULL;
cm->resumePolling(); cm->resumePolling();
currentStep = IAP_STATE_READY; currentStep = IAP_STATE_READY;
m_config->boardStatus->setText("Bootloader?"); m_config->boardStatus->setText(tr("Bootloader?"));
return; return;
} }
// dfu.StatusRequest(); // dfu.StatusRequest();
QTimer::singleShot(500, &m_eventloop, SLOT(quit())); sleep(500);
m_eventloop.exec();
dfu->findDevices(); dfu->findDevices();
log(QString("Found ") + QString::number(dfu->numberOfDevices) + QString(" device(s).")); log(QString("Found %1 device(s).").arg(QString::number(dfu->numberOfDevices)));
if (dfu->numberOfDevices < 0 || dfu->numberOfDevices > 3) { if (dfu->numberOfDevices < 0 || dfu->numberOfDevices > 3) {
log("Inconsistent number of devices! Aborting"); log("Inconsistent number of devices! Aborting");
delete dfu; delete dfu;
@ -358,7 +446,7 @@ void UploaderGadgetWidget::goToBootloader(UAVObject *callerObj, bool success)
dw->setDeviceID(i); dw->setDeviceID(i);
dw->setDfu(dfu); dw->setDfu(dfu);
dw->populate(); dw->populate();
m_config->systemElements->addTab(dw, QString("Device") + QString::number(i)); m_config->systemElements->addTab(dw, tr("Device") + QString::number(i));
} }
// Need to re-enable in case we were not connected // Need to re-enable in case we were not connected
@ -380,20 +468,14 @@ void UploaderGadgetWidget::goToBootloader(UAVObject *callerObj, bool success)
void UploaderGadgetWidget::systemHalt() void UploaderGadgetWidget::systemHalt()
{ {
FlightStatus *status = getFlightStatus();
// The board can not be halted when in armed state. // The board can not be halted when in armed state.
// If board is armed, or arming. Show message with notice. // If board is armed, or arming. Show message with notice.
FlightStatus *status = getFlightStatus();
if (status->getArmed() == FlightStatus::ARMED_DISARMED) { if (status->getArmed() == FlightStatus::ARMED_DISARMED) {
goToBootloader(); goToBootloader();
} else { } else {
QMessageBox mbox(this); cannotHaltMessageBox();
mbox.setText(QString(tr("The controller board is armed and can not be halted.\n\n"
"Please make sure the board is not armed and then press halt again to proceed\n"
"or use the rescue option to force a firmware upgrade.")));
mbox.setStandardButtons(QMessageBox::Ok);
mbox.setIcon(QMessageBox::Warning);
mbox.exec();
} }
} }
@ -418,13 +500,7 @@ void UploaderGadgetWidget::systemReset()
log("Board Reset initiated."); log("Board Reset initiated.");
goToBootloader(); goToBootloader();
} else { } else {
QMessageBox mbox(this); cannotResetMessageBox();
mbox.setText(QString(tr("The controller board is armed and can not be reset.\n\n"
"Please make sure the board is not armed and then press reset again to proceed\n"
"or power cycle to force a board reset.")));
mbox.setStandardButtons(QMessageBox::Ok);
mbox.setIcon(QMessageBox::Warning);
mbox.exec();
} }
} }
@ -440,20 +516,17 @@ void UploaderGadgetWidget::systemSafeBoot()
void UploaderGadgetWidget::systemEraseBoot() void UploaderGadgetWidget::systemEraseBoot()
{ {
QMessageBox msgBox; switch (confirmEraseSettingsMessageBox()) {
int result; case QMessageBox::Ok:
msgBox.setWindowTitle(tr("Erase Settings"));
msgBox.setInformativeText(tr("Do you want to erase all settings from the board?\nSettings cannot be recovered after this operation.\nThe board will be restarted and all the setting erased"));
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel | QMessageBox::Help);
result = msgBox.exec();
if (result == QMessageBox::Ok) {
commonSystemBoot(true, true); commonSystemBoot(true, true);
} else if (result == QMessageBox::Help) { break;
case QMessageBox::Help:
QDesktopServices::openUrl(QUrl(tr("http://wiki.openpilot.org/display/Doc/Erase+board+settings"), QUrl::StrictMode)); QDesktopServices::openUrl(QUrl(tr("http://wiki.openpilot.org/display/Doc/Erase+board+settings"), QUrl::StrictMode));
break;
} }
} }
/** /**
* Tells the system to boot (from Bootloader state) * Tells the system to boot (from Bootloader state)
* @param[in] safeboot Indicates whether the firmware should use the stock HWSettings * @param[in] safeboot Indicates whether the firmware should use the stock HWSettings
@ -494,7 +567,7 @@ void UploaderGadgetWidget::commonSystemBoot(bool safeboot, bool erase)
cm->resumePolling(); cm->resumePolling();
m_config->rescueButton->setEnabled(true); m_config->rescueButton->setEnabled(true);
m_config->telemetryLink->setEnabled(true); m_config->telemetryLink->setEnabled(true);
m_config->boardStatus->setText("Running"); m_config->boardStatus->setText(tr("Running"));
if (currentStep == IAP_STATE_BOOTLOADER) { if (currentStep == IAP_STATE_BOOTLOADER) {
// Freeze the tabs, they are not useful anymore and their buttons // Freeze the tabs, they are not useful anymore and their buttons
// will cause segfaults or weird stuff if we use them. // will cause segfaults or weird stuff if we use them.
@ -531,32 +604,25 @@ bool UploaderGadgetWidget::autoUpdate()
delete dfu; delete dfu;
dfu = NULL; dfu = NULL;
} }
QEventLoop loop;
QTimer timer; if (USBMonitor::instance()->availableDevices(0x20a0, -1, -1, -1).length() > 0) {
timer.setSingleShot(true); // wait for all boards to be disconnected
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); ConnectionWaiter waiter(0, BOARD_EVENT_TIMEOUT);
while (USBMonitor::instance()->availableDevices(0x20a0, -1, -1, -1).length() > 0) { connect(&waiter, SIGNAL(timeChanged(int)), this, SLOT(autoUpdateDisconnectProgress(int)));
emit autoUpdateSignal(WAITING_DISCONNECT, QVariant()); if (waiter.exec() == ConnectionWaiter::TimedOut) {
if (QMessageBox::warning(this, tr("OpenPilot Uploader"), tr("Please disconnect your OpenPilot board"), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Cancel) { emit autoUpdateSignal(FAILURE, QVariant(tr("Timed out while waiting for all boards to be disconnected!")));
emit autoUpdateSignal(FAILURE, QVariant());
return false; return false;
} }
timer.start(500);
loop.exec();
} }
emit autoUpdateSignal(WAITING_CONNECT, 0);
autoUpdateConnectTimeout = 0; // wait for a board to connect
m_timer = new QTimer(this); ConnectionWaiter waiter(1, BOARD_EVENT_TIMEOUT);
connect(m_timer, SIGNAL(timeout()), this, SLOT(performAuto())); connect(&waiter, SIGNAL(timeChanged(int)), this, SLOT(autoUpdateConnectProgress(int)));
m_timer->start(1000); if (waiter.exec() == ConnectionWaiter::TimedOut) {
connect(USBMonitor::instance(), SIGNAL(deviceDiscovered(USBPortInfo)), &m_eventloop, SLOT(quit())); emit autoUpdateSignal(FAILURE, QVariant(tr("Timed out while waiting for a board to be connected!")));
m_eventloop.exec();
if (!m_timer->isActive()) {
m_timer->stop();
emit autoUpdateSignal(FAILURE, QVariant());
return false; return false;
} }
m_timer->stop();
dfu = new DFUObject(DFU_DEBUG, false, QString()); dfu = new DFUObject(DFU_DEBUG, false, QString());
dfu->AbortOperation(); dfu->AbortOperation();
emit autoUpdateSignal(JUMP_TO_BL, QVariant()); emit autoUpdateSignal(JUMP_TO_BL, QVariant());
@ -581,6 +647,7 @@ bool UploaderGadgetWidget::autoUpdate()
emit autoUpdateSignal(FAILURE, QVariant()); emit autoUpdateSignal(FAILURE, QVariant());
return false; return false;
} }
QString filename; QString filename;
emit autoUpdateSignal(LOADING_FW, QVariant()); emit autoUpdateSignal(LOADING_FW, QVariant());
switch (dfu->devices[0].ID) { switch (dfu->devices[0].ID) {
@ -617,9 +684,10 @@ bool UploaderGadgetWidget::autoUpdate()
emit autoUpdateSignal(FAILURE, QVariant()); emit autoUpdateSignal(FAILURE, QVariant());
return false; return false;
} }
QEventLoop eventLoop;
firmware = file.readAll(); firmware = file.readAll();
connect(dfu, SIGNAL(progressUpdated(int)), this, SLOT(autoUpdateProgress(int))); connect(dfu, SIGNAL(progressUpdated(int)), this, SLOT(autoUpdateFlashProgress(int)));
connect(dfu, SIGNAL(uploadFinished(OP_DFU::Status)), &m_eventloop, SLOT(quit())); connect(dfu, SIGNAL(uploadFinished(OP_DFU::Status)), &eventLoop, SLOT(quit()));
emit autoUpdateSignal(UPLOADING_FW, QVariant()); emit autoUpdateSignal(UPLOADING_FW, QVariant());
if (!dfu->enterDFU(0)) { if (!dfu->enterDFU(0)) {
emit autoUpdateSignal(FAILURE, QVariant()); emit autoUpdateSignal(FAILURE, QVariant());
@ -630,7 +698,7 @@ bool UploaderGadgetWidget::autoUpdate()
emit autoUpdateSignal(FAILURE, QVariant()); emit autoUpdateSignal(FAILURE, QVariant());
return false; return false;
} }
m_eventloop.exec(); eventLoop.exec();
QByteArray desc = firmware.right(100); QByteArray desc = firmware.right(100);
emit autoUpdateSignal(UPLOADING_DESC, QVariant()); emit autoUpdateSignal(UPLOADING_DESC, QVariant());
if (dfu->UploadDescription(desc) != OP_DFU::Last_operation_Success) { if (dfu->UploadDescription(desc) != OP_DFU::Last_operation_Success) {
@ -642,7 +710,17 @@ bool UploaderGadgetWidget::autoUpdate()
return true; return true;
} }
void UploaderGadgetWidget::autoUpdateProgress(int value) void UploaderGadgetWidget::autoUpdateDisconnectProgress(int value)
{
emit autoUpdateSignal(WAITING_DISCONNECT, value);
}
void UploaderGadgetWidget::autoUpdateConnectProgress(int value)
{
emit autoUpdateSignal(WAITING_CONNECT, value);
}
void UploaderGadgetWidget::autoUpdateFlashProgress(int value)
{ {
emit autoUpdateSignal(UPLOADING_FW, value); emit autoUpdateSignal(UPLOADING_FW, value);
} }
@ -658,62 +736,62 @@ void UploaderGadgetWidget::systemRescue()
cm->disconnectDevice(); cm->disconnectDevice();
// stop the polling thread: otherwise it will mess up DFU // stop the polling thread: otherwise it will mess up DFU
cm->suspendPolling(); cm->suspendPolling();
// Delete all previous tabs: // Delete all previous tabs:
while (m_config->systemElements->count()) { while (m_config->systemElements->count()) {
QWidget *qw = m_config->systemElements->widget(0); QWidget *qw = m_config->systemElements->widget(0);
m_config->systemElements->removeTab(0); m_config->systemElements->removeTab(0);
delete qw; delete qw;
} }
// Existing DFU objects will have a handle over USB and will // Existing DFU objects will have a handle over USB and will
// disturb everything for the rescue process: // disturb everything for the rescue process:
if (dfu) { if (dfu) {
delete dfu; delete dfu;
dfu = NULL; dfu = NULL;
} }
// Avoid users pressing Rescue twice. // Avoid users pressing Rescue twice.
m_config->rescueButton->setEnabled(false); m_config->rescueButton->setEnabled(false);
// Now we're good to go: // Now we're good to go
clearLog(); clearLog();
log("**********************************************************"); log("**********************************************************");
log("** Follow those instructions to attempt a system rescue **"); log("** Follow those instructions to attempt a system rescue **");
log("**********************************************************"); log("**********************************************************");
log("You will be prompted to first connect USB, then system power"); log("You will be prompted to first connect USB, then system power");
// Check if boards are connected and, if yes, prompt user to disconnect them all
if (USBMonitor::instance()->availableDevices(0x20a0, -1, -1, -1).length() > 0) { if (USBMonitor::instance()->availableDevices(0x20a0, -1, -1, -1).length() > 0) {
if (QMessageBox::warning(this, tr("OpenPilot Uploader"), tr("Please disconnect your OpenPilot board"), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Cancel) { QString labelText = QString("<p align=\"left\">%1</p>").arg(tr("Please disconnect your OpenPilot board."));
int result = ConnectionWaiter::openDialog(tr("System Rescue"), labelText, 0, BOARD_EVENT_TIMEOUT, this);
switch (result) {
case ConnectionWaiter::Canceled:
m_config->rescueButton->setEnabled(true);
return;
case ConnectionWaiter::TimedOut:
QMessageBox::warning(this, tr("System Rescue"), tr("Timed out while waiting for all boards to be disconnected!"));
m_config->rescueButton->setEnabled(true); m_config->rescueButton->setEnabled(true);
return; return;
} }
} }
// Now we're good to go:
clearLog(); // Now prompt user to connect board
log("**********************************************************"); QString labelText = QString("<p align=\"left\">%1<br>%2</p>").arg(tr("Please connect your OpenPilot board.")).arg(tr("Board must be connected to the USB port!"));
log("** Follow those instructions to attempt a system rescue **"); int result = ConnectionWaiter::openDialog(tr("System Rescue"), labelText, 1, BOARD_EVENT_TIMEOUT, this);
log("**********************************************************"); switch (result) {
log("You will be prompted to first connect USB, then system power"); case ConnectionWaiter::Canceled:
m_progress = new QProgressDialog(tr("Please connect your OpenPilot board (USB only!)"), tr("Cancel"), 0, 20); m_config->rescueButton->setEnabled(true);
QProgressBar *bar = new QProgressBar(m_progress); return;
bar->setFormat("Timeout");
m_progress->setBar(bar); case ConnectionWaiter::TimedOut:
m_progress->setMinimumDuration(0); QMessageBox::warning(this, tr("System Rescue"), tr("Timed out while waiting for a board to be connected!"));
m_progress->setRange(0, 20);
connect(m_progress, SIGNAL(canceled()), this, SLOT(cancel()));
m_timer = new QTimer(this);
connect(m_timer, SIGNAL(timeout()), this, SLOT(perform()));
m_timer->start(1000);
connect(USBMonitor::instance(), SIGNAL(deviceDiscovered(USBPortInfo)), &m_eventloop, SLOT(quit()));
m_eventloop.exec();
if (!m_timer->isActive()) {
m_progress->close();
m_timer->stop();
QMessageBox::warning(this, tr("OpenPilot Uploader"), tr("No board connection was detected!"));
m_config->rescueButton->setEnabled(true); m_config->rescueButton->setEnabled(true);
return; return;
} }
m_progress->close();
m_timer->stop(); log("Detecting first board...");
log("... Detecting First Board...");
repaint();
dfu = new DFUObject(DFU_DEBUG, false, QString()); dfu = new DFUObject(DFU_DEBUG, false, QString());
dfu->AbortOperation(); dfu->AbortOperation();
if (!dfu->enterDFU(0)) { if (!dfu->enterDFU(0)) {
@ -732,7 +810,8 @@ void UploaderGadgetWidget::systemRescue()
m_config->rescueButton->setEnabled(true); m_config->rescueButton->setEnabled(true);
return; return;
} }
log(QString("Found ") + QString::number(dfu->numberOfDevices) + QString(" device(s).")); log(QString("Found %1 device(s).").arg(dfu->numberOfDevices));
if (dfu->numberOfDevices > 5) { if (dfu->numberOfDevices > 5) {
log("Inconsistent number of devices, aborting!"); log("Inconsistent number of devices, aborting!");
delete dfu; delete dfu;
@ -747,36 +826,15 @@ void UploaderGadgetWidget::systemRescue()
dw->setDeviceID(i); dw->setDeviceID(i);
dw->setDfu(dfu); dw->setDfu(dfu);
dw->populate(); dw->populate();
m_config->systemElements->addTab(dw, QString("Device") + QString::number(i)); m_config->systemElements->addTab(dw, tr("Device") + QString::number(i));
} }
m_config->haltButton->setEnabled(false); m_config->haltButton->setEnabled(false);
m_config->resetButton->setEnabled(false); m_config->resetButton->setEnabled(false);
bootButtonsSetEnable(true); bootButtonsSetEnable(true);
m_config->rescueButton->setEnabled(false); m_config->rescueButton->setEnabled(false);
currentStep = IAP_STATE_BOOTLOADER; // So that we can boot from the GUI afterwards.
}
void UploaderGadgetWidget::perform() // So that we can boot from the GUI afterwards.
{ currentStep = IAP_STATE_BOOTLOADER;
if (m_progress->value() == 19) {
m_timer->stop();
m_eventloop.exit();
}
m_progress->setValue(m_progress->value() + 1);
}
void UploaderGadgetWidget::performAuto()
{
++autoUpdateConnectTimeout;
emit autoUpdateSignal(WAITING_CONNECT, autoUpdateConnectTimeout * 5);
if (autoUpdateConnectTimeout == 20) {
m_timer->stop();
m_eventloop.exit();
}
}
void UploaderGadgetWidget::cancel()
{
m_timer->stop();
m_eventloop.exit();
} }
void UploaderGadgetWidget::uploadStarted() void UploaderGadgetWidget::uploadStarted()
@ -823,6 +881,7 @@ void UploaderGadgetWidget::startAutoUpdate()
m_config->splitter->setEnabled(false); m_config->splitter->setEnabled(false);
m_config->autoUpdateGroupBox->setVisible(true); m_config->autoUpdateGroupBox->setVisible(true);
m_config->autoUpdateOkButton->setEnabled(false); m_config->autoUpdateOkButton->setEnabled(false);
connect(this, SIGNAL(autoUpdateSignal(uploader::AutoUpdateStep, QVariant)), this, SLOT(autoUpdateStatus(uploader::AutoUpdateStep, QVariant))); connect(this, SIGNAL(autoUpdateSignal(uploader::AutoUpdateStep, QVariant)), this, SLOT(autoUpdateStatus(uploader::AutoUpdateStep, QVariant)));
autoUpdate(); autoUpdate();
} }
@ -831,14 +890,13 @@ void UploaderGadgetWidget::finishAutoUpdate()
{ {
disconnect(this, SIGNAL(autoUpdateSignal(uploader::AutoUpdateStep, QVariant)), this, SLOT(autoUpdateStatus(uploader::AutoUpdateStep, QVariant))); disconnect(this, SIGNAL(autoUpdateSignal(uploader::AutoUpdateStep, QVariant)), this, SLOT(autoUpdateStatus(uploader::AutoUpdateStep, QVariant)));
m_config->autoUpdateOkButton->setEnabled(true); m_config->autoUpdateOkButton->setEnabled(true);
connect(&autoUpdateCloseTimer, SIGNAL(timeout()), this, SLOT(closeAutoUpdate()));
autoUpdateCloseTimer.start(AUTOUPDATE_CLOSE_TIMEOUT); // wait a bit and "close" auto update
QTimer::singleShot(AUTOUPDATE_CLOSE_TIMEOUT, this, SLOT(closeAutoUpdate()));
} }
void UploaderGadgetWidget::closeAutoUpdate() void UploaderGadgetWidget::closeAutoUpdate()
{ {
autoUpdateCloseTimer.stop();
disconnect(&autoUpdateCloseTimer, SIGNAL(timeout()), this, SLOT(closeAutoUpdate()));
m_config->autoUpdateGroupBox->setVisible(false); m_config->autoUpdateGroupBox->setVisible(false);
m_config->buttonFrame->setEnabled(true); m_config->buttonFrame->setEnabled(true);
m_config->splitter->setEnabled(true); m_config->splitter->setEnabled(true);
@ -846,37 +904,57 @@ void UploaderGadgetWidget::closeAutoUpdate()
void UploaderGadgetWidget::autoUpdateStatus(uploader::AutoUpdateStep status, QVariant value) void UploaderGadgetWidget::autoUpdateStatus(uploader::AutoUpdateStep status, QVariant value)
{ {
QString msg;
int remaining;
switch (status) { switch (status) {
case uploader::WAITING_DISCONNECT: case uploader::WAITING_DISCONNECT:
m_config->autoUpdateLabel->setText("Waiting for all OpenPilot boards to be disconnected from USB."); m_config->autoUpdateLabel->setText(tr("Waiting for all OpenPilot boards to be disconnected from USB."));
m_config->autoUpdateProgressBar->setMaximum(BOARD_EVENT_TIMEOUT / 1000);
m_config->autoUpdateProgressBar->setValue(value.toInt());
remaining = m_config->autoUpdateProgressBar->maximum() - m_config->autoUpdateProgressBar->value();
m_config->autoUpdateProgressBar->setFormat(tr("Timing out in %1 seconds").arg(remaining));
break; break;
case uploader::WAITING_CONNECT: case uploader::WAITING_CONNECT:
m_config->autoUpdateLabel->setText("Please connect the OpenPilot board to the USB port."); m_config->autoUpdateLabel->setText(tr("Please connect the OpenPilot board to the USB port."));
m_config->autoUpdateProgressBar->setMaximum(BOARD_EVENT_TIMEOUT / 1000);
m_config->autoUpdateProgressBar->setValue(value.toInt()); m_config->autoUpdateProgressBar->setValue(value.toInt());
remaining = m_config->autoUpdateProgressBar->maximum() - m_config->autoUpdateProgressBar->value();
m_config->autoUpdateProgressBar->setFormat(tr("Timing out in %1 seconds").arg(remaining));
break; break;
case uploader::JUMP_TO_BL: case uploader::JUMP_TO_BL:
m_config->autoUpdateProgressBar->setValue(0); m_config->autoUpdateProgressBar->setValue(0);
m_config->autoUpdateLabel->setText("Bringing the board into boot loader mode."); m_config->autoUpdateLabel->setText(tr("Bringing the board into boot loader mode."));
break; break;
case uploader::LOADING_FW: case uploader::LOADING_FW:
m_config->autoUpdateLabel->setText("Preparing to upload firmware to the board."); m_config->autoUpdateLabel->setText(tr("Preparing to upload firmware to the board."));
break; break;
case uploader::UPLOADING_FW: case uploader::UPLOADING_FW:
m_config->autoUpdateLabel->setText("Uploading firmware to the board."); m_config->autoUpdateLabel->setText(tr("Uploading firmware to the board."));
m_config->autoUpdateProgressBar->setFormat("%p%");
m_config->autoUpdateProgressBar->setMaximum(100);
m_config->autoUpdateProgressBar->setValue(value.toInt()); m_config->autoUpdateProgressBar->setValue(value.toInt());
break; break;
case uploader::UPLOADING_DESC: case uploader::UPLOADING_DESC:
m_config->autoUpdateLabel->setText("Uploading description of the new firmware to the board."); m_config->autoUpdateLabel->setText(tr("Uploading description of the new firmware to the board."));
break; break;
case uploader::BOOTING: case uploader::BOOTING:
m_config->autoUpdateLabel->setText("Rebooting the board."); m_config->autoUpdateLabel->setText(tr("Rebooting the board."));
break; break;
case uploader::SUCCESS: case uploader::SUCCESS:
m_config->autoUpdateLabel->setText("<font color='green'>Board was updated successfully, press OK to finish.</font>"); m_config->autoUpdateProgressBar->setValue(m_config->autoUpdateProgressBar->maximum());
msg = tr("Board was updated successfully.");
msg += " " + tr("Press OK to finish.");
m_config->autoUpdateLabel->setText(QString("<font color='green'>%1</font>").arg(msg));
finishAutoUpdate(); finishAutoUpdate();
break; break;
case uploader::FAILURE: case uploader::FAILURE:
m_config->autoUpdateLabel->setText("<font color='red'>Something went wrong, you will have to manually upgrade the board. Press OK to continue.</font>"); msg = value.toString();
if (msg.isEmpty()) {
msg = tr("Something went wrong, you will have to manually upgrade the board.");
}
msg += " " + tr("Press OK to finish.");
m_config->autoUpdateLabel->setText(QString("<font color='red'>%1</font>").arg(msg));
finishAutoUpdate(); finishAutoUpdate();
break; break;
} }
@ -887,9 +965,8 @@ void UploaderGadgetWidget::autoUpdateStatus(uploader::AutoUpdateStep status, QVa
*/ */
void UploaderGadgetWidget::log(QString str) void UploaderGadgetWidget::log(QString str)
{ {
qDebug() << str; qDebug() << "UploaderGadgetWidget -" << str;
m_config->textBrowser->append(str); m_config->textBrowser->append(str);
m_config->textBrowser->repaint();
} }
void UploaderGadgetWidget::clearLog() void UploaderGadgetWidget::clearLog()
@ -908,92 +985,45 @@ UploaderGadgetWidget::~UploaderGadgetWidget()
delete qw; delete qw;
qw = 0; qw = 0;
} }
if (m_progress) {
delete m_progress;
m_progress = 0;
}
if (m_timer) {
delete m_timer;
m_timer = 0;
}
}
/**
Shows a message box with an error string.
@param errorString The error string to display.
@param errorNumber Not used
*/
void UploaderGadgetWidget::error(QString errorString, int errorNumber)
{
Q_UNUSED(errorNumber);
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText(errorString);
msgBox.exec();
m_config->boardStatus->setText(errorString);
}
/**
Shows a message box with an information string.
@param infoString The information string to display.
@param infoNumber Not used
*/
void UploaderGadgetWidget::info(QString infoString, int infoNumber)
{
Q_UNUSED(infoNumber);
m_config->boardStatus->setText(infoString);
}
void UploaderGadgetWidget::versionMatchCheck()
{
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
deviceDescriptorStruct boardDescription = utilMngr->getBoardDescriptionStruct();
QByteArray uavoHashArray;
QString uavoHash = VersionInfo::uavoHashArray();
uavoHash.chop(2);
uavoHash.remove(0, 2);
uavoHash = uavoHash.trimmed();
bool ok;
foreach(QString str, uavoHash.split(",")) {
uavoHashArray.append(str.toInt(&ok, 16));
}
QByteArray fwVersion = boardDescription.uavoHash;
if (fwVersion != uavoHashArray) {
QString gcsDescription = VersionInfo::revision();
QString gcsGitHash = gcsDescription.mid(gcsDescription.indexOf(":") + 1, 8);
gcsGitHash.remove(QRegExp("^[0]*"));
QString gcsGitDate = gcsDescription.mid(gcsDescription.indexOf(" ") + 1, 14);
QString gcsUavoHashStr;
QString fwUavoHashStr;
foreach(char i, fwVersion) {
fwUavoHashStr.append(QString::number(i, 16).right(2));
}
foreach(char i, uavoHashArray) {
gcsUavoHashStr.append(QString::number(i, 16).right(2));
}
QString gcsVersion = gcsGitDate + " (" + gcsGitHash + "-" + gcsUavoHashStr.left(8) + ")";
QString fwVersion = boardDescription.gitDate + " (" + boardDescription.gitHash + "-" + fwUavoHashStr.left(8) + ")";
QString warning = QString(tr(
"GCS and firmware versions of the UAV objects set do not match which can cause configuration problems. "
"GCS version: %1 Firmware version: %2.")).arg(gcsVersion).arg(fwVersion);
msg->showMessage(warning);
}
} }
void UploaderGadgetWidget::openHelp() void UploaderGadgetWidget::openHelp()
{ {
QDesktopServices::openUrl(QUrl("http://wiki.openpilot.org/x/AoBZ", QUrl::StrictMode)); QDesktopServices::openUrl(QUrl("http://wiki.openpilot.org/x/AoBZ", QUrl::StrictMode));
} }
int UploaderGadgetWidget::confirmEraseSettingsMessageBox()
{
QMessageBox msgBox(this);
msgBox.setWindowTitle(tr("Confirm Settings Erase?"));
msgBox.setIcon(QMessageBox::Question);
msgBox.setText(tr("Do you want to erase all settings from the board?"));
msgBox.setInformativeText(tr("Settings cannot be recovered after this operation.\nThe board will be restarted and all settings erased."));
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel | QMessageBox::Help);
return msgBox.exec();
}
int UploaderGadgetWidget::cannotHaltMessageBox()
{
QMessageBox msgBox(this);
msgBox.setWindowTitle(tr("Cannot Halt Board!"));
msgBox.setIcon(QMessageBox::Warning);
msgBox.setText(tr("The controller board is armed and can not be halted."));
msgBox.setInformativeText(tr("Please make sure the board is not armed and then press Halt again to proceed or use Rescue to force a firmware upgrade."));
msgBox.setStandardButtons(QMessageBox::Ok);
return msgBox.exec();
}
int UploaderGadgetWidget::cannotResetMessageBox()
{
QMessageBox msgBox(this);
msgBox.setWindowTitle(tr("Cannot Reset Board!"));
msgBox.setIcon(QMessageBox::Warning);
msgBox.setText(tr("The controller board is armed and can not be reset."));
msgBox.setInformativeText(tr("Please make sure the board is not armed and then press reset again to proceed or power cycle to force a board reset."));
msgBox.setStandardButtons(QMessageBox::Ok);
return msgBox.exec();
}

View File

@ -29,79 +29,111 @@
#define UPLOADERGADGETWIDGET_H #define UPLOADERGADGETWIDGET_H
#include "ui_uploader.h" #include "ui_uploader.h"
#include "delay.h"
#include "devicewidget.h"
#include "runningdevicewidget.h"
#include "op_dfu.h"
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "coreplugin/icore.h"
#include "coreplugin/connectionmanager.h"
#include "ophid/inc/ophid_plugin.h"
#include <QWidget>
#include <QLabel>
#include <QLineEdit>
#include <QThread>
#include <QMessageBox>
#include <QTimer>
#include "devicedescriptorstruct.h"
#include <QProgressDialog>
#include <QErrorMessage>
#include <QDesktopServices>
#include "uploader_global.h" #include "uploader_global.h"
#include "enums.h" #include "enums.h"
#include "op_dfu.h"
#include <QProgressDialog>
using namespace OP_DFU; using namespace OP_DFU;
using namespace uploader; using namespace uploader;
class FlightStatus; class FlightStatus;
class UAVObject;
class TimedDialog : public QProgressDialog {
Q_OBJECT
public:
TimedDialog(const QString &title, const QString &labelText, int timeout, QWidget *parent = 0, Qt::WindowFlags flags = 0);
private slots:
void perform();
private:
QProgressBar *bar;
};
// A helper class to wait for board connection and disconnection events
// until a the desired number of connected boards is found
// or until a timeout is reached
class ConnectionWaiter : public QObject {
Q_OBJECT
public:
ConnectionWaiter(int targetDeviceCount, int timeout, QWidget *parent = 0);
enum ResultCode { Ok, Canceled, TimedOut };
public slots:
int exec();
void cancel();
void quit();
static int openDialog(const QString &title, const QString &labelText, int targetDeviceCount, int timeout, QWidget *parent = 0, Qt::WindowFlags flags = 0);
signals:
void timeChanged(int elapsed);
private slots:
void perform();
void deviceEvent();
private:
QEventLoop eventLoop;
QTimer timer;
// timeout in ms
int timeout;
// elapsed time in seconds
int elapsed;
int targetDeviceCount;
int result;
};
class UPLOADER_EXPORT UploaderGadgetWidget : public QWidget { class UPLOADER_EXPORT UploaderGadgetWidget : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
UploaderGadgetWidget(QWidget *parent = 0); UploaderGadgetWidget(QWidget *parent = 0);
~UploaderGadgetWidget(); ~UploaderGadgetWidget();
static const int BOARD_EVENT_TIMEOUT;
static const int AUTOUPDATE_CLOSE_TIMEOUT;
void log(QString str); void log(QString str);
bool autoUpdateCapable(); bool autoUpdateCapable();
public slots: public slots:
void onAutopilotConnect(); void onAutopilotConnect();
void onAutopilotDisconnect(); void onAutopilotDisconnect();
void populate(); void populate();
void openHelp(); void openHelp();
bool autoUpdate(); bool autoUpdate();
void autoUpdateProgress(int); void autoUpdateDisconnectProgress(int);
void autoUpdateConnectProgress(int);
void autoUpdateFlashProgress(int);
signals: signals:
void autoUpdateSignal(uploader::AutoUpdateStep, QVariant); void autoUpdateSignal(uploader::AutoUpdateStep, QVariant);
private: private:
Ui_UploaderWidget *m_config; Ui_UploaderWidget *m_config;
DFUObject *dfu; DFUObject *dfu;
IAPStep currentStep; IAPStep currentStep;
bool resetOnly; bool resetOnly;
void clearLog(); void clearLog();
QString getPortDevice(const QString &friendName); QString getPortDevice(const QString &friendName);
QProgressDialog *m_progress;
QTimer *m_timer;
QLineEdit *openFileNameLE;
QEventLoop m_eventloop;
QErrorMessage *msg;
void connectSignalSlot(QWidget *widget); void connectSignalSlot(QWidget *widget);
int autoUpdateConnectTimeout;
FlightStatus *getFlightStatus(); FlightStatus *getFlightStatus();
void bootButtonsSetEnable(bool enabled); void bootButtonsSetEnable(bool enabled);
static const int AUTOUPDATE_CLOSE_TIMEOUT; int confirmEraseSettingsMessageBox();
QTimer autoUpdateCloseTimer; int cannotHaltMessageBox();
int cannotResetMessageBox();
private slots: private slots:
void onPhisicalHWConnect(); void onPhysicalHWConnect();
void versionMatchCheck();
void error(QString errorString, int errorNumber);
void info(QString infoString, int infoNumber);
void goToBootloader(UAVObject * = NULL, bool = false); void goToBootloader(UAVObject * = NULL, bool = false);
void systemHalt(); void systemHalt();
void systemReset(); void systemReset();
@ -111,9 +143,6 @@ private slots:
void commonSystemBoot(bool safeboot = false, bool erase = false); void commonSystemBoot(bool safeboot = false, bool erase = false);
void systemRescue(); void systemRescue();
void getSerialPorts(); void getSerialPorts();
void perform();
void performAuto();
void cancel();
void uploadStarted(); void uploadStarted();
void uploadEnded(bool succeed); void uploadEnded(bool succeed);
void downloadStarted(); void downloadStarted();

View File

@ -26,10 +26,11 @@
*/ */
#include "uploaderplugin.h" #include "uploaderplugin.h"
#include "uploadergadgetfactory.h" #include "uploadergadgetfactory.h"
#include <QtPlugin>
#include <QStringList>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <QStringList>
UploaderPlugin::UploaderPlugin() UploaderPlugin::UploaderPlugin()
{ {
// Do nothing // Do nothing
@ -44,8 +45,10 @@ bool UploaderPlugin::initialize(const QStringList & args, QString *errMsg)
{ {
Q_UNUSED(args); Q_UNUSED(args);
Q_UNUSED(errMsg); Q_UNUSED(errMsg);
mf = new UploaderGadgetFactory(this); mf = new UploaderGadgetFactory(this);
addAutoReleasedObject(mf); addAutoReleasedObject(mf);
return true; return true;
} }

View File

@ -44,6 +44,7 @@ public:
void extensionsInitialized(); void extensionsInitialized();
bool initialize(const QStringList & arguments, QString *errorString); bool initialize(const QStringList & arguments, QString *errorString);
void shutdown(); void shutdown();
private: private:
UploaderGadgetFactory *mf; UploaderGadgetFactory *mf;
}; };