diff --git a/.gitignore b/.gitignore index 6c4d8b39f..03797f84f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +# Exclude temporary and system files +.DS_Store # /flight/ /flight/*.pnproj diff --git a/HISTORY.txt b/HISTORY.txt index 626a41593..aba9effab 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -1,5 +1,9 @@ Short summary of changes. For a complete list see the git log. +2011-12-10 +Merged a change that sorts the UAVO fields based on size. Because this changes +all of the objects, erase all existing flash files based on this. + 2011-11-04 New Spektrum/JR satellite receiver driver implementation. It now provides explicit selection of DSM2 (and DSMJ), DSMX (10bit) and diff --git a/MILESTONES.txt b/MILESTONES.txt index b146d09b7..14242d2f2 100644 --- a/MILESTONES.txt +++ b/MILESTONES.txt @@ -157,6 +157,11 @@ C: Anders Johansson (dezent) D: November 2011 V: http://www.youtube.com/watch?v=Xfas2TUhOPw +M: First OpenPilot over 1km FixedWing navigation flight +C: Eric Price (Corvus Corax) +D: December 2011 +V: http://www.youtube.com/watch?v=nWNWuUiUTNg + M: First Altitude Hold using Sonar C: @@ -184,8 +189,6 @@ An incomplete list of some future Milestones is below: * First fixed wing navigation flight * First Multirotor navigation flight * First Helicopter navigation flight -* First over 1km navigation flight * First over 5km navigation flight * First "Follow Me" navigation flight * First Channel Crossing with OpenPilot - diff --git a/flight/CopterControl/System/coptercontrol.c b/flight/CopterControl/System/coptercontrol.c index 7d4ca0627..a7cd909d9 100644 --- a/flight/CopterControl/System/coptercontrol.c +++ b/flight/CopterControl/System/coptercontrol.c @@ -70,6 +70,12 @@ int main() * */ PIOS_Board_Init(); +#ifdef ERASE_FLASH + PIOS_Flash_W25X_EraseChip(); + PIOS_LED_Off(LED1); + while (1) ; +#endif + /* Initialize modules */ MODULE_INITIALISE_ALL @@ -82,11 +88,11 @@ int main() /* If all is well we will never reach here as the scheduler will now be running. */ /* Do some indication to user that something bad just happened */ - PIOS_LED_Off(LED1); \ - for(;;) { \ - PIOS_LED_Toggle(LED1); \ - PIOS_DELAY_WaitmS(100); \ - }; + PIOS_LED_Off(LED1); + while (1) { + PIOS_LED_Toggle(LED1); + PIOS_DELAY_WaitmS(100); + } return 0; } diff --git a/flight/CopterControl/System/pios_board.c b/flight/CopterControl/System/pios_board.c index f895d8e2b..e80d4e51a 100644 --- a/flight/CopterControl/System/pios_board.c +++ b/flight/CopterControl/System/pios_board.c @@ -1430,7 +1430,9 @@ void PIOS_Board_Init(void) { #endif /* PIOS_INCLUDE_USB_HID */ PIOS_IAP_Init(); +#ifndef ERASE_FLASH PIOS_WDG_Init(); +#endif } /** diff --git a/flight/Modules/Actuator/actuator.c b/flight/Modules/Actuator/actuator.c index 4f2e9fdb7..1995355e3 100644 --- a/flight/Modules/Actuator/actuator.c +++ b/flight/Modules/Actuator/actuator.c @@ -207,7 +207,7 @@ static void actuatorTask(void* parameters) nMixers ++; } } - if((nMixers < 2) && !ActuatorCommandReadOnly(dummy)) //Nothing can fly with less than two mixers. + if((nMixers < 2) && !ActuatorCommandReadOnly()) //Nothing can fly with less than two mixers. { setFailsafe(); // So that channels like PWM buzzer keep working continue; diff --git a/flight/Modules/ManualControl/manualcontrol.c b/flight/Modules/ManualControl/manualcontrol.c index 6e4150861..d4c2ff0fb 100644 --- a/flight/Modules/ManualControl/manualcontrol.c +++ b/flight/Modules/ManualControl/manualcontrol.c @@ -189,19 +189,19 @@ static void manualControlTask(void *parameters) lastActivityTime = lastSysTime; } - if (ManualControlCommandReadOnly(&cmd)) { + if (ManualControlCommandReadOnly()) { FlightTelemetryStatsData flightTelemStats; FlightTelemetryStatsGet(&flightTelemStats); if(flightTelemStats.Status != FLIGHTTELEMETRYSTATS_STATUS_CONNECTED) { /* trying to fly via GCS and lost connection. fall back to transmitter */ UAVObjMetadata metadata; - UAVObjGetMetadata(&cmd, &metadata); + ManualControlCommandGetMetadata(&metadata); metadata.access = ACCESS_READWRITE; - UAVObjSetMetadata(&cmd, &metadata); + ManualControlCommandSetMetadata(&metadata); } } - if (!ManualControlCommandReadOnly(&cmd)) { + if (!ManualControlCommandReadOnly()) { bool valid_input_detected = true; diff --git a/flight/PiOS/Common/pios_flashfs_objlist.c b/flight/PiOS/Common/pios_flashfs_objlist.c index 23c39905e..cdcabdafe 100644 --- a/flight/PiOS/Common/pios_flashfs_objlist.c +++ b/flight/PiOS/Common/pios_flashfs_objlist.c @@ -56,8 +56,8 @@ struct fileHeader { } __attribute__((packed)); -#define OBJECT_TABLE_MAGIC 0x85FB3C33 -#define OBJ_MAGIC 0x3015AE71 +#define OBJECT_TABLE_MAGIC 0x85FB3D35 +#define OBJ_MAGIC 0x3015A371 #define OBJECT_TABLE_START 0x00000010 #define OBJECT_TABLE_END 0x00010000 #define SECTOR_SIZE 0x00010000 diff --git a/flight/UAVObjects/inc/uavobjecttemplate.h b/flight/UAVObjects/inc/uavobjecttemplate.h index 9564d05d2..f106dd8ba 100644 --- a/flight/UAVObjects/inc/uavobjecttemplate.h +++ b/flight/UAVObjects/inc/uavobjecttemplate.h @@ -67,7 +67,7 @@ #define $(NAME)InstUpdated(instId) UAVObjUpdated($(NAME)Handle(), instId) #define $(NAME)GetMetadata(dataOut) UAVObjGetMetadata($(NAME)Handle(), dataOut) #define $(NAME)SetMetadata(dataIn) UAVObjSetMetadata($(NAME)Handle(), dataIn) -#define $(NAME)ReadOnly(dataIn) UAVObjReadOnly($(NAME)Handle()) +#define $(NAME)ReadOnly() UAVObjReadOnly($(NAME)Handle()) // Object data typedef struct { diff --git a/ground/openpilotgcs/src/plugins/config/configoutputwidget.cpp b/ground/openpilotgcs/src/plugins/config/configoutputwidget.cpp index 53553ac2e..0aa4ee809 100644 --- a/ground/openpilotgcs/src/plugins/config/configoutputwidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/configoutputwidget.cpp @@ -81,10 +81,10 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren // Connect the help button connect(m_config->outputHelp, SIGNAL(clicked()), this, SLOT(openHelp())); - addWidget(m_config->outputRate3); - addWidget(m_config->outputRate2); - addWidget(m_config->outputRate1); - + addWidget(m_config->cb_outputRate4); + addWidget(m_config->cb_outputRate3); + addWidget(m_config->cb_outputRate2); + addWidget(m_config->cb_outputRate1); addWidget(m_config->spinningArmed); UAVObjectManager *objManager = pm->getObject(); @@ -277,8 +277,17 @@ void ConfigOutputWidget::refreshWidgetsValues() m_config->spinningArmed->setChecked(actuatorSettingsData.MotorsSpinWhileArmed == ActuatorSettings::MOTORSSPINWHILEARMED_TRUE); // Get Output rates for both banks - m_config->outputRate1->setValue(actuatorSettingsData.ChannelUpdateFreq[0]); - m_config->outputRate2->setValue(actuatorSettingsData.ChannelUpdateFreq[1]); + if(m_config->cb_outputRate1->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[0]))==-1) + { + m_config->cb_outputRate1->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[0])); + } + if(m_config->cb_outputRate2->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[1]))==-1) + { + m_config->cb_outputRate2->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[1])); + } + m_config->cb_outputRate1->setCurrentIndex(m_config->cb_outputRate1->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[0]))); + m_config->cb_outputRate2->setCurrentIndex(m_config->cb_outputRate2->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[1]))); + UAVObjectUtilManager* utilMngr = pm->getObject(); if (utilMngr) { int board = utilMngr->getBoardModel(); @@ -288,24 +297,34 @@ void ConfigOutputWidget::refreshWidgetsValues() m_config->chBank2->setText("4"); m_config->chBank3->setText("5,7-8"); m_config->chBank4->setText("6,9-10"); - m_config->outputRate1->setEnabled(true); - m_config->outputRate2->setEnabled(true); - m_config->outputRate3->setEnabled(true); - m_config->outputRate4->setEnabled(true); - m_config->outputRate3->setValue(actuatorSettingsData.ChannelUpdateFreq[2]); - m_config->outputRate4->setValue(actuatorSettingsData.ChannelUpdateFreq[3]); + m_config->cb_outputRate1->setEnabled(true); + m_config->cb_outputRate2->setEnabled(true); + m_config->cb_outputRate3->setEnabled(true); + m_config->cb_outputRate4->setEnabled(true); + if(m_config->cb_outputRate3->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[2]))==-1) + { + m_config->cb_outputRate3->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[2])); + } + if(m_config->cb_outputRate4->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[3]))==-1) + { + m_config->cb_outputRate4->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[3])); + } + m_config->cb_outputRate3->setCurrentIndex(m_config->cb_outputRate3->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[2]))); + m_config->cb_outputRate4->setCurrentIndex(m_config->cb_outputRate4->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[3]))); } else if ((board & 0xff00) == 256 ) { // Mainboard family - m_config->outputRate1->setEnabled(true); - m_config->outputRate2->setEnabled(true); - m_config->outputRate3->setEnabled(false); - m_config->outputRate4->setEnabled(false); + m_config->cb_outputRate1->setEnabled(true); + m_config->cb_outputRate2->setEnabled(true); + m_config->cb_outputRate3->setEnabled(false); + m_config->cb_outputRate4->setEnabled(false); m_config->chBank1->setText("1-4"); m_config->chBank2->setText("5-8"); m_config->chBank3->setText("-"); m_config->chBank4->setText("-"); - m_config->outputRate3->setValue(0); - m_config->outputRate4->setValue(0); + m_config->cb_outputRate3->addItem("0"); + m_config->cb_outputRate3->setCurrentIndex(m_config->cb_outputRate3->findText("0")); + m_config->cb_outputRate4->addItem("0"); + m_config->cb_outputRate4->setCurrentIndex(m_config->cb_outputRate4->findText("0")); } } @@ -342,11 +361,10 @@ void ConfigOutputWidget::updateObjectsFromWidgets() } // Set update rates - actuatorSettingsData.ChannelUpdateFreq[0] = m_config->outputRate1->value(); - actuatorSettingsData.ChannelUpdateFreq[1] = m_config->outputRate2->value(); - actuatorSettingsData.ChannelUpdateFreq[2] = m_config->outputRate3->value(); - actuatorSettingsData.ChannelUpdateFreq[3] = m_config->outputRate4->value(); - + actuatorSettingsData.ChannelUpdateFreq[0] = m_config->cb_outputRate1->currentText().toUInt(); + actuatorSettingsData.ChannelUpdateFreq[1] = m_config->cb_outputRate2->currentText().toUInt(); + actuatorSettingsData.ChannelUpdateFreq[2] = m_config->cb_outputRate3->currentText().toUInt(); + actuatorSettingsData.ChannelUpdateFreq[3] = m_config->cb_outputRate4->currentText().toUInt(); // Apply settings actuatorSettings->setData(actuatorSettingsData); } diff --git a/ground/openpilotgcs/src/plugins/config/inputchannelform.cpp b/ground/openpilotgcs/src/plugins/config/inputchannelform.cpp index 1eca667a8..98f71ea31 100644 --- a/ground/openpilotgcs/src/plugins/config/inputchannelform.cpp +++ b/ground/openpilotgcs/src/plugins/config/inputchannelform.cpp @@ -94,6 +94,7 @@ void inputChannelForm::groupUpdated() break; case ManualControlSettings::CHANNELGROUPS_GCS: count = 5; + break; case ManualControlSettings::CHANNELGROUPS_NONE: count = 0; break; diff --git a/ground/openpilotgcs/src/plugins/config/output.ui b/ground/openpilotgcs/src/plugins/config/output.ui index 47940e1ae..de87ef7eb 100644 --- a/ground/openpilotgcs/src/plugins/config/output.ui +++ b/ground/openpilotgcs/src/plugins/config/output.ui @@ -38,102 +38,6 @@ 2 - - - - false - - - Setup "TurboPWM" here: usual value is 400 Hz for multirotor airframes. -Leave at 50Hz for fixed wing. - - - 400 - - - - - - - - - - - Qt::AlignCenter - - - - - - - - - - - Qt::AlignCenter - - - - - - - - - - - Qt::AlignCenter - - - - - - - false - - - Setup "TurboPWM" here: usual value is 400 Hz for multirotor airframes. -Leave at 50Hz for fixed wing. - - - 400 - - - - - - - false - - - Setup "TurboPWM" here: usual value is 400 Hz for multirotor airframes. -Leave at 50Hz for fixed wing. - - - 400 - - - - - - - false - - - Setup "TurboPWM" here: usual value is 400 Hz for multirotor airframes. -Leave at 50Hz for fixed wing. - - - 400 - - - - - - - - - - - Qt::AlignCenter - - - @@ -206,6 +110,230 @@ Leave at 50Hz for fixed wing. + + + + false + + + Setup "TurboPWM" here: usual value is 400 Hz for multirotor airframes. +Leave at 50Hz for fixed wing. + + + + 50 + + + + + 60 + + + + + 125 + + + + + 165 + + + + + 270 + + + + + 330 + + + + + 400 + + + + + + + + false + + + Setup "TurboPWM" here: usual value is 400 Hz for multirotor airframes. +Leave at 50Hz for fixed wing. + + + + 50 + + + + + 60 + + + + + 125 + + + + + 165 + + + + + 270 + + + + + 330 + + + + + 400 + + + + + + + + false + + + Setup "TurboPWM" here: usual value is 400 Hz for multirotor airframes. +Leave at 50Hz for fixed wing. + + + + 50 + + + + + 60 + + + + + 125 + + + + + 165 + + + + + 270 + + + + + 330 + + + + + 400 + + + + + + + + false + + + Setup "TurboPWM" here: usual value is 400 Hz for multirotor airframes. +Leave at 50Hz for fixed wing. + + + + 50 + + + + + 60 + + + + + 125 + + + + + 165 + + + + + 270 + + + + + 330 + + + + + 400 + + + + + + + + - + + + Qt::AlignCenter + + + + + + + - + + + Qt::AlignCenter + + + + + + + - + + + Qt::AlignCenter + + + + + + + - + + + Qt::AlignCenter + + + @@ -351,10 +479,6 @@ Applies and Saves all settings to SD - outputRate1 - outputRate2 - outputRate3 - outputRate4 channelOutTest saveRCOutputToRAM saveRCOutputToSD diff --git a/ground/openpilotgcs/src/plugins/config/outputchannelform.h b/ground/openpilotgcs/src/plugins/config/outputchannelform.h index e0cae75d2..7d492dc1a 100644 --- a/ground/openpilotgcs/src/plugins/config/outputchannelform.h +++ b/ground/openpilotgcs/src/plugins/config/outputchannelform.h @@ -30,7 +30,7 @@ #include #include "ui_outputchannelform.h" -class ConfigInputWidget; +class ConfigOnputWidget; class OutputChannelForm : public QWidget { @@ -39,7 +39,7 @@ class OutputChannelForm : public QWidget public: explicit OutputChannelForm(const int index, QWidget *parent = NULL, const bool showLegend = false); ~OutputChannelForm(); - friend class ConfigInputWidget; + friend class ConfigOnputWidget; void setAssignment(const QString &assignment); int index() const; diff --git a/ground/openpilotgcs/src/plugins/config/outputchannelform.ui b/ground/openpilotgcs/src/plugins/config/outputchannelform.ui index 49924e06e..cb1fd73f2 100644 --- a/ground/openpilotgcs/src/plugins/config/outputchannelform.ui +++ b/ground/openpilotgcs/src/plugins/config/outputchannelform.ui @@ -6,8 +6,8 @@ 0 0 - 562 - 49 + 605 + 56 @@ -136,6 +136,18 @@ + + + 0 + 0 + + + + + 40 + 0 + + Check to invert the channel. @@ -143,6 +155,18 @@ + + + 0 + 0 + + + + + 40 + 0 + + Output mode @@ -213,11 +237,17 @@ - + 0 0 + + + 25 + 0 + + Rev. @@ -226,11 +256,17 @@ - + 0 0 + + + 25 + 0 + + Link diff --git a/ground/openpilotgcs/src/plugins/gcscontrol/gcscontrol.ui b/ground/openpilotgcs/src/plugins/gcscontrol/gcscontrol.ui index fdcac0346..f48029e47 100644 --- a/ground/openpilotgcs/src/plugins/gcscontrol/gcscontrol.ui +++ b/ground/openpilotgcs/src/plugins/gcscontrol/gcscontrol.ui @@ -1,134 +1,140 @@ - - - GCSControl - - - - 0 - 0 - 653 - 295 - - - - - 0 - 0 - - - - Form - - - - 2 - - - 5 - - - - - - - - - GCS Control - - - - - - - Armed - - - - - - - Flight Mode: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - - 10 - - - 0 - - - - - - 0 - 0 - - - - - 100 - 100 - - - - false - - - - - - - - 0 - 0 - - - - - 100 - 100 - - - - - - - - Qt::Vertical - - - - 2 - 40 - - - - - - - - - - - JoystickControl - QWidget -
joystickcontrol.h
- 1 -
-
- - -
+ + + GCSControl + + + + 0 + 0 + 653 + 295 + + + + + 0 + 0 + + + + Form + + + background:transparent + + + + 2 + + + 5 + + + + + + + + + GCS Control + + + + + + + Armed + + + + + + + Flight Mode: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + 10 + + + 0 + + + + + + 0 + 0 + + + + + 100 + 100 + + + + false + + + background:transparent + + + + + + + Qt::Vertical + + + + 2 + 40 + + + + + + + + + 0 + 0 + + + + + 100 + 100 + + + + + + + + + + + JoystickControl + QWidget +
joystickcontrol.h
+ 1 +
+
+ + +
diff --git a/ground/openpilotgcs/src/plugins/gcscontrol/images/joystick.svg b/ground/openpilotgcs/src/plugins/gcscontrol/images/joystick.svg index 729a48476..386881587 100644 --- a/ground/openpilotgcs/src/plugins/gcscontrol/images/joystick.svg +++ b/ground/openpilotgcs/src/plugins/gcscontrol/images/joystick.svg @@ -1,5 +1,5 @@ - + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - + xlink:href="data:image/png;base64,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" + transform="translate(1,1)" + id="image41" + style="opacity:0.75"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 50 % + + 75 % + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 75 % + + 50 % + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ground/openpilotgcs/src/plugins/logging/logfile.cpp b/ground/openpilotgcs/src/plugins/logging/logfile.cpp index f02bce22a..7a74d6367 100644 --- a/ground/openpilotgcs/src/plugins/logging/logfile.cpp +++ b/ground/openpilotgcs/src/plugins/logging/logfile.cpp @@ -88,9 +88,12 @@ void LogFile::timerFired() if(file.bytesAvailable() > 4) { - // TODO: going back in time will be a problem - while ((myTime.elapsed() - timeOffset) * playbackSpeed > lastTimeStamp) { + int time; + time = myTime.elapsed(); + // TODO: going back in time will be a problem + while ((lastPlayed + ((time - timeOffset)* playbackSpeed) > lastTimeStamp)) { + lastPlayed += ((time - timeOffset)* playbackSpeed); if(file.bytesAvailable() < 4) { stopReplay(); return; @@ -98,6 +101,11 @@ void LogFile::timerFired() file.read((char *) &dataSize, sizeof(dataSize)); + if (dataSize<1 || dataSize>(1024*1024)) { + qDebug() << "Error: Logfile corrupted! Unlikely packet size: " << dataSize << "\n"; + stopReplay(); + return; + } if(file.bytesAvailable() < dataSize) { stopReplay(); return; @@ -113,7 +121,19 @@ void LogFile::timerFired() return; } + int save=lastTimeStamp; file.read((char *) &lastTimeStamp,sizeof(lastTimeStamp)); + // some validity checks + if (lastTimeStamp (60*60*1000)) { // gap of more than 60 minutes) + qDebug() << "Error: Logfile corrupted! Unlikely timestamp " << lastTimeStamp << " after "<< save << "\n"; + stopReplay(); + return; + } + + timeOffset = time; + time = myTime.elapsed(); + } } else { stopReplay(); @@ -125,6 +145,7 @@ bool LogFile::startReplay() { dataBuffer.clear(); myTime.restart(); timeOffset = 0; + lastPlayed = 0; playbackSpeed = 1; file.read((char *) &lastTimeStamp,sizeof(lastTimeStamp)); timer.setInterval(10); @@ -142,12 +163,11 @@ bool LogFile::stopReplay() { void LogFile::pauseReplay() { timer.stop(); - pausedTime = myTime.elapsed(); } void LogFile::resumeReplay() { - timeOffset += myTime.elapsed() - pausedTime; + timeOffset = myTime.elapsed(); timer.start(); } diff --git a/ground/openpilotgcs/src/plugins/logging/logfile.h b/ground/openpilotgcs/src/plugins/logging/logfile.h index 861249e4a..a07e1832a 100644 --- a/ground/openpilotgcs/src/plugins/logging/logfile.h +++ b/ground/openpilotgcs/src/plugins/logging/logfile.h @@ -27,7 +27,7 @@ public: bool stopReplay(); public slots: - void setReplaySpeed(double val) { playbackSpeed = pow(10,(val)/100); qDebug() << playbackSpeed; }; + void setReplaySpeed(double val) { playbackSpeed = val; qDebug() << playbackSpeed; }; void pauseReplay(); void resumeReplay(); @@ -45,11 +45,11 @@ protected: QTime myTime; QFile file; qint32 lastTimeStamp; + qint32 lastPlayed; QMutex mutex; int timeOffset; - int pausedTime; double playbackSpeed; }; diff --git a/ground/openpilotgcs/src/plugins/rawhid/rawhid.pro b/ground/openpilotgcs/src/plugins/rawhid/rawhid.pro index 4a3557982..f857ef72a 100644 --- a/ground/openpilotgcs/src/plugins/rawhid/rawhid.pro +++ b/ground/openpilotgcs/src/plugins/rawhid/rawhid.pro @@ -7,9 +7,11 @@ HEADERS += rawhid_global.h \ rawhid.h \ pjrc_rawhid.h \ rawhid_const.h \ - usbmonitor.h + usbmonitor.h \ + usbsignalfilter.h SOURCES += rawhidplugin.cpp \ - rawhid.cpp + rawhid.cpp \ + usbsignalfilter.cpp FORMS += RESOURCES += DEFINES += RAWHID_LIBRARY diff --git a/ground/openpilotgcs/src/plugins/rawhid/rawhidplugin.h b/ground/openpilotgcs/src/plugins/rawhid/rawhidplugin.h index 0bbeac524..ee9aa49aa 100644 --- a/ground/openpilotgcs/src/plugins/rawhid/rawhidplugin.h +++ b/ground/openpilotgcs/src/plugins/rawhid/rawhidplugin.h @@ -31,7 +31,7 @@ #include "rawhid_global.h" #include "rawhid.h" #include "usbmonitor.h" - +#include "usbsignalfilter.h" #include "coreplugin/iconnection.h" #include diff --git a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor.h b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor.h index 1d8eea087..fd114042f 100644 --- a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor.h +++ b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor.h @@ -202,5 +202,4 @@ private: #endif }; - #endif // USBMONITOR_H diff --git a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_win.cpp b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_win.cpp index c2ab1fa9c..aa653179a 100644 --- a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_win.cpp +++ b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_win.cpp @@ -78,6 +78,15 @@ USBMonitor::~USBMonitor() QList USBMonitor::availableDevices(int vid, int pid, int bcdDeviceMSB, int bcdDeviceLSB) { QList allPorts = availableDevices(); + qDebug()<<"USBMonitor::availableDevices list off all ports:"; + qDebug()<<"USBMonitor::availableDevices total ports:"< thePortsWeWant; qDebug()<<"USBMonitor::availableDevices bcdLSB="< USBMonitor::availableDevices(int vid, int pid, int bcdDeviceM ( (port.bcdDevice&0x00ff) ==bcdDeviceLSB || bcdDeviceLSB==-1)) thePortsWeWant.append(port); } + qDebug()<<"USBMonitor::availableDevices list off matching ports vid pid bcdMSD bcdLSD:"< +void USBSignalFilter::m_deviceDiscovered(USBPortInfo port) +{ + if((port.vendorID==m_vid || m_vid==-1) && (port.productID==m_pid || m_pid==-1) && ((port.bcdDevice>>8)==m_boardModel || m_boardModel==-1) && + ( (port.bcdDevice&0x00ff) ==m_runState || m_runState==-1)) + { + qDebug()<<"USBSignalFilter emit device discovered"; + emit deviceDiscovered(); + } +} + +USBSignalFilter::USBSignalFilter(int vid, int pid, int boardModel, int runState): + m_vid(vid), + m_pid(pid), + m_boardModel(boardModel), + m_runState(runState) +{ + connect(USBMonitor::instance(),SIGNAL(deviceDiscovered(USBPortInfo)),this,SLOT(m_deviceDiscovered(USBPortInfo))); +} + + diff --git a/ground/openpilotgcs/src/plugins/rawhid/usbsignalfilter.h b/ground/openpilotgcs/src/plugins/rawhid/usbsignalfilter.h new file mode 100644 index 000000000..6a9310d46 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/rawhid/usbsignalfilter.h @@ -0,0 +1,21 @@ +#ifndef USBSIGNALFILTER_H +#define USBSIGNALFILTER_H +#include +#include "usbmonitor.h" + +class RAWHID_EXPORT USBSignalFilter : public QObject +{ + Q_OBJECT +private: + int m_vid; + int m_pid; + int m_boardModel; + int m_runState; +signals: + void deviceDiscovered(); +private slots: + void m_deviceDiscovered(USBPortInfo port); +public: + USBSignalFilter(int vid, int pid, int boardModel, int runState); +}; +#endif // USBSIGNALFILTER_H diff --git a/ground/openpilotgcs/src/plugins/scope/plotdata.cpp b/ground/openpilotgcs/src/plugins/scope/plotdata.cpp index f2d4bb5af..e05bf7a1b 100644 --- a/ground/openpilotgcs/src/plugins/scope/plotdata.cpp +++ b/ground/openpilotgcs/src/plugins/scope/plotdata.cpp @@ -49,9 +49,14 @@ PlotData::PlotData(QString p_uavObject, QString p_uavField) xData = new QVector(); yData = new QVector(); + yDataHistory = new QVector(); curve = 0; scalePower = 0; + interpolationSamples = 1; + interpolationSum = 0.0f; + correctionSum = 0.0f; + correctionCount = 0; yMinimum = 0; yMaximum = 0; @@ -78,6 +83,7 @@ PlotData::~PlotData() { delete xData; delete yData; + delete yDataHistory; } @@ -91,7 +97,24 @@ bool SequencialPlotData::append(UAVObject* obj) if (field) { //Shift data forward and put the new value at the front - yData->append( valueAsDouble(obj, field) * pow(10, scalePower)); + + // calculate interpolated (smoothed) value + double currentValue = valueAsDouble(obj, field) * pow(10, scalePower); + yDataHistory->append( currentValue ); + interpolationSum += currentValue; + if(yDataHistory->size() > interpolationSamples) { + interpolationSum -= yDataHistory->first(); + yDataHistory->pop_front(); + } + // make sure to correct the sum every interpolationSamples steps to prevent it + // from running away due to flouting point rounding errors + correctionSum += currentValue; + if (++correctionCount >= interpolationSamples) { + interpolationSum = correctionSum; + correctionSum = 0.0f; + correctionCount = 0; + } + yData->append(interpolationSum/yDataHistory->size()); if (yData->size() > m_xWindowSize) { yData->pop_front(); } else @@ -117,8 +140,25 @@ bool ChronoPlotData::append(UAVObject* obj) //Put the new value at the front QDateTime NOW = QDateTime::currentDateTime(); + // calculate interpolated (smoothed) value + double currentValue = valueAsDouble(obj, field) * pow(10, scalePower); + yDataHistory->append( currentValue ); + interpolationSum += currentValue; + if(yDataHistory->size() > interpolationSamples) { + interpolationSum -= yDataHistory->first(); + yDataHistory->pop_front(); + } + // make sure to correct the sum every interpolationSamples steps to prevent it + // from running away due to flouting point rounding errors + correctionSum += currentValue; + if (++correctionCount >= interpolationSamples) { + interpolationSum = correctionSum; + correctionSum = 0.0f; + correctionCount = 0; + } + double valueX = NOW.toTime_t() + NOW.time().msec() / 1000.0; - double valueY = valueAsDouble(obj, field) * pow(10, scalePower); + double valueY = interpolationSum/yDataHistory->size(); xData->append(valueX); yData->append(valueY); diff --git a/ground/openpilotgcs/src/plugins/scope/plotdata.h b/ground/openpilotgcs/src/plugins/scope/plotdata.h index 2d61f12c6..a547f2b91 100644 --- a/ground/openpilotgcs/src/plugins/scope/plotdata.h +++ b/ground/openpilotgcs/src/plugins/scope/plotdata.h @@ -72,12 +72,17 @@ public: QString uavSubField; bool haveSubField; int scalePower; //This is the power to which each value must be raised + int interpolationSamples; + double interpolationSum; + double correctionSum; + int correctionCount; double yMinimum; double yMaximum; double m_xWindowSize; QwtPlotCurve* curve; QVector* xData; QVector* yData; + QVector* yDataHistory; virtual bool append(UAVObject* obj) = 0; virtual PlotType plotType() = 0; diff --git a/ground/openpilotgcs/src/plugins/scope/scopegadget.cpp b/ground/openpilotgcs/src/plugins/scope/scopegadget.cpp index ccf4a8b82..b4b1f24fa 100644 --- a/ground/openpilotgcs/src/plugins/scope/scopegadget.cpp +++ b/ground/openpilotgcs/src/plugins/scope/scopegadget.cpp @@ -61,12 +61,14 @@ void ScopeGadget::loadConfiguration(IUAVGadgetConfiguration* config) QString uavObject = plotCurveConfig->uavObject; QString uavField = plotCurveConfig->uavField; int scale = plotCurveConfig->yScalePower; + int interpolation = plotCurveConfig->yInterpolationSamples; QRgb color = plotCurveConfig->color; widget->addCurvePlot( uavObject, uavField, scale, + interpolation, QPen( QBrush(QColor(color),Qt::SolidPattern), // (qreal)2, (qreal)1, diff --git a/ground/openpilotgcs/src/plugins/scope/scopegadgetconfiguration.cpp b/ground/openpilotgcs/src/plugins/scope/scopegadgetconfiguration.cpp index 63a48e495..6337be38f 100644 --- a/ground/openpilotgcs/src/plugins/scope/scopegadgetconfiguration.cpp +++ b/ground/openpilotgcs/src/plugins/scope/scopegadgetconfiguration.cpp @@ -65,6 +65,7 @@ ScopeGadgetConfiguration::ScopeGadgetConfiguration(QString classId, QSettings* q color = qSettings->value("color").value(); plotCurveConf->color = color; plotCurveConf->yScalePower = qSettings->value("yScalePower").toInt(); + plotCurveConf->yInterpolationSamples = qSettings->value("yInterpolationSamples").toInt(); plotCurveConf->yMinimum = qSettings->value("yMinimum").toDouble(); plotCurveConf->yMaximum = qSettings->value("yMaximum").toDouble(); @@ -118,6 +119,7 @@ IUAVGadgetConfiguration *ScopeGadgetConfiguration::clone() newPlotCurveConf->uavField = currentPlotCurveConf->uavField; newPlotCurveConf->color = currentPlotCurveConf->color; newPlotCurveConf->yScalePower = currentPlotCurveConf->yScalePower; + newPlotCurveConf->yInterpolationSamples = currentPlotCurveConf->yInterpolationSamples; newPlotCurveConf->yMinimum = currentPlotCurveConf->yMinimum; newPlotCurveConf->yMaximum = currentPlotCurveConf->yMaximum; @@ -157,6 +159,7 @@ void ScopeGadgetConfiguration::saveConfig(QSettings* qSettings) const { qSettings->setValue("uavField", plotCurveConf->uavField); qSettings->setValue("color", plotCurveConf->color); qSettings->setValue("yScalePower", plotCurveConf->yScalePower); + qSettings->setValue("yInterpolationSamples", plotCurveConf->yInterpolationSamples); qSettings->setValue("yMinimum", plotCurveConf->yMinimum); qSettings->setValue("yMaximum", plotCurveConf->yMaximum); diff --git a/ground/openpilotgcs/src/plugins/scope/scopegadgetconfiguration.h b/ground/openpilotgcs/src/plugins/scope/scopegadgetconfiguration.h index 1aadcaf5b..570ebe1f9 100644 --- a/ground/openpilotgcs/src/plugins/scope/scopegadgetconfiguration.h +++ b/ground/openpilotgcs/src/plugins/scope/scopegadgetconfiguration.h @@ -41,6 +41,7 @@ struct PlotCurveConfiguration QString uavField; int yScalePower; //This is the power to which each value must be raised QRgb color; + int yInterpolationSamples; double yMinimum; double yMaximum; }; diff --git a/ground/openpilotgcs/src/plugins/scope/scopegadgetoptionspage.cpp b/ground/openpilotgcs/src/plugins/scope/scopegadgetoptionspage.cpp index e44ccb08f..d0d364b68 100644 --- a/ground/openpilotgcs/src/plugins/scope/scopegadgetoptionspage.cpp +++ b/ground/openpilotgcs/src/plugins/scope/scopegadgetoptionspage.cpp @@ -101,9 +101,10 @@ QWidget* ScopeGadgetOptionsPage::createPage(QWidget *parent) QString uavObject = plotData->uavObject; QString uavField = plotData->uavField; int scale = plotData->yScalePower; + int interpolation = plotData->yInterpolationSamples; QVariant varColor = plotData->color; - addPlotCurveConfig(uavObject,uavField,scale,varColor); + addPlotCurveConfig(uavObject,uavField,scale,interpolation,varColor); } if(m_config->plotCurveConfigs().count() > 0) @@ -163,6 +164,10 @@ void ScopeGadgetOptionsPage::setYAxisWidgetFromPlotCurve() int rgb = varColor.toInt(&parseOK); setButtonColor(QColor((QRgb)rgb)); + + int interpolation = listItem->data(Qt::UserRole + 4).toInt(&parseOK); + if(!parseOK) interpolation = 1; + options_page->spnInterpolationSamples->setValue(interpolation); } void ScopeGadgetOptionsPage::setButtonColor(const QColor &color) @@ -235,6 +240,10 @@ void ScopeGadgetOptionsPage::apply() newPlotCurveConfigs->color = QColor(Qt::black).rgb(); else newPlotCurveConfigs->color = (QRgb)rgb; + + newPlotCurveConfigs->yInterpolationSamples = listItem->data(Qt::UserRole + 4).toInt(&parseOK); + if(!parseOK) + newPlotCurveConfigs->yInterpolationSamples = 1; plotCurveConfigs.append(newPlotCurveConfigs); } @@ -261,6 +270,7 @@ void ScopeGadgetOptionsPage::on_btnAddCurve_clicked() if(!parseOK) scale = 0; + int interpolation = options_page->spnInterpolationSamples->value(); QVariant varColor = (int)QColor(options_page->btnColor->text()).rgb(); @@ -270,27 +280,27 @@ void ScopeGadgetOptionsPage::on_btnAddCurve_clicked() options_page->lstCurves->currentItem()->text() == uavObject + "." + uavField) { QListWidgetItem *listWidgetItem = options_page->lstCurves->currentItem(); - setCurvePlotProperties(listWidgetItem,uavObject,uavField,scale,varColor); + setCurvePlotProperties(listWidgetItem,uavObject,uavField,scale,interpolation,varColor); }else { - addPlotCurveConfig(uavObject,uavField,scale,varColor); + addPlotCurveConfig(uavObject,uavField,scale,interpolation,varColor); options_page->lstCurves->setCurrentRow(options_page->lstCurves->count() - 1); } } -void ScopeGadgetOptionsPage::addPlotCurveConfig(QString uavObject, QString uavField, int scale, QVariant varColor) +void ScopeGadgetOptionsPage::addPlotCurveConfig(QString uavObject, QString uavField, int scale, int interpolation, QVariant varColor) { //Add a new curve config to the list QString listItemDisplayText = uavObject + "." + uavField; options_page->lstCurves->addItem(listItemDisplayText); QListWidgetItem *listWidgetItem = options_page->lstCurves->item(options_page->lstCurves->count() - 1); - setCurvePlotProperties(listWidgetItem,uavObject,uavField,scale,varColor); + setCurvePlotProperties(listWidgetItem,uavObject,uavField,scale,interpolation,varColor); } -void ScopeGadgetOptionsPage::setCurvePlotProperties(QListWidgetItem *listWidgetItem,QString uavObject, QString uavField, int scale, QVariant varColor) +void ScopeGadgetOptionsPage::setCurvePlotProperties(QListWidgetItem *listWidgetItem,QString uavObject, QString uavField, int scale, int interpolation, QVariant varColor) { bool parseOK = false; @@ -306,6 +316,7 @@ void ScopeGadgetOptionsPage::setCurvePlotProperties(QListWidgetItem *listWidgetI listWidgetItem->setData(Qt::UserRole + 1,QVariant(uavField)); listWidgetItem->setData(Qt::UserRole + 2,QVariant(scale)); listWidgetItem->setData(Qt::UserRole + 3,varColor); + listWidgetItem->setData(Qt::UserRole + 4,QVariant(interpolation)); } /*! diff --git a/ground/openpilotgcs/src/plugins/scope/scopegadgetoptionspage.h b/ground/openpilotgcs/src/plugins/scope/scopegadgetoptionspage.h index cbbf9201b..39c0b3ea5 100644 --- a/ground/openpilotgcs/src/plugins/scope/scopegadgetoptionspage.h +++ b/ground/openpilotgcs/src/plugins/scope/scopegadgetoptionspage.h @@ -66,8 +66,8 @@ private: Ui::ScopeGadgetOptionsPage *options_page; ScopeGadgetConfiguration *m_config; - void addPlotCurveConfig(QString uavObject, QString uavField, int scale, QVariant varColor); - void setCurvePlotProperties(QListWidgetItem *listWidgetItem, QString uavObject, QString uavField, int scale, QVariant varColor); + void addPlotCurveConfig(QString uavObject, QString uavField, int scale, int interpolation, QVariant varColor); + void setCurvePlotProperties(QListWidgetItem *listWidgetItem, QString uavObject, QString uavField, int scale, int interpolation, QVariant varColor); void setYAxisWidgetFromPlotCurve(); void setButtonColor(const QColor &color); diff --git a/ground/openpilotgcs/src/plugins/scope/scopegadgetoptionspage.ui b/ground/openpilotgcs/src/plugins/scope/scopegadgetoptionspage.ui index 2aaee1942..b3d22faa0 100644 --- a/ground/openpilotgcs/src/plugins/scope/scopegadgetoptionspage.ui +++ b/ground/openpilotgcs/src/plugins/scope/scopegadgetoptionspage.ui @@ -159,6 +159,32 @@
+ + + + Display smoothed interpolation: + + + + + + + samples + + + 1 + + + 1001 + + + 10 + + + 1 + + + @@ -268,7 +294,7 @@ Update - Log data to csv file + Log data to csv file (not interpolated) diff --git a/ground/openpilotgcs/src/plugins/scope/scopegadgetwidget.cpp b/ground/openpilotgcs/src/plugins/scope/scopegadgetwidget.cpp index dfbd9d614..12f6974b8 100644 --- a/ground/openpilotgcs/src/plugins/scope/scopegadgetwidget.cpp +++ b/ground/openpilotgcs/src/plugins/scope/scopegadgetwidget.cpp @@ -356,7 +356,7 @@ void ScopeGadgetWidget::setupChronoPlot() // scaleWidget->setMinBorderDist(0, fmw); } -void ScopeGadgetWidget::addCurvePlot(QString uavObject, QString uavFieldSubField, int scaleOrderFactor, QPen pen) +void ScopeGadgetWidget::addCurvePlot(QString uavObject, QString uavFieldSubField, int scaleOrderFactor, int interpolationSamples, QPen pen) { PlotData* plotData; @@ -369,6 +369,7 @@ void ScopeGadgetWidget::addCurvePlot(QString uavObject, QString uavFieldSubField plotData->m_xWindowSize = m_xWindowSize; plotData->scalePower = scaleOrderFactor; + plotData->interpolationSamples = interpolationSamples; //If the y-bounds are supplied, set them if (plotData->yMinimum != plotData->yMaximum) @@ -446,6 +447,7 @@ void ScopeGadgetWidget::uavObjectReceived(UAVObject* obj) foreach(PlotData* plotData, m_curvesData.values()) { if (plotData->append(obj)) m_csvLoggingDataUpdated=1; } + csvLoggingAddData(); } void ScopeGadgetWidget::replotNewData() @@ -609,6 +611,7 @@ int ScopeGadgetWidget::csvLoggingStart() m_csvLoggingStartTime = NOW; m_csvLoggingHeaderSaved=0; m_csvLoggingDataSaved=0; + m_csvLoggingBuffer.clear(); QDir PathCheck(m_csvLoggingPath); if (!PathCheck.exists()) { @@ -676,13 +679,50 @@ int ScopeGadgetWidget::csvLoggingInsertHeader() return 0; } +int ScopeGadgetWidget::csvLoggingAddData() +{ + if (!m_csvLoggingStarted) return -1; + m_csvLoggingDataValid=0; + QDateTime NOW = QDateTime::currentDateTime(); + QString tempString; + + QTextStream ss( &tempString ); + ss << NOW.toString("yyyy-MM-dd") << ", " << NOW.toString("hh:mm:ss.z") << ", " ; + +#if QT_VERSION >= 0x040700 + ss <<(NOW.toMSecsSinceEpoch() - m_csvLoggingStartTime.toMSecsSinceEpoch())/1000.00; +#else + ss <<(NOW.toTime_t() - m_csvLoggingStartTime.toTime_t()); +#endif + ss << ", " << m_csvLoggingConnected << ", " << m_csvLoggingDataUpdated; + m_csvLoggingDataUpdated=0; + + foreach(PlotData* plotData2, m_curvesData.values()) + { + ss << ", "; + if (plotData2->xData->isEmpty ()) + { + } + else + { + ss << QString().sprintf("%3.6g",plotData2->yDataHistory->last()/pow(10,plotData2->scalePower)); + m_csvLoggingDataValid=1; + } + } + ss << endl; + if (m_csvLoggingDataValid) + { + QTextStream ts( &m_csvLoggingBuffer ); + ts << tempString; + } + + return 0; +} + int ScopeGadgetWidget::csvLoggingInsertData() { if (!m_csvLoggingStarted) return -1; m_csvLoggingDataSaved=1; - m_csvLoggingDataValid=0; - QDateTime NOW = QDateTime::currentDateTime(); - QString tempString; if(m_csvLoggingFile.open(QIODevice::WriteOnly | QIODevice::Append)== FALSE) { @@ -690,38 +730,11 @@ int ScopeGadgetWidget::csvLoggingInsertData() } else { - QTextStream ss( &tempString ); - ss << NOW.toString("yyyy-MM-dd") << ", " << NOW.toString("hh:mm:ss.z") << ", " ; - -#if QT_VERSION >= 0x040700 - ss <<(NOW.toMSecsSinceEpoch() - m_csvLoggingStartTime.toMSecsSinceEpoch())/1000.00; -#else - ss <<(NOW.toTime_t() - m_csvLoggingStartTime.toTime_t()); -#endif - ss << ", " << m_csvLoggingConnected << ", " << m_csvLoggingDataUpdated; - m_csvLoggingDataUpdated=0; - - foreach(PlotData* plotData2, m_curvesData.values()) - { - ss << ", "; - if (plotData2->xData->isEmpty ()) - { - } - else - { - ss << QString().sprintf("%3.6g",plotData2->yData->last()/pow(10,plotData2->scalePower)); - m_csvLoggingDataValid=1; - } - } - ss << endl; - if (m_csvLoggingDataValid) - { - QTextStream ts( &m_csvLoggingFile ); - ts << tempString; - } + QTextStream ts( &m_csvLoggingFile ); + ts << m_csvLoggingBuffer; m_csvLoggingFile.close(); } - + m_csvLoggingBuffer.clear(); return 0; } diff --git a/ground/openpilotgcs/src/plugins/scope/scopegadgetwidget.h b/ground/openpilotgcs/src/plugins/scope/scopegadgetwidget.h index fd8aaf550..98da3beb6 100644 --- a/ground/openpilotgcs/src/plugins/scope/scopegadgetwidget.h +++ b/ground/openpilotgcs/src/plugins/scope/scopegadgetwidget.h @@ -110,7 +110,7 @@ public: int refreshInterval(){return m_refreshInterval;} - void addCurvePlot(QString uavObject, QString uavFieldSubField, int scaleOrderFactor = 0, QPen pen = QPen(Qt::black)); + void addCurvePlot(QString uavObject, QString uavFieldSubField, int scaleOrderFactor = 0, int interpolationSamples = 1, QPen pen = QPen(Qt::black)); //void removeCurvePlot(QString uavObject, QString uavField); void clearCurvePlots(); int csvLoggingStart(); @@ -166,11 +166,13 @@ private: QString m_csvLoggingName; QString m_csvLoggingPath; + QString m_csvLoggingBuffer; QFile m_csvLoggingFile; QMutex mutex; int csvLoggingInsertHeader(); + int csvLoggingAddData(); int csvLoggingInsertData(); void deleteLegend(); diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp b/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp index 8841429fa..da71fd943 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp @@ -492,6 +492,45 @@ QVariant UAVObjectField::getValue(quint32 index) return QVariant(); } +bool UAVObjectField::checkValue(const QVariant& value, quint32 index) +{ + QMutexLocker locker(obj->getMutex()); + // Check that index is not out of bounds + if ( index >= numElements ) + { + return false; + } + // Get metadata + UAVObject::Metadata mdata = obj->getMetadata(); + // Update value if the access mode permits + if ( mdata.gcsAccess == UAVObject::ACCESS_READWRITE ) + { + switch (type) + { + case INT8: + case INT16: + case INT32: + case UINT8: + case UINT16: + case UINT32: + case FLOAT32: + case STRING: + return true; + break; + case ENUM: + { + qint8 tmpenum = options.indexOf( value.toString() ); + return ((tmpenum < 0) ? false : true); + break; + } + default: + qDebug() << "checkValue: other types" << type; + Q_ASSERT(0); // To catch any programming errors where we tried to test invalid values + break; + } + } +} + void UAVObjectField::setValue(const QVariant& value, quint32 index) { QMutexLocker locker(obj->getMutex()); diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.h b/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.h index 9ae9d0d72..3cefc25e6 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.h +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.h @@ -56,6 +56,7 @@ public: qint32 pack(quint8* dataOut); qint32 unpack(const quint8* dataIn); QVariant getValue(quint32 index = 0); + bool checkValue(const QVariant& data, quint32 index = 0); void setValue(const QVariant& data, quint32 index = 0); double getDouble(quint32 index = 0); void setDouble(double value, quint32 index = 0); diff --git a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp index 285bc7cbf..b082e1eb5 100644 --- a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp +++ b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp @@ -153,6 +153,7 @@ void UAVSettingsImportExportFactory::importUAVSettings() // - Update each field // - Issue and "updated" command bool error=false; + bool setError=false; QDomNode field = node.firstChild(); while(!field.isNull()) { QDomElement f = field.toElement(); @@ -161,16 +162,24 @@ void UAVSettingsImportExportFactory::importUAVSettings() if (uavfield) { QStringList list = f.attribute("values").split(","); if (list.length() == 1) { - uavfield->setValue(f.attribute("values")); + if (false == uavfield->checkValue(f.attribute("values"))) { + qDebug() << "checkValue returned false on: " << uavObjectName << f.attribute("values"); + setError = true; + } else + uavfield->setValue(f.attribute("values")); } else { // This is an enum: int i=0; QStringList list = f.attribute("values").split(","); foreach (QString element, list) { - uavfield->setValue(element,i++); + if (false == uavfield->checkValue(element,i)) { + qDebug() << "checkValue(list) returned false on: " << uavObjectName << list; + setError = true; + } else + uavfield->setValue(element,i); + i++; } } - error = false; } else { error = true; } @@ -183,7 +192,9 @@ void UAVSettingsImportExportFactory::importUAVSettings() } else if (uavObjectID != obj->getObjID()) { qDebug() << "Mismatch for Object " << uavObjectName << uavObjectID << " - " << obj->getObjID(); swui.addLine(uavObjectName, "Warning (ObjectID mismatch)", true); - } else + } else if (setError) { + swui.addLine(uavObjectName, "Warning (Objects field value(s) invalid)", false); + } else swui.addLine(uavObjectName, "OK", true); } } diff --git a/ground/openpilotgcs/src/plugins/uploader/op_dfu.cpp b/ground/openpilotgcs/src/plugins/uploader/op_dfu.cpp index 549201989..961103d22 100644 --- a/ground/openpilotgcs/src/plugins/uploader/op_dfu.cpp +++ b/ground/openpilotgcs/src/plugins/uploader/op_dfu.cpp @@ -80,30 +80,41 @@ DFUObject::DFUObject(bool _debug,bool _use_serial,QString portname): } else { + mready = false; QEventLoop m_eventloop; QTimer::singleShot(200,&m_eventloop, SLOT(quit())); m_eventloop.exec(); QList devices; devices = USBMonitor::instance()->availableDevices(0x20a0,-1,-1,USBMonitor::Bootloader); - if (devices.length()==1) { - hidHandle.open(1,devices.first().vendorID,devices.first().productID,0,0); + if (devices.length()==1 && hidHandle.open(1,devices.first().vendorID,devices.first().productID,0,0)==1) { qDebug()<<"OP_DFU detected first time"; + mready=true; } else { // Wait for the board to appear on the USB bus: - connect(USBMonitor::instance(), SIGNAL(deviceDiscovered(USBPortInfo)),&m_eventloop, SLOT(quit())); - QTimer::singleShot(15000,&m_eventloop, SLOT(quit())); - m_eventloop.exec(); - disconnect(USBMonitor::instance(), SIGNAL(deviceDiscovered(USBPortInfo)),&m_eventloop, SLOT(quit())); - devices = USBMonitor::instance()->availableDevices(0x20a0,-1,-1,USBMonitor::Bootloader); - if (devices.length()==1) { - QTimer::singleShot(1000,&m_eventloop, SLOT(quit())); - m_eventloop.exec(); - hidHandle.open(1,devices.first().vendorID,devices.first().productID,0,0); - qDebug()<<"OP_DFU detected after delay"; - } - else { - qDebug() << devices.length() << " device(s) detected, don't know what to do!"; - mready = false; + USBSignalFilter filter(0x20a0,-1,-1,USBMonitor::Bootloader); + connect(&filter, SIGNAL(deviceDiscovered()),&m_eventloop, SLOT(quit())); + for(int x=0;x<4;++x) + { + qDebug()<<"OP_DFU trying to detect bootloader:"<availableDevices(0x20a0,-1,-1,USBMonitor::Bootloader); + if (devices.length()==1) { + if(hidHandle.open(1,devices.first().vendorID,devices.first().productID,0,0)==1) + { + qDebug()<<"OP_DFU detected after delay"; + mready=true; + break; + } + } + else { + qDebug() << devices.length() << " device(s) detected, don't know what to do!"; + mready = false; + } } } diff --git a/ground/openpilotgcs/src/plugins/uploader/op_dfu.h b/ground/openpilotgcs/src/plugins/uploader/op_dfu.h index 233e8274f..79624b546 100644 --- a/ground/openpilotgcs/src/plugins/uploader/op_dfu.h +++ b/ground/openpilotgcs/src/plugins/uploader/op_dfu.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/ground/uavobjgenerator/uavobjectparser.cpp b/ground/uavobjgenerator/uavobjectparser.cpp index 8a69bd9a1..b7fff07c3 100644 --- a/ground/uavobjgenerator/uavobjectparser.cpp +++ b/ground/uavobjgenerator/uavobjectparser.cpp @@ -205,6 +205,9 @@ QString UAVObjectParser::parseXML(QString& xml, QString& filename) // Get next element childNode = childNode.nextSibling(); } + + // Sort all fields according to size + qStableSort(info->fields.begin(), info->fields.end(), fieldTypeLessThan); // Sort all fields according to size qStableSort(info->fields.begin(), info->fields.end(), fieldTypeLessThan); diff --git a/package/osx/OpenPilot.dmg b/package/osx/OpenPilot.dmg index c8e1056fb..9d231cdf6 100644 Binary files a/package/osx/OpenPilot.dmg and b/package/osx/OpenPilot.dmg differ diff --git a/package/osx/package b/package/osx/package index e481353ff..8a4860b5d 100755 --- a/package/osx/package +++ b/package/osx/package @@ -30,8 +30,10 @@ cp "${ROOT_DIR}/HISTORY.txt" "/Volumes/${VOL_NAME}" hdiutil detach ${device} -echo "Resizing dmg" -hdiutil resize -size 250m ${TEMP_FILE} +min=`hdiutil resize ${TEMP_FILE} | awk \{print\ \$\1\}` +echo "Resizing dmg to ${min}" + +hdiutil resize -sectors ${min} ${TEMP_FILE} hdiutil convert "${TEMP_FILE}" -format UDZO -o "${OUT_FILE}" # cleanup