From 61321e78f26c4937358da1d75febeff66975d699 Mon Sep 17 00:00:00 2001 From: zeisele <zeisele@iastate.edu> Date: Wed, 23 Mar 2022 04:18:58 +0100 Subject: [PATCH] log block tab changes and graphing preparation --- .../gui/MicroCART/crazyflieworker.cpp | 12 + groundStation/gui/MicroCART/crazyflieworker.h | 1 + groundStation/gui/MicroCART/logworker.cpp | 45 ++++ groundStation/gui/MicroCART/logworker.h | 43 ++++ groundStation/gui/MicroCART/mainwindow.cpp | 91 ++++++-- groundStation/gui/MicroCART/mainwindow.h | 9 + groundStation/gui/MicroCART/mainwindow.ui | 207 +++++++++++++++++- 7 files changed, 387 insertions(+), 21 deletions(-) create mode 100644 groundStation/gui/MicroCART/logworker.cpp create mode 100644 groundStation/gui/MicroCART/logworker.h diff --git a/groundStation/gui/MicroCART/crazyflieworker.cpp b/groundStation/gui/MicroCART/crazyflieworker.cpp index cb241a10c..5fa186c7c 100644 --- a/groundStation/gui/MicroCART/crazyflieworker.cpp +++ b/groundStation/gui/MicroCART/crazyflieworker.cpp @@ -35,6 +35,18 @@ void CrazyflieWorker::connectBackend() paramGroupList.append(qgName); } emit(gotParamGroups(paramGroupList)); + QStringList logVariablesList; + struct toc_group curGroup; + for(int i = 0; i < logGroups.size(); i++) { + curGroup = logGroups.at(i); + for(int j = 0; j < logGroups.at(i).entryNames.size(); j++) { + QString qvName(logGroups.at(i).groupName.c_str()); + qvName = qvName.append("."); + qvName = qvName.append(logGroups.at(i).entryNames.at(j).c_str()); + logVariablesList.append(qvName); + } + } + emit(gotLogVariables(logVariablesList)); } /** diff --git a/groundStation/gui/MicroCART/crazyflieworker.h b/groundStation/gui/MicroCART/crazyflieworker.h index 43d37fc49..42dca39f0 100644 --- a/groundStation/gui/MicroCART/crazyflieworker.h +++ b/groundStation/gui/MicroCART/crazyflieworker.h @@ -42,6 +42,7 @@ public: signals: void gotParamValue(QString paramName, float value); void gotParamGroups(QStringList paramGroupList); + void gotLogVariables(QStringList logVariables); void gotGroupEntries(int box, QStringList groupEntries); void connected(); void disconnected(); diff --git a/groundStation/gui/MicroCART/logworker.cpp b/groundStation/gui/MicroCART/logworker.cpp new file mode 100644 index 000000000..f09c4b9b9 --- /dev/null +++ b/groundStation/gui/MicroCART/logworker.cpp @@ -0,0 +1,45 @@ +#include "logworker.h" +#include <iostream> +#include <unistd.h> +#include <sys/stat.h> + +LogWorker::LogWorker(QObject *parent) : QObject(parent), conn(NULL) +{ +} + +LogWorker::~LogWorker() +{ + disconnectBackend(); +} + +/** + * @brief CrazyflieWorker::connectBackend + * Command the worker to connect to the backend + * will set the private class struct, conn, once done. + * The connected() signal is emitted once complete. + */ +void LogWorker::connectBackend() +{ + if (conn == NULL) { + conn = ucart_backendConnect(); + emit (connected()); + } else { + qInfo() << "Attempted to connect crazyflieworker when already connected!"; + } + +} + +/** + * @brief CrazyflieWorker::disconnectBackend + * Command the worker to disconnect from the backend, + * sets the conn struct to null and emits the + * disconnected() signal once complete + */ +void LogWorker::disconnectBackend() +{ + if (conn) { + ucart_backendDisconnect(conn); + conn = NULL; + emit (disconnected()); + } +} \ No newline at end of file diff --git a/groundStation/gui/MicroCART/logworker.h b/groundStation/gui/MicroCART/logworker.h new file mode 100644 index 000000000..539a168c6 --- /dev/null +++ b/groundStation/gui/MicroCART/logworker.h @@ -0,0 +1,43 @@ +#ifndef LOGWORKER_H +#define LOGWORKER_H + +#include <QObject> +#include <fstream> +#include <sstream> +#include <vector> +#include <QStringList> +#include "frontend_common.h" +#include "frontend_param.h" +#include "frontend_override.h" +#include "frontend_logfile.h" +#include "setpoint.h" +#include <QDebug> + + +/** + * @brief The crazyflieworker class + * This class handles communication for the crazyflie, + * reading log values and setting parameter values + */ +class LogWorker : public QObject +{ + Q_OBJECT +public: + explicit LogWorker(QObject *parent = nullptr); + ~LogWorker(); + + +signals: + void connected(); + void disconnected(); + + +public slots: + void connectBackend(); + void disconnectBackend(); + +private: + struct backend_conn * conn; +}; + +#endif // LOGWORKER_H diff --git a/groundStation/gui/MicroCART/mainwindow.cpp b/groundStation/gui/MicroCART/mainwindow.cpp index 7835d8577..47d5ca653 100644 --- a/groundStation/gui/MicroCART/mainwindow.cpp +++ b/groundStation/gui/MicroCART/mainwindow.cpp @@ -55,24 +55,24 @@ MainWindow::MainWindow(QWidget *parent) : workerStartTimer->setSingleShot(true); /* Create a thread for workers */ - QThread* workerThread = new QThread(this); + //QThread* workerThread = new QThread(this); /* Create a worker to update the tracker */ - TrackerWorker * trackerWorker = new TrackerWorker(); + // TrackerWorker * trackerWorker = new TrackerWorker(); /* Move it to the worker thread. This means that slots of this worker * will run in the worker thread, and not block the UI */ - trackerWorker->moveToThread(workerThread); + //trackerWorker->moveToThread(workerThread); /* Connect tracker worker */ - connect(trackerWorker, SIGNAL (finished(float, float, float, float, float, float)), - this, SLOT (updateTracker(float, float, float, float, float, float))); + //connect(trackerWorker, SIGNAL (finished(float, float, float, float, float, float)), + // this, SLOT (updateTracker(float, float, float, float, float, float))); - connect(trackerWorker, SIGNAL (finished(float, float, float, float, float, float)), - posIndicator, SLOT(updatePos(float,float,float,float,float,float))); + //connect(trackerWorker, SIGNAL (finished(float, float, float, float, float, float)), + // posIndicator, SLOT(updatePos(float,float,float,float,float,float))); - connect(trackerWorker, SIGNAL (finished(float, float, float, float, float, float)), - attIndicator, SLOT(updateAttitude(float, float, float, float, float, float))); + //connect(trackerWorker, SIGNAL (finished(float, float, float, float, float, float)), + // attIndicator, SLOT(updateAttitude(float, float, float, float, float, float))); backendProcess->setProcessChannelMode(QProcess::MergedChannels); @@ -102,7 +102,19 @@ MainWindow::MainWindow(QWidget *parent) : crazyflieWorker = new CrazyflieWorker(); crazyflieWorker->moveToThread(cfThread); + QThread * logThread = new QThread(this); + logWorker = new LogWorker(); + logWorker->moveToThread(logThread); + /* connect signals for crazyflie worker */ + connect(ui->logEntriesComboBox1, SIGNAL (currentIndexChanged(int)), this, SLOT (getLogEntryBoxChange1(int))); + connect(ui->logEntriesComboBox2, SIGNAL (currentIndexChanged(int)), this, SLOT (getLogEntryBoxChange2(int))); + connect(ui->logEntriesComboBox3, SIGNAL (currentIndexChanged(int)), this, SLOT (getLogEntryBoxChange3(int))); + connect(ui->logEntriesComboBox4, SIGNAL (currentIndexChanged(int)), this, SLOT (getLogEntryBoxChange4(int))); + connect(ui->logEntriesComboBox5, SIGNAL (currentIndexChanged(int)), this, SLOT (getLogEntryBoxChange5(int))); + connect(ui->pb_startLog, SIGNAL (clicked()), logWorker, SLOT (getLogValues(QString, QString, QString, QString, QString))); + connect(logWorker, SIGNAL (gotLogValues(QStringList)), this, SLOT (graphLogs(QStringList))); + connect(this, SIGNAL (rateSetpointSignal(float, float, float, float)), crazyflieWorker, SLOT (setCurrAttRateSetpoint(float, float, float, float))); connect(this, SIGNAL (angleSetpointSignal(float, float, float, float)), crazyflieWorker, SLOT (setCurrAttSetpoint(float, float, float, float))); connect(crazyflieTimer, SIGNAL(timeout()), this, SLOT(trigger_send_setpoint())); @@ -110,6 +122,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(this, SIGNAL(triggerAttRateSetpointSend()), crazyflieWorker, SLOT(sendAttRateSetpoint())); connect(this, SIGNAL(triggerMixedAttSetpointSend()), crazyflieWorker, SLOT(sendMixedAttSetpoint())); connect(crazyflieWorker, SIGNAL (gotParamGroups(QStringList)), this, SLOT (setParamGroups(QStringList))); + connect(crazyflieWorker, SIGNAL (gotLogVariables(QStringList)), this, SLOT (setLoggingVariableBox(QStringList))); connect(ui->paramGroupComboBox, SIGNAL (currentIndexChanged(int)), this, SLOT (getGroupBoxChange(int))); connect(ui->paramGroupComboBox_2, SIGNAL (currentIndexChanged(int)), this, SLOT (getGroupBox2Change(int))); @@ -125,15 +138,18 @@ MainWindow::MainWindow(QWidget *parent) : connect(crazyflieWorker, SIGNAL (gotParamValue(QString, float)), this, SLOT (displayParamValue(QString, float))); /* Connect and disconnect from backend when signals emitted */ - connect(workerStartTimer, SIGNAL (timeout()), trackerWorker, SLOT (connectBackend())); + //connect(workerStartTimer, SIGNAL (timeout()), trackerWorker, SLOT (connectBackend())); + connect(workerStartTimer, SIGNAL (timeout()), logWorker, SLOT (connectBackend())); connect(workerStartTimer, SIGNAL (timeout()), controlWorker, SLOT (connectBackend())); connect(workerStartTimer, SIGNAL (timeout()), crazyflieWorker, SLOT (connectBackend())); - connect(this, SIGNAL (connectWorkers()), trackerWorker, SLOT (connectBackend())); + //connect(this, SIGNAL (connectWorkers()), trackerWorker, SLOT (connectBackend())); + connect(this, SIGNAL (connectWorkers()), logWorker, SLOT (connectBackend())); connect(this, SIGNAL (connectWorkers()), controlWorker, SLOT (connectBackend())); connect(this, SIGNAL (connectWorkers()), crazyflieWorker, SLOT (connectBackend())); - connect(this, SIGNAL (disconnectWorkers()), trackerWorker, SLOT (disconnectBackend())); + //connect(this, SIGNAL (disconnectWorkers()), trackerWorker, SLOT (disconnectBackend())); + connect(this, SIGNAL (disconnectWorkers()), logWorker, SLOT (disconnectBackend())); connect(this, SIGNAL (disconnectWorkers()), controlWorker, SLOT (disconnectBackend())); connect(this, SIGNAL (disconnectWorkers()), crazyflieWorker, SLOT (disconnectBackend())); @@ -146,8 +162,11 @@ MainWindow::MainWindow(QWidget *parent) : connect(controlWorker, SIGNAL (connected()), this, SLOT (workerConnected())); connect(controlWorker, SIGNAL (disconnected()), this, SLOT (workerDisconnected())); - connect(trackerWorker, SIGNAL (connected()), this, SLOT (workerConnected())); - connect(trackerWorker, SIGNAL (disconnected()), this, SLOT (workerDisconnected())); + //connect(trackerWorker, SIGNAL (connected()), this, SLOT (workerConnected())); + //connect(trackerWorker, SIGNAL (disconnected()), this, SLOT (workerDisconnected())); + + connect(logWorker, SIGNAL (connected()), this, SLOT (workerConnected())); + connect(logWorker, SIGNAL (disconnected()), this, SLOT (workerDisconnected())); connect(crazyflieWorker, SIGNAL (connected()), this, SLOT (workerConnected())); connect(crazyflieWorker, SIGNAL (disconnected()), this, SLOT (workerDisconnected())); @@ -156,7 +175,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(trackerTimer, SIGNAL(timeout()), this, SLOT(updatePosAtt())); // connect(ui->pbRefresh, SIGNAL (clicked()), this, SLOT (updatePosAtt())); - connect(this, SIGNAL(getPosAttFromBackend()), trackerWorker, SLOT(process())); + //connect(this, SIGNAL(getPosAttFromBackend()), trackerWorker, SLOT(process())); /* Timer used for next setpoint */ nextSpTimer->setSingleShot(true); @@ -165,9 +184,10 @@ MainWindow::MainWindow(QWidget *parent) : /* Start the things */ trackerTimer->start(100); crazyflieTimer->start(100); - workerThread->start(); + //workerThread->start(); cwThread->start(); cfThread->start(); + logThread->start(); matlabProcess->start(); /* Connect the setpointlist to the model */ @@ -352,6 +372,10 @@ void MainWindow::setParamGroups(QStringList groupNames) { ui->paramGroupComboBox_2->addItems(groupNames); } +void MainWindow::setLoggingVariableBox(QStringList variableNames) { + ui->logVariableList->addItems(variableNames); +} + void MainWindow::getGroupBoxChange(int index) { // for(int i = 0; i < ui->paramGroupComboBox->count(); i++) { // ui->paramEntriesComboBox->removeItem(i); @@ -993,3 +1017,38 @@ void MainWindow::on_gamepadPitchScale_valueChanged(int arg1) ui->pitchVizBar->setMinimum(std::abs(arg1) * -1); ui->pitchVizBar->setMaximum(std::abs(arg1)); } + +void MainWindow::graphLogs(QStringList logs) +{ + ui->dataPlot->graph(0)->setPen(QPen(Qt::blue)); + ui->dataPlot->graph(1)->setPen(QPen(Qt::red)); + ui->dataPlot->graph(2)->setPen(QPen(Qt::green)); + ui->dataPlot->graph(3)->setPen(QPen(Qt::black)); + //ui->dataPlot->graph(4)->setPen(QPen(Qt::purple)); + + + //parse data and put into vector + QVector<float> x0(logs.size()), y0(logs.size()); + QVector<float> x1(logs.size()), y1(logs.size()); + QVector<float> x2(logs.size()), y2(logs.size()); + QVector<float> x3(logs.size()), y3(logs.size()); + QVector<float> x4(logs.size()), y4(logs.size()); + + for(int i=0; i< logs.size(); i++) { + //use tokenizer here + } + + //start graph and set data + ui->dataPlot->addGraph(); + // ui->dataPlot->graph(0)->setData(x0, y0); + + //set lables and boundaries + ui->dataPlot->xAxis->setLabel("time"); + ui->dataPlot->yAxis->setLabel("angle"); + + ui->dataPlot->xAxis->setRange(0, 1); + ui->dataPlot->yAxis->setRange(0, 360); + + ui->dataPlot->replot(); +} + diff --git a/groundStation/gui/MicroCART/mainwindow.h b/groundStation/gui/MicroCART/mainwindow.h index becd6e3f5..a7bbcb446 100644 --- a/groundStation/gui/MicroCART/mainwindow.h +++ b/groundStation/gui/MicroCART/mainwindow.h @@ -8,6 +8,7 @@ #include "quaditem.h" #include "gamepadmonitor.h" #include "crazyflieworker.h" +#include "logworker.h" namespace Ui { @@ -37,6 +38,9 @@ signals: void triggerAttSetpointSend(); void triggerAttRateSetpointSend(); void triggerMixedAttSetpointSend(); + void getLogValues(QString log1, QString log2, QString log3, QString log4, QString log5); + + private slots: void on_pbStart_clicked(); @@ -113,6 +117,7 @@ private slots: void setParamGroups(QStringList groupNames); void getGroupBoxChange(int index); void getGroupBox2Change(int index); + void setLoggingVariableBox(QStringList variableNames); void displayParamValue(QString param, float value); void getEntryBoxChange(int index); void getEntryBoxChange2(int index); @@ -146,6 +151,9 @@ private slots: void on_gamepadPitchScale_valueChanged(int arg1); + void graphLogs(QStringList logs); + + private: Ui::MainWindow *ui; QStandardItemModel * setpointList; @@ -163,6 +171,7 @@ private: int connectedWorkers; GamepadMonitor *gamepadMonitor; CrazyflieWorker *crazyflieWorker; + LogWorker *logWorker; }; #endif // MAINWINDOW_H diff --git a/groundStation/gui/MicroCART/mainwindow.ui b/groundStation/gui/MicroCART/mainwindow.ui index c202a2c5c..ca31bb05e 100644 --- a/groundStation/gui/MicroCART/mainwindow.ui +++ b/groundStation/gui/MicroCART/mainwindow.ui @@ -33,7 +33,7 @@ </size> </property> <property name="currentIndex"> - <number>2</number> + <number>3</number> </property> <widget class="QWidget" name="backend"> <attribute name="title"> @@ -132,7 +132,7 @@ </widget> <widget class="QWidget" name="param"> <attribute name="title"> - <string>Param</string> + <string>Parameters</string> </attribute> <widget class="QComboBox" name="paramGroupComboBox"> <property name="geometry"> @@ -794,12 +794,128 @@ </widget> <widget class="QWidget" name="plots"> <attribute name="title"> - <string>Plots</string> + <string>Log Blocks</string> </attribute> + <widget class="QComboBox" name="comboBox"> + <property name="geometry"> + <rect> + <x>410</x> + <y>680</y> + <width>201</width> + <height>25</height> + </rect> + </property> + <item> + <property name="text"> + <string>Logging Block</string> + </property> + </item> + </widget> + <widget class="QPushButton" name="pushButton"> + <property name="geometry"> + <rect> + <x>330</x> + <y>750</y> + <width>80</width> + <height>25</height> + </rect> + </property> + <property name="text"> + <string>Resume</string> + </property> + </widget> + <widget class="QPushButton" name="pushButton_2"> + <property name="geometry"> + <rect> + <x>470</x> + <y>750</y> + <width>80</width> + <height>25</height> + </rect> + </property> + <property name="text"> + <string>Pause</string> + </property> + </widget> + <widget class="QPushButton" name="pushButton_3"> + <property name="geometry"> + <rect> + <x>600</x> + <y>750</y> + <width>80</width> + <height>25</height> + </rect> + </property> + <property name="text"> + <string>Delete</string> + </property> + </widget> + <widget class="QPushButton" name="pushButton_4"> + <property name="geometry"> + <rect> + <x>330</x> + <y>520</y> + <width>401</width> + <height>25</height> + </rect> + </property> + <property name="text"> + <string>Open Logging Block Setup File</string> + </property> + </widget> + <widget class="QPushButton" name="pushButton_5"> + <property name="geometry"> + <rect> + <x>330</x> + <y>610</y> + <width>141</width> + <height>25</height> + </rect> + </property> + <property name="text"> + <string>Refresh Log Blocks</string> + </property> + </widget> + <widget class="QPushButton" name="pushButton_6"> + <property name="geometry"> + <rect> + <x>590</x> + <y>610</y> + <width>141</width> + <height>25</height> + </rect> + </property> + <property name="text"> + <string>Stop All Log Blocks</string> + </property> + </widget> + <widget class="QLabel" name="label_2"> + <property name="geometry"> + <rect> + <x>460</x> + <y>450</y> + <width>141</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Log Block Commands</string> + </property> + </widget> + <widget class="QListWidget" name="logVariableList"> + <property name="geometry"> + <rect> + <x>5</x> + <y>0</y> + <width>1101</width> + <height>441</height> + </rect> + </property> + </widget> </widget> <widget class="QWidget" name="navigation"> <attribute name="title"> - <string>Navigation</string> + <string>Control</string> </attribute> <layout class="QVBoxLayout" name="verticalLayout_3"> <item> @@ -1016,6 +1132,9 @@ <property name="orientation"> <enum>Qt::Vertical</enum> </property> + <property name="sizeType"> + <enum>QSizePolicy::MinimumExpanding</enum> + </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> @@ -1024,6 +1143,84 @@ </property> </spacer> </item> + <item> + <widget class="QLabel" name="logging_label"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Logging Variables</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="logEntriesComboBox1"> + <property name="currentText"> + <string>Logging Variable 1</string> + </property> + <item> + <property name="text"> + <string>Logging Variable 1</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QComboBox" name="logEntriesComboBox2"> + <item> + <property name="text"> + <string>Logging Variable 2</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QComboBox" name="logEntriesComboBox3"> + <item> + <property name="text"> + <string>Logging Variable 3</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QComboBox" name="logEntriesComboBox4"> + <item> + <property name="text"> + <string>Logging Variable 4</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QComboBox" name="logEntriesComboBox5"> + <item> + <property name="text"> + <string>Logging Variable 5</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QPushButton" name="pb_startLog"> + <property name="text"> + <string>Start Logging</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pb_stopLog"> + <property name="text"> + <string>Stop Logging</string> + </property> + </widget> + </item> <item> <layout class="QFormLayout" name="formLayout"> <property name="fieldGrowthPolicy"> @@ -1190,7 +1387,7 @@ <resources/> <connections/> <buttongroups> - <buttongroup name="buttonGroup_2"/> <buttongroup name="AngleRateButtonGroup"/> + <buttongroup name="buttonGroup_2"/> </buttongroups> </ui> -- GitLab