Added Simple polynomial fitting functions written by Henry M. Forson. Added a graph that displays the old and new iSpindel calibration curve. Implemented delete row from the data.

Sat, 14 Oct 2023 16:10:14 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Sat, 14 Oct 2023 16:10:14 +0200
changeset 506
ea07f6c97a69
parent 505
7ae4d022cf8f
child 507
fa07b6c6238a

Added Simple polynomial fitting functions written by Henry M. Forson. Added a graph that displays the old and new iSpindel calibration curve. Implemented delete row from the data.

CMakeLists.txt file | annotate | diff | comparison | revisions
src/CalibrateiSpindel.cpp file | annotate | diff | comparison | revisions
src/CalibrateiSpindel.h file | annotate | diff | comparison | revisions
translations/bmsapp_en.ts file | annotate | diff | comparison | revisions
translations/bmsapp_nl.ts file | annotate | diff | comparison | revisions
ui/AboutDialog.ui file | annotate | diff | comparison | revisions
ui/CalibrateiSpindel.ui file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Sat Oct 14 11:23:24 2023 +0200
+++ b/CMakeLists.txt	Sat Oct 14 16:10:14 2023 +0200
@@ -253,6 +253,7 @@
     ${SRCDIR}/analog/led.cpp
     ${SRCDIR}/analog/wallclock.cpp
     ${SRCDIR}/global.cpp
+    ${SRCDIR}/polyfit.cpp
   )
 
   set( HDRS
@@ -322,6 +323,7 @@
     ${SRCDIR}/analog/led.h
     ${SRCDIR}/analog/wallclock.h
     ${SRCDIR}/global.h
+    ${SRCDIR}/polyfit.h
   )
 
   set( UIS
--- a/src/CalibrateiSpindel.cpp	Sat Oct 14 11:23:24 2023 +0200
+++ b/src/CalibrateiSpindel.cpp	Sat Oct 14 16:10:14 2023 +0200
@@ -18,6 +18,7 @@
 #include "../ui/ui_CalibrateiSpindel.h"
 #include "global.h"
 #include "Utils.h"
+#include "polyfit.h"
 #include "MainWindow.h"
 
 
@@ -55,9 +56,7 @@
             } else {
 
 	    	QJsonObject jsonObj = jsonResponse.object();
-//	    	qDebug() << "polyData: " << jsonObj["polyData"].toArray();
 		QJsonArray polyData = jsonObj.value("polyData").toArray();
-//		qDebug() << polyData;
 		for (int i = 0; i < polyData.size(); i++) {
 		    Old[i] = New[i] = polyData.at(i).toDouble();
 		    qDebug() << i << New[i];
@@ -68,15 +67,15 @@
 	    	qDebug() << "calData:  " << jsonObj["calData"].toArray();
 		QJsonArray calData = jsonObj.value("calData").toArray();
 		qDebug() << calData;
-		totaldata = 0;
+		oldtotal = 0;
 		for (int i = 0; i < calData.size(); i++) {
 		    QJsonObject calObj = calData.at(i).toObject();
 		    oCal[i].plato = nCal[i].plato = calObj["plato"].toDouble();
 		    oCal[i].angle = nCal[i].angle = calObj["angle"].toDouble();
 		    oCal[i].sg = nCal[i].sg = Utils::plato_to_sg(oCal[i].plato);
-		    totaldata++;
+		    oldtotal++;
 		}
-
+		newtotal = oldtotal;
 	    }
 	}
 
@@ -93,9 +92,9 @@
     QString w;
     QWidget* pWidget;
     QHBoxLayout* pLayout;
-    double  d;
+    double  d, x[12], y[12];
 
-    qDebug() << "refreshTable" << totaldata;
+    qDebug() << "refreshTable" << oldtotal << newtotal;
 
     /*
      * During filling the table turn off the cellChanged signal because every cell that is filled
@@ -111,11 +110,18 @@
     ui->dataTable->setColumnWidth(3,  55);	/* Del button	*/
     ui->dataTable->setHorizontalHeaderLabels(labels);
     ui->dataTable->verticalHeader()->hide();
-    ui->dataTable->setRowCount(totaldata);
+    ui->dataTable->setRowCount(newtotal);
+
+    for (int i = 0; i < 12; i++) {
+	x[i] = y[i] = 0;
+    }
 
