diff --git a/.github/workflows/buildQmake_wf.yml b/.github/workflows/buildQmake_wf.yml new file mode 100644 index 0000000..5b1e966 --- /dev/null +++ b/.github/workflows/buildQmake_wf.yml @@ -0,0 +1,28 @@ +name: buildQmake_wf.yml +on: + workflow_call: + inputs: + qmakeflags: + required: false + type: string + binaryfilename: + required: true + type: string +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: qt6-base-dev qt5-qmake qtbase5-dev libqt6serialport6 libqt6serialport6-dev libqt5serialport5 libqt5serialport5-dev nlohmann-json3-dev socat gengetopt + version: 1.0 + - name: Build with qmake + run: /usr/bin/qmake VolanteAlphaQT.pro ${{ inputs.qmakeflags }} && make + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + name: ${{ inputs.binaryfilename }} + path: ${{ github.workspace }}/bin/${{ inputs.binaryfilename }} + if-no-files-found: error \ No newline at end of file diff --git a/.github/workflows/deploy_wf.yml b/.github/workflows/deploy_wf.yml new file mode 100644 index 0000000..c8b849e --- /dev/null +++ b/.github/workflows/deploy_wf.yml @@ -0,0 +1,9 @@ +name: deploy_wf +on: + push: + branches: [ master, workflow-stuff ] +jobs: + deploy-production: + uses: + ./.github/workflows/deploymentProduction_wf.yml + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/deploymentProduction_wf.yml b/.github/workflows/deploymentProduction_wf.yml new file mode 100644 index 0000000..0ab80dc --- /dev/null +++ b/.github/workflows/deploymentProduction_wf.yml @@ -0,0 +1,11 @@ +#A workflow to deploy the application to a banana pi Zero M2 +name: deploymentProduction_wf +on: workflow_call +jobs: + build-qt-desktop: + uses: ./.github/workflows/buildQmake_wf.yml + with: + qmakeflags: "CONFIG+=release_armv7Cortex" + binaryfilename: VolanteAlphaQT + + diff --git a/.github/workflows/testQTarmv7_wf.yml b/.github/workflows/testQTarmv7_wf.yml new file mode 100644 index 0000000..743aa3a --- /dev/null +++ b/.github/workflows/testQTarmv7_wf.yml @@ -0,0 +1,38 @@ +name: testQTarmv7_wf +on: + workflow_call: + inputs: + suite: + required: false + type: string +jobs: + build-qt-tests-armv7: + uses: ./.github/workflows/buildQmake_wf.yml + with: + qmakeflags: "CONFIG+=\"test release_armv7Cortex\"" + binaryfilename: VolanteAlphaQT_testes + test-qt-armv7: + needs: [build-qt-desktop] + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Fetch artifacts from build-qt-desktop + uses: dawidd6/action-download-artifact@v2 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + path: bin + workflow: ${{ github.event.workflow_run.workflow_id }} + workflow_conclusion: completed + name: VolanteAlphaQT_testes + # open ssh connection to the server + - name: Setup permissions + run: chmod u+x $GITHUB_WORKSPACE/bin/VolanteAlphaQT_testes + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: qt6-base-dev qt5-qmake qtbase5-dev libqt6serialport6 libqt6serialport6-dev libqt5serialport5 libqt5serialport5-dev nlohmann-json3-dev socat gengetopt + version: 1.0 + - name: Run tests + run: cd $GITHUB_WORKSPACE/bin && ./VolanteAlphaQT_testes -platform offscreen + + diff --git a/.github/workflows/testQTdesktop_wf.yml b/.github/workflows/testQTdesktop_wf.yml new file mode 100644 index 0000000..2a6a18d --- /dev/null +++ b/.github/workflows/testQTdesktop_wf.yml @@ -0,0 +1,38 @@ +name: testQTdesktop_wf +on: + workflow_call: + inputs: + suite: + required: false + type: string +jobs: + build-qt-desktop: + uses: ./.github/workflows/buildQmake_wf.yml + with: + qmakeflags: "CONFIG+=test" + binaryfilename: VolanteAlphaQT_testes + test-qt-desktop: + needs: [build-qt-desktop] + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Fetch artifacts from build-qt-desktop + uses: dawidd6/action-download-artifact@v2 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + path: bin + workflow: ${{ github.event.workflow_run.workflow_id }} + workflow_conclusion: completed + name: VolanteAlphaQT_testes + # open ssh connection to the server + - name: Setup permissions + run: chmod u+x $GITHUB_WORKSPACE/bin/VolanteAlphaQT_testes + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: qt6-base-dev qt5-qmake qtbase5-dev libqt6serialport6 libqt6serialport6-dev libqt5serialport5 libqt5serialport5-dev nlohmann-json3-dev socat gengetopt + version: 1.0 + - name: Run tests + run: cd $GITHUB_WORKSPACE/bin && ./VolanteAlphaQT_testes -platform offscreen + + diff --git a/.github/workflows/test_wf.yml b/.github/workflows/test_wf.yml new file mode 100644 index 0000000..72cd7d0 --- /dev/null +++ b/.github/workflows/test_wf.yml @@ -0,0 +1,10 @@ +name: test_wf +on: + push: + branches: [ master, workflow-stuff ] +jobs: + test-qt-desktop: + uses: + ./.github/workflows/testQTdesktop_wf.yml + secrets: inherit + \ No newline at end of file diff --git a/.gitignore b/.gitignore index b3b7c50..b233a1a 100644 --- a/.gitignore +++ b/.gitignore @@ -72,7 +72,12 @@ CMakeLists.txt.user* *.dll *.exe +**args.c +**args.h bin build -*.code-workspace \ No newline at end of file +*.code-workspace +serialLog**.txt +**.log +.vscode \ No newline at end of file diff --git a/README.md b/README.md index d5409bd..8c9f94a 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,15 @@ -# Volante Alpha +# Volante Alpha -> [![main_wf](https://github.com/FSLART/volante_alpha_qt/actions/workflows/main_wf.yml/badge.svg?branch=master)](https://github.com/FSLART/volante_alpha_qt/actions/workflows/main_wf.yml) + +[![test_wf](https://github.com/FSLART/volante_alpha_qt/actions/workflows/test_wf.yml/badge.svg?branch=master)](https://github.com/FSLART/volante_alpha_qt/actions/workflows/test_wf.yml) [![deploy_wf](https://github.com/FSLART/volante_alpha_qt/actions/workflows/deploy_wf.yml/badge.svg?branch=master)](https://github.com/FSLART/volante_alpha_qt/actions/workflows/deploy_wf.yml) Bem vindo! Este repo tem o propósito de uma implementação do software que será usado tanto para o volante do T14 para fazer alguns testes, como no futuro para modelos mais recentes. A sua implementação atualmente encontra-se em QT 6.0 com base nas bibliotecas nativas em C++. Para compilar o projeto necessitarás de qMake(uma implementação inspirada no software Cmake e make) existindo cerca de 4 ambientes, estes sendo: **Profile, Debug, Release e Testing** +## v1.0.0 + +Apesar de não ter havido versionamento pois o desenvolvimento foi apressado e houveram prioridades este release é exclusivamente para as variáveis do T-14 e não deve ser usado para outros veiculos pois terão variaveis de controlo diferente às usadas. + # Ambientes Deverás usar o software qtcreator já que ajuda a executar o qmake e o make com todo o make eyecandy para poderes fazer debugging e dar set up automatico de alguns ambientes listados acima. Três dos quatro ambientes são criados automaticamente pelo qtcreator, mas um deles (Testing) terá de ser criado manualmente no qtcreator, pois não vem por defeito. @@ -43,7 +49,7 @@ test{ Se mudares a linha e tua responsabilidade mudares as alterações de volta antes de fazeres um commit. O .pro nao deve ser ignorado pois causa a que toda a gente tenha de manualmente criar o ficheiro. Ignorar isto pode causar problemas futuros. ---------- +--- # Dependencias @@ -59,6 +65,8 @@ Para o BSON irás precisar de uma biblioteca json, especificamente: https://github.com/nlohmann/json Poderás usar a seguinte package com o pacman ``nlohmann-json``. Foi usada a versão `nlohmann-json-3.11.2-1-any` para o desenvolvimento +Para testes terás de instalar gengetopt e socat. + # Manutenção do README Se notares que o .readme está bastante desatualizado e pertences à equipa deves chatear uma pessoa apropriada. A partida no futuro existerá um manual tanto para utilizadores como para developers. diff --git a/VolanteAlphaQT.pro b/VolanteAlphaQT.pro index 94ce0bf..c6842e6 100644 --- a/VolanteAlphaQT.pro +++ b/VolanteAlphaQT.pro @@ -1,8 +1,9 @@ ###################################################################### # Automatically generated by qmake (3.1) Wed Feb 8 13:19:20 2023 ###################################################################### +defines += __LART_T14__ -QT += core gui widgets serialport +QT += core gui widgets serialport TEMPLATE = app TARGET = VolanteAlphaQT @@ -21,38 +22,101 @@ RCC_DIR = build # Please consult the documentation of the deprecated API in order to know # how to port your code away from it. # You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 # Input -HEADERS += src/contarotacoes.h \ - src/mainwindow.h \ - src/store.h - +HEADERS += \ + #Constants Macros Aux stuff + src/references/bson_var.h \ + #UI and other non operational stuff + src/flabel.h \ + src/contarotacoes.h \ + src/contamudancas.h \ + src/mainwindow.h \ + #Biz Logic + src/store.h -SOURCES += src/contarotacoes.cpp \ - src/main.cpp \ - src/mainwindow.cpp \ - src/store.cpp +SOURCES += \ + #Constants Macros Aux stuff + #UI and other non operational stuff + src/flabel.cpp \ + src/contarotacoes.cpp \ + src/contamudancas.cpp \ + src/main.cpp \ + src/mainwindow.cpp \ + #Biz Logic + src/store.cpp FORMS += src/mainwindow.ui TRANSLATIONS += src/VolanteAlphaQT_1_en_US.ts test{ - message(A configurar a build de testes...) + + message(A configurar a build de testes...) - TARGET = VolanteAlphaQT_testes + TARGET = VolanteAlphaQT_testes + # run command before compiling + #go to + system(gengetopt --input=./test/args.ggo --output-dir=./test -F args) - QT += testlib - SOURCES -= src/main.cpp - - HEADERS += \ - test/tst_contarotacoes.h \ - test/tst_serialport.h + QT += testlib + SOURCES -= src/main.cpp + SOURCES += test/main.cpp + HEADERS += \ + test/args.h \ + test/aux.h \ + test/tst_contarotacoes.h \ + test/tst_contamudancas.h \ + test/tst_serialport.h \ + test/tst_flabels.h - SOURCES += \ - test/tst_contarotacoes.cpp \ - test/tst_serialport.cpp + + + SOURCES += \ + test/args.c \ + test/aux.cpp \ + test/tst_flabels.cpp \ + test/tst_contarotacoes.cpp \ + test/tst_contamudancas.cpp \ + test/tst_serialport.cpp } +release_armv7Cortex{ + QT = + CONFIG -= debug ltcg + defines += __LART_DEPLOY__ + + CROSS_COMPILER_NAME = "arm-linux-gnueabihf" + #DEFINES += CROSS_COMPILER_NAME=\"$$CROSS_COMPILER_NAME" + + QMAKE_CC = $$CROSS_COMPILER_NAME-gcc + QMAKE_CXX = $$CROSS_COMPILER_NAME-g++ + + QMAKE_LINK = $$CROSS_COMPILER_NAME-ld.gold + QMAKE_LINK_SHLIB = $$CROSS_COMPILER_NAME-ld.gold + QMAKE_LIBS_EGL = -lEGL -lGLESv2 + QMAKE_LIBS_OPENVG = -lEGL -lOpenVG -lGLESv2 + QMAKE_INCDIR_BCM_HOST = $$[QT_SYSROOT]/opt/vc/include + QMAKE_LIBDIR_BCM_HOST = $$[QT_SYSROOT]/opt/vc/lib + QMAKE_LIBS += -I$$[QT_SYSROOT]/usr/include/nlohmann + QMAKE_LIBS_BCM_HOST = -lbcm_host + QT_ARMV7_COMPILER_VERSION = $$system($$QMAKE_CXX -dumpversion) + DEFINES += QT_ARMV7_COMPILER_VERSION=\"$$QT_ARMV7_COMPILER_VERSION\" + QT_ARMV7_SO_LOCATION = /usr/lib/gcc/$$CROSS_COMPILER_NAME/$$QT_ARMV7_COMPILER_VERSION/qt + DEFINES += QT_ARMV7_SO_LOCATION=$$QT_ARMV7_SO_LOCATION + # TODO: This is strange... check if theres something more adequate + QMAKE_CXXFLAGS *= -I/usr/include/nlohmann -I$$QT_ARMV7_SO_LOCATION + QMAKE_CXXFLAGS *= -mfloat-abi=hard -mfpu=neon -mthumb -mthumb-interwork -mcpu=cortex-a7 -mtune=cortex-a7 -mabi=aapcs-linux -mhard-float -mno-unaligned-access -fPIC + QMAKE_LFLAGS_RELEASE *= -shared -mfloat-abi=hard -mfpu=neon -mthumb -mthumb-interwork -mcpu=cortex-a7 -mtune=cortex-a7 -mabi=aapcs-linux -mhard-float -mno-unaligned-access -O2 -flto=4 -fno-fat-lto-objects -fuse-linker-plugin -fuse-ld=bfd + QMAKE_LFLAGS_RELEASE -= -Wl,-O1 + + + # spaggeti code... + message($$QMAKE_LIBS) + QMAKE_LIBS -= -lpthread + QMAKE_LIBS += -L$$QT_ARMV7_SO_LOCATION/libpthread.so.0 -L$$QT_ARMV7_SO_LOCATION/libQt5Widgets.so -L$$QT_ARMV7_SO_LOCATION/libQt5Gui.so -L$$QT_ARMV7_SO_LOCATION/libQt5SerialPort.so -L$$QT_ARMV7_SO_LOCATION/libQt5Core.so + + +} diff --git a/src/contamudancas.cpp b/src/contamudancas.cpp new file mode 100644 index 0000000..88c92ec --- /dev/null +++ b/src/contamudancas.cpp @@ -0,0 +1,170 @@ +#include "contamudancas.h" +#include "contarotacoes.h" +#include "mainwindow.h" +#include +static store * store_pnt = nullptr; +ContaMudancas::ContaMudancas( QWidget *parent) + : ContaRotacoes(parent){ + this->m_mudanca=0; + try{ + MainWindow* w = qobject_cast(parent->parent()); + store_pnt=w->getStore(); + connect(store_pnt,&store::gearShiftChanged, this, &ContaMudancas::handleChangedMudanca); + }catch(...){ + //TODO proper notices + qDebug() << "Error: ContaMudancas::ContaMudancas( QWidget *parent) failed to connect to store"; + + } + +} + + +const int padding = 10; + +void ContaMudancas::paintEvent(QPaintEvent *event){ + ContaRotacoes::paintEvent(event); + //draw a big QString centered in the middle of the widget with getGraphicalTextMudanca(m_mudanca) + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + const auto group = QPalette::Active; + const auto role = QPalette::Text; + + + auto palette=this->palette(); + painter.setPen(QPen(palette.color(group, role))); + painter.setFont(QFont("Arial", width()/padding*4)); + //rect add padding vertical + painter.drawText(this->rect().adjusted(0, padding*4, 0, 0), Qt::AlignCenter, getGraphicalTextMudanca(m_mudanca)); + +} +int ContaMudancas::getVisibleMudanca(){ + return m_mudanca; +} +QString ContaMudancas::getGraphicalTextMudanca(int a){ + switch (a) { + case 0: + return QString("N"); + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + return QString::number(a); + default: + return QString("?"); + + + } +} +void ContaMudancas::handleChangedMudanca(int newValue, int oldValue){ + //remove unused warning + (void)oldValue; + + // value< m_maxValue || this should be in the if for better data quality but in case of a ill fate, it might be interesting to see the values + if( newValue >= -1){ + this->m_mudanca = newValue; + this->update(); + } +} +ContaMudancas::~ContaMudancas(){ + disconnect(store_pnt,&store::gearShiftChanged, this, &ContaMudancas::handleChangedMudanca); +} +QColor ContaMudancas::getGraphicColorWhipper(){ + switch (m_mudanca) { + case 0: + { + double ratio = (double)(m_value)/m_maxValue; + int red=std::floor(255* (1-ratio)); + int blue=std::floor(255*ratio); + return QColor(red,0,blue); + } + break; + case 1: + case 2: + if(m_value<400){ + //return deep red + return QColor(200,0,50); + }else if(m_value<800){ + return QColor(255,0,0); + }else if(m_value<1200){ + //return light green + return QColor(0,230,0); + }else if(m_value<1300){ + //return light green + return QColor(0,230,230); + }else if(m_value<1400){ + //return light green + return QColor(0,230,0); + }else if(m_value<2000){ + //return light green + return QColor(255,0,0); + }else{ + return QColor(200,0,50); + } + break; + case 3: + if(m_value<400){ + //return deep red + return QColor(200,0,50); + }else if(m_value<800){ + return QColor(255,0,0); + }else if(m_value<1200){ + //return light green + return QColor(0,230,0); + }else if(m_value<1300){ + //return light green + return QColor(0,230,230); + }else if(m_value<1400){ + //return light green + return QColor(0,230,0); + }else if(m_value<2000){ + //return light green + return QColor(255,0,0); + }else{ + return QColor(200,0,50); + } + break; + case 4: + case 5: + case 6: + if(m_value<400){ + //return deep red + return QColor(200,0,50); + }else if(m_value<800){ + return QColor(255,0,0); + }else if(m_value<1200){ + //return light green + return QColor(0,230,0); + }else if(m_value<1300){ + //return light green + return QColor(0,230,230); + }else if(m_value<1400){ + //return light green + return QColor(0,230,0); + }else if(m_value<2000){ + //return light green + return QColor(255,0,0); + }else{ + return QColor(200,0,50); + } + break; + default: + return QColor(0,0,0); + break; + + } + +} +int ContaMudancas::getPositionFromVariationSlope(){ + const int minPhi = -720; + //maximum whipper of the arc + //const int maxPhi = 270*16; + const int maxPhi = 4320; + + //TODO EXAMPLE CODE THIS IS SUPPOSED TO BE UNDER SUPERVISION + double ratio = ((double)m_value)/((double)m_maxValue); + + int currentPhi =((int)((double)(ratio)*(maxPhi-minPhi))); + return currentPhi; +} diff --git a/src/contamudancas.h b/src/contamudancas.h new file mode 100644 index 0000000..0a2008f --- /dev/null +++ b/src/contamudancas.h @@ -0,0 +1,27 @@ +#ifndef CONTAMUDANCAS_H +#define CONTAMUDANCAS_H + +#include "contarotacoes.h" +#include +#include +#include +#include + +class ContaMudancas : public ContaRotacoes{ + Q_OBJECT + public: + explicit ContaMudancas( QWidget *parent = nullptr); + ~ContaMudancas(); + void paintEvent(QPaintEvent *event) override; + int getVisibleMudanca(); + QColor getGraphicColorWhipper() override; + int getPositionFromVariationSlope() override; + QString getGraphicalTextMudanca(int a); + protected: + + int m_mudanca=0; + public slots: + void handleChangedMudanca(int newValue, int oldValue); +}; + +#endif // CONTAMUDANCAS_H diff --git a/src/contarotacoes.cpp b/src/contarotacoes.cpp index 1955351..35cd18a 100644 --- a/src/contarotacoes.cpp +++ b/src/contarotacoes.cpp @@ -1,34 +1,58 @@ #include "contarotacoes.h" - +static store * store_pnt = nullptr; ContaRotacoes::ContaRotacoes( QWidget *parent) - : QWidget(parent){ - m_value=1000; - //q is a static variable that you get from calling the static function getStore() from mainwindow + : QWidget(parent){ + m_value=0; + + //q is a static variable that you get from calling the static function getStore() from mainwindow //find MainWindow and get the store - MainWindow* w = qobject_cast(parent->parent()); + try{ + MainWindow* w = qobject_cast(parent->parent()); + store_pnt=w->getStore(); + connect(store_pnt,&store::rpmChanged, this, &ContaRotacoes::handleChangedValue); + }catch(...){ + //TODO proper notices + qDebug() << "Error: ContaRotacoes::ContaRotacoes( QWidget *parent) failed to connect to store"; - connect(w->getStore(),&store::rpmChanged, this, &ContaRotacoes::handleChangedValue); + } m_maxValue=MAX_ROTATIONS_DEFAULT; +} +ContaRotacoes::~ContaRotacoes(){ + disconnect(store_pnt,&store::rpmChanged, this, &ContaRotacoes::handleChangedValue); + } void ContaRotacoes::paintEvent(QPaintEvent *event){ - //padding of the line - const int padding = 10; - const int size = width()-(padding*2); - - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - //draw an arc from -45 degrees to 225 degrees - painter.setPen(QPen(Qt::black, 10)); - painter.setBrush(Qt::NoBrush); - drawContaRotacoes(painter, size, padding); - drawRotacoesText(painter, size, padding); + //remove the warning for unused *event + (void)event; + + //padding of the line + const int padding = 10; + const int size = width()-(padding*2); + ; + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + const auto group = QPalette::Active; + const auto role = QPalette::Text; + + + auto palette=this->palette(); + + /*Get Brush */ + painter.setPen(QPen(palette.color(group, role),25)); + + + painter.setBrush(Qt::NoBrush); + drawContaRotacoes(painter, size, padding); + drawRotacoesText(painter, size, padding); } void ContaRotacoes::handleChangedValue(int newValue, int oldValue){ + //remove unused warning + (void)oldValue; // value< m_maxValue || this should be in the if for better data quality but in case of a ill fate, it might be interesting to see the values - if( newValue >= 0){ + if( newValue >= 0){ this->m_value = newValue; this->update(); } @@ -38,39 +62,43 @@ void ContaRotacoes::handleChangedValue(int newValue, int oldValue){ void ContaRotacoes::drawContaRotacoes(QPainter &painter, int size, int padding=10){ //normal matrix - painter.resetTransform(); + painter.resetTransform(); //minimum whipper of the arc - //const int minPhi = -45*16; - const int minPhi = -720; - //maximum whipper of the arc - //const int maxPhi = 270*16; - const int maxPhi = 4320; - double ratio = ((double)m_value)/((double)m_maxValue); - - int currentPhi =((int)((double)(ratio)*(maxPhi-minPhi))); - - painter.translate(size,0); - painter.scale(-1.0, 1.0); - //due to the mirrowing of the arc padding is weird - painter.drawArc(-padding,height()/3, size, size, minPhi, maxPhi); - painter.setPen(QPen(Qt::red, 4)); - painter.drawArc(-padding, height()/3, size, size,minPhi, currentPhi); + //const int minPhi = -45*16; + const int minPhi = -720; + //maximum whipper of the arc + //const int maxPhi = 270*16; + const int maxPhi = 4320; + + + painter.translate(size,0); + painter.scale(-1.0, 1.0); + //due to the mirrowing of the arc padding is weird + painter.drawArc(-padding, height()/3, size, size, minPhi, maxPhi); + QColor pen = getGraphicColorWhipper(); + painter.setPen(QPen(pen, 20)); + painter.drawArc(-padding, height()/3, size, size,minPhi, getPositionFromVariationSlope()); } void ContaRotacoes::drawRotacoesText(QPainter &painter, int size, int padding=10){ //normal matrix - painter.resetTransform(); + painter.resetTransform(); + const auto group = QPalette::Active; + const auto role = QPalette::Text; - //draw the text - painter.setPen(QPen(Qt::black, 3)); - - //make the font size scale with the width of the widget - auto fontSize= width()/padding; - QFont font = painter.font(); + auto palette=this->palette(); + + //draw the text + painter.setPen(QPen(palette.color(group, role), 3)); + + //make the font size scale with the width of the widget + auto fontSize= width()/padding; - font.setPointSizeF(fontSize); - painter.setFont(font); - painter.drawText(QRect(padding,height()/6,size,fontSize), Qt::AlignCenter, QString::number(m_value)); + QFont font = painter.font(); + + font.setPointSizeF(fontSize); + painter.setFont(font); + painter.drawText(QRect(padding,height()/6,size,fontSize), Qt::AlignCenter, QString::number(m_value)); } int ContaRotacoes::getValue () const{ @@ -79,3 +107,21 @@ int ContaRotacoes::getValue () const{ int ContaRotacoes::getMaxValue () const{ return m_maxValue; } +QColor ContaRotacoes::getGraphicColorWhipper(){ + //TODO EXAMPLE CODE THIS IS SUPPOSED TO BE UNDER SUPERVISION + int red=std::floor(255* (1-(m_value/m_maxValue))); + int blue=std::floor(255*m_value/m_maxValue); + return QColor(red,0,blue); +} +int ContaRotacoes::getPositionFromVariationSlope(){ + //minimum whipper of the arc + //const int minPhi = -45*16; + const int minPhi = -720; + //maximum whipper of the arc + //const int maxPhi = 270*16; + const int maxPhi = 4320; + //TODO EXAMPLE CODE THIS IS SUPPOSED TO BE UNDER SUPERVISION + double ratio = ((double)m_value)/((double)m_maxValue); + int currentPhi =((int)((double)(ratio)*(maxPhi-minPhi))); + return currentPhi; +} diff --git a/src/contarotacoes.h b/src/contarotacoes.h index 54e8a34..7c899fd 100644 --- a/src/contarotacoes.h +++ b/src/contarotacoes.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "mainwindow.h" #define MAX_ROTATIONS_DEFAULT 20000 @@ -13,16 +14,22 @@ class ContaRotacoes : public QWidget Q_OBJECT public: explicit ContaRotacoes( QWidget *parent = nullptr); + ~ContaRotacoes(); int getValue () const; int getMaxValue () const; + //QTColor + virtual QColor getGraphicColorWhipper(); + virtual int getPositionFromVariationSlope(); protected: void paintEvent(QPaintEvent *event) override; - + int m_maxValue=MAX_ROTATIONS_DEFAULT; + int m_value; + private: void drawContaRotacoes(QPainter &painter, int size, int padding); void drawRotacoesText(QPainter &painter, int size, int padding); - int m_maxValue=MAX_ROTATIONS_DEFAULT; - int m_value; + + public slots: void handleChangedValue (int newValue, int oldValue); diff --git a/src/flabel.cpp b/src/flabel.cpp new file mode 100644 index 0000000..68a94f1 --- /dev/null +++ b/src/flabel.cpp @@ -0,0 +1,15 @@ +#include "flabel.h" + +FLabel::FLabel(QWidget *parent) : QLabel(parent){ + +} + +void FLabel::setVisual(int newValue, int oldValue){ + this->setText(QString::number(newValue)); +} +void FLabel::setVisual(float newValue, float oldValue){ + this->setText(QString::number(newValue)); +} +void FLabel::setVisual(QString newValue, QString oldValue){ + this->setText(newValue); +} diff --git a/src/flabel.h b/src/flabel.h new file mode 100644 index 0000000..b6d0aa8 --- /dev/null +++ b/src/flabel.h @@ -0,0 +1,19 @@ +#ifndef FLABEL_H +#define FLABEL_H +#include +#include +#include +#include +#include "store.h" + +class FLabel : public QLabel{ + Q_OBJECT; + public: + explicit FLabel(QWidget *parent = nullptr); + public slots: + void setVisual(int newValue, int oldValue); + void setVisual(float newValue, float oldValue); + void setVisual(QString newValue, QString oldValue); + +}; +#endif // FLABEL_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b875166..dd359c3 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3,18 +3,42 @@ #include "./store.h" #include #include +#include "flabel.h" static store* store_ref; -MainWindow::MainWindow(QWidget *parent) +MainWindow::MainWindow(QWidget *parent, QString serialDev) : QMainWindow(parent) , ui(new Ui::MainWindow){ - store_ref = new store(); - ui->setupUi(this); + store_ref = new store(serialDev); + ui->setupUi(this); + //store_ref->setParent(this); + //store_ref->requestSlotAttachment(); + FLabel* EngineTemperature_Label= this->findChild("EngineTemperature_Label"); + FLabel* OilPressure_Label = this->findChild("OilPressure_Label"); + FLabel* OilTemperature_Label = this->findChild("OilTemperature_Label"); + FLabel* BatteryVoltage_Label = this->findChild("BatteryVoltage_Label"); + FLabel* VehicleSpeed_Label = this->findChild("VehicleSpeed_Label"); + FLabel* DataLogger_Label = this->findChild("DataLogger_Label"); + FLabel* Lambda_Label = this->findChild("Lambda_Label"); + FLabel* TcSlip_Label = this->findChild("TcSlip_Label"); + FLabel* TcLaunch_Label = this->findChild("TcLaunch_Label"); + + + connect(store_ref, &store::engineTemperatureChanged, EngineTemperature_Label, (void (FLabel::*)(int, int))&FLabel::setVisual); + connect(store_ref, &store::oilPressureChanged, OilPressure_Label, (void (FLabel::*)(float, float))&FLabel::setVisual); + connect(store_ref, &store::oilTemperatureChanged, OilTemperature_Label, (void (FLabel::*)(float, float))&FLabel::setVisual); + connect(store_ref, &store::batteryVoltageChanged, BatteryVoltage_Label, (void (FLabel::*)(float, float))&FLabel::setVisual); + connect(store_ref, &store::vehicleSpeedChanged, VehicleSpeed_Label, (void (FLabel::*)(int, int))&FLabel::setVisual); + connect(store_ref, &store::dataLoggerChanged, DataLogger_Label, (void (FLabel::*)(int, int))&FLabel::setVisual); + connect(store_ref, &store::lambdaChanged, Lambda_Label, (void (FLabel::*)(float, float))&FLabel::setVisual); + connect(store_ref, &store::tcSlipChanged, TcSlip_Label, (void (FLabel::*)(int, int))&FLabel::setVisual); + connect(store_ref, &store::tcLaunchChanged, TcLaunch_Label, (void (FLabel::*)(int, int))&FLabel::setVisual); } + //with great power comes great *frickery... This function is by reference and should be used for startup stuff store* MainWindow::getStore(){ return store_ref; diff --git a/src/mainwindow.h b/src/mainwindow.h index dcb2b55..8bbb3f5 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -13,7 +13,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); + MainWindow(QWidget *parent = nullptr, QString serialDev=nullptr); store* getStore(); ~MainWindow(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 1d88fc6..ba1cedf 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -16,6 +16,454 @@ 1 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + + + Source Code Pro + 12 + + VolanteAlpha @@ -34,21 +482,138 @@ - + - - - - 0 - 0 - - - - TextLabel - - + + + + + Oil Pressure + + + + + + + __0__ + + + + + + + Oil Temperature + + + + + + + __0__ + + + + + + + Engine Temperature + + + + + + + __0__ + + + + + + + Battery Voltage + + + + + + + __0__ + + + + + + + DataLogger Status + + + + + + + __OFF(DEFAULT)__ + + + + + + + Vehicle Speed: + + + + + + + __0__ + + + + + + + Lambda Mixture: + + + + + + + __0.0__ + + + + + + + Tc Slip: + + + + + + + __0__ + + + + + + + TC Launch: + + + + + + + __0__ + + + + @@ -73,7 +638,7 @@ 30 - + 0 @@ -87,23 +652,6 @@ - - - - - - - 0 - 0 - - - - TextLabel - - - - - @@ -114,7 +662,7 @@ 0 0 670 - 22 + 26 @@ -122,11 +670,16 @@ - ContaRotacoes + ContaMudancas QWidget -
src/contarotacoes.h
+
src/contamudancas.h
1
+ + FLabel + QLabel +
src/flabel.h
+
diff --git a/src/references/bson_var.h b/src/references/bson_var.h new file mode 100644 index 0000000..5530a0f --- /dev/null +++ b/src/references/bson_var.h @@ -0,0 +1,16 @@ +#ifndef BSON_VAR_H +#define BSON_VAR_H +//T_14 +#define BSON_RPM "rpm" +#define BSON_GEARSHIFT "gear" +#define BSON_ENGINETEMPERATURE "eng_t" +#define BSON_OILPRESSURE "oil_p" +#define BSON_OILTEMPERATURE "oil_t" +#define BSON_BATTERYVOLTAGE "bat_v" +#define BSON_VEHICLESPEED "vel" +#define BSON_DATALOGGERSTATUS "dtl_s" +#define BSON_AFR "af_r" +#define BSON_TCSLIP "tc_s" +#define BSON_TCLAUNCH "tc_l" + +#endif // BSON_VAR_H diff --git a/src/references/system_var.h b/src/references/system_var.h new file mode 100644 index 0000000..83f97c6 --- /dev/null +++ b/src/references/system_var.h @@ -0,0 +1 @@ +#define __LART_NULL_DEVICE_DESCRIPTOR__ "/dev/null" \ No newline at end of file diff --git a/src/store.cpp b/src/store.cpp index 5f3a810..e25936a 100644 --- a/src/store.cpp +++ b/src/store.cpp @@ -1,40 +1,128 @@ #include "store.h" -#include - +#include "mainwindow.h" +#include "references/bson_var.h" +#include "flabel.h" +#define __LART_T14__ using json = nlohmann::json; int store::setupSerial() { - QSerialPort* serial= new QSerialPort(); - serial->setPortName(this->dev); - serial->setBaudRate(QSerialPort::Baud115200); - serial->setDataBits(QSerialPort::Data8); - serial->setStopBits(QSerialPort::OneStop); - serial->setParity(QSerialPort::NoParity); - serial->setFlowControl(QSerialPort::NoFlowControl); - if (!serial->open(QIODevice::ReadWrite)) { + QSerialPort* serial= new QSerialPort(); + serial->setPortName(this->dev); + serial->setBaudRate(this->baud); + serial->setDataBits(QSerialPort::Data8); + serial->setStopBits(QSerialPort::OneStop); + serial->setParity(QSerialPort::OddParity); + serial->setFlowControl(QSerialPort::NoFlowControl); + if (!serial->open(QIODevice::ReadWrite)) { qDebug() << "Can't open " << this->dev << ", error code" << serial->error(); - return 1; - } + serialLog.append("||Can't open " + this->dev + ", error code" + serial->errorString()+"||"); + return 1; + } - this->port = serial; - connect(this->port, &QSerialPort::readyRead, this, &store::handleReadyRead); - connect(this->port, &QSerialPort::errorOccurred, this, &store::handleError); + this->port = serial; + //clear garbage + this->port->flush(); + connect(this->port, &QSerialPort::readyRead, this, &store::handleReadyRead); + connect(this->port, &QSerialPort::errorOccurred, this, &store::handleError); return 0; } +//MUST REVIEW!! this probs is overcomplicated and im too tired+(my code effect) +int store::startGeneralErrorLog(uint depth){ + //check if file is not null + if(!errorLog.exists()){ + //get todays date and time and use it as a filename + QDateTime now = QDateTime::currentDateTime(); + QString dateStr = now.toString("hhmmss_dd-MM-yyyy"); + dateStr = "errorLog_"+dateStr+".log"; + errorLog.setFileName(dateStr); + + if(errorLog.open(QIODevice::WriteOnly|QIODevice::Unbuffered)){ + return 1; + } + return 0; + } + try { + if(!errorLog.isOpen()){ + scribeError("Apparently the error log was closed, yet the pointer was not set to nullptr.", error_severity::MAJOR); + if(depth>0){ + //... Qcreator kept saying me this was possible... + scribeError("Something is really wrong, the depth is too big, and memory seems insane", error_severity::CRITICAL); + } + return startGeneralErrorLog(++depth); + }else{ + scribeError("A request to open error log was made yet the file was already opened, Avoid multiple calls to startGeneralErrorLog", error_severity::WARNING); + + } + } catch (...) { + //TODO handle exception graphically + qDebug() << "An exception occurred while trying to open the error log"; + return 1; //TODO return a more meaningful error code + } + return 0; +} + +void store::stopGeneralErrorLog(){ + try { + if(!errorLog.isOpen()){ + throw "The error log was already closed"; + + } + errorLog.close(); + } catch (...) { + //TODO handle exception graphically + qDebug() << "An exception occurred while trying to close the error log"; + } +} +qint64 store::scribeError(QString error, error_severity severity){ + qint64 ret = 0; + //check if error is initialized if not + if(error==nullptr){ + error = "An error occurred but no error message was provided"; + } -store::store( QString dev, QObject *parent ): QObject(parent){ + try{ + if(!errorLog.isOpen()){ + startGeneralErrorLog(); + } + + //append a timestamp to the error and write it to the file + QDateTime now = QDateTime::currentDateTime(); + QString dateStr = now.toString("hh:mm:ss dd-MM-yyyy"); + error.prepend(dateStr + " |" + QString::number(severity) + "|*_"); + + ret= errorLog.write(error.toUtf8()+"|EOL|\n"); + if (severity>=error_severity::CRITICAL){ + //TODO handle exception graphically + + //freeze the program for 3 secs + this->thread()->msleep(3000); + + //its pretty much garanteed but just in case + assert(severity>=error_severity::CRITICAL); + } + }catch(...){ + //TODO handle exception graphically + qDebug() << "An exception occurred while trying to write to the error log"; + } + + return ret; +} +store::store( QString dev, QSerialPort::BaudRate baud, QObject *parent): QObject(parent){ + this->baud = baud; //if Qstring dev is empty, use default device if(dev.isEmpty()){ this->dev = DEFAULT_DEVICE; }else{ this->dev = dev; } - setupSerial(); - + //int8_t retries = LOG_MAX_RETRIES; + //wtf? TODO: retry system + startGeneralErrorLog(); } + void store::forceRead(qint64 len){ while (port->bytesAvailable() < len) { if (!port->waitForReadyRead(1000)) { @@ -46,18 +134,17 @@ void store::forceRead(qint64 len){ } port->read(bufferMessage.data(), len); } -//destructor for store void store::handleReadyRead(){ bufferMessage=port->readAll(); serialLog.append(bufferMessage); - //can be optimized using pointers or even a variable as a "bookmark" wether a int or pointer - lastMessage.append(bufferMessage); + //can be optimized using pointers or even a variable as a "bookmark" wether a int or pointer + lastMessage.append(bufferMessage); //regex BSON_WARNING value in bufferMessage if its found set markerBSON_WARNING to the first character after BSON_WARNING - QString* temp = new QString(lastMessage); - if(temp->contains(BSON_WARNING)){ + + if(lastMessage.contains(BSON_WARNING)){ bsonMining(); } @@ -77,7 +164,7 @@ void store::bsonMining(){ int length = shrinked[0] | shrinked[1] << 8| shrinked[2] <<16| shrinked[3]<<24; if(shrinked.size() < length){ - qDebug() << "BSON WARNING FOUND BUT NOT ENOUGH BYTES"; + //qDebug() << "BSON WARNING FOUND BUT NOT ENOUGH BYTES"; return; } @@ -90,15 +177,27 @@ void store::bsonMining(){ return bsonMining(); } store::~store(){ - //print to a file serial log - //close serial port - QFile file("serialLog.txt"); - if (file.open(QIODevice::WriteOnly)) { - file.write(serialLog); - file.close(); - } + //make shure all slots are disconnected + + this->disconnect(); + try{ + closeSerial(); + QDateTime now = QDateTime::currentDateTime(); + QString dateStr = now.toString("hhmmss_dd-MM-yyyy"); + dateStr.append("serialLog.txt"); + QFile file(dateStr); + if (file.open(QIODevice::WriteOnly)) { + file.write(serialLog); + file.close(); + }else{ + scribeError("Failed to write serial log to file", error_severity::MAJOR); + } - closeSerial(); + stopGeneralErrorLog(); + }catch(...){ + qDebug() << "Failed to destroy store"; + } + } void store::handleError(QSerialPort::SerialPortError serialPortError) @@ -113,17 +212,52 @@ void store::handleError(QSerialPort::SerialPortError serialPortError) } } void store::parseBson(std::vector v){ - qDebug()<< "Parsing Incoming BSON"; try { - - json j = json::from_bson(v); - //read element "rpm" - if(j.contains("rpm")){ - - this->setRpm(j["rpm"]); - qDebug() << "RPM: " << this->getRpm(); + //TODO this is ugly + + if(j.contains(BSON_RPM)){ + this->setRpm(j[BSON_RPM]); + } + if(j.contains(BSON_GEARSHIFT)){ + this->setGearShift(j[BSON_GEARSHIFT]); + } + if(j.contains(BSON_ENGINETEMPERATURE)){ + this->setEngineTemperature(j[BSON_ENGINETEMPERATURE]); + } + if(j.contains(BSON_OILPRESSURE)){ + EncodingUnion t; + t.encoded=j[BSON_OILPRESSURE]; + this->setOilPressure(t.decoded); + } + if(j.contains(BSON_OILTEMPERATURE)){ + EncodingUnion t; + t.encoded=j[BSON_OILTEMPERATURE]; + this->setOilTemperature(t.decoded); + } + if(j.contains(BSON_BATTERYVOLTAGE)){ + EncodingUnion t; + t.encoded=j[BSON_BATTERYVOLTAGE]; + this->setBatteryVoltage(t.decoded); + } + if(j.contains(BSON_VEHICLESPEED)){ + this->setVehicleSpeed(j[BSON_VEHICLESPEED]); + } + if(j.contains(BSON_DATALOGGERSTATUS)){ + this->setDataLoggerStatus(j[BSON_DATALOGGERSTATUS]); + } + if(j.contains(BSON_AFR)){ + EncodingUnion t; + t.encoded=j[BSON_AFR]; + this->setLambda(t.decoded); + } + if(j.contains(BSON_TCSLIP)){ + this->setTcSlip(j[BSON_TCSLIP]); + } + if(j.contains(BSON_TCLAUNCH)){ + this->setTcLaunch(j[BSON_TCLAUNCH]); } + } catch (json::parse_error& e) { qDebug() << "parse error at byte " << e.byte << "\n"; qDebug() << "message: " << v << "\n"; @@ -138,9 +272,16 @@ void store::parseBson(std::vector v){ int store::closeSerial(){ // TODO: Error handling? - int i =0; - port->close(); - return i; + try { + if(port->isOpen()){ + port->close(); + } + }catch(...){ + qDebug()<< "Couldnt close the serial port"; + return 1; + + } + return 0; } //getters and setters int store::getRpm() const{ @@ -156,7 +297,7 @@ int store::getEngineTemperature() const{ float store::getOilPressure() const{ return this->m_oilPressure; } -int store::getOilTemperature() const{ +float store::getOilTemperature() const{ return this->m_oilTemperature; } float store::getBatteryVoltage() const{ @@ -179,43 +320,84 @@ int store::getTcLaunch() const{ return this->m_tractionLaunch; } void store::setRpm(int rpm){ - if(rpm>=0&& rpm !=this->m_rotationsPerMinute){ - int oldRpm=this->m_rotationsPerMinute; - this->m_rotationsPerMinute=rpm; - emit rpmChanged(this->m_rotationsPerMinute, oldRpm); - } + if(rpm>=0){ + if(rpm !=this->m_rotationsPerMinute){ + int oldRpm=this->m_rotationsPerMinute; + this->m_rotationsPerMinute=rpm; + emit rpmChanged(this->m_rotationsPerMinute, oldRpm); + } + }else{ + this->scribeError(__LART_STORE_SETRPM_ERROR__, store::error_severity::MINOR); + } } void store::setGearShift(int gearShift){ - if(gearShift>=0){ - this->m_gearShift=gearShift; + qDebug() << "setGearShift"; + if(gearShift>=0&&gearShift<=6){ + if(gearShift !=this->m_gearShift){ + int oldGearShift=this->m_gearShift; + this->m_gearShift=gearShift; + emit gearShiftChanged(this->m_gearShift, oldGearShift); + } + }else{ + this->scribeError(__LART_STORE_SETGEARSHIFT_ERROR__, store::error_severity::MINOR); } } void store::setEngineTemperature(int engineTemperature){ + qDebug() << "setEngineTemperature"; + int oldEngineTemperature = this->m_engineTemperature; this->m_engineTemperature=engineTemperature; + emit engineTemperatureChanged(this->m_engineTemperature, oldEngineTemperature); } void store::setOilPressure(float oilPressure){ + float oldOilPressure = this->m_oilPressure; this->m_oilPressure=oilPressure; + emit oilPressureChanged(this->m_oilPressure, oldOilPressure); } -void store::setOilTemperature(int oilTemperature){ +void store::setOilTemperature(float oilTemperature){ + float oldOilTemperature = this->m_oilTemperature; this->m_oilTemperature=oilTemperature; + emit oilTemperatureChanged(this->m_oilTemperature, oldOilTemperature); } void store::setBatteryVoltage(float batteryVoltage){ + float oldBatteryVoltage = this->m_batteryVoltage; this->m_batteryVoltage=batteryVoltage; + emit batteryVoltageChanged(this->m_batteryVoltage, oldBatteryVoltage); } void store::setVehicleSpeed(int vehicleVelocity){ + int oldVehicleVelocity = this->m_vehicleVelocity; this->m_vehicleVelocity=vehicleVelocity; + emit vehicleSpeedChanged(this->m_vehicleVelocity, oldVehicleVelocity); } void store::setDataLoggerStatus(int dataLoggerStatus){ + int oldDataLoggerStatus = this->m_dataLoggerStatus; this->m_dataLoggerStatus=dataLoggerStatus; + emit dataLoggerChanged(this->m_dataLoggerStatus, oldDataLoggerStatus); } void store::setLambda(float lambda){ + float oldLambda = this->m_lambdaMixtureAirFuel; this->m_lambdaMixtureAirFuel=lambda; + emit lambdaChanged(this->m_lambdaMixtureAirFuel, oldLambda); + } void store::setTcSlip(int tcSlip){ + int oldTcSlip = this->m_tractionSlip; this->m_tractionSlip=tcSlip; + emit tcSlipChanged(this->m_tractionSlip, oldTcSlip); } void store::setTcLaunch(int tcLaunch){ + int oldTcLaunch = this->m_tractionLaunch; this->m_tractionLaunch=tcLaunch; + emit tcLaunchChanged(this->m_tractionLaunch, oldTcLaunch); +} + +void store::setBaudRate(QSerialPort::BaudRate baud){ + + this->baud=baud; + this->port->setBaudRate(baud); + +} +QSerialPort::BaudRate store::getBaudRate() const{ + return baud; } diff --git a/src/store.h b/src/store.h index 994eb48..302033d 100644 --- a/src/store.h +++ b/src/store.h @@ -9,19 +9,46 @@ #include #include #include -#include #include -#include -#include #include #include +#include +#include #include #include -#include +#include +#include + +#include +#include +#include +#include +//QVBoxLayout +#include #include +#include "references/bson_var.h" +#if !defined __arm__ || !defined __aarch64__ + #ifdef _WIN32 + #define DEFAULT_DEVICE "COM3" + #elif defined __linux__ + #ifdef __LART_DEPLOY__ + #define DEFAULT_DEVICE "/dev/ttyS0" + #else + #define DEFAULT_DEVICE "/dev/ttyACM0" + #endif + #endif +#else + #define DEFAULT_DEVICE "/dev/ttyS0" +#endif + +typedef union { + float decoded; + int32_t encoded; +} EncodingUnion; + -#define DEFAULT_DEVICE "/dev/ttyACM0" #define BSON_WARNING "\xFF\xFF\xFF\xFF" +#define LOG_MAX_RETRIES 4 #define BSON_SKIP_BYTES 9 /* ! \class store @@ -36,7 +63,17 @@ class store: public QObject{ Q_OBJECT; Q_PROPERTY(int m_rotationsPerMinute READ getRpm WRITE setRpm NOTIFY rpmChanged); + + + public: + enum error_severity { + INFO=0, + WARNING=1, + MINOR=2, + MAJOR=3, + CRITICAL=100 + }; QString dev; QSerialPort* port=nullptr; void handleReadyRead(); @@ -47,18 +84,22 @@ class store: public QObject{ QByteArray lastMessage; QByteArray bufferMessage; char * markerBSON_WARNING=nullptr; - + void parseBson(std::vector v); - void bsonMining(); - explicit store(QString dev="", QObject *parent = nullptr); + void bsonMining(); + int requestSlotAttachment(); + qint64 scribeError(QString error, error_severity severity=error_severity::INFO); + explicit store(QString dev="", QSerialPort::BaudRate baud = QSerialPort::Baud115200, QObject *parent = nullptr); ~store(); //getters and setters + QSerialPort::BaudRate getBaudRate() const; + int getRpm() const; int getGearShift() const; int getEngineTemperature() const; float getOilPressure() const; - int getOilTemperature() const; + float getOilTemperature() const; float getBatteryVoltage() const; int getVehicleSpeed() const; int getDataLoggerStatus() const; @@ -67,35 +108,59 @@ class store: public QObject{ int getTcLaunch() const; void setRpm(int rpm); void setGearShift(int gearShift); - void setEngineTemperature(int engineTemperature); + void setEngineTemperature(int engineTemperature); void setOilPressure(float oilPressure); - void setOilTemperature(int oilTemperature); + void setOilTemperature(float oilTemperature); void setBatteryVoltage(float batteryVoltage); void setVehicleSpeed(int vehicleVelocity); void setDataLoggerStatus(int dataLoggerStatus); void setLambda(float lambda); void setTcSlip(int tcSlip); void setTcLaunch(int tcLaunch); + + void setBaudRate(QSerialPort::BaudRate baud); + protected: - int setupSerial(); + int startGeneralErrorLog(uint depth=0); + void stopGeneralErrorLog(); + int setupSerial(); + // bool setSlots=false; + // int setupSlots(); int closeSerial(); + signals: void rpmChanged(int newRpm, int oldRpm); + void gearShiftChanged(int newGearShift, int oldGearShift); + void engineTemperatureChanged(int newEngineTemperature, int oldEngineTemperature); + void oilTemperatureChanged(float newOilTemperature, float oldOilTemperature); + void oilPressureChanged(float newOilPressure, float oldOilPressure); + void batteryVoltageChanged(float newBatteryVoltage, float oldBatteryVoltage); + void vehicleSpeedChanged(int newVehicleSpeed, int oldVehicleSpeed); + void dataLoggerChanged(int newDataLogger, int oldDataLogger); + void lambdaChanged(float newLambda, float oldLambda); + void tcSlipChanged(int newTCSlip, int oldTCSlip); + void tcLaunchChanged(int newTcLaunch, int oldTcLaunch); + private: - int m_rotationsPerMinute; - int m_gearShift; - int m_engineTemperature; - float m_oilPressure; - float m_oilTemperature; - float m_batteryVoltage; - int m_vehicleVelocity; - int m_dataLoggerStatus; - //todo ask stuff about this - float m_lambdaMixtureAirFuel; - int m_tractionSlip; - int m_tractionLaunch; + QSerialPort::BaudRate baud; + QFile errorLog; + int m_rotationsPerMinute=0; + int m_gearShift=0; + int m_engineTemperature=0; + float m_oilPressure=0; + float m_oilTemperature=0; + float m_batteryVoltage=0; + int m_vehicleVelocity=0; + int m_dataLoggerStatus=0; + float m_lambdaMixtureAirFuel=0; + int m_tractionSlip=0; + int m_tractionLaunch=0; + }; +// Logging Macros +#define __LART_STORE_SETRPM_ERROR__ "store::setRpm(int rpm)->Rpm is negative" +#define __LART_STORE_SETGEARSHIFT_ERROR__ "store::setGearShift(int gearShift)->GearShift is out of bounds" #endif // STORE_H diff --git a/test/args.ggo b/test/args.ggo new file mode 100755 index 0000000..f0c453b --- /dev/null +++ b/test/args.ggo @@ -0,0 +1,7 @@ +package "VolanteAlphaQT_test" +version "1.0" +purpose "To provide a binary capable of unit testing the VolanteAlphaQT package" +description "A unit testing software for the VolanteAlphaQT package, used for LART project" +versiontext "A0.0.1T" + +option "singlesuite" s "only launches the provided suite" string optional diff --git a/test/aux.cpp b/test/aux.cpp new file mode 100644 index 0000000..ae5b2ac --- /dev/null +++ b/test/aux.cpp @@ -0,0 +1,12 @@ + +#include "aux.h" + +AuxSingleton& AuxSingleton::getInstance() { + static AuxSingleton instance; + return instance; +} + +int AuxSingleton::randomInt(int offset=0, int n=255){ + QRandomGenerator a = QRandomGenerator::securelySeeded(); + return a.bounded(n)+offset; +} \ No newline at end of file diff --git a/test/aux.h b/test/aux.h new file mode 100644 index 0000000..57dc3f8 --- /dev/null +++ b/test/aux.h @@ -0,0 +1,17 @@ +#ifndef AUX_H +#define AUX_H +#include +#include +#include +#include +class AuxSingleton{ + public: + static AuxSingleton& getInstance(); + int randomInt(int offset=0, int n=255); + AuxSingleton(const AuxSingleton&) = delete; + AuxSingleton& operator=(const AuxSingleton&) = delete; + + private: + AuxSingleton() = default; +}; +#endif // AUX_H diff --git a/test/main.cpp b/test/main.cpp new file mode 100644 index 0000000..991ffbb --- /dev/null +++ b/test/main.cpp @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include "args.h" +//write me a macro that includes all .h files in the test folder +#include "tst_flabels.h" +#include "tst_serialport.h" +#include "tst_contarotacoes.h" +#include "tst_contamudancas.h" + +typedef struct{ + uint32_t id; + QString name; + QObject* test; + +}suite; + +suite fullsuite [] = { + {0,QString("SerialPort"),new Tst_serialport}, + {1,QString("ContaRotacoes"),new Tst_contarotacoes}, + {2,QString("ContaMudancas"), new Tst_contamudancas}, + {3,QString("FLabels"), new Tst_flabels} +}; +int main(int argc, char *argv[]){ + + QApplication app(argc, argv); + //frick Qparser + struct gengetopt_args_info args; + if (cmdline_parser(argc, argv, &args)!= 0 ){ + qDebug() << "Error parsing command line arguments"; + return 1; + } + + + + int status = 0; + for(int i = 0; i < (int)(sizeof(fullsuite)/sizeof(suite)); i++){ + status |= QTest::qExec(fullsuite[i].test, argc, argv); + } + + cmdline_parser_free(&args); + return status; + +} + diff --git a/test/tst_contamudancas.cpp b/test/tst_contamudancas.cpp new file mode 100644 index 0000000..d432907 --- /dev/null +++ b/test/tst_contamudancas.cpp @@ -0,0 +1,86 @@ +#include "tst_contamudancas.h" + + +/*void Tst_contamudancas::checkRpmChangesFromStoreToGraphicText(){ + //TODO find a way to solve bellow apparently it crashes violently with a permission dennied in this context + QProcess socat; + socat.startDetached("socat pty,raw,echo=0,b115200,link=/tmp/banana, pty,raw,echo=0,b115200,link=/tmp/tango"); + MainWindow ui= MainWindow(nullptr,"/tmp/banana"); + + //ui.add a widget contarotacoes with name _test + ContaMudancas _test = ContaMudancas(&ui); + _test.setObjectName("_test"); + + auto s = ui.getStore(); + s->setRpm(100); + int a = ui.findChild("_test")->getValue(); + socat.kill(); + + QCOMPARE(a, 100); +}*/ +void Tst_contamudancas::checkMudancaChangesFromStore(){ + //TODO find a way to solve bellow apparently it crashes violently with a permission dennied in this context + QProcess socat; + socat.startDetached(program, args); + MainWindow ui= MainWindow(nullptr,"/tmp/banana"); + + //ui.add a widget contarotacoes with name _test + ContaMudancas _test = ContaMudancas(&ui); + _test.setObjectName("_test"); + + auto s = ui.getStore(); + s->setGearShift(1); + int a = ui.findChild("_test")->getVisibleMudanca(); + socat.kill(); + QCOMPARE(a, 1); +} + +void Tst_contamudancas::checkGearShiftEncoding(){ + //TODO find a way to solve bellow apparently it crashes violently with a permission dennied in this context + QProcess socat; + socat.startDetached(program, args); + MainWindow ui= MainWindow(nullptr,"/tmp/banana"); + + ContaMudancas _test = ContaMudancas(&ui); + + QCOMPARE(_test.getGraphicalTextMudanca(0), QString("N")); + for(int i = 1; i < 6; i++){ + QCOMPARE(_test.getGraphicalTextMudanca(i),QString::number(i)); + } + socat.kill(); + +} + +void Tst_contamudancas::checkRPMErrorLogging(){ + QProcess socat; + socat.startDetached(program, args); + MainWindow ui= MainWindow(nullptr,"/tmp/banana"); + + QDir dir = QDir::currentPath(); + dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); + dir.setSorting(QDir::Time); + QFileInfoList list = dir.entryInfoList(); + QFile file(list.first().absoluteFilePath()); + file.open(QIODevice::ReadOnly); + file.seek(file.size()); + QTextStream in(&file); + ui.getStore()->setGearShift(-1); + //read the last line + QString line = in.readLine(); + ui.getStore()->setGearShift(7); + //read the last line + QString line2 = in.readLine(); + + //open the most recent file in the folder + socat.kill(); + //read the last line + + + + + QVERIFY(line.contains(__LART_STORE_SETGEARSHIFT_ERROR__)); + QVERIFY(line2.contains(__LART_STORE_SETGEARSHIFT_ERROR__)); + + +} + diff --git a/test/tst_contamudancas.h b/test/tst_contamudancas.h new file mode 100644 index 0000000..a2d2a31 --- /dev/null +++ b/test/tst_contamudancas.h @@ -0,0 +1,23 @@ +#ifndef TST_CONTAMUDANCAS_H +#define TST_CONTAMUDANCAS_H + +#include +#include +#include +#include +#include "tst_contarotacoes.h" +#include "../src/contamudancas.h" +#include "../src/store.h" +#include "../src/mainwindow.h" +class Tst_contamudancas : public Tst_contarotacoes +{ + Q_OBJECT + private slots: + //void checkRpmChangesFromStoreToGraphicText(); + void checkMudancaChangesFromStore(); + void checkGearShiftEncoding(); + void checkRPMErrorLogging(); + +}; + +#endif // TST_CONTAMUDANCAS_H diff --git a/test/tst_contarotacoes.cpp b/test/tst_contarotacoes.cpp index 864154e..fb9e594 100644 --- a/test/tst_contarotacoes.cpp +++ b/test/tst_contarotacoes.cpp @@ -1,13 +1,59 @@ #include "tst_contarotacoes.h" +#include "qcoreapplication.h" + +void Tst_contarotacoes::setupTest(){ + program="socat"; + args = QStringList(); + + args.append("pty,raw,echo=0,b115200,link=/tmp/banana,"); + args.append("pty,raw,echo=0,b115200,link=/tmp/tango"); +} void Tst_contarotacoes::checkRpmChangesFromStoreToGraphicText(){ - MainWindow ui; + //TODO find a way to solve bellow apparently it crashes violently with a permission dennied in this context + QProcess socat; + + socat.startDetached(program, args); + MainWindow ui= MainWindow(nullptr,"/tmp/banana"); + + //ui.add a widget contarotacoes with name _test + ContaRotacoes _test = ContaRotacoes(&ui); + _test.setObjectName("_test"); + + auto s = ui.getStore(); s->setRpm(100); - int a = ui.findChild("contarotacoes")->getValue(); + int a = ui.findChild("_test")->getValue(); + socat.kill(); + QCOMPARE(a, 100); } -//QTEST_MAIN(Tst_contarotacoes) +void Tst_contarotacoes::checkRotationErrorLogging(){ + QProcess socat; + socat.startDetached(program, args); + MainWindow ui= MainWindow(nullptr,"/tmp/banana"); + + + + //open the most recent file in the folder + QDir dir = QDir::currentPath(); + dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); + dir.setSorting(QDir::Time); + QFileInfoList list = dir.entryInfoList(); + QFile file(list.first().absoluteFilePath()); + file.open(QIODevice::ReadOnly); + file.seek(file.size()); + + QTextStream in(&file); + ui.getStore()->setRpm(-1); + QString line = in.readLine(); + socat.kill(); + file.close(); + QVERIFY(line.contains(__LART_STORE_SETRPM_ERROR__)); + + + +} diff --git a/test/tst_contarotacoes.h b/test/tst_contarotacoes.h index 5c2b349..bbc95a6 100644 --- a/test/tst_contarotacoes.h +++ b/test/tst_contarotacoes.h @@ -4,14 +4,20 @@ #include #include #include +#include #include "../src/contarotacoes.h" #include "../src/store.h" #include "../src/mainwindow.h" class Tst_contarotacoes : public QObject { Q_OBJECT - private slots: + public: + QString program; + QStringList args; + private slots: + void setupTest(); void checkRpmChangesFromStoreToGraphicText(); + void checkRotationErrorLogging(); }; #endif // TST_CONTAROTACOES_H diff --git a/test/tst_flabels.cpp b/test/tst_flabels.cpp new file mode 100644 index 0000000..8a170a2 --- /dev/null +++ b/test/tst_flabels.cpp @@ -0,0 +1,16 @@ +#include "tst_flabels.h" + +void Tst_flabels::setup(){ + //create a MainWindww + this->ui= MainWindow(nullptr, __LART_NULL_DEVICE_DESCRIPTOR__); + //get the ui store + pstore = this->ui.store; + +} +void Tst_flabels::checkFLabelsLogicalChange(){ + pstore->setRpm(10); + QCOMPARE(pstore->getRpm(), 10); +} +void Tst_flabels::cleanup(){ + +} \ No newline at end of file diff --git a/test/tst_flabels.h b/test/tst_flabels.h new file mode 100644 index 0000000..96ff19c --- /dev/null +++ b/test/tst_flabels.h @@ -0,0 +1,27 @@ +#include "aux.h" +#ifndef TST_FLABELS_H +#include +#include +#include +#include +#include +#include "../src/mainwindow.h" +#include "aux.h" +// TODO: this will likely fail in the future +#include "../src/references/system_var.h" + +class Tst_flabels : public QObject { + Q_OBJECT; + public: + AuxSingleton instance; + + protected: + MainWindow ui; + store * pstore; + + private slots: + void setup(); + void checkFLabelsLogicalChange(); + void cleanup(); +}; +#endif // TST_FLABELS_H diff --git a/test/tst_serialport.cpp b/test/tst_serialport.cpp index 0c30ab0..8340c18 100644 --- a/test/tst_serialport.cpp +++ b/test/tst_serialport.cpp @@ -11,9 +11,16 @@ using namespace std; 0x72, 0x70, 0x6D, 0x00, 0x10, 0x27, 0x00, 0x00, 0x00}; +void Tst_serialport::setup(){ + program="socat"; + args = QStringList(); + + args.append("pty,raw,echo=0,b115200,link=/tmp/banana,"); + args.append("pty,raw,echo=0,b115200,link=/tmp/tango"); +} void Tst_serialport::sanityCheck(){ //-d -d -d -d - socat.startDetached("socat pty,raw,echo=0,b115200,link=/tmp/banana, pty,raw,echo=0,b115200,link=/tmp/tango"); + socat.startDetached(program, args); sleep(2); _store = new store("/tmp/banana"); @@ -85,25 +92,45 @@ void Tst_serialport::partitionedSlowBsonMessage(){ _store->port->waitForReadyRead(); QCOMPARE(_store->getRpm(),10000); } -void Tst_serialport::prependingTrash(){ +/*void Tst_serialport::debugFailing(){ _store->lastMessage.clear(); _store->setRpm(0); tangoWriteSetup(); + char msg[]= {'\x20','\xF9','\x04','\x9D','\x56','\x05','\x66','\x81','\x86','\x7F','\xA9','\xA0','\xF1','\x77','\xAA','\x13','\xAD','\x2F','\x8B','\x47','\x21','\xA3','\x88','\x54','\x19','\xD4','\x7C','\xFA','\x8A','\x26','\xB0','\x56','\x59','\x22','\xDD','\x3C','\x8E','\x92','\x11','\xE2','\x18','\x14','\xCC','\xE1','\x73','\x77','\x23','\xF1','\x9E','\x45','\x09','\xD2','\xAB','\x34','\x51','\x88','\x07','\xFB','\x0B','\xA9','\x4C','\x1E','\x84','\xDC','\x7E','\x67','\x59','\xA3','\x00','\xA1','\x0A','\xB1','\x48','\x5C','\x39','\x8E','\xCF','\xA8','\x36','\x96','\x23','\x19','\x30','\x6B','\x38','\x8B','\x9F','\xCF','\x53','\x3E','\x3B','\x55','\x4A','\x19','\xA7','\x2C','\x6F','\xED','\x4A','\xEA','\xA2','\x96','\x1D','\xFB','\x1A','\xDB','\x1E','\xB7','\x23','\x55','\x1D','\x58','\x52','\x1C','\x6C','\x6D','\x58','\x57','\xE5','\xD4','\xCA','\xEC','\xD0','\x52','\xCA','\x16','\xC5','\x70','\xF3','\x63','\x73','\xE8','\xBD','\xA0','\x23','\xE1','\x23','\xF0','\xD9','\x03','\xA1','\x04','\xBE','\x52','\x6B','\x59','\x1C','\x0D','\x4B','\x49','\xB8','\x67','\x13','\xAA','\x17','\x4F','\x9A','\x87','\xC5','\xDF','\xC9','\x80','\xCF','\xEE','\xE3','\x31','\xB2','\x35','\x21','\xAF','\xCA','\xB1','\x10','\x82','\x37','\x63','\x3A','\xEB','\x4E','\xA9','\x67','\x8F','\x12','\xE0','\x1F','\x2F','\xE3','\xD2','\xBD','\x10','\x06','\xCD','\xDF','\x4D','\x25','\xC1','\xBF','\x3D','\x0B','\xAB','\x60','\xB4','\x93','\xAB','\xB8','\x86','\x2B','\x03','\xAC','\x1B','\x78','\x3E','\x39','\x8D','\xC6','\x79','\x3F','\x26','\x36','\x04','\x6A','\x03','\x4C','\x1F','\xD5','\x8C','\xA7','\x0E','\x56','\xF8','\x9A','\x3F','\x43','\xEA','\xCA','\x90','\x32','\xAB','\xC9','\xB0','\x01','\x4A','\x7F','\x99','\x64','\x64','\x31','\x8B','\x65','\xC7','\xBA','\x58','\x26','\xEF','\x85','\x76','\x51','\x4A','\xB6','\x8F','\x2F','\x82','\xCD','\xF5','\x8A','\xBA','\x4F','\x3D','\xFC','\x68','\x7C','\xC3','\xD9','\x4F','\x99','\x97','\x06','\x47','\xFE','\xE3','\x48','\xB7','\xCF','\x44','\x78','\x1C','\xBD','\x75','\x20','\xA5','\x95','\x89','\xB1','\x57','\xE6','\x97','\x7A','\x8F','\x6D','\x23','\x08','\x78','\x42','\x20','\x77','\xA7','\x76','\xD5','\x8A','\x4A','\xAF','\xA9','\xF9','\x7A','\xC2','\x30','\x17','\x1A','\x9C','\x41','\x76','\xB1','\x0D','\x2F','\x9C','\xFD','\xB7','\x82','\xDB','\xCE','\x97','\x5D','\x27','\xB0','\x62','\x55','\x8C','\x7C','\x84','\x7A','\x49','\xE0','\x02','\x3C','\x1D','\x9A','\xE4','\x9A','\x1A','\xB7','\x86','\xA4','\x67','\xF5','\x4E','\x76','\x0B','\x1E','\x98','\xA7','\x9C','\xDB','\x95','\x22','\xDF','\x70','\x9D','\xF3','\x9A','\xF4','\xAF','\x01','\xC6','\x27','\x86','\x4D','\x84','\x3C','\x6E','\x87','\x1D','\x0A','\x18','\xA3','\xF6','\xFB','\x07','\x34','\xE2','\xBB','\x26','\x16','\xA2','\x55','\xC0','\xD4','\xD5','\xEC','\x8A','\x56','\x42','\x43','\xB8','\x0F','\x6F','\x86','\x0B','\xFD','\xCC','\xE1','\x80','\xFB','\x01','\xDF','\x3C','\x2F','\x22','\x5F','\x79','\xAD','\x51','\xD9','\xDA','\x4C','\xCB','\x88','\x99','\x80','\x8F','\x94','\x08','\x84','\x95','\x90','\x30','\x3F','\x10','\xAF','\x9B','\xB9','\x28','\x98','\x43','\xBE','\x1C','\x9A','\xCA','\xCE','\x5A','\xE1','\x1B','\x46','\x1C','\xB8','\x0F','\x15','\xB1','\x9F','\x47','\x09','\x9C','\xF9','\x3B','\x05','\xB4','\x2D','\x65','\xC9','\x79','\x8D','\xBE','\xC5','\x13','\xB9','\x19','\x81','\xCF','\xA0','\xD9','\x75','\x8C','\xD9','\x82','\x3E','\xD5','\x3E','\x89','\xE3','\xD8','\xEC','\x6E','\x6D','\xA8','\x77','\x12','\x09','\x8B','\xD8','\x83','\xD7','\x4A','\x31','\x0C','\xFA','\x18','\x4F','\x61','\x53','\x34','\xFA','\xCF','\xCC','\x3B','\xF8','\x6C','\xD2','\xA2','\xC1','\xA1','\x28','\xB7','\x5A','\x8D','\xD2','\x4A','\x64','\x42','\xB2','\x08','\xBB','\x75','\xBB','\x72','\x6E','\xC0','\xE0','\x50','\x29','\xEE','\x03','\xDE','\x98','\xB1','\xA2','\x5F','\x1A','\xDE','\xFA','\x3D','\xA6','\x9E','\x06','\xFD','\x6B','\xC8','\x0A','\xA0','\x2F','\xDB','\xE1','\xEE','\x0E','\x56','\x7B','\xEF','\x1A','\x74','\xB7','\xD5','\x1F','\x26','\x3A','\xED','\x42','\xAE','\x9C','\x1F','\xF7','\x09','\x2D','\xA2','\x9C','\xA0','\x60','\x8C','\x0B','\x25','\xA4','\x33','\x73','\xAF','\x55','\xCC','\xD9','\xC0','\x42','\xD5','\x83','\x02','\x45','\xC0','\x9D','\x69','\xF2','\x6D','\xD3','\xAE','\x1C','\xA7','\xEE','\x03','\x26','\x3B','\x0F','\x14','\x9A','\x9F','\x9F','\x55','\x90','\xFD','\x42','\x4C','\x68','\x32','\xAC','\xE9','\x5F','\xC3','\x5A','\xE2','\x20','\x7E','\xBC','\x18','\xC4','\x66','\x1C','\xCC','\x78','\xBE','\x2E','\x0F','\xD2','\x7D','\x66','\x79','\x1E','\x69','\xB2','\xB9','\x93','\xED','\x9F','\xC4','\x6D','\x88','\xA1','\x29','\xBE','\x59','\x02','\xE2','\x47','\xD4','\xED','\x51','\x7B','\xFE','\x30','\x0C','\x32','\x99','\xED','\xD0','\x62','\x4A','\x48','\x3C','\xB8','\x65','\xB4','\xC7','\x74','\x89','\x73','\x28','\xBF','\x40','\x58','\x76','\x4F','\xAB','\x09','\x01','\x18','\xA5','\xAE','\x18','\x1E','\x3A','\x94','\x21','\x59','\xD4','\x7F','\xFE','\xB5','\x4C','\xC0','\x4D','\xA7','\x18','\xF0','\x3E','\xED','\x83','\xDE','\xB1','\xF4','\xDA','\xB2','\xE8','\x62','\x54','\xE3','\xCC','\xED','\xDF','\x16','\x3A','\x91','\x7D','\xD1','\xE3','\x0B','\x7A','\xDA','\xAA','\x3D','\xE3','\x13','\x48','\x52','\xBB','\x31','\x30','\xA1','\x94','\x6B','\xD7','\x22','\xCD','\x4F','\x1B','\x6B','\x6B','\xAA','\x31','\x3A','\xA1','\x5B','\xCD','\x09','\x41','\xDC','\x43','\xD8','\x1A','\xB5','\x3F','\x8F','\xDD','\x8C','\xFB','\x4D','\x14','\x3C','\x5E','\x04','\xF8','\x73','\xD7','\x10','\xE7','\x36','\x14','\x3A','\x3B','\xB5','\x75','\xE2','\xBC','\x70','\x17','\x37','\x2D','\xFC','\x63','\xDE','\x43','\x66','\x54','\x7C','\x5D','\x9E','\x0A','\x8C','\x26','\x26','\x2D','\x46','\xAA','\x89','\x9D','\x52','\x0B','\x54','\x8F','\x3B','\xB3','\xFA','\x39','\xDF','\x3E','\xC7','\x90','\xBB','\x93','\x59','\x2A','\x9C','\xF2','\x77','\x32','\x42','\x4D','\x71','\x99','\x45','\x37','\x74','\x8E','\xE0','\xE7','\xC4','\xE7','\xCB','\x94','\x26','\xBA','\x20','\x5B','\xF0','\xA8','\xC8','\xBA','\x97','\x28','\xD7','\x82','\x58','\x3C','\x5B','\xEA','\x1C','\x94','\x78','\x38','\x45','\x1D','\xCB','\x9A','\x00','\x49','\x0D','\x76','\x9A','\xC7','\xDE','\xEE','\x8A','\xFD','\x75','\x8F','\xCA','\xC3','\x9D','\xE5','\x88','\xC3','\x94','\xB0','\xD7','\x9D','\x78','\xCA','\x3E','\x7C','\xE3','\x83','\xE6','\x45','\xFC','\x5C','\x85','\x03','\xD9','\x2F','\x79','\xB0','\xA8','\xD8','\x04'}; + //random amount from 0 to 1000 + + for(int i = 0; i < sizeof(msg); i++){ + //write a random byte from 0 to 255 + //the chance of landing 0xFF 4 times in a row is 1/256^4 or 1/65536, which is very unlikely, theres also a chance of landing an ff prepending the actual message + tango.putChar(msg[i]); + tango.waitForBytesWritten(); + } + tango.write(rpm_message, 18); + tango.waitForBytesWritten(); + tango.close(); + _store->port->waitForReadyRead(); + QCOMPARE(_store->getRpm(),10000); +}*/ +void Tst_serialport::prependingTrash(){ + //open a unbuffered file to write to + _store->lastMessage.clear(); + _store->setRpm(0); + tangoWriteSetup(); //random amount from 0 to 1000 - int random = randomInt(0,1000); + int random = instance.randomInt(0,1000); for(int i = 0; i < random; i++){ //write a random byte from 0 to 255 //the chance of landing 0xFF 4 times in a row is 1/256^4 or 1/65536, which is very unlikely, theres also a chance of landing an ff prepending the actual message - tango.putChar((char)randomInt(0,255)); + char t = (char)instance.randomInt(0,255); + tango.putChar(t); tango.waitForBytesWritten(); } tango.write(rpm_message, 18); tango.waitForBytesWritten(); tango.close(); _store->port->waitForReadyRead(); - - QCOMPARE(_store->getRpm(),10000); + QCOMPARE(_store->getRpm(),10000); } @@ -115,11 +142,11 @@ void Tst_serialport::suffixingTrash(){ //random amount from 0 to 1000 tango.write(rpm_message, 18); - int random = randomInt(0,1000); + int random = instance.randomInt(0,1000); for(int i = 0; i < random; i++){ //write a random byte from 0 to 255 //the chance of landing 0xFF 4 times in a row is 1/256^4 or 1/65536, which is very unlikely, theres also a chance of landing an ff prepending the actual message - tango.putChar((char)randomInt(0,255)); + tango.putChar((char)instance.randomInt(0,255)); tango.waitForBytesWritten(); } tango.waitForBytesWritten(); @@ -129,19 +156,48 @@ void Tst_serialport::suffixingTrash(){ QCOMPARE(_store->getRpm(),10000); } +void Tst_serialport::updatingRPM(){ + _store->lastMessage.clear(); + _store->setRpm(0); + tangoWriteSetup(); + + tango.write(rpm_message, 18); + tango.waitForBytesWritten(); + tango.close(); + _store->port->waitForReadyRead(); + + QCOMPARE(_store->getRpm(),10000); + _store->setRpm(0); + tangoWriteSetup(); + char * rpm_message2 = new char[18]; + memcpy(rpm_message2,rpm_message,18); + int a = instance.randomInt(0, 10000); + rpm_message2[13]= (char)(a & 0xFF); + rpm_message2[14]= (char)((a >> 8) & 0xFF); + rpm_message2[15]= (char)((a >> 16) & 0xFF); + rpm_message2[16]= (char)((a >> 24) & 0xFF); + + + tango.write(rpm_message2, 18); + tango.waitForBytesWritten(); + tango.close(); + _store->port->waitForReadyRead(); + + QCOMPARE(_store->getRpm(),a); +} void Tst_serialport::closeHandle(){ socat.close(); _store->~store(); } -QTEST_MAIN(Tst_serialport) +//QTEST_MAIN(Tst_serialport) //functions void Tst_serialport::tangoWriteSetup(){ tango.setPortName("/tmp/tango"); - tango.setBaudRate(QSerialPort::Baud115200); + tango.setBaudRate(QSerialPort::Baud115200); tango.setDataBits(QSerialPort::Data8); tango.setStopBits(QSerialPort::OneStop); tango.setParity(QSerialPort::NoParity); @@ -149,7 +205,3 @@ void Tst_serialport::tangoWriteSetup(){ tango.open(QIODevice::WriteOnly); } -int Tst_serialport::randomInt(int offset=0, int n=255){ - QRandomGenerator a = QRandomGenerator::securelySeeded(); - return a.bounded(n)+offset; -} diff --git a/test/tst_serialport.h b/test/tst_serialport.h index 1e4febf..44723ac 100644 --- a/test/tst_serialport.h +++ b/test/tst_serialport.h @@ -1,5 +1,6 @@ #ifndef TST_SERIALPORT_H #define TST_SERIALPORT_H +#include #include #include #include @@ -17,23 +18,29 @@ #include #include "../src/store.h" #include "../src/mainwindow.h" -class Tst_serialport : public QObject -{ +#include "aux.h" +class Tst_serialport : public QObject { Q_OBJECT + public: + QString program; + QStringList args; + AuxSingleton instance; private: QProcess socat; - store * _store; + store * _store; void tangoWriteSetup(); - int randomInt(int offset, int n); - + private slots: + void setup(); void sanityCheck(); void checkSendMessage(); void storeMessage(); void bsonTest(); + //void debugFailing(); + void prependingTrash(); void partitionedSlowBsonMessage(); - void prependingTrash(); void suffixingTrash(); + void updatingRPM(); void closeHandle(); };