diff --git a/SavvyCAN.pro b/SavvyCAN.pro index 1a4ba41..b02ce61 100644 --- a/SavvyCAN.pro +++ b/SavvyCAN.pro @@ -34,7 +34,8 @@ SOURCES += main.cpp\ dbcsignaleditor.cpp \ framefileio.cpp \ filecomparatorwindow.cpp \ - mainsettingsdialog.cpp + mainsettingsdialog.cpp \ + discretestatewindow.cpp HEADERS += mainwindow.h \ can_structs.h \ @@ -57,7 +58,8 @@ HEADERS += mainwindow.h \ framefileio.h \ config.h \ filecomparatorwindow.h \ - mainsettingsdialog.h + mainsettingsdialog.h \ + discretestatewindow.h FORMS += mainwindow.ui \ graphingwindow.ui \ @@ -70,7 +72,8 @@ FORMS += mainwindow.ui \ dbcmaineditor.ui \ dbcsignaleditor.ui \ filecomparatorwindow.ui \ - mainsettingsdialog.ui + mainsettingsdialog.ui \ + discretestatewindow.ui DISTFILES += diff --git a/discretestatewindow.cpp b/discretestatewindow.cpp new file mode 100644 index 0000000..d198ae3 --- /dev/null +++ b/discretestatewindow.cpp @@ -0,0 +1,196 @@ +#include "discretestatewindow.h" +#include "ui_discretestatewindow.h" +#include "mainwindow.h" + +DiscreteStateWindow::DiscreteStateWindow(const QVector *frames, QWidget *parent) : + QDialog(parent), + ui(new Ui::DiscreteStateWindow) +{ + ui->setupUi(this); + + modelFrames = frames; + operatingState = DWStates::IDLE; + + timer = new QTimer(); + timer->setInterval(100); + + connect(ui->btnStart, SIGNAL(clicked(bool)), this, SLOT(handleStartButton())); + connect(timer, SIGNAL(timeout()), this, SLOT(handleTick())); + connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int))); +} + +DiscreteStateWindow::~DiscreteStateWindow() +{ + timer->stop(); + + for (int i = 0; i < stateFrames.count(); i++) + { + stateFrames[i]->clear(); + delete(stateFrames[i]); + } + + delete timer; + delete ui; +} + +void DiscreteStateWindow::updatedFrames(int numFrames) +{ + CANFrame thisFrame; + if (numFrames == -1) //all frames deleted. Kill the display + { + } + else if (numFrames == -2) //all new set of frames. Reset + { + } + else //just got some new frames. See if they are relevant. + { + for (int i = modelFrames->count() - numFrames; i < modelFrames->count(); i++) + { + thisFrame = modelFrames->at(i); + if (operatingState == DWStates::IDLE) stateFrames[0]->append(thisFrame); + else stateFrames[currToggleState + 1]->append(thisFrame); + } + } +} + +void DiscreteStateWindow::showEvent(QShowEvent* event) +{ + QDialog::showEvent(event); + + readSettings(); + + qDebug() << "DiscreteState show event was processed"; +} + +void DiscreteStateWindow::closeEvent(QCloseEvent *event) +{ + Q_UNUSED(event); + writeSettings(); +} + +void DiscreteStateWindow::readSettings() +{ + QSettings settings; + if (settings.value("Main/SaveRestorePositions", false).toBool()) + { + resize(settings.value("DiscreteState/WindowSize", QSize(400, 300)).toSize()); + move(settings.value("DiscreteState/WindowPos", QPoint(50, 50)).toPoint()); + } + +} + +void DiscreteStateWindow::writeSettings() +{ + QSettings settings; + + if (settings.value("Main/SaveRestorePositions", false).toBool()) + { + settings.setValue("DiscreteState/WindowSize", size()); + settings.setValue("DiscreteState/WindowPos", pos()); + } +} + +void DiscreteStateWindow::updateStateLabel() +{ + QPalette pal; + switch(operatingState) + { + case DWStates::IDLE: + ui->lblStatus->setText("WAIT"); + pal = ui->lblStatus->palette(); + pal.setColor(QPalette::WindowText, Qt::red); + ui->lblStatus->setPalette(pal); + break; + case DWStates::COUNTDOWN_SIGNAL: + ui->lblStatus->setText(QString::number(ticksUntilStateChange * 0.1, 'f', 1) + "..."); + pal = ui->lblStatus->palette(); + pal.setColor(QPalette::WindowText, Qt::blue); + ui->lblStatus->setPalette(pal); + break; + case DWStates::COUNTDOWN_WAITING: + ui->lblStatus->setText("Return to resting state"); + pal = ui->lblStatus->palette(); + pal.setColor(QPalette::WindowText, Qt::red); + ui->lblStatus->setPalette(pal); + break; + case DWStates::GETTING_SIGNAL: + ui->lblStatus->setText("Go to state " + QString::number(currToggleState + 1)); + pal = ui->lblStatus->palette(); + pal.setColor(QPalette::WindowText, Qt::green); + ui->lblStatus->setPalette(pal); + break; + } +} + +void DiscreteStateWindow::handleStartButton() +{ + operatingState = DWStates::COUNTDOWN_SIGNAL; + + ticksPerStateChange = ticksUntilStateChange = ui->spinFreq->value() * 10; + numToggleStates = ui->spinStates->value(); + numIterations = ui->spinIterations->value(); + + currToggleState = 0; + currIteration = 0; + + for (int i = 0; i < stateFrames.count(); i++) + { + stateFrames[i]->clear(); + delete(stateFrames[i]); + } + + for (int j = 0; j <= numToggleStates; j++) + { + stateFrames.append(new QVector()); + } + + timer->start(); +} + +void DiscreteStateWindow::handleTick() +{ + switch (operatingState) + { + case DWStates::IDLE: + break; + case DWStates::COUNTDOWN_SIGNAL: + ticksUntilStateChange--; + if (ticksUntilStateChange == 0) + { + ticksUntilStateChange = ticksPerStateChange; + operatingState = DWStates::GETTING_SIGNAL; + } + break; + case DWStates::COUNTDOWN_WAITING: + ticksUntilStateChange--; + if (ticksUntilStateChange == 0) + { + ticksUntilStateChange = ticksPerStateChange; + currIteration++; + if (currIteration == numIterations) + { + operatingState = DWStates::IDLE; + timer->stop(); + //call to calculate our findings here. + } + else operatingState = DWStates::COUNTDOWN_SIGNAL; + } + break; + case DWStates::GETTING_SIGNAL: + ticksUntilStateChange--; + if (ticksUntilStateChange == 0) + { + ticksUntilStateChange = ticksPerStateChange; + operatingState = DWStates::COUNTDOWN_WAITING; + currToggleState++; + if (currToggleState == numToggleStates) currToggleState = 0; + } + break; + } + updateStateLabel(); +} + +void DiscreteStateWindow::calculateResults() +{ + +} diff --git a/discretestatewindow.h b/discretestatewindow.h new file mode 100644 index 0000000..311f7be --- /dev/null +++ b/discretestatewindow.h @@ -0,0 +1,57 @@ +#ifndef DISCRETESTATEWINDOW_H +#define DISCRETESTATEWINDOW_H + +#include +#include +#include "can_structs.h" + +namespace Ui { +class DiscreteStateWindow; +} + +namespace DWStates { +enum DiscreteWindowState +{ + IDLE, + COUNTDOWN_SIGNAL, + COUNTDOWN_WAITING, + GETTING_SIGNAL +}; +} + +using namespace DWStates; +class DiscreteStateWindow : public QDialog +{ + Q_OBJECT + +public: + explicit DiscreteStateWindow(const QVector *frames, QWidget *parent = 0); + ~DiscreteStateWindow(); + void showEvent(QShowEvent*); + +private slots: + void updatedFrames(int); + void handleStartButton(); + void handleTick(); + +private: + Ui::DiscreteStateWindow *ui; + const QVector *modelFrames; + QList< QVector *> stateFrames; + QTimer *timer; + DiscreteWindowState operatingState; + int ticksUntilStateChange; + int ticksPerStateChange; + int numToggleStates; + int currToggleState; + int numIterations; + int currIteration; + + void closeEvent(QCloseEvent *event); + void readSettings(); + void writeSettings(); + void updateStateLabel(); + void calculateResults(); +}; + +#endif // DISCRETESTATEWINDOW_H diff --git a/discretestatewindow.ui b/discretestatewindow.ui new file mode 100644 index 0000000..ed01b92 --- /dev/null +++ b/discretestatewindow.ui @@ -0,0 +1,154 @@ + + + DiscreteStateWindow + + + + 0 + 0 + 400 + 300 + + + + Single/Multi State WIndow + + + + + + Candidate Matches: + + + + + + + + 1 + + + + + + + + + + Number of States: + + + + + + + Toggle Frequency (Seconds) + + + + + + + 1 + + + 30 + + + 2 + + + + + + + 1 + + + 20 + + + + + + + Iterations + + + + + + + 1 + + + 10 + + + + + + + + + Go for it + + + + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 120 + 120 + 120 + + + + + + + + + Nirmala UI + 26 + 75 + true + + + + WAIT + + + + + + + + diff --git a/mainwindow.cpp b/mainwindow.cpp index fe17f50..bb36260 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -10,9 +10,13 @@ /* Things that were planned for the GVRET-PC project but never completed. + Single / Multi state - The goal is to find bits that change based on toggles or discrete state items (shifters, etc) + Range state - Find things that range like accelerator pedal inputs, road speed, tach, etc + fuzzy scope - Try to find potential places where a given value might be stored - offer guesses and the program tries to find candidates for you +or, try to find things that appear to be multi-byte integers */ QString MainWindow::loadedFileName = ""; @@ -104,6 +108,7 @@ MainWindow::MainWindow(QWidget *parent) : dbcMainEditor = NULL; comparatorWindow = NULL; settingsDialog = NULL; + discreteStateWindow = NULL; dbcHandler = new DBCHandler; bDirty = false; inhibitFilterUpdate = false; @@ -224,6 +229,12 @@ MainWindow::~MainWindow() delete settingsDialog; } + if (discreteStateWindow) + { + discreteStateWindow->close(); + delete discreteStateWindow; + } + delete ui; delete dbcHandler; model->clearFrames(); @@ -983,7 +994,11 @@ void MainWindow::showComparisonWindow() void MainWindow::showSingleMultiWindow() { - //not done yet + if (!discreteStateWindow) + { + discreteStateWindow = new DiscreteStateWindow(model->getListReference()); + } + discreteStateWindow->show(); } void MainWindow::showRangeWindow() diff --git a/mainwindow.h b/mainwindow.h index 6d7ea61..488b42c 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -17,6 +17,7 @@ #include "dbchandler.h" #include "dbcmaineditor.h" #include "mainsettingsdialog.h" +#include "discretestatewindow.h" namespace Ui { class MainWindow; @@ -115,6 +116,7 @@ private: DBCMainEditor *dbcMainEditor; FileComparatorWindow *comparatorWindow; MainSettingsDialog *settingsDialog; + DiscreteStateWindow *discreteStateWindow; //various private storage QLabel lbStatusConnected; diff --git a/serialworker.h b/serialworker.h index 0b3c3b7..d3d7b18 100644 --- a/serialworker.h +++ b/serialworker.h @@ -9,6 +9,8 @@ #include "can_structs.h" #include "canframemodel.h" +namespace SERIALSTATE { + enum STATE //keep this enum synchronized with the Arduino firmware project { IDLE, @@ -24,6 +26,9 @@ enum STATE //keep this enum synchronized with the Arduino firmware project SET_SINGLEWIRE_MODE }; +} + +using namespace SERIALSTATE; class SerialWorker : public QObject { Q_OBJECT