Compare commits

...

30 Commits

Author SHA1 Message Date
Roberto Viola
07606facba adding inclination custom message too 2024-11-09 18:49:48 +01:00
Roberto Viola
bd0e7033c2 Merge branch 'master' into zwift-hub-gear-custom 2024-11-09 18:42:47 +01:00
Roberto Viola
0337c08252 first custom gear test 2024-11-09 15:48:01 +01:00
Roberto Viola
8b60b56dc2 Update ftmsbike.cpp 2024-11-09 15:43:06 +01:00
Roberto Viola
f3d8b3964c Merge branch 'master' into tacx_wheel_diameter 2024-11-09 15:37:11 +01:00
Roberto Viola
06253998ee Update wahookickrsnapbike.cpp 2024-11-04 15:08:26 +01:00
Roberto Viola
dbb9ba3510 implementing 2024-11-04 14:31:58 +01:00
Roberto Viola
ad802f7d2d Merge branch 'master' into tacx_wheel_diameter 2024-11-04 14:28:42 +01:00
Roberto Viola
9cc02dede9 ftms wheel circumference for gears 2024-10-30 15:57:31 +01:00
Roberto Viola
82a6afe6b6 kickr core to wahookickr class 2024-10-29 12:28:13 +01:00
Roberto Viola
a7b8e63235 fixing UI and settings 2024-10-29 08:50:33 +01:00
Roberto Viola
d7c3a84adb adding max and minGears 2024-10-29 08:21:59 +01:00
Roberto Viola
64b9ec9d72 fixing gear conversion 2024-10-29 08:17:38 +01:00
Roberto Viola
379cf8d7de Update project.pbxproj 2024-10-29 08:02:08 +01:00
Roberto Viola
2f2989f90d completed? 2024-10-28 15:40:00 +01:00
Roberto Viola
6fac9770be qml finally saves the settings correctly 2024-10-28 15:09:13 +01:00
Roberto Viola
8d07d7c3f7 Merge branch 'master' into Custom-gearing-ranges/ratios-(Discussion-#2671) 2024-10-28 13:44:31 +01:00
Roberto Viola
f85f743499 i need to save the first 3 static objects and use it in the wahoo module 2024-10-28 11:11:05 +01:00
Roberto Viola
74c37f5624 Update gears.qml 2024-10-28 09:46:58 +01:00
Roberto Viola
527396eafc Revert "Update gears.qml"
This reverts commit 0f149448b3.
2024-10-28 09:18:54 +01:00
Roberto Viola
0f149448b3 Update gears.qml 2024-10-25 16:28:33 +02:00
Roberto Viola
ed1599ca8e need to center the values in the table 2024-10-24 15:08:25 +02:00
Roberto Viola
89808ae65b fixing casting to double 2024-10-24 11:15:51 +02:00
Roberto Viola
2da194f073 Merge branch 'master' into Custom-gearing-ranges/ratios-(Discussion-#2671) 2024-10-24 11:00:46 +02:00
Roberto Viola
d712621b7b fixing formula 2024-10-23 11:47:05 +02:00
Roberto Viola
1c06260036 Merge branch 'master' into Custom-gearing-ranges/ratios-(Discussion-#2671) 2024-10-23 11:44:26 +02:00
Roberto Viola
2d1364497e Update virtualbike_zwift.swift 2024-10-22 15:40:04 +02:00
Roberto Viola
cc7757bfcd Update project.pbxproj 2024-10-22 15:38:44 +02:00
Roberto Viola
49c7a96c81 Merge branch 'master' into Custom-gearing-ranges/ratios-(Discussion-#2671) 2024-10-22 15:32:50 +02:00
Roberto Viola
05d598ffcf first raw version 2024-10-21 14:06:48 +02:00
8 changed files with 246 additions and 217 deletions

View File

@@ -4068,7 +4068,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 933;
CURRENT_PROJECT_VERSION = 935;
DEVELOPMENT_TEAM = 6335M7T29D;
ENABLE_BITCODE = NO;
GCC_PREPROCESSOR_DEFINITIONS = "ADB_HOST=1";
@@ -4259,7 +4259,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 933;
CURRENT_PROJECT_VERSION = 935;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 6335M7T29D;
ENABLE_BITCODE = NO;
@@ -4486,7 +4486,7 @@
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 933;
CURRENT_PROJECT_VERSION = 935;
DEVELOPMENT_TEAM = 6335M7T29D;
ENABLE_BITCODE = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -4582,7 +4582,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 933;
CURRENT_PROJECT_VERSION = 935;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 6335M7T29D;
ENABLE_BITCODE = YES;
@@ -4674,7 +4674,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 933;
CURRENT_PROJECT_VERSION = 935;
DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\"";
ENABLE_BITCODE = YES;
ENABLE_PREVIEWS = YES;
@@ -4788,7 +4788,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 933;
CURRENT_PROJECT_VERSION = 935;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\"";
ENABLE_BITCODE = YES;

View File

@@ -15,6 +15,7 @@
#include "keepawakehelper.h"
#endif
#include <chrono>
#include "wheelcircumference.h"
#ifdef Q_OS_IOS
extern quint8 QZ_EnableDiscoveryCharsAndDescripttors;
@@ -35,6 +36,8 @@ ftmsbike::ftmsbike(bool noWriteResistance, bool noHeartService, int8_t bikeResis
initDone = false;
connect(refresh, &QTimer::timeout, this, &ftmsbike::update);
refresh->start(settings.value(QZSettings::poll_device_time, QZSettings::default_poll_device_time).toInt());
wheelCircumference::GearTable g;
g.printTable();
}
void ftmsbike::writeCharacteristicZwiftPlay(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log,
@@ -130,9 +133,8 @@ void ftmsbike::init() {
void ftmsbike::zwiftPlayInit() {
QSettings settings;
bool gears_zwift_ratio = settings.value(QZSettings::gears_zwift_ratio, QZSettings::default_gears_zwift_ratio).toBool();
if(zwiftPlayService && gears_zwift_ratio) {
if(zwiftPlayService) {
uint8_t rideOn[] = {0x52, 0x69, 0x64, 0x65, 0x4f, 0x6e, 0x02, 0x01};
writeCharacteristicZwiftPlay(rideOn, sizeof(rideOn), "rideOn", false, true);
@@ -170,6 +172,18 @@ void ftmsbike::zwiftPlayInit() {
}
}
void ftmsbike::setWheelDiameter(double diameter) {
uint8_t write[] = {FTMS_SET_WHEEL_CIRCUMFERENCE, 0x00, 0x00};
diameter = diameter * 10.0;
write[1] = ((uint16_t)diameter) & 0xFF;
write[2] = ((uint16_t)diameter) >> 8;
writeCharacteristic(write, sizeof(write), QStringLiteral("setWheelCircumference ") + QString::number(diameter));
}
void ftmsbike::forcePower(int16_t requestPower) {
if(resistance_lvl_mode) {
forceResistance(resistanceFromPowerRequest(requestPower));
@@ -285,113 +299,61 @@ void ftmsbike::update() {
if (((virtualBike && !virtualBike->ftmsDeviceConnected()) || !virtualBike || resistance_lvl_mode) &&
(requestPower == 0 || requestPower == -1)) {
init();
forceResistance(requestResistance + (gears() * 5));
if(requestResistance != - 1)
forceResistance(requestResistance + (gears() * 5));
else
setWheelDiameter(wheelCircumference::gearsToWheelDiameter(gears()));
}
}
requestResistance = -1;
}
if((virtualBike && virtualBike->ftmsDeviceConnected()) && lastGearValue != gears() && lastRawRequestedInclinationValue != -100 && lastPacketFromFTMS.length() >= 7) {
qDebug() << "injecting fake ftms frame in order to send the new gear value ASAP" << lastPacketFromFTMS.toHex(' ');
ftmsCharacteristicChanged(QLowEnergyCharacteristic(), lastPacketFromFTMS);
setWheelDiameter(wheelCircumference::gearsToWheelDiameter(gears()));
}
QSettings settings;
bool gears_zwift_ratio = settings.value(QZSettings::gears_zwift_ratio, QZSettings::default_gears_zwift_ratio).toBool();
if(zwiftPlayService && gears_zwift_ratio && lastGearValue != gears()) {
uint8_t gear1[] = {0x04, 0x2a, 0x03, 0x10, 0xdc, 0xec};
uint8_t gear2[] = {0x04, 0x2a, 0x04, 0x10, 0xdc, 0xec, 0x01};
uint32_t gear_value = 0;
switch((int)gears()) {
case 1:
gear_value = 0x3acc;
break;
case 2:
gear_value = 0x43fc;
break;
case 3:
gear_value = 0x4dac;
break;
case 4:
gear_value = 0x56d5;
break;
case 5:
gear_value = 0x608c;
break;
case 6:
gear_value = 0x6be8;
break;
case 7:
gear_value = 0x77c4;
break;
case 8:
gear_value = 0x183a0;
break;
case 9:
gear_value = 0x191a8;
break;
case 10:
gear_value = 0x19fb0;
break;
case 11:
gear_value = 0x1adb8;
break;
case 12:
gear_value = 0x1bbc0;
break;
case 13:
gear_value = 0x1cbf3;
break;
case 14:
gear_value = 0x1dca8;
break;
case 15:
gear_value = 0x1ecdc;
break;
case 16:
gear_value = 0x1fd90;
break;
case 17:
gear_value = 0x290d4;
break;
case 18:
gear_value = 0x2a498;
break;
case 19:
gear_value = 0x2b7dc;
break;
case 20:
gear_value = 0x2cb9f;
break;
case 21:
gear_value = 0x2e2d8;
break;
case 22:
gear_value = 0x2fa90;
break;
case 23:
gear_value = 0x391c8;
break;
case 24:
gear_value = 0x3acf3;
break;
default:
// Gestione del caso di default
if(zwiftPlayService && lastGearValue != gears()) {
QSettings settings;
wheelCircumference::GearTable table;
wheelCircumference::GearTable::GearInfo g = table.getGear((int)gears());
double original_ratio = ((double)settings.value(QZSettings::gear_crankset_size, QZSettings::default_gear_crankset_size).toDouble()) /
((double)settings.value(QZSettings::gear_cog_size, QZSettings::default_gear_cog_size).toDouble());
double current_ratio = ((double)g.crankset / (double)g.rearCog);
uint32_t gear_value = static_cast<uint32_t>(10000.0 * (current_ratio/original_ratio) * (42.0/14.0));
qDebug() << "zwift hub gear current ratio" << current_ratio << g.crankset << g.rearCog << "gear_value" << gear_value << "original_ratio" << original_ratio;
QByteArray proto;
proto.append(0x04); // Length prefix
proto.append(0x2a); // Field number/wire type
// Calculate varint size inline
uint32_t temp = gear_value;
int size = 0;
do {
size++;
temp >>= 7;
if(size > 3) {
qDebug() << "ERROR! on while";
break;
}
} while (temp > 0);
// Use 0x03 for 2-byte values, 0x04 for 3-byte values
proto.append(size <= 2 ? 0x03 : 0x04);
proto.append(0x10); // Field marker
// Encode value as varint
temp = gear_value;
while (temp > 0x7F) {
proto.append((temp & 0x7F) | 0x80);
temp >>= 7;
}
gear_value = gear_value * settings.value(QZSettings::gears_gain, QZSettings::default_gears_gain).toDouble();
if(gear_value < 0x10000) {
gear1[4] = gear_value & 0xFF;
gear1[5] = ((gear_value & 0xFF00) >> 8) & 0xFF;
writeCharacteristicZwiftPlay(gear1, sizeof(gear1), "gear", false, true);
} else {
gear2[4] = gear_value & 0xFF;
gear2[5] = ((gear_value & 0xFF00) >> 8) & 0xFF;
gear2[6] = ((gear_value & 0xFF0000) >> 16) & 0xFF;
writeCharacteristicZwiftPlay(gear2, sizeof(gear2), "gear", false, true);
}
proto.append(temp & 0x7F);
writeCharacteristicZwiftPlay((uint8_t*)proto.data(), sizeof(proto), "gear", false, true);
uint8_t gearApply[] = {0x00, 0x08, 0x88, 0x04};
writeCharacteristicZwiftPlay(gearApply, sizeof(gearApply), "gearApply", false, true);
@@ -1053,13 +1015,12 @@ void ftmsbike::ftmsCharacteristicChanged(const QLowEnergyCharacteristic &charact
QByteArray b = newValue;
QSettings settings;
bool gears_zwift_ratio = settings.value(QZSettings::gears_zwift_ratio, QZSettings::default_gears_zwift_ratio).toBool();
if (gattWriteCharControlPointId.isValid()) {
qDebug() << "routing FTMS packet to the bike from virtualbike" << characteristic.uuid() << newValue.toHex(' ');
// handling gears
if (b.at(0) == FTMS_SET_INDOOR_BIKE_SIMULATION_PARAMS && ((zwiftPlayService == nullptr && gears_zwift_ratio) || !gears_zwift_ratio)) {
if (b.at(0) == FTMS_SET_INDOOR_BIKE_SIMULATION_PARAMS && zwiftPlayService == nullptr) {
double min_inclination = settings.value(QZSettings::min_inclination, QZSettings::default_min_inclination).toDouble();
lastPacketFromFTMS.clear();
for(int i=0; i<b.length(); i++)
@@ -1076,18 +1037,50 @@ void ftmsbike::ftmsCharacteristicChanged(const QLowEnergyCharacteristic &charact
}
b[3] = slope & 0xFF;
b[4] = slope >> 8;
qDebug() << "applying gears mod" << gears() << slope;
/*} else if(b.at(0) == FTMS_SET_INDOOR_BIKE_SIMULATION_PARAMS && zwiftPlayService != nullptr && gears_zwift_ratio) {
b[4] = slope >> 8;
} else if(b.at(0) == FTMS_SET_INDOOR_BIKE_SIMULATION_PARAMS && zwiftPlayService != nullptr) {
int16_t slope = (((uint8_t)b.at(3)) + (b.at(4) << 8));
uint8_t gear2[] = {0x04, 0x22, 0x02, 0x10, 0x00};
int g = (int)(((double)slope / 100.0) + settings.value(QZSettings::gears_offset, QZSettings::default_gears_offset).toDouble());
if(g < 0) {
g = 0;
QByteArray message;
// Command code 0x04
message.append(0x04);
// SimulationParam tag (field 4 << 3 | wire_type 2 = 34)
message.append(0x22);
// Lunghezza payload (11 bytes)
message.append(0x0b);
// Wind (field 1) - fisso a 0
message.append(0x08); // tag
message.append((uint8_t)0x00); // value = 0
// Incline (field 2)
message.append(0x10); // tag
qint32 inclineX100 = static_cast<qint32>(slope);
// varint inclination
while (inclineX100 >= 0x80) {
message.append((inclineX100 & 0x7F) | 0x80);
inclineX100 >>= 7;
}
gear2[4] = g;
writeCharacteristicZwiftPlay(gear2, sizeof(gear2), "gearInclination", false, false);*/
message.append(inclineX100 & 0x7F);
// CWa (field 3) - fix a 10220 (1.022 / 2)
message.append(0x18); // tag
message.append(0xec); // 236
message.append(0x27); // 39
// Crr (field 4) - fix a 400 (0.004)
message.append(0x20); // tag
message.append(0x90); // 144
message.append(0x03); // 3
writeCharacteristicZwiftPlay((uint8_t*)message.data(), message.length(), "gearInclination", false, false);
return;
} else if(b.at(0) == FTMS_SET_TARGET_POWER && zwiftPlayService != nullptr) {
qDebug() << "discarding";
return;
} else if(b.at(0) == FTMS_SET_TARGET_POWER && b.length() > 2) {
lastPacketFromFTMS.clear();
for(int i=0; i<b.length(); i++)

View File

@@ -26,6 +26,7 @@
#include <QObject>
#include <QString>
#include "wheelcircumference.h"
#include "devices/bike.h"
#ifdef Q_OS_IOS
@@ -85,6 +86,7 @@ class ftmsbike : public bike {
void init();
void forceResistance(resistance_t requestResistance);
void forcePower(int16_t requestPower);
void setWheelDiameter(double diameter);
uint16_t wattsFromResistance(double resistance);
QTimer *refresh;

View File

@@ -7,6 +7,7 @@
#include <QSettings>
#include <QThread>
#include <math.h>
#include "wheelcircumference.h"
#ifdef Q_OS_ANDROID
#include "keepawakehelper.h"
#include <QLowEnergyConnectionParameters>
@@ -123,7 +124,7 @@ void tacxneo2::update() {
auto virtualBike = this->VirtualBike();
if (requestResistance != -1) {
if (requestResistance != currentResistance().value() || lastGearValue != gears()) {
if (requestResistance != currentResistance().value()) {
emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance));
if (((virtualBike && !virtualBike->ftmsDeviceConnected()) || !virtualBike) &&
(requestPower == 0 || requestPower == -1)) {
@@ -135,15 +136,18 @@ void tacxneo2::update() {
}
if (requestInclination != -100) {
emit debug(QStringLiteral("writing inclination ") + QString::number(requestInclination));
forceInclination(requestInclination + gears()); // since this bike doesn't have the concept of resistance,
forceInclination(requestInclination); // since this bike doesn't have the concept of resistance,
// i'm using the gears in the inclination
requestInclination = -100;
} else if((virtualBike && virtualBike->ftmsDeviceConnected()) && lastGearValue != gears() && lastRawRequestedInclinationValue != -100) {
} else if((virtualBike && virtualBike->ftmsDeviceConnected()) && lastRawRequestedInclinationValue != -100) {
// in order to send the new gear value ASAP
forceInclination(lastRawRequestedInclinationValue + gears()); // since this bike doesn't have the concept of resistance,
forceInclination(lastRawRequestedInclinationValue); // since this bike doesn't have the concept of resistance,
// i'm using the gears in the inclination
}
if(lastGearValue != gears())
setUserConfiguration(wheelCircumference::gearsToWheelDiameter(gears()), 1);
lastGearValue = gears();
if (requestPower != -1) {

View File

@@ -32,7 +32,7 @@ wahookickrsnapbike::wahookickrsnapbike(bool noWriteResistance, bool noHeartServi
connect(refresh, &QTimer::timeout, this, &wahookickrsnapbike::update);
QSettings settings;
refresh->start(settings.value(QZSettings::poll_device_time, QZSettings::default_poll_device_time).toInt());
GearTable g;
wheelCircumference::GearTable g;
g.printTable();
}
@@ -197,7 +197,7 @@ void wahookickrsnapbike::update() {
}
QThread::msleep(700);
QByteArray d = setWheelCircumference(gearsToWheelDiameter(gears()));
QByteArray d = setWheelCircumference(wheelCircumference::gearsToWheelDiameter(gears()));
uint8_t e[20];
setGears(settings.value(QZSettings::gears_current_value, QZSettings::default_gears_current_value).toDouble());
memcpy(e, d.constData(), d.length());
@@ -271,7 +271,7 @@ void wahookickrsnapbike::update() {
}
if (lastGearValue != gears()) {
QByteArray a = setWheelCircumference(gearsToWheelDiameter(gears()));
QByteArray a = setWheelCircumference(wheelCircumference::gearsToWheelDiameter(gears()));
uint8_t b[20];
memcpy(b, a.constData(), a.length());
writeCharacteristic(b, a.length(), "setWheelCircumference", false, false);
@@ -295,17 +295,6 @@ void wahookickrsnapbike::update() {
}
}
double wahookickrsnapbike::gearsToWheelDiameter(double gear) {
QSettings settings;
GearTable table;
if(gear < 1) gear = 1;
else if(gear > table.maxGears) gear = table.maxGears;
double original_ratio = ((double)settings.value(QZSettings::gear_crankset_size, QZSettings::default_gear_crankset_size).toDouble()) / ((double)settings.value(QZSettings::gear_cog_size, QZSettings::default_gear_cog_size).toDouble());
GearTable::GearInfo g = table.getGear((int)gear);
double current_ratio = ((double)g.crankset / (double)g.rearCog);
return (((double)settings.value(QZSettings::gear_circumference, QZSettings::default_gear_circumference).toDouble()) / original_ratio) * ((double)current_ratio);
}
void wahookickrsnapbike::serviceDiscovered(const QBluetoothUuid &gatt) {
emit debug(QStringLiteral("serviceDiscovered ") + gatt.toString());
}
@@ -871,7 +860,7 @@ bool wahookickrsnapbike::inclinationAvailableByHardware() {
}
double wahookickrsnapbike::maxGears() {
GearTable g;
wheelCircumference::GearTable g;
return g.maxGears;
}

View File

@@ -26,6 +26,7 @@
#include <QObject>
#include <QString>
#include "wheelcircumference.h"
#include "devices/bike.h"
#include "virtualdevices/virtualbike.h"
@@ -113,87 +114,6 @@ class wahookickrsnapbike : public bike {
resistance_t lastForcedResistance = -1;
double gearsToWheelDiameter(double gear);
class GearTable {
public:
int maxGears = 12;
struct GearInfo {
int gear;
int crankset;
int rearCog;
};
void loadGearSettings() {
QSettings settings;
QString gearConfig = settings.value("gear_configuration").toString();
if (gearConfig.isEmpty()) {
gearConfig = "1|38|44|true\n2|38|38|true\n3|38|32|true\n4|38|28|true\n"
"5|38|24|true\n6|38|21|true\n7|38|19|true\n8|38|17|true\n"
"9|38|15|true\n10|38|13|true\n11|38|11|true\n12|38|10|true";
}
gears.clear();
maxGears = 0;
// Parsa la configurazione
QStringList rows = gearConfig.split('\n');
for (const QString& row : rows) {
QStringList parts = row.split('|');
if (parts.size() >= 4 && (parts[3] == "true")) {
GearInfo config;
config.gear = parts[0].toInt();
config.crankset = parts[1].toInt();
config.rearCog = parts[2].toInt();
gears.push_back(config);
maxGears = qMax(maxGears, config.gear);
}
}
}
void addGear(int gear, int crankset, int rearCog) {
gears.push_back({gear, crankset, rearCog});
}
void removeGear(int gear) {
gears.erase(std::remove_if(gears.begin(), gears.end(),
[gear](const GearInfo& info) { return info.gear == gear; }),
gears.end());
}
void printTable() const {
qDebug() << "| Gear | Crankset | Rear Cog |\n";
qDebug() << "|------|----------|----------|\n";
for (const auto& gear : gears) {
qDebug() << "| " << gear.gear << " | " << gear.crankset
<< " | " << gear.rearCog << " |\n";
}
}
GearInfo getGear(int gearNumber) const {
auto it = std::find_if(gears.begin(), gears.end(),
[gearNumber](const GearInfo& info) { return info.gear == gearNumber; });
if (it != gears.end()) {
return *it;
}
return GearInfo();
}
GearTable() {
loadGearSettings();
}
private:
std::vector<GearInfo> gears;
};
#ifdef Q_OS_IOS
lockscreen *h = 0;
#endif

View File

@@ -312,6 +312,7 @@ HEADERS += \
$$PWD/devices/trxappgateusbelliptical/trxappgateusbelliptical.h \
$$PWD/ergtable.h \
$$PWD/treadmillErgTable.h \
$$PWD/wheelcircumference.h \
QTelnet.h \
devices/bkoolbike/bkoolbike.h \
devices/csaferower/csafe.h \

120
src/wheelcircumference.h Normal file
View File

@@ -0,0 +1,120 @@
#ifndef WHEELCIRCUMFERENCE_H
#define WHEELCIRCUMFERENCE_H
#include <QtCore/qbytearray.h>
#ifndef Q_OS_ANDROID
#include <QtCore/qcoreapplication.h>
#else
#include <QtGui/qguiapplication.h>
#endif
#include <QtCore/qlist.h>
#include <QtCore/qmutex.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/qtimer.h>
#include <QDateTime>
#include <QObject>
#include <QString>
#include <QSettings>
#include <QDebug>
#include "qzsettings.h"
class wheelCircumference : public QObject {
Q_OBJECT
public:
static double gearsToWheelDiameter(double gear) {
QSettings settings;
GearTable table;
if(gear < 1) gear = 1;
else if(gear > table.maxGears) gear = table.maxGears;
double original_ratio = ((double)settings.value(QZSettings::gear_crankset_size, QZSettings::default_gear_crankset_size).toDouble()) / ((double)settings.value(QZSettings::gear_cog_size, QZSettings::default_gear_cog_size).toDouble());
GearTable::GearInfo g = table.getGear((int)gear);
double current_ratio = ((double)g.crankset / (double)g.rearCog);
return (((double)settings.value(QZSettings::gear_circumference, QZSettings::default_gear_circumference).toDouble()) / original_ratio) * ((double)current_ratio);
}
class GearTable {
public:
int maxGears = 12;
struct GearInfo {
int gear;
int crankset;
int rearCog;
};
void loadGearSettings() {
QSettings settings;
QString gearConfig = settings.value("gear_configuration").toString();
if (gearConfig.isEmpty()) {
gearConfig = "1|38|44|true\n2|38|38|true\n3|38|32|true\n4|38|28|true\n"
"5|38|24|true\n6|38|21|true\n7|38|19|true\n8|38|17|true\n"
"9|38|15|true\n10|38|13|true\n11|38|11|true\n12|38|10|true";
}
gears.clear();
maxGears = 0;
// Parsa la configurazione
QStringList rows = gearConfig.split('\n');
for (const QString& row : rows) {
QStringList parts = row.split('|');
if (parts.size() >= 4 && (parts[3] == "true")) {
GearInfo config;
config.gear = parts[0].toInt();
config.crankset = parts[1].toInt();
config.rearCog = parts[2].toInt();
gears.push_back(config);
maxGears = qMax(maxGears, config.gear);
}
}
}
void addGear(int gear, int crankset, int rearCog) {
gears.push_back({gear, crankset, rearCog});
}
void removeGear(int gear) {
gears.erase(std::remove_if(gears.begin(), gears.end(),
[gear](const GearInfo& info) { return info.gear == gear; }),
gears.end());
}
void printTable() const {
qDebug() << "| Gear | Crankset | Rear Cog |\n";
qDebug() << "|------|----------|----------|\n";
for (const auto& gear : gears) {
qDebug() << "| " << gear.gear << " | " << gear.crankset
<< " | " << gear.rearCog << " |\n";
}
}
GearInfo getGear(int gearNumber) const {
auto it = std::find_if(gears.begin(), gears.end(),
[gearNumber](const GearInfo& info) { return info.gear == gearNumber; });
if (it != gears.end()) {
return *it;
}
return GearInfo();
}
GearTable() {
loadGearSettings();
}
private:
std::vector<GearInfo> gears;
};
};
#endif // WHEELCIRCUMFERENCE_H