void FlowViewWindow::updatedFrames(int numFrames) { CANFrame thisFrame; if (numFrames == -1) //all frames deleted. Kill the display { ui->listFrameID->clear(); foundID.clear(); currentPosition = 0; refreshIDList(); updateFrameLabel(); removeAllGraphs(); memset(refBytes, 0, 8); memset(currBytes, 0, 8); updateDataView(); } else if (numFrames == -2) //all new set of frames. Reset { ui->listFrameID->clear(); foundID.clear(); currentPosition = 0; refreshIDList(); if (ui->listFrameID->count() > 0) { changeID(ui->listFrameID->item(0)->text()); ui->listFrameID->setCurrentRow(0); } updateFrameLabel(); } else //just got some new frames. See if they are relevant. { int refID = frameCache[0].ID; bool needRefresh = false; for (int i = modelFrames->count() - numFrames; i < modelFrames->count(); i++) { thisFrame = modelFrames->at(i); if (thisFrame.ID == refID) { frameCache.append(thisFrame); if (ui->cbLiveMode->checkState() == Qt::Checked) { currentPosition = frameCache.count() - 1; needRefresh = true; } } } if (needRefresh) { updateDataView(); if (ui->cbSync->checkState() == Qt::Checked) emit sendCenterTimeID(frameCache[currentPosition].ID, frameCache[currentPosition].timestamp / 1000000.0); } } }
void FlowViewWindow::btnFwdOneClick() { playbackTimer->stop(); playbackActive = false; updatePosition(true); updateDataView(); }
void FlowViewWindow::btnBackOneClick() { playbackTimer->stop(); //pushing this button halts automatic playback playbackActive = false; updatePosition(false); updateDataView(); }
void FlowViewWindow::btnStopClick() { playbackTimer->stop(); //pushing this button halts automatic playback playbackActive = false; currentPosition = 0; memcpy(currBytes, frameCache.at(currentPosition).data, 8); memcpy(refBytes, currBytes, 8); updateFrameLabel(); updateDataView(); }
void PlotWindow::signalSmoothingChanged() { // Filter the data filterCurveData(); // Update the plots setCurveData(); _plot->replot(); // Update other windows viewing this data emit updateDataView(); }
void FlowViewWindow::gotCenterTimeID(int32_t ID, double timestamp) { uint64_t t_stamp; t_stamp = timestamp * 1000000l; qDebug() << "timestamp: " << t_stamp; changeID(QString::number(ID)); //to be sure we're focused on the proper ID for (int j = 0; j < ui->listFrameID->count(); j++) { int thisNum = Utility::ParseStringToNum(ui->listFrameID->item(j)->text()); if (thisNum == ID) { ui->listFrameID->setCurrentRow(j); break; } } int bestIdx = -1; for (int i = 0; i < frameCache.count(); i++) { if (frameCache[i].timestamp > t_stamp) { bestIdx = i - 1; break; } } qDebug() << "Best index " << bestIdx; if (bestIdx > -1) { currentPosition = bestIdx; if (ui->cbAutoRef->isChecked()) { memcpy(refBytes, currBytes, 8); } memcpy(currBytes, frameCache.at(currentPosition).data, 8); updateDataView(); } }
void FlowViewWindow::timerTriggered() { if (!playbackActive || (ui->cbLiveMode->checkState() == Qt::Checked)) { playbackTimer->stop(); return; } if (playbackForward) { updatePosition(true); } else { updatePosition(false); } updateDataView(); if (!ui->cbLoopPlayback->isChecked()) { if (currentPosition == 0) playbackActive = false; if (currentPosition == (frameCache.count() - 1)) playbackActive = false; } }
void FlowViewWindow::changeID(QString newID) { //parse the ID and then load up the frame cache with just messages with that ID. int id = Utility::ParseStringToNum(newID); frameCache.clear(); if (modelFrames->count() == 0) return; playbackTimer->stop(); playbackActive = false; for (int x = 0; x < modelFrames->count(); x++) { CANFrame thisFrame = modelFrames->at(x); if (thisFrame.ID == id) { for (int j = thisFrame.len; j < 8; j++) thisFrame.data[j] = 0; frameCache.append(thisFrame); } } currentPosition = 0; if (frameCache.count() == 0) return; removeAllGraphs(); for (int c = 0; c < frameCache.at(0).len; c++) { createGraph(c); } updateGraphLocation(); memcpy(currBytes, frameCache.at(currentPosition).data, 8); memcpy(refBytes, currBytes, 8); updateDataView(); }
void FlowViewWindow::btnPauseClick() { playbackActive = false; playbackTimer->stop(); updateDataView(); }
PlotWindow::PlotWindow( boost::shared_ptr<GoogleMapWindow> google_map, boost::shared_ptr<DataStatisticsWindow> stats_view) { // Create the plot _plot = new QwtPlot(); // Create HR zone markers const QColor hr_zone_colours[5] = {HR_ZONE1_COLOUR, HR_ZONE2_COLOUR, HR_ZONE3_COLOUR, HR_ZONE4_COLOUR, HR_ZONE5_COLOUR}; _hr_zone_markers.resize(5); for (unsigned int i=0; i < _hr_zone_markers.size(); ++i) { _hr_zone_markers[i] = new HRZoneItem; _hr_zone_markers[i]->attach(_plot); _hr_zone_markers[i]->hide(); // Set the fill colour QColor c(hr_zone_colours[i]); c.setAlpha(40); _hr_zone_markers[i]->setColour(c); } // Create lap markers _lap_markers.resize(0); // Connect this window to the google map connect(this, SIGNAL(setMarkerPosition(int)), google_map.get(), SLOT(setMarkerPosition(int))); connect(this, SIGNAL(beginSelection(int)), google_map.get(), SLOT(beginSelection(int))); connect(this, SIGNAL(endSelection(int)), google_map.get(), SLOT(endSelection(int))); connect(this, SIGNAL(zoomSelection(int,int)), google_map.get(), SLOT(zoomSelection(int,int))); connect(this, SIGNAL(deleteSelection()), google_map.get(), SLOT(deleteSelection())); connect(this, SIGNAL(panSelection(int)), google_map.get(), SLOT(moveSelection(int))); connect(this, SIGNAL(panAndHoldSelection(int)), google_map.get(), SLOT(moveAndHoldSelection(int))); connect(this, SIGNAL(updateDataView()), google_map.get(), SLOT(definePathColour())); // Connect this window to the statistical viewer connect(this, SIGNAL(zoomSelection(int,int)), stats_view.get(), SLOT(displaySelectedRideStats(int,int))); connect(this, SIGNAL(panAndHoldSelection(int)), stats_view.get(), SLOT(moveSelection(int))); connect(this, SIGNAL(deleteSelection()), stats_view.get(), SLOT(deleteSelection())); connect(this, SIGNAL(updateDataView()), stats_view.get(), SLOT(displayCompleteRideStats())); // Setup the axis _plot->enableAxis(QwtPlot::yRight,true); _plot->setAxisAutoScale(QwtPlot::xBottom,true); QwtText axis_text; QFont font = _plot->axisFont(QwtPlot::xBottom); font.setPointSize(8); axis_text.setFont(font); axis_text.setText("HR (bpm) Speed (km/h) Cadence (rpm)\nPower (W) Temp (C)"); _plot->setAxisTitle(QwtPlot::yLeft,axis_text); axis_text.setText("Elevation (m)"); _plot->setAxisTitle(QwtPlot::yRight,axis_text); axis_text.setText("Distance (km)"); _plot->setAxisTitle(QwtPlot::xBottom,axis_text); // Define the curves to plot QColor c; _curve_hr = new QwtPlotCurve("Heart Rate"); c = HR_COLOUR; _curve_hr->setPen(c); _curve_hr->setYAxis(QwtPlot::yLeft); _curve_cadence = new QwtPlotCurve("Cadence"); c = CADENCE_COLOUR; _curve_cadence->setPen(c); _curve_cadence->setYAxis(QwtPlot::yLeft); _curve_speed = new QwtPlotCurve("Speed"); c = SPEED_COLOUR; _curve_speed->setPen(c); _curve_speed->setYAxis(QwtPlot::yLeft); _curve_power = new QwtPlotCurve("Power"); c = POWER_COLOUR; _curve_power->setPen(c); _curve_power->setYAxis(QwtPlot::yLeft); _curve_temp = new QwtPlotCurve("Temp"); c = TEMP_COLOUR; _curve_temp->setPen(c); _curve_temp->setYAxis(QwtPlot::yLeft); _curve_alt = new QwtPlotCurve("Elevation"); _curve_alt->setRenderHint(QwtPlotItem::RenderAntialiased); c = ALT_COLOUR; _curve_alt->setPen(c); _curve_alt->setBrush(c); _curve_alt->setYAxis(QwtPlot::yRight); _curve_alt->setBaseline(-300.0); // ensure display is correct even when -ve altitude _curve_alt->attach(_plot); _curve_cadence->attach(_plot); _curve_speed->attach(_plot); _curve_hr->attach(_plot); _curve_power->attach(_plot); _curve_temp->attach(_plot); // Checkboxes for graph plots _hr_cb.reset(new QCheckBox("Heart Rate")); _speed_cb.reset(new QCheckBox("Speed")); _alt_cb.reset(new QCheckBox("Elevation")); _cadence_cb.reset(new QCheckBox("Cadence")); _power_cb.reset(new QCheckBox("Power")); _temp_cb.reset(new QCheckBox("Temp")); _laps_cb = new QCheckBox("Laps"); _hr_zones_cb = new QCheckBox("HR Zones"); _hr_cb->setChecked(true); _speed_cb->setChecked(true); _alt_cb->setChecked(true); _cadence_cb->setChecked(true); _power_cb->setChecked(false); _temp_cb->setChecked(false); _laps_cb->setChecked(true); _hr_zones_cb->setChecked(false); QPalette plt; plt.setColor(QPalette::WindowText, HR_COLOUR); _hr_cb->setPalette(plt); plt.setColor(QPalette::WindowText, SPEED_COLOUR); _speed_cb->setPalette(plt); plt.setColor(QPalette::WindowText, ALT_COLOUR); _alt_cb->setPalette(plt); plt.setColor(QPalette::WindowText, CADENCE_COLOUR); _cadence_cb->setPalette(plt); plt.setColor(QPalette::WindowText, POWER_COLOUR); _power_cb->setPalette(plt); plt.setColor(QPalette::WindowText, TEMP_COLOUR); _temp_cb->setPalette(plt); connect(_hr_cb.get(), SIGNAL(stateChanged(int)),this,SLOT(curveSelectionChanged())); connect(_speed_cb.get(), SIGNAL(stateChanged(int)),this,SLOT(curveSelectionChanged())); connect(_alt_cb.get(), SIGNAL(stateChanged(int)),this,SLOT(curveSelectionChanged())); connect(_cadence_cb.get(), SIGNAL(stateChanged(int)),this,SLOT(curveSelectionChanged())); connect(_power_cb.get(), SIGNAL(stateChanged(int)),this,SLOT(curveSelectionChanged())); connect(_temp_cb.get(), SIGNAL(stateChanged(int)),this,SLOT(curveSelectionChanged())); connect(_laps_cb, SIGNAL(stateChanged(int)),this,SLOT(lapSelectionChanged())); connect(_hr_zones_cb, SIGNAL(stateChanged(int)),this,SLOT(hrZoneSelectionChanged())); // Plot picker for numerical display _plot_picker1 = new QwtCustomPlotPicker( QwtPlot::xBottom, QwtPlot::yLeft, _data_log, _plot->canvas(), _hr_cb, _speed_cb, _alt_cb, _cadence_cb, _power_cb, _temp_cb); _plot_picker1->setRubberBandPen(QColor(Qt::white)); _plot_picker1->setTrackerPen(QColor(Qt::black)); _plot_picker1->setStateMachine(new QwtPickerTrackerMachine()); connect(_plot_picker1, SIGNAL(moved(const QPointF&)), this, SLOT(setMarkerPosition(const QPointF&))); // Plot picker for drawing user selection _plot_picker2 = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft, QwtPlotPicker::NoRubberBand, QwtPicker::AlwaysOff, _plot->canvas()); _plot_picker2->setStateMachine(new QwtPickerDragPointMachine()); connect(_plot_picker2, SIGNAL(appended(const QPointF&)), this, SLOT(beginSelection(const QPointF&))); connect(_plot_picker2, SIGNAL(moved(const QPointF&)), this, SLOT(endSelection(const QPointF&))); // Plot zoomer _plot_zoomer = new QwtCustomPlotZoomer(QwtPlot::xBottom, QwtPlot::yLeft, _plot->canvas()); _plot_zoomer->setRubberBand(QwtPicker::UserRubberBand); _plot_zoomer->setRubberBandPen(QColor(Qt::white)); _plot_zoomer->setTrackerMode(QwtPicker::AlwaysOff); _plot_zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::RightButton, Qt::ControlModifier); _plot_zoomer->setMousePattern(QwtEventPattern::MouseSelect3,Qt::RightButton); connect(_plot_zoomer, SIGNAL(zoomed(const QRectF&)), this, SLOT(zoomSelection(const QRectF&))); // Plot panner _plot_panner = new QwtPlotPanner(_plot->canvas()); _plot_panner->setMouseButton(Qt::MidButton); connect(_plot_panner, SIGNAL(moved(int, int)), this, SLOT(panSelection(int, int))); connect(_plot_panner, SIGNAL(panned(int, int)), this, SLOT(panAndHoldSelection(int, int))); // Selection for x-axis measurement _x_axis_measurement = new QComboBox; _x_axis_measurement->insertItem(0, "x-axis = time"); _x_axis_measurement->insertItem(1, "x-axis = distance"); _x_axis_measurement->setCurrentIndex(1); _plot->setAxisScaleDraw(QwtPlot::xBottom, new XAxisScaleDraw(tr("dist"))); connect(_x_axis_measurement,SIGNAL(currentIndexChanged(int)), this, SLOT(xAxisUnitsChanged(int))); connect(_x_axis_measurement,SIGNAL(currentIndexChanged(int)), _plot_picker1, SLOT(xAxisUnitsChanged(int))); // Selection for signal smoothing _smoothing_selection = new QSpinBox; _smoothing_selection->setRange(1,50); _smoothing_selection->setPrefix("Smoothing: "); _smoothing_selection->setValue(5); // default value connect(_smoothing_selection, SIGNAL(valueChanged(int)),this,SLOT(signalSmoothingChanged())); // Layout the GUI QWidget* plot_options_widget = new QWidget; QVBoxLayout* vlayout1 = new QVBoxLayout(plot_options_widget); vlayout1->addWidget(_hr_cb.get()); vlayout1->addWidget(_speed_cb.get()); vlayout1->addWidget(_alt_cb.get()); vlayout1->addWidget(_cadence_cb.get()); vlayout1->addWidget(_power_cb.get()); vlayout1->addWidget(_temp_cb.get()); vlayout1->addWidget(_x_axis_measurement); vlayout1->addWidget(_smoothing_selection); vlayout1->addWidget(_laps_cb); vlayout1->addWidget(_hr_zones_cb); vlayout1->addStretch(); QHBoxLayout* hlayout2 = new QHBoxLayout(this); hlayout2->addWidget(_plot); hlayout2->addWidget(plot_options_widget); resize(700,270); // Disable all controls until ride data is loaded setEnabled(false); }