Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ftms wheel diamater for gears #2715

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions src/devices/ftmsbike/ftmsbike.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,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,
Expand Down Expand Up @@ -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;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why setting circumference as diameter*10, no mistake here?


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));
Expand Down Expand Up @@ -285,14 +299,16 @@ void ftmsbike::update() {
if (((virtualBike && !virtualBike->ftmsDeviceConnected()) || !virtualBike) &&
(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;
Expand Down Expand Up @@ -1065,13 +1081,8 @@ void ftmsbike::ftmsCharacteristicChanged(const QLowEnergyCharacteristic &charact
lastPacketFromFTMS.append(b.at(i));
qDebug() << "lastPacketFromFTMS" << lastPacketFromFTMS.toHex(' ');
int16_t slope = (((uint8_t)b.at(3)) + (b.at(4) << 8));
if (gears() != 0) {
slope += (gears() * 50);
}
b[3] = slope & 0xFF;
b[4] = slope >> 8;

qDebug() << "applying gears mod" << gears() << slope;
b[4] = slope >> 8;
/*} else if(b.at(0) == FTMS_SET_INDOOR_BIKE_SIMULATION_PARAMS && zwiftPlayService != nullptr && gears_zwift_ratio) {
int16_t slope = (((uint8_t)b.at(3)) + (b.at(4) << 8));
uint8_t gear2[] = {0x04, 0x22, 0x02, 0x10, 0x00};
Expand Down
2 changes: 2 additions & 0 deletions src/devices/ftmsbike/ftmsbike.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <QObject>
#include <QString>

#include "wheelcircumference.h"
#include "devices/bike.h"

#ifdef Q_OS_IOS
Expand Down Expand Up @@ -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;
Expand Down
19 changes: 4 additions & 15 deletions src/devices/wahookickrsnapbike/wahookickrsnapbike.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ wahookickrsnapbike::wahookickrsnapbike(bool noWriteResistance, bool noHeartServi
initDone = false;
connect(refresh, &QTimer::timeout, this, &wahookickrsnapbike::update);
refresh->start(200ms);
GearTable g;
wheelCircumference::GearTable g;
g.printTable();
}

Expand Down Expand Up @@ -194,7 +194,7 @@ void wahookickrsnapbike::update() {
}
QThread::msleep(700);

QByteArray d = setWheelCircumference(gearsToWheelDiameter(gears()));
QByteArray d = setWheelCircumference(wheelCircumference::gearsToWheelDiameter(gears()));
uint8_t e[20];
setGears(1);
memcpy(e, d.constData(), d.length());
Expand Down Expand Up @@ -267,7 +267,7 @@ void wahookickrsnapbike::update() {
memcpy(b, a.constData(), a.length());
writeCharacteristic(b, a.length(), "setResistance", false, true);
} else if (virtualBike && virtualBike->ftmsDeviceConnected() && 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, true);
Expand All @@ -291,17 +291,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());
}
Expand Down Expand Up @@ -856,7 +845,7 @@ bool wahookickrsnapbike::inclinationAvailableByHardware() {
}

double wahookickrsnapbike::maxGears() {
GearTable g;
wheelCircumference::GearTable g;
return g.maxGears;
}

Expand Down
82 changes: 1 addition & 81 deletions src/devices/wahookickrsnapbike/wahookickrsnapbike.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <QObject>
#include <QString>

#include "wheelcircumference.h"
#include "devices/bike.h"
#include "virtualdevices/virtualbike.h"

Expand Down Expand Up @@ -111,87 +112,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
Expand Down
1 change: 1 addition & 0 deletions src/qdomyos-zwift.pri
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,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 \
Expand Down
120 changes: 120 additions & 0 deletions src/wheelcircumference.h
Original file line number Diff line number Diff line change
@@ -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
Loading