Realtime checkpoint - WIN32 and Configurable Realtime

Fixups to compile video on WIN32 and added more configurability
in the realtime screens, but still not the chart and video use-case
needs to be decided.
This commit is contained in:
Mark Liversedge
2011-04-10 18:03:21 +01:00
parent 26402f0c36
commit 21afde2d0b
11 changed files with 209 additions and 59 deletions

View File

@@ -55,6 +55,9 @@ DialWindow::DialWindow(MainWindow *mainWindow) :
// setup fontsize etc
resizeEvent(NULL);
// set to zero
telemetryUpdate(RealtimeData());
}
void
@@ -85,15 +88,38 @@ void
DialWindow::telemetryUpdate(RealtimeData rtData)
{
// we got some!
RealtimeData::DataSeries series = static_cast<RealtimeData::DataSeries>(seriesSelector->itemData(seriesSelector->currentIndex()).toInt());
RealtimeData::DataSeries series = static_cast<RealtimeData::DataSeries>
(seriesSelector->itemData(seriesSelector->currentIndex()).toInt());
double value = rtData.value(series);
valueLabel->setText(QString("%1").arg(round(value)));
switch (series) {
case RealtimeData::Time:
case RealtimeData::LapTime:
{
long msecs = value;
valueLabel->setText(QString("%1:%2:%3.%4").arg(msecs/3600000)
.arg((msecs%3600000)/60000,2,10,QLatin1Char('0'))
.arg((msecs%60000)/1000,2,10,QLatin1Char('0'))
.arg((msecs%1000)/100));
}
break;
default:
valueLabel->setText(QString("%1").arg(round(value)));
break;
}
}
void DialWindow::resizeEvent(QResizeEvent * )
{
if (geometry().height()-37 < 0) return;
QFont font;
font.setPointSize(geometry().height()/2);
font.setPointSize((geometry().height()-37));
font.setWeight(QFont::Bold);
valueLabel->setFont(font);
}

View File

@@ -279,6 +279,7 @@ class MainWindow : public QMainWindow
SummaryWindow *summaryWindow;
DiaryWindow *diaryWindow;
HomeWindow *homeWindow;
TrainWindow *trainWindow;
AllPlotWindow *allPlotWindow;
HistogramWindow *histogramWindow;
WeeklySummaryWindow *weeklySummaryWindow;
@@ -297,9 +298,6 @@ class MainWindow : public QMainWindow
RideMetadata *_rideMetadata;
QSplitter *summarySplitter;
// Train
TrainWindow *trainWindow;
//QwtPlotCurve *weeklyBSCurve;
//QwtPlotCurve *weeklyRICurve;
PerformanceManagerWindow *performanceManagerWindow;

View File

