From f31bfbd796ddd07a503f57425ef384a778e9c5f5 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 24 Apr 2024 15:15:35 +0200 Subject: [PATCH] different speed offsets depending on the incline of the treadmill #2121 (#2141) * different speed offsets depending on the incline of the treadmill (Discussion #2121) * Update strydrunpowersensor.cpp * overriding request speed * Update treadmill.cpp * Update nordictrackifitadbtreadmill.cpp * Update project.pbxproj --- .../horizontreadmill/horizontreadmill.cpp | 19 ++++++------ .../nordictrackifitadbtreadmill.cpp | 4 +-- .../strydrunpowersensor.cpp | 1 + src/devices/treadmill.cpp | 21 +++++++++++++ src/devices/treadmill.h | 3 ++ src/qzsettings.cpp | 4 ++- src/qzsettings.h | 2 ++ src/settings.qml | 30 ++++++++++++++++++- 8 files changed, 70 insertions(+), 14 deletions(-) diff --git a/src/devices/horizontreadmill/horizontreadmill.cpp b/src/devices/horizontreadmill/horizontreadmill.cpp index 5ab1b5f80..69fb4c632 100644 --- a/src/devices/horizontreadmill/horizontreadmill.cpp +++ b/src/devices/horizontreadmill/horizontreadmill.cpp @@ -1358,10 +1358,10 @@ void horizontreadmill::characteristicChanged(const QLowEnergyCharacteristic &cha if (characteristic.uuid() == QBluetoothUuid((quint16)0xFFF4) && lastPacketComplete.length() > 70 && lastPacketComplete.at(0) == 0x55 && lastPacketComplete.at(5) == 0x17) { - Speed = (((double)(((uint16_t)((uint8_t)lastPacketComplete.at(25)) << 8) | + parseSpeed((((double)(((uint16_t)((uint8_t)lastPacketComplete.at(25)) << 8) | (uint16_t)((uint8_t)lastPacketComplete.at(24)))) / 100.0) * - 1.60934; // miles/h + 1.60934); // miles/h emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); Inclination = treadmillInclinationOverride((double)((uint8_t)lastPacketComplete.at(30)) / 10.0); @@ -1386,9 +1386,8 @@ void horizontreadmill::characteristicChanged(const QLowEnergyCharacteristic &cha distanceEval = true; } else if (characteristic.uuid() == QBluetoothUuid((quint16)0xFFF4) && newValue.length() > 70 && newValue.at(0) == 0x55 && newValue.at(5) == 0x12) { - Speed = - (((double)(((uint16_t)((uint8_t)newValue.at(62)) << 8) | (uint16_t)((uint8_t)newValue.at(61)))) / 1000.0) * - 1.60934; // miles/h + parseSpeed((((double)(((uint16_t)((uint8_t)newValue.at(62)) << 8) | (uint16_t)((uint8_t)newValue.at(61)))) / 1000.0) * + 1.60934); // miles/h emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); Inclination = treadmillInclinationOverride((double)((uint8_t)newValue.at(63)) / 10.0); @@ -1413,7 +1412,7 @@ void horizontreadmill::characteristicChanged(const QLowEnergyCharacteristic &cha distanceEval = true; } else if (characteristic.uuid() == QBluetoothUuid((quint16)0xFFF4) && newValue.length() == 29 && newValue.at(0) == 0x55) { - Speed = ((double)(((uint16_t)((uint8_t)newValue.at(15)) << 8) | (uint16_t)((uint8_t)newValue.at(14)))) / 10.0; + parseSpeed(((double)(((uint16_t)((uint8_t)newValue.at(15)) << 8) | (uint16_t)((uint8_t)newValue.at(14)))) / 10.0); emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); // Inclination = (double)((uint8_t)newValue.at(3)) / 10.0; @@ -1477,9 +1476,9 @@ void horizontreadmill::characteristicChanged(const QLowEnergyCharacteristic &cha index += 2; if (!Flags.moreData) { - Speed = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + parseSpeed(((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))) / - 100.0; + 100.0); index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); } @@ -1626,9 +1625,9 @@ void horizontreadmill::characteristicChanged(const QLowEnergyCharacteristic &cha index += 3; if (!Flags.moreData && newValue.length() > index + 1) { - Speed = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + parseSpeed(((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))) / - 100.0; + 100.0); emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); index += 2; } diff --git a/src/devices/nordictrackifitadbtreadmill/nordictrackifitadbtreadmill.cpp b/src/devices/nordictrackifitadbtreadmill/nordictrackifitadbtreadmill.cpp index aecc1e704..7fb7a7420 100644 --- a/src/devices/nordictrackifitadbtreadmill/nordictrackifitadbtreadmill.cpp +++ b/src/devices/nordictrackifitadbtreadmill/nordictrackifitadbtreadmill.cpp @@ -226,7 +226,7 @@ void nordictrackifitadbtreadmill::processPendingDatagrams() { QStringList aValues = line.split(" "); if (aValues.length()) { speed = getDouble(aValues.last()); - Speed = speed; + parseSpeed(speed); } } else if (line.contains(QStringLiteral("Changed Grade"))) { QStringList aValues = line.split(" "); @@ -425,7 +425,7 @@ void nordictrackifitadbtreadmill::onWatt(double watt) { void nordictrackifitadbtreadmill::onSpeedInclination(double speed, double inclination) { - Speed = speed; + parseSpeed(speed); Inclination = inclination; QSettings settings; diff --git a/src/devices/strydrunpowersensor/strydrunpowersensor.cpp b/src/devices/strydrunpowersensor/strydrunpowersensor.cpp index 8686d0c25..a0fa3aed9 100644 --- a/src/devices/strydrunpowersensor/strydrunpowersensor.cpp +++ b/src/devices/strydrunpowersensor/strydrunpowersensor.cpp @@ -327,6 +327,7 @@ void strydrunpowersensor::characteristicChanged(const QLowEnergyCharacteristic & // Unit is in m/s with a resolution of 1/256 uint16_t speedMs = (((uint16_t)((uint8_t)newValue.at(2)) << 8) | (uint16_t)((uint8_t)newValue.at(1))); double speed = (((double)speedMs) / 256.0) * 3.6; // km/h + emit speedChanged(speed); double cadence = (uint8_t)newValue.at(3) * cadence_multiplier; if (newValue.length() >= 6 && InstantaneousStrideLengthPresent) { instantaneousStrideLengthCMAvailableFromDevice = true; diff --git a/src/devices/treadmill.cpp b/src/devices/treadmill.cpp index c085a9cb1..80dcc867b 100644 --- a/src/devices/treadmill.cpp +++ b/src/devices/treadmill.cpp @@ -11,9 +11,15 @@ treadmill::treadmill() {} void treadmill::changeSpeed(double speed) { QSettings settings; + bool stryd_speed_instead_treadmill = settings.value(QZSettings::stryd_speed_instead_treadmill, QZSettings::default_stryd_speed_instead_treadmill).toBool(); m_lastRawSpeedRequested = speed; speed /= settings.value(QZSettings::speed_gain, QZSettings::default_speed_gain).toDouble(); speed -= settings.value(QZSettings::speed_offset, QZSettings::default_speed_offset).toDouble(); + if(stryd_speed_instead_treadmill && Speed.value() > 0) { + double delta = (Speed.value() - rawSpeed.value()); + qDebug() << "stryd_speed_instead_treadmill so override speed by " << delta; + speed -= delta; + } qDebug() << "changeSpeed" << speed << autoResistanceEnable << m_difficult << m_difficult_offset << m_lastRawSpeedRequested; RequestedSpeed = (speed * m_difficult) + m_difficult_offset; if (autoResistanceEnable) @@ -129,6 +135,7 @@ void treadmill::clearStats() { moving.clear(true); elapsed.clear(true); Speed.clear(false); + rawSpeed.clear(false); KCal.clear(true); Distance.clear(true); Distance1s.clear(true); @@ -152,6 +159,7 @@ void treadmill::setPaused(bool p) { moving.setPaused(p); elapsed.setPaused(p); Speed.setPaused(p); + rawSpeed.setPaused(p); KCal.setPaused(p); Distance.setPaused(p); Distance1s.setPaused(p); @@ -172,6 +180,7 @@ void treadmill::setLap() { moving.setLap(true); elapsed.setLap(true); Speed.setLap(false); + rawSpeed.setLap(false); KCal.setLap(true); Distance.setLap(true); Distance1s.setLap(true); @@ -463,6 +472,17 @@ QTime treadmill::lastRequestedPace() { } } +void treadmill::parseSpeed(double speed) { + QSettings settings; + bool stryd_speed_instead_treadmill = settings.value(QZSettings::stryd_speed_instead_treadmill, QZSettings::default_stryd_speed_instead_treadmill).toBool(); + if(!stryd_speed_instead_treadmill) { + Speed = speed; + } else { + qDebug() << "speed from the treadmill is discarded since we are using the one from the power sensor"; + } + rawSpeed = speed; +} + /* * Running Stress Score */ @@ -553,3 +573,4 @@ void treadmill::changePower(int32_t power) { } metric treadmill::lastRequestedPower() { return RequestedPower; } + diff --git a/src/devices/treadmill.h b/src/devices/treadmill.h index 2c558ad8d..955da5cca 100644 --- a/src/devices/treadmill.h +++ b/src/devices/treadmill.h @@ -70,6 +70,7 @@ class treadmill : public bluetoothdevice { double requestInclination = -100; double lastSpeed = 0.0; double lastInclination = 0; + metric rawSpeed; metric RequestedSpeed; metric RequestedInclination; metric InstantaneousStrideLengthCM; @@ -83,6 +84,8 @@ class treadmill : public bluetoothdevice { int16_t requestPower = -1; treadmillErgTable _ergTable; + void parseSpeed(double speed); + private: bool simulateInclinationWithSpeed(); void evaluateStepCount(); diff --git a/src/qzsettings.cpp b/src/qzsettings.cpp index 1d7934501..924803691 100644 --- a/src/qzsettings.cpp +++ b/src/qzsettings.cpp @@ -722,6 +722,7 @@ const QString QZSettings::tile_step_count_order = QStringLiteral("tile_step_coun const QString QZSettings::tile_erg_mode_enabled = QStringLiteral("tile_erg_mode_enabled"); const QString QZSettings::tile_erg_mode_order = QStringLiteral("tile_erg_mode_order"); const QString QZSettings::toorx_srx_3500 = QStringLiteral("toorx_srx_3500"); +const QString QZSettings::stryd_speed_instead_treadmill = QStringLiteral("stryd_speed_instead_treadmill"); const QString QZSettings::inclination_delay_seconds = QStringLiteral("inclination_delay_seconds"); const QString QZSettings::ergDataPoints = QStringLiteral("ergDataPoints"); const QString QZSettings::default_ergDataPoints = QStringLiteral(""); @@ -736,7 +737,7 @@ const QString QZSettings::treadmillDataPoints = QStringLiteral("treadmillDataPoi const QString QZSettings::default_treadmillDataPoints = QStringLiteral(""); const QString QZSettings::nordictrack_s20i_treadmill = QStringLiteral("nordictrack_s20i_treadmill"); -const uint32_t allSettingsCount = 620; +const uint32_t allSettingsCount = 621; QVariant allSettings[allSettingsCount][2] = { {QZSettings::cryptoKeySettingsProfiles, QZSettings::default_cryptoKeySettingsProfiles}, @@ -1352,6 +1353,7 @@ QVariant allSettings[allSettingsCount][2] = { {QZSettings::tile_erg_mode_enabled, QZSettings::default_tile_erg_mode_enabled}, {QZSettings::tile_erg_mode_order, QZSettings::default_tile_erg_mode_order}, {QZSettings::toorx_srx_3500, QZSettings::default_toorx_srx_3500}, + {QZSettings::stryd_speed_instead_treadmill, QZSettings::default_stryd_speed_instead_treadmill}, {QZSettings::inclination_delay_seconds, QZSettings::default_inclination_delay_seconds}, {QZSettings::ergDataPoints, QZSettings::default_ergDataPoints}, {QZSettings::proform_carbon_tl, QZSettings::default_proform_carbon_tl}, diff --git a/src/qzsettings.h b/src/qzsettings.h index 64404c6e7..d4541bd0f 100644 --- a/src/qzsettings.h +++ b/src/qzsettings.h @@ -2028,6 +2028,8 @@ class QZSettings { static const QString toorx_srx_3500; static constexpr bool default_toorx_srx_3500 = false; + static const QString stryd_speed_instead_treadmill; + static constexpr bool default_stryd_speed_instead_treadmill = false; static const QString inclination_delay_seconds; static constexpr float default_inclination_delay_seconds = 0.0; diff --git a/src/settings.qml b/src/settings.qml index ffd84b8ab..c2f023ce7 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -914,7 +914,7 @@ import QtQuick.Dialogs 1.0 property int tile_erg_mode_order: 52 // from version 2.16.45 - property bool toorx_srx_3500: false + property bool toorx_srx_3500: false property real inclination_delay_seconds: 0.0 // from version 2.16.47 @@ -934,6 +934,7 @@ import QtQuick.Dialogs 1.0 // from version 2.16.54 property bool nordictrack_s20i_treadmill: false + property bool stryd_speed_instead_treadmill: false } function paddingZeros(text, limit) { @@ -8384,6 +8385,33 @@ import QtQuick.Dialogs 1.0 color: Material.color(Material.Lime) } + SwitchDelegate { + text: qsTr("Use speed from the power sensor") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.stryd_speed_instead_treadmill + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.stryd_speed_instead_treadmill = checked + } + + Label { + text: qsTr("If you have a bluetooth treadmill and also a Stryd device connected to QZ and you want to use the speed from the stryd instead of the speed of the treadmill, enable this. Default: disabled.") + font.bold: true + font.italic: true + font.pixelSize: 9 + textFormat: Text.PlainText + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + color: Material.color(Material.Lime) + } + Label { id: labelPowerSensorName text: qsTr("Power Sensor:")