diff --git a/pages/pagemotorcomparison.cpp b/pages/pagemotorcomparison.cpp index 59f4bf4d3..a59bd1f15 100644 --- a/pages/pagemotorcomparison.cpp +++ b/pages/pagemotorcomparison.cpp @@ -201,6 +201,10 @@ PageMotorComparison::PageMotorComparison(QWidget *parent) : [this]() { settingChanged(); }); connect(ui->testModeRpmPowerButton, &QRadioButton::toggled, [this]() { settingChanged(); }); + connect(ui->testModeExpButton, &QRadioButton::toggled, + [this]() { settingChanged(); }); + connect(ui->testModeVbusButton, &QRadioButton::toggled, + [this]() { settingChanged(); }); connect(ui->testLiveUpdateBox, &QCheckBox::toggled, [this](bool checked) { (void)checked; settingChanged(); }); @@ -318,6 +322,39 @@ PageMotorComparison::PageMotorComparison(QWidget *parent) : addDataItem(name, ui->m2PlotTable, hasScale); }; + mSettingUpdateRequired = false; + mSettingUpdateTimer = new QTimer(this); + mSettingUpdateTimer->start(20); + + connect(mSettingUpdateTimer, &QTimer::timeout, [this]() { + if (mSettingUpdateRequired) { + ui->testTorqueBox->setEnabled(ui->testModeTorqueButton->isChecked() || + ui->testModeRpmButton->isChecked() || + ui->testModeVbusButton->isChecked()); + ui->testPowerBox->setEnabled(ui->testModeRpmPowerButton->isChecked() || + ui->testModeExpButton->isChecked()); + ui->testRpmStartBox->setEnabled(ui->testModeRpmPowerButton->isChecked() || + ui->testModeExpButton->isChecked()); + ui->testRpmBox->setEnabled(ui->testModeRpmPowerButton->isChecked() || + ui->testModeExpButton->isChecked() || + ui->testModeRpmButton->isChecked() || + ui->testModeTorqueButton->isChecked()); + ui->testExpBox->setEnabled(ui->testModeExpButton->isChecked()); + ui->testExpBaseTorqueBox->setEnabled(ui->testModeExpButton->isChecked()); + ui->testVbusBox->setEnabled(ui->testModeVbusButton->isChecked()); + + if (ui->tabWidget->currentIndex() == 1) { + setQmlMotorParams(); + } + + if (ui->testLiveUpdateBox->isChecked()) { + on_testRunButton_clicked(); + } + + mSettingUpdateRequired = false; + } + }); + addDataItemBoth("Efficiency"); addDataItemBoth("Mot Loss Tot"); addDataItemBoth("Mot Loss Res"); @@ -393,19 +430,7 @@ void PageMotorComparison::setVesc(VescInterface *vesc) void PageMotorComparison::settingChanged() { - ui->testTorqueBox->setEnabled(ui->testModeTorqueButton->isChecked() || ui->testModeRpmButton->isChecked()); - ui->testPowerBox->setEnabled(ui->testModeRpmPowerButton->isChecked() || ui->testModeExpButton->isChecked()); - ui->testRpmStartBox->setEnabled(ui->testModeRpmPowerButton->isChecked() || ui->testModeExpButton->isChecked()); - ui->testExpBox->setEnabled(ui->testModeExpButton->isChecked()); - ui->testExpBaseTorqueBox->setEnabled(ui->testModeExpButton->isChecked()); - - if (ui->tabWidget->currentIndex() == 1) { - setQmlMotorParams(); - } - - if (ui->testLiveUpdateBox->isChecked()) { - on_testRunButton_clicked(); - } + mSettingUpdateRequired = true; } bool PageMotorComparison::reloadConfigs() @@ -542,7 +567,7 @@ void PageMotorComparison::updateDataAndPlot(double posx, double yMin, double yMa md.configure(&mM2Config, getParamsUi(2)); md.update(posx, torque); updateTable(md, ui->m2PlotTable); - } else { + } else if (ui->testModeExpButton->isChecked()) { double rpm_start = ui->testRpmStartBox->value(); double rps = posx * 2.0 * M_PI / 60.0; double prop_exp = ui->testExpBox->value(); @@ -560,6 +585,14 @@ void PageMotorComparison::updateDataAndPlot(double posx, double yMin, double yMa md.configure(&mM2Config, getParamsUi(2)); md.update(posx, torque); updateTable(md, ui->m2PlotTable); + } else if (ui->testModeVbusButton->isChecked()) { + MotorData md; + md.configure(&mM1Config, getParamsUi(1)); + md.updateTorqueVBus(posx, ui->testVbusBox->value()); + updateTable(md, ui->m1PlotTable); + md.configure(&mM2Config, getParamsUi(2)); + md.updateTorqueVBus(posx, ui->testVbusBox->value()); + updateTable(md, ui->m2PlotTable); } } } @@ -932,6 +965,37 @@ void PageMotorComparison::on_testRunButton_clicked() updateGraphs(xAxis, yAxes, names); }; + auto plotVbusSweep = [this, updateData, updateGraphs, plotPoints](QTableWidget *table, + ConfigParams &config, MotorDataParams param) { + double torque = fabs(ui->testTorqueBox->value()); + double vbus = ui->testVbusBox->value(); + + QVector xAxis; + QVector > yAxes; + QVector names; + + double torque_start = -torque; + if (!ui->testNegativeBox->isChecked()) { + torque_start = torque / plotPoints; + } + + for (double t = torque_start;t < torque;t += (torque / plotPoints)) { + MotorData md; + md.configure(&config, param); + md.updateTorqueVBus(t, vbus); + xAxis.append(t); + updateData(md, table, yAxes, names); + + if (md.rpm_motor_shaft >= param.maxRpm) { + mVesc->emitMessageDialog("Max RPM", "Maximum motor shaft RPM exceeded", false); + break; + } + } + + ui->plot->xAxis->setLabel("Torque (Nm)"); + updateGraphs(xAxis, yAxes, names); + }; + auto plotQmlSweep = [this, updateData, updateGraphs, plotPoints](QTableWidget *table, ConfigParams &config, MotorDataParams param, int motor) { @@ -990,10 +1054,14 @@ void PageMotorComparison::on_testRunButton_clicked() ui->plot->clearGraphs(); plotPowerSweep(ui->m1PlotTable, mM1Config, getParamsUi(1)); plotPowerSweep(ui->m2PlotTable, mM2Config, getParamsUi(2)); - } else { + } else if (ui->testModeExpButton->isChecked()) { ui->plot->clearGraphs(); plotPropSweep(ui->m1PlotTable, mM1Config, getParamsUi(1)); plotPropSweep(ui->m2PlotTable, mM2Config, getParamsUi(2)); + } else if (ui->testModeVbusButton->isChecked()) { + ui->plot->clearGraphs(); + plotVbusSweep(ui->m1PlotTable, mM1Config, getParamsUi(1)); + plotVbusSweep(ui->m2PlotTable, mM2Config, getParamsUi(2)); } } diff --git a/pages/pagemotorcomparison.h b/pages/pagemotorcomparison.h index 23c6eaa11..702a9c8cd 100644 --- a/pages/pagemotorcomparison.h +++ b/pages/pagemotorcomparison.h @@ -22,6 +22,7 @@ #include #include +#include #include "vescinterface.h" #include "configparams.h" #include "widgets/qcustomplot.h" @@ -134,9 +135,23 @@ struct MotorData { params = prm; } - Q_INVOKABLE void update(double rpm, double torque) { + Q_INVOKABLE bool updateTorqueVBus(double torque, double vbus) { + double rpm_guess = 1000.0; + + for (int i = 0;i < 20;i++) { + if (!update(rpm_guess, torque)) { + return false; + } + + rpm_guess *= vbus / vbus_min; + } + + return true; + } + + Q_INVOKABLE bool update(double rpm, double torque) { if (config == nullptr) { - return; + return false; } // See https://www.mathworks.com/help/physmod/sps/ref/pmsm.html @@ -214,6 +229,8 @@ struct MotorData { kv_bldc = rpm_motor_shaft / (vbus_min * (sqrt(3.0) / 2.0)); kv_bldc_noload = (60.0 * 0.95) / (lambda * (3.0 / 2.0) * M_PI * 2.0 * pole_pairs); + + return true; } ConfigParams *config; @@ -336,6 +353,8 @@ private slots: QPair mVerticalLineYLast; bool mRunDone; Utility mUtil; + QTimer *mSettingUpdateTimer; + bool mSettingUpdateRequired; bool mQmlXNameOk; bool mQmlXMinOk; diff --git a/pages/pagemotorcomparison.ui b/pages/pagemotorcomparison.ui index be7e70918..6331861af 100644 --- a/pages/pagemotorcomparison.ui +++ b/pages/pagemotorcomparison.ui @@ -6,8 +6,8 @@ 0 0 - 1586 - 946 + 1450 + 945 @@ -41,7 +41,7 @@ - Common + Custom @@ -61,6 +61,26 @@ + + + + Sweep from the start RPM to the end RPM at the set Power. + + + RPM/Power + + + + + + + <html><head/><body><p>Torque + RPM Exponential mode. Sweep from 0 to end RPM and use the base torque + exponent on the RPM to derive the power requirement. The test will be scaled such that the specified power is at the full RPM. The power for the base torque will be required in addition to that.</p><p>Propellers and impellers in air and water usually just have the exponent while traction vehicles have a base torque from the rolling resistance + an exponent from wind resistance.</p></body></html> + + + Exp + + + @@ -87,23 +107,13 @@ - - - - Sweep from the start RPM to the end RPM at the set Power. - - - RPM/Power - - - - - + + - <html><head/><body><p>Torque + RPM Exponential mode. Sweep from 0 to end RPM and use the base torque + exponent on the RPM to derive the power requirement. The test will be scaled such that the specified power is at the full RPM. The power for the base torque will be required in addition to that.</p><p>Propellers and impellers in air and water usually just have the exponent while traction vehicles have a base torque from the rolling resistance + an exponent from wind resistance.</p></body></html> + Torque sweep while keeping the bus voltage constant. - Torque + Exp + Vbus @@ -273,13 +283,32 @@ - + Include negative RPM and Torque in tests. - Include Negative + Negative + + + + + + + false + + + V + + + 1 + + + 9999.000000000000000 + + + 48.000000000000000