-    for (int i = 0; i < totaldata; i++) {
+    for (int i = 0; i < newtotal; i++) {
 	qDebug() << i << nCal[i].sg << nCal[i].plato << nCal[i].angle;
 
+	y[i] = nCal[i].plato;
+	x[i] = nCal[i].angle;
+
 	w = QString("%1").arg(nCal[i].sg, 1, 'f', 4, '0');
 	QTableWidgetItem *item = new QTableWidgetItem(w);
 	item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
@@ -143,6 +149,59 @@
         pWidget->setLayout(pLayout);
         ui->dataTable->setCellWidget(i, 3, pWidget);
     }
+    int rc = Polyfit::polyfit(newtotal, x, y, 4, New);
+    qDebug() << "poly:" << rc << New[0] << New[1] << New[2] << New[3];
+
+    _data_new = QString("(%1 * x^3) + (%2 * x^2) + (%3 * x) + %4").arg(New[0], 0, 'f', 9, '0').arg(New[1], 0, 'f', 9, '0').arg(New[2], 0, 'f', 9, '0').arg(New[3], 0, 'f', 9, '0');
+    ui->newEdit->setText(_data_new);
+
+    /*
+     * Check the new formula against the old formula.
+     */
+    this->textIsChanged = (_data_old.compare(_data_new) == 0) ? false:true;
+    qDebug() << "changed" << this->textIsChanged << _data_old.compare(_data_new);
+    CalibrateiSpindel::WindowTitle();
+
+    new_plot = new QLineSeries();
+    old_plot = new QLineSeries();
+
+    for (int i = 0; i < oldtotal; i++) {
+	old_plot->append(oCal[i].angle, oCal[i].plato);
+    }
+    for (int i = 0; i < newtotal; i++) {
+	new_plot->append(nCal[i].angle, nCal[i].plato);
+    }
+
+    old_plot->setName(tr("Old"));
+    new_plot->setName(tr("New"));
+
+    chart = new QChart();
+    chart->setTitle(tr("Calibration plot"));
+    chart->addSeries(old_plot);
+    chart->addSeries(new_plot);
+
+    QValueAxis *axisX = new QValueAxis;
+    axisX->setRange(10, 80);
+    axisX->setTickCount(8);
+    axisX->setLabelFormat("%.0f");
+    axisX->setTitleText(tr("Angle"));
+    axisX->setLabelsFont(QFont("Helvetica", 8, QFont::Normal));
+    chart->addAxis(axisX, Qt::AlignBottom);
+    old_plot->attachAxis(axisX);
+    new_plot->attachAxis(axisX);
+
+    QValueAxis *axisY = new QValueAxis;
+    axisY->setRange(0, 20);
+    axisY->setTickCount(11);
+    axisY->setLabelFormat("%.1f");
+    axisY->setTitleText("Plato");
+    axisY->setLabelsFont(QFont("Helvetica", 8, QFont::Normal));
+    chart->addAxis(axisY, Qt::AlignLeft);
+    old_plot->attachAxis(axisY);
+    new_plot->attachAxis(axisY);
+
+    ui->chartView->setRenderHint(QPainter::Antialiasing);
+    ui->chartView->setChart(chart);
 
     this->ignoreChanges = false;
 }
@@ -170,13 +229,33 @@
 {
     QPushButton *pb = qobject_cast<QPushButton *>(QObject::sender());
     int row = pb->objectName().toInt();
-    qDebug() << "Delete row" << row;
+    qDebug() << "Delete row" << row << newtotal;
+
+    if (newtotal < 4) {
+	QMessageBox::warning(this, tr("iSpindel calibrate"), tr("You cannot delete too many rows."));
+	return;
+    }
+
+    if (row == (newtotal - 1)) {
+	qDebug() << "Delete last row";
+	newtotal--;
+    } else {
+	newtotal--;
+    	for (int i = row; i < newtotal; i++) {
+	    nCal[i].sg = nCal[i+1].sg;
+	    nCal[i].plato = nCal[i+1].plato;
+	    nCal[i].angle = nCal[i+1].angle;
+	    qDebug() << i << " < " << i+1;
+    	}
+    }
+
+    emit refreshTable();
 }
 
 
 void CalibrateiSpindel::on_addButton_clicked()
 {
-    qDebug() << "Add row" << totaldata;
+    qDebug() << "Add row" << newtotal;
 }
 
 
--- a/src/CalibrateiSpindel.h	Sat Oct 14 11:23:24 2023 +0200
+++ b/src/CalibrateiSpindel.h	Sat Oct 14 16:10:14 2023 +0200
@@ -1,14 +1,8 @@
 #ifndef _CALIBRATEISPINDEL_H
 #define _CALIBRATEISPINDEL_H
 
