forked from cagnulein/qdomyos-zwift
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtrainprogram.h
More file actions
202 lines (180 loc) · 6.55 KB
/
Copy pathtrainprogram.h
File metadata and controls
202 lines (180 loc) · 6.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#ifndef TRAINPROGRAM_H
#define TRAINPROGRAM_H
#include "bluetooth.h"
#include <QGeoCoordinate>
#include <QMutex>
#include <QObject>
#include <QSet>
#include <QTime>
#include <QTimer>
#ifdef Q_OS_IOS
#include "ios/lockscreen.h"
#endif
#include "zwift-api/PlayerStateWrapper.h"
#include "zwift-api/zwift_client_auth.h"
#ifdef Q_CC_MSVC
#include "zwift-api/zwift_messages.pb.h"
#endif
class trainrow {
public:
QTime duration = QTime(0, 0, 0, 0);
QDateTime started = QDateTime();
QDateTime ended = QDateTime();
double distance = -1;
double speed = -1;
double lower_speed = -1; // used for peloton
double average_speed = -1; // used for peloton
double upper_speed = -1; // used for peloton
double fanspeed = -1;
double inclination = -200;
double lower_inclination = -200; // used for peloton
double average_inclination = -200; // used for peloton
double upper_inclination = -200; // used for peloton
resistance_t resistance = -1;
resistance_t lower_resistance = -1;
resistance_t average_resistance = -1; // used for peloton
resistance_t upper_resistance = -1;
int8_t requested_peloton_resistance = -1;
int8_t lower_requested_peloton_resistance = -1;
int8_t average_requested_peloton_resistance = -1; // used for peloton
int8_t upper_requested_peloton_resistance = -1;
int8_t pace_intensity = -1; // used for peloton
int16_t cadence = -1;
int16_t lower_cadence = -1;
int16_t average_cadence = -1; // used for peloton
int16_t upper_cadence = -1;
bool forcespeed = false;
int8_t loopTimeHR = 10;
int8_t zoneHR = -1;
int16_t HRmin = -1;
int16_t HRmax = -1;
double maxSpeed = -1;
double minSpeed = -1;
int8_t maxResistance = -1;
int32_t power = -1;
int32_t mets = -1;
QTime rampDuration = QTime(0, 0, 0, 0); // QZ split the ramp in 1 second segments. This field will tell you how long
// is the ramp from this very moment
QTime rampElapsed = QTime(0, 0, 0, 0);
QTime gpxElapsed = QTime(0, 0, 0, 0);
double latitude = NAN;
double longitude = NAN;
double altitude = NAN;
double azimuth = NAN;
// Text events with time offsets
struct TextEvent {
uint32_t timeoffset = 0; // Time offset in seconds from the start of this row
QString message;
};
QList<TextEvent> textEvents;
QString toString() const;
};
class trainprogram : public QObject {
Q_OBJECT
public:
trainprogram(const QList<trainrow> &, bluetooth *b, QString *description = nullptr, QString *tags = nullptr,
bool videoAvailable = false);
void save(const QString &filename);
static trainprogram *load(const QString &filename, bluetooth *b, QString Extension);
static QList<trainrow> loadXML(const QString &filename, BLUETOOTH_TYPE device_type);
static bool saveXML(const QString &filename, const QList<trainrow> &rows);
static bool hasTargetPower(const QString &filename);
QTime totalElapsedTime();
QTime currentRowElapsedTime();
QTime currentRowRemainingTime();
QTime remainingTime();
double currentTargetMets();
QTime duration();
double totalDistance();
trainrow currentRow();
trainrow getRowFromCurrent(uint32_t offset);
void increaseElapsedTime(int32_t i);
void decreaseElapsedTime(int32_t i);
int32_t offsetElapsedTime() { return offset; }
void clearRows();
double avgSpeedFromGpxStep(int gpxStep, int seconds);
double TimeRateFromGPX(double gpxsecs, double videosecs, double currentspeed, int recordingFactor);
int TotalGPXSecs();
double weightedInclination(int step);
double medianInclination(int step);
bool overridePowerForCurrentRow(double power);
bool overrideZoneHRForCurrentRow(uint8_t zone);
bool powerzoneWorkout() {
foreach(trainrow r, rows) {
if(r.power != -1) return true;
}
return false;
}
QList<trainrow> rows;
QList<trainrow> loadedRows; // rows as loaded
QString description = "";
QString tags = "";
bool enabled = true;
bool videoAvailable = false;
void setVideoAvailable(bool v) {videoAvailable = v;}
void restart();
bool isStarted() { return started; }
void scheduler(int tick);
void applySpeedFilter();
public slots:
void onTapeStarted();
void scheduler();
private slots:
void pelotonOCRprocessPendingDatagrams();
signals:
void start();
void stop(bool paused);
void lap();
void changeSpeed(double speed);
bool changeFanSpeed(uint8_t speed);
void changeInclination(double grade, double inclination);
void changeNextInclination300Meters(QList<MetersByInclination>);
void changeResistance(resistance_t resistance);
void changeRequestedPelotonResistance(int8_t resistance);
void changeCadence(int16_t cadence);
void changePower(int32_t power);
void changeSpeedAndInclination(double speed, double inclination);
void changeGeoPosition(QGeoCoordinate p, double azimuth, double avgAzimuthNext300Meters);
void changeTimestamp(QTime source, QTime actual);
void toastRequest(QString message);
void zwiftLoginState(bool ok);
void intervalTransitionApplied();
private:
void end();
mutable QRecursiveMutex schedulerMutex;
double avgAzimuthNext300Meters();
QList<MetersByInclination> inclinationNext300Meters();
QList<MetersByInclination> avgInclinationNext300Meters();
double avgInclinationNext100Meters(int step);
uint32_t calculateTimeForRow(int32_t row);
uint32_t calculateTimeForRowMergingRamps(int32_t row);
double calculateDistanceForRow(int32_t row);
bluetooth *bluetoothManager;
bool started = false;
int32_t ticks = 0;
uint16_t currentStep = 0;
int32_t offset = 0;
double lastOdometer = 0;
double currentStepDistance = 0;
QTimer timer;
double lastGpxRateSetAt = 0.0;
double lastGpxRateSet = 0.0;
double lastGpxSpeedSet = 0.0;
int lastStepTimestampChanged = 0;
double lastCurrentStepDistance = 0.0;
QTime lastCurrentStepTime = QTime(0, 0, 0);
int64_t currentTimerJitter = 0;
QDateTime lastSchedulerCall = QDateTime::currentDateTime();
QUdpSocket* pelotonOCRsocket = nullptr;
void pelotonOCRcomputeTime(QString t);
AuthToken* zwift_auth_token = nullptr;
World* zwift_world = nullptr;
int zwift_player_id = -1;
// Track which text events have been shown for each row
QSet<QString> shownTextEvents; // Format: "row_index:timeoffset"
#ifdef Q_OS_IOS
lockscreen *h = 0;
#endif
~trainprogram();
};
#endif // TRAINPROGRAM_H