@@ -128,7 +128,7 @@ QuarqdClient::parseElement(QString &strBuf) // updates QuarqdClient::telemetry
if (ok && mid != "nan" && mid != "inf") {
telemetry.setWatts(value);
telemetry.setTime(getTimeStamp(str));
telemetry.setMsecs(getTimeStamp(str));
lastReadWatts = elapsedTime.elapsed();
}
} else if(str.startsWith(cadenceStr))
@@ -142,7 +142,7 @@ QuarqdClient::parseElement(QString &strBuf) // updates QuarqdClient::telemetry
if (ok && mid != "nan" && mid != "inf") {
telemetry.setCadence(value);
telemetry.setTime(getTimeStamp(str));
telemetry.setMsecs(getTimeStamp(str));
lastReadCadence = elapsedTime.elapsed();
}
} else if(str.startsWith(speedStr))
@@ -163,7 +163,7 @@ QuarqdClient::parseElement(QString &strBuf) // updates QuarqdClient::telemetry
telemetry.setWheelRpm(value);
lastReadSpeed = elapsedTime.elapsed();
}
telemetry.setTime(getTimeStamp(str));
telemetry.setMsecs(getTimeStamp(str));
}
} else if(str.startsWith(heartRateStr))
{
@@ -176,7 +176,7 @@ QuarqdClient::parseElement(QString &strBuf) // updates QuarqdClient::telemetry
if (ok && mid != "nan" && mid != "inf") {
telemetry.setHr(value);
telemetry.setTime(getTimeStamp(str));
telemetry.setMsecs(getTimeStamp(str));
}
} else if(str.startsWith(sensorDropStr) || str.startsWith(sensorStaleStr) || str.startsWith(sensorLostStr))//Try and save
{

View File

@@ -25,7 +25,7 @@ RealtimeData::RealtimeData()
{
name[0] = '\0';
watts = hr = speed = wheelRpm = cadence = load = 0;
time = 0;
msecs = lapMsecs = bikeScore = joules = 0;
}
void RealtimeData::setName(char *name)
@@ -40,10 +40,6 @@ void RealtimeData::setHr(double hr)
{
this->hr = (int)hr;
}
void RealtimeData::setTime(long time)
{
this->time = time;
}
void RealtimeData::setSpeed(double speed)
{
this->speed = speed;
@@ -60,6 +56,31 @@ void RealtimeData::setLoad(double load)
{
this->load = load;
}
void RealtimeData::setMsecs(long x)
{
this->msecs = x;
}
void RealtimeData::setLapMsecs(long x)
{
this->lapMsecs = x;
}
void RealtimeData::setDistance(double x)
{
this->distance = x;
}
void RealtimeData::setJoules(long x)
{
this->joules = x;
}
void RealtimeData::setBikeScore(long x)
{
this->bikeScore = x;
}
void RealtimeData::setXPower(long x)
{
this->xPower = x;
}
char *
RealtimeData::getName()
{
@@ -73,11 +94,6 @@ double RealtimeData::getHr()
{
return hr;
}
long RealtimeData::getTime()
{
return time;
}
double RealtimeData::getSpeed()
{
return speed;
@@ -94,12 +110,51 @@ double RealtimeData::getLoad()
{
return load;
}
long RealtimeData::getMsecs()
{
return msecs;
}
long RealtimeData::getLapMsecs()
{
return lapMsecs;
}
double RealtimeData::getDistance()
{
return distance;
}
long RealtimeData::getJoules()
{
return joules;
}
long RealtimeData::getBikeScore()
{
return bikeScore;
}
long RealtimeData::getXPower()
{
return xPower;
}
double RealtimeData::value(DataSeries series) const
{
switch (series) {
case Time: return time;
case Time: return msecs;
break;
case LapTime: return lapMsecs;
break;
case Distance: return distance;
break;
case Joules: return joules;
break;
case BikeScore: return bikeScore;
break;
case XPower: return xPower;
break;
case Watts: return watts;
@@ -135,11 +190,16 @@ const QList<RealtimeData::DataSeries> &RealtimeData::listDataSeries()
// better populate it first!
seriesList << None;
seriesList << Time;
seriesList << LapTime;
seriesList << Distance;
seriesList << Watts;
seriesList << Speed;
seriesList << Cadence;
seriesList << HeartRate;
seriesList << Load;
seriesList << BikeScore;
seriesList << XPower;
seriesList << Joules;
}
return seriesList;
}
@@ -155,6 +215,21 @@ QString RealtimeData::seriesName(DataSeries series)
case Time: return tr("Time");
break;
case LapTime: return tr("Lap Time");
break;
case BikeScore: return tr("BikeScore");
break;
case Joules: return tr("Joules");
break;
case XPower: return tr("XPower");
break;
case Distance: return tr("Distance");
break;
case Watts: return tr("Power");
break;

View File

@@ -30,7 +30,10 @@ class RealtimeData
public:
// abstract to dataseries
enum dataseries { None=0, Time, Watts, Speed, Cadence, HeartRate, Load };
enum dataseries { None=0, Time, LapTime, Distance, Lap,
Watts, Speed, Cadence, HeartRate, Load,
XPower, BikeScore, Joules };
typedef enum dataseries DataSeries;
double value(DataSeries) const;
static QString seriesName(DataSeries);
@@ -38,6 +41,7 @@ public:
RealtimeData();
void reset(); // set all values to zero
void setName(char *name);
void setWatts(double watts);
void setHr(double hr);
@@ -46,6 +50,13 @@ public:
void setWheelRpm(double wheelRpm);
void setCadence(double aCadence);
void setLoad(double load);
void setMsecs(long);
void setLapMsecs(long);
void setDistance(double);
void setBikeScore(long);
void setJoules(long);
void setXPower(long);
char *getName();
double getWatts();
double getHr();
@@ -54,13 +65,27 @@ public:
double getWheelRpm();
double getCadence();
double getLoad();
long getMsecs();
long getLapMsecs();
double getDistance();
long getBikeScore();
long getJoules();
long getXPower();
private:
char name[64];
unsigned long time;
// realtime telemetry
double hr, watts, speed, wheelRpm, load;
double cadence; // in rpm
// derived data
double distance;
int lap;
long msecs;
long lapMsecs;
long bikeScore, joules, xPower;
};

View File

@@ -561,32 +561,45 @@ void RealtimeWindow::guiUpdate() // refreshes the telemetry
if (status&RT_RUNNING && deviceController->doesPull() == true) {
deviceController->getRealtimeData(rtData);
main->notifyTelemetryUpdate(rtData); // signal everyone to update telemetry
// Distance assumes current speed for the last second. from km/h to km/sec
displayDistance += displaySpeed / (5 * 3600); // XXX assumes 200ms refreshrate
displayWorkoutDistance += displaySpeed / (5 * 3600); // XXX assumes 200ms refreshrate
rtData.setDistance(displayDistance);
// time
total_msecs = session_elapsed_msec + session_time.elapsed();
lap_msecs = lap_elapsed_msec + lap_time.elapsed();
rtData.setMsecs(total_msecs);
rtData.setLapMsecs(lap_msecs);
// metrics
rtData.setJoules(kjoules);
rtData.setBikeScore(bikescore);
rtData.setXPower(xpower);
// update those LCDs!
timeLCD->display(QString("%1:%2:%3.%4").arg(total_msecs/3600000)
.arg((total_msecs%3600000)/60000,2,10,QLatin1Char('0'))
.arg((total_msecs%60000)/1000,2,10,QLatin1Char('0'))
.arg((total_msecs%1000)/100));
laptimeLCD->display(QString("%1:%2:%3.%4").arg(lap_msecs/3600000,2)
.arg((lap_msecs%3600000)/60000,2,10,QLatin1Char('0'))
.arg((lap_msecs%60000)/1000,2,10,QLatin1Char('0'))
.arg((lap_msecs%1000)/100));
// local stuff ...
displayPower = rtData.getWatts();
displayCadence = rtData.getCadence();
displayHeartRate = rtData.getHr();
displaySpeed = rtData.getSpeed();
displayLoad = rtData.getLoad();
// go update the displays...
main->notifyTelemetryUpdate(rtData); // signal everyone to update telemetry
}
// Distance assumes current speed for the last second. from km/h to km/sec
displayDistance += displaySpeed / (5 * 3600); // XXX assumes 200ms refreshrate
displayWorkoutDistance += displaySpeed / (5 * 3600); // XXX assumes 200ms refreshrate
total_msecs = session_elapsed_msec + session_time.elapsed();
lap_msecs = lap_elapsed_msec + lap_time.elapsed();
// update those LCDs!
timeLCD->display(QString("%1:%2:%3.%4").arg(total_msecs/3600000)
.arg((total_msecs%3600000)/60000,2,10,QLatin1Char('0'))
.arg((total_msecs%60000)/1000,2,10,QLatin1Char('0'))
.arg((total_msecs%1000)/100));
laptimeLCD->display(QString("%1:%2:%3.%4").arg(lap_msecs/3600000,2)
.arg((lap_msecs%3600000)/60000,2,10,QLatin1Char('0'))
.arg((lap_msecs%60000)/1000,2,10,QLatin1Char('0'))
.arg((lap_msecs%1000)/100));
// Cadence, HR and Power needs to be rounded to 0 decimal places
powerLCD->display(round(displayPower));
double val = round(displaySpeed * (useMetricUnits ? 1.0 : MILES_PER_KM) * 10.00)/10.00;

View File

@@ -228,7 +228,7 @@ bool SimpleNetworkClient::read_next_line(QMutexLocker &locker,
read_into_me.setName(namechar);
read_into_me.setWatts(watts);
read_into_me.setHr(hr);
read_into_me.setTime(time);
read_into_me.setMsecs(time);
read_into_me.setSpeed(speed);
read_into_me.setCadence(rpm);
read_into_me.setLoad(load);
@@ -238,7 +238,7 @@ DISPATCHER->dispatch(&read_into_me);
printf("Read from network: %f %f %ld %f %f %f\n",
read_into_me.getWatts(), read_into_me.getHr(),
read_into_me.getTime(), read_into_me.getSpeed(),
read_into_me.getMsecs(), read_into_me.getSpeed(),
read_into_me.getCadence(), read_into_me.getLoad());
}
return true;
@@ -251,7 +251,7 @@ bool SimpleNetworkClient::write_next_line(QMutexLocker &locker,
int num_written;
snprintf(buffer, MAX_BYTES_PER_LINE-1,
"%.2f %.2f %ld %.2f %.2f %.3f\n",
record.getWatts(), record.getHr(), record.getTime(),
record.getWatts(), record.getHr(), record.getMsecs(),
record.getSpeed(), record.getCadence(), record.getLoad());
locker.unlock();
num_written = server.write(buffer, strlen(buffer));

View File

@@ -32,7 +32,7 @@ GcWindow(parent), home(home), main(parent)
"-I", "dummy", /* Don't use any interface */
"--ignore-config", /* Don't use VLC's config */
"--extraintf=logger", //log anything
"--verbose=2" // -1 = no output at all
"--verbose=-1" // -1 = no output at all
};
/* create an exception handler */
@@ -66,13 +66,14 @@ GcWindow(parent), home(home), main(parent)
x11Container = new QX11EmbedContainer(this);
layout->addWidget(x11Container);
libvlc_media_player_set_xwindow (mp, x11Container->winId());
//vlc_exceptions(&exceptions);
#endif
#ifdef WIN32
container = new QWidget(this);
layout->addWidget(container);
libvlc_media_player_set_hwnd (mp, container->winId());
#endif
#if 0 // XXX what abut windows and mac!!!
/* or on windows */
libvlc_media_player_set_hwnd (mp, hwnd);
/* or on mac os */
#if 0 // XXX what abut mac!!!
libvlc_media_player_set_nsobject (mp, view);
#endif
@@ -82,8 +83,10 @@ GcWindow(parent), home(home), main(parent)
VideoWindow::~VideoWindow()
{
#ifdef Q_OS_LINUX
// unembed vlc backend first
x11Container->discardClient();
#endif
// stop playback & wipe player
libvlc_media_player_stop (mp);
@@ -95,9 +98,5 @@ VideoWindow::~VideoWindow()
void VideoWindow::resizeEvent(QResizeEvent * )
{
#if 0
if (isVisible()) {
x11Container->show();
}
#endif
// do nothing .. for now
}

View File

@@ -33,13 +33,16 @@ extern "C" {
// QT stuff etc
#include <QtGui>
#include <QTimer>
#include <QX11EmbedContainer>
#include "MainWindow.h"
#include "DeviceConfiguration.h"
#include "DeviceTypes.h"
#include "RealtimeData.h"
#include "TrainTool.h"
#ifdef Q_OS_LINUX
#include <QX11EmbedContainer>
#endif
class VideoWindow : public GcWindow
{
Q_OBJECT
@@ -71,6 +74,9 @@ class VideoWindow : public GcWindow
#ifdef Q_OS_LINUX
QX11EmbedContainer *x11Container;
#endif
#ifdef WIN32
QWidget *container;
#endif
};
#endif // _GC_VideoWindow_h

View File

@@ -92,8 +92,10 @@ D2XX_INCLUDE = /usr/local/include/D2XX
# will need to use the latest distro (e.g. Meerkat
# on Ubuntu) to be sure apt-get installs the latest
# builds (we need 1.1.6 or higher).
#
# e.g. LINUX
#VLC_INSTALL = /usr/include/vlc/
# e.g. WINDOWS
#VLC_INSTALL = /c/GC/vlc-1.1.8/sdk
# We recommend a debug build for development, and a static build for releases.
CONFIG += debug

View File

@@ -92,10 +92,16 @@ qwt3d {
# are we supporting video playback?
!isEmpty( VLC_INSTALL ) {
INCLUDEPATH += $${VLC_INSTALL}/include
LIBS += -lvlc
DEFINES += GC_HAVE_VLC
HEADERS += VideoWindow.h
SOURCES += VideoWindow.cpp
win32 {
LIBS += $${VLC_INSTALL}/lib/libvlc.dll.a
LIBS += $${VLC_INSTALL}/lib/libvlccore.dll.a
} else {
LIBS += -lvlc
}
}
macx {