-#include <QDialog>
-// #include <QDoubleSpinBox>
-// #include <QCheckBox>
-// #include <QComboBox>
-// #include <QRadioButton>
-// #include <QLineEdit>
-#include <QDialogButtonBox>
-#include <QJsonDocument>
+#include "MainWindow.h"
+
 
 struct Calibrate {
     double	sg;
@@ -43,7 +37,10 @@
 private:
     Ui::CalibrateiSpindel *ui;
     QString _node, _alias, _data_old, _data_new;
-    int recno, totaldata;
+    QChartView *chartView;
+    QChart *chart;
+    QLineSeries *new_plot, *old_plot;
+    int recno, oldtotal, newtotal;
     QJsonDocument data;
     bool ignoreChanges = false;
     bool textIsChanged = false;
--- a/translations/bmsapp_en.ts	Sat Oct 14 11:23:24 2023 +0200
+++ b/translations/bmsapp_en.ts	Sat Oct 14 16:10:14 2023 +0200
@@ -90,28 +90,54 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/CalibrateiSpindel.cpp" line="106"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="105"/>
         <source>SG</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/CalibrateiSpindel.cpp" line="106"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="105"/>
         <source>°Plato</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/CalibrateiSpindel.cpp" line="106"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="105"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="196"/>
         <source>Angle</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/CalibrateiSpindel.cpp" line="106"/>
-        <location filename="../src/CalibrateiSpindel.cpp" line="138"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="105"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="144"/>
         <source>Del</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/CalibrateiSpindel.cpp" line="202"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="184"/>
+        <source>Old</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../src/CalibrateiSpindel.cpp" line="185"/>
+        <source>New</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../src/CalibrateiSpindel.cpp" line="188"/>
+        <source>Calibration plot</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../src/CalibrateiSpindel.cpp" line="244"/>
+        <source>iSpindel calibrate</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../src/CalibrateiSpindel.cpp" line="244"/>
+        <source>You cannot delete too many rows.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../src/CalibrateiSpindel.cpp" line="290"/>
         <source>BMSapp - Calibrate iSpindel %1</source>
         <translation type="unfinished"></translation>
     </message>
--- a/translations/bmsapp_nl.ts	Sat Oct 14 11:23:24 2023 +0200
+++ b/translations/bmsapp_nl.ts	Sat Oct 14 16:10:14 2023 +0200
@@ -144,28 +144,54 @@
         <translation type="unfinished">Terug</translation>
     </message>
     <message>
-        <location filename="../src/CalibrateiSpindel.cpp" line="106"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="105"/>
         <source>SG</source>
         <translation type="unfinished">SG</translation>
     </message>
     <message>
-        <location filename="../src/CalibrateiSpindel.cpp" line="106"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="105"/>
         <source>°Plato</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/CalibrateiSpindel.cpp" line="106"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="105"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="196"/>
         <source>Angle</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/CalibrateiSpindel.cpp" line="106"/>
-        <location filename="../src/CalibrateiSpindel.cpp" line="138"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="105"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="144"/>
         <source>Del</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/CalibrateiSpindel.cpp" line="202"/>
+        <location filename="../src/CalibrateiSpindel.cpp" line="184"/>
+        <source>Old</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../src/CalibrateiSpindel.cpp" line="185"/>
+        <source>New</source>
+        <translation type="unfinished">Nieuw</translation>
+    </message>
+    <message>
+        <location filename="../src/CalibrateiSpindel.cpp" line="188"/>
+        <source>Calibration plot</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../src/CalibrateiSpindel.cpp" line="244"/>
+        <source>iSpindel calibrate</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../src/CalibrateiSpindel.cpp" line="244"/>
+        <source>You cannot delete too many rows.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../src/CalibrateiSpindel.cpp" line="290"/>
         <source>BMSapp - Calibrate iSpindel %1</source>
         <translation type="unfinished"></translation>
     </message>
--- a/ui/AboutDialog.ui	Sat Oct 14 11:23:24 2023 +0200
+++ b/ui/AboutDialog.ui	Sat Oct 14 16:10:14 2023 +0200
@@ -58,7 +58,12 @@
 
 Plugins: AnalogWidgets
 Author: Tomasz Ziobrowski
-License: GPL v2</string>
+License: GPL v2
+
+Code: Simple polynomial fitting functions.
+Author: Henry M. Forson, Melbourne, Florida USA
+License: MIT
+</string>
      </property>
     </widget>
    </item>
--- a/ui/CalibrateiSpindel.ui	Sat Oct 14 11:23:24 2023 +0200
+++ b/ui/CalibrateiSpindel.ui	Sat Oct 14 16:10:14 2023 +0200
@@ -97,7 +97,7 @@
         <x>110</x>
         <y>100</y>
         <width>361</width>
-        <height>381</height>
+        <height>391</height>
        </rect>
       </property>
      </widget>
@@ -198,10 +198,30 @@
        <bool>true</bool>
       </property>
      </widget>
+     <widget class="QChartView" name="chartView">
+      <property name="geometry">
+       <rect>
+        <x>480</x>
+        <y>100</y>
+        <width>481</width>
+        <height>391</height>
+       </rect>
+      </property>
+      <property name="lineWidth">
+       <number>0</number>
+      </property>
+     </widget>
     </widget>
    </item>
   </layout>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>QChartView</class>
+   <extends>QGraphicsView</extends>
+   <header>QtCharts</header>
+  </customwidget>
+ </customwidgets>
  <tabstops>
   <tabstop>nameEdit</tabstop>
   <tabstop>quitButton</tabstop>

mercurial