Fixes for many issues in flowview, graphing window, and frame playback.
In FlowView: - Drastically improved functionality of live mode. It actually works now - Fixed several crash bugs - Program didn't used to pick up new frames properly. This is now corrected. In Graphing window: - Fixed dynamic updates to work properly even under heavy bus loads In frame playback: - Fixed a bug where single stepping through frames didn't send them over canbus
This commit is contained in:
+8
-3
@@ -48,7 +48,9 @@ SOURCES += main.cpp\
|
|||||||
udsscanwindow.cpp \
|
udsscanwindow.cpp \
|
||||||
can_structs.cpp \
|
can_structs.cpp \
|
||||||
isotp_interpreterwindow.cpp \
|
isotp_interpreterwindow.cpp \
|
||||||
isotp_handler.cpp
|
isotp_handler.cpp \
|
||||||
|
deltawindow.cpp \
|
||||||
|
deltamodel.cpp
|
||||||
|
|
||||||
HEADERS += mainwindow.h \
|
HEADERS += mainwindow.h \
|
||||||
can_structs.h \
|
can_structs.h \
|
||||||
@@ -83,7 +85,9 @@ HEADERS += mainwindow.h \
|
|||||||
fuzzingwindow.h \
|
fuzzingwindow.h \
|
||||||
udsscanwindow.h \
|
udsscanwindow.h \
|
||||||
isotp_interpreterwindow.h \
|
isotp_interpreterwindow.h \
|
||||||
isotp_handler.h
|
isotp_handler.h \
|
||||||
|
deltawindow.h \
|
||||||
|
deltamodel.h
|
||||||
|
|
||||||
FORMS += mainwindow.ui \
|
FORMS += mainwindow.ui \
|
||||||
graphingwindow.ui \
|
graphingwindow.ui \
|
||||||
@@ -105,7 +109,8 @@ FORMS += mainwindow.ui \
|
|||||||
dbcloadsavewindow.ui \
|
dbcloadsavewindow.ui \
|
||||||
fuzzingwindow.ui \
|
fuzzingwindow.ui \
|
||||||
udsscanwindow.ui \
|
udsscanwindow.ui \
|
||||||
isotp_interpreterwindow.ui
|
isotp_interpreterwindow.ui \
|
||||||
|
deltawindow.ui
|
||||||
|
|
||||||
DISTFILES +=
|
DISTFILES +=
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef CONFIG
|
#ifndef CONFIG
|
||||||
#define CONFIG
|
#define CONFIG
|
||||||
|
|
||||||
#define VERSION 155
|
#define VERSION 156
|
||||||
|
|
||||||
//try to keep this in sync.
|
//try to keep this in sync.
|
||||||
//SavvyCAN will complain if you connect a GVRET board with a revision
|
//SavvyCAN will complain if you connect a GVRET board with a revision
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#include "deltamodel.h"
|
||||||
|
|
||||||
|
DeltaModel::DeltaModel(QObject *parent)
|
||||||
|
: QAbstractTableModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DeltaModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
// FIXME: Implement me!
|
||||||
|
}
|
||||||
|
|
||||||
|
int DeltaModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
if (!parent.isValid())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// FIXME: Implement me!
|
||||||
|
}
|
||||||
|
|
||||||
|
int DeltaModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
if (!parent.isValid())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// FIXME: Implement me!
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DeltaModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
// FIXME: Implement me!
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef DELTAMODEL_H
|
||||||
|
#define DELTAMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
|
class DeltaModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DeltaModel(QObject *parent = 0);
|
||||||
|
|
||||||
|
// Header:
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
// Basic functionality:
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DELTAMODEL_H
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#include "deltawindow.h"
|
||||||
|
#include "ui_deltawindow.h"
|
||||||
|
|
||||||
|
DeltaWindow::DeltaWindow(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::DeltaWindow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeltaWindow::~DeltaWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef DELTAWINDOW_H
|
||||||
|
#define DELTAWINDOW_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class DeltaWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DeltaWindow : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DeltaWindow(QWidget *parent = 0);
|
||||||
|
~DeltaWindow();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::DeltaWindow *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DELTAWINDOW_H
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>DeltaWindow</class>
|
||||||
|
<widget class="QDialog" name="DeltaWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>978</width>
|
||||||
|
<height>654</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="tableView"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
+55
-15
@@ -158,9 +158,9 @@ void FlowViewWindow::writeSettings()
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Keyboard shortcuts to allow for quick work without needing to move around a mouse.
|
* Keyboard shortcuts to allow for quick work without needing to move around a mouse.
|
||||||
* E = resume or pause playback
|
* R = resume or pause playback
|
||||||
* Q = go back one frame
|
* T = go back one frame
|
||||||
* W = go forward one frame
|
* Y = go forward one frame
|
||||||
*/
|
*/
|
||||||
bool FlowViewWindow::eventFilter(QObject *obj, QEvent *event)
|
bool FlowViewWindow::eventFilter(QObject *obj, QEvent *event)
|
||||||
{
|
{
|
||||||
@@ -371,27 +371,64 @@ void FlowViewWindow::updatedFrames(int numFrames)
|
|||||||
else //just got some new frames. See if they are relevant.
|
else //just got some new frames. See if they are relevant.
|
||||||
{
|
{
|
||||||
if (numFrames > modelFrames->count()) return;
|
if (numFrames > modelFrames->count()) return;
|
||||||
int refID = frameCache[0].ID;
|
int refID;
|
||||||
|
if (frameCache.count() > 0) refID = frameCache[0].ID;
|
||||||
|
else refID = 0;
|
||||||
bool needRefresh = false;
|
bool needRefresh = false;
|
||||||
for (int i = modelFrames->count() - numFrames; i < modelFrames->count(); i++)
|
for (int i = modelFrames->count() - numFrames; i < modelFrames->count(); i++)
|
||||||
{
|
{
|
||||||
thisFrame = modelFrames->at(i);
|
thisFrame = modelFrames->at(i);
|
||||||
|
|
||||||
|
if (!foundID.contains(thisFrame.ID))
|
||||||
|
{
|
||||||
|
foundID.append(thisFrame.ID);
|
||||||
|
QListWidgetItem* item = new QListWidgetItem(Utility::formatNumber(thisFrame.ID), ui->listFrameID);
|
||||||
|
}
|
||||||
|
|
||||||
if (thisFrame.ID == refID)
|
if (thisFrame.ID == refID)
|
||||||
{
|
{
|
||||||
frameCache.append(thisFrame);
|
frameCache.append(thisFrame);
|
||||||
if (ui->cbLiveMode->checkState() == Qt::Checked)
|
|
||||||
|
for (int k = 0; k < 8; k++)
|
||||||
{
|
{
|
||||||
currentPosition = frameCache.count() - 1;
|
if (ui->cbTimeGraph->isChecked())
|
||||||
|
{
|
||||||
|
if (secondsMode){
|
||||||
|
x[k].append((double)(thisFrame.timestamp) / 1000000.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x[k].append(thisFrame.timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x[k].append(x[k].count());
|
||||||
|
}
|
||||||
|
y[k].append(thisFrame.data[k]);
|
||||||
needRefresh = true;
|
needRefresh = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ui->cbLiveMode->checkState() == Qt::Checked)
|
||||||
|
{
|
||||||
|
currentPosition = frameCache.count() - 1;
|
||||||
|
memcpy(currBytes, frameCache.at(currentPosition).data, 8);
|
||||||
|
memcpy(refBytes, currBytes, 8);
|
||||||
|
|
||||||
|
}
|
||||||
if (needRefresh)
|
if (needRefresh)
|
||||||
{
|
{
|
||||||
|
for (int k = 0; k < 8; k++)
|
||||||
|
{
|
||||||
|
graphRef[k]->setData(x[k], y[k]);
|
||||||
|
}
|
||||||
|
ui->graphView->replot();
|
||||||
updateDataView();
|
updateDataView();
|
||||||
if (ui->cbSync->checkState() == Qt::Checked) emit sendCenterTimeID(frameCache[currentPosition].ID, frameCache[currentPosition].timestamp / 1000000.0);
|
if (ui->cbSync->checkState() == Qt::Checked) emit sendCenterTimeID(frameCache[currentPosition].ID, frameCache[currentPosition].timestamp / 1000000.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updateFrameLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlowViewWindow::removeAllGraphs()
|
void FlowViewWindow::removeAllGraphs()
|
||||||
@@ -409,7 +446,10 @@ void FlowViewWindow::createGraph(int byteNum)
|
|||||||
|
|
||||||
int numEntries = frameCache.count();
|
int numEntries = frameCache.count();
|
||||||
|
|
||||||
QVector<double> x(numEntries), y(numEntries);
|
x[byteNum].clear();
|
||||||
|
y[byteNum].clear();
|
||||||
|
x[byteNum].resize(numEntries);
|
||||||
|
y[byteNum].resize(numEntries);
|
||||||
|
|
||||||
for (int j = 0; j < numEntries; j++)
|
for (int j = 0; j < numEntries; j++)
|
||||||
{
|
{
|
||||||
@@ -418,26 +458,26 @@ void FlowViewWindow::createGraph(int byteNum)
|
|||||||
if (graphByTime)
|
if (graphByTime)
|
||||||
{
|
{
|
||||||
if (secondsMode){
|
if (secondsMode){
|
||||||
x[j] = (double)(frameCache[j].timestamp) / 1000000.0;
|
x[byteNum][j] = (double)(frameCache[j].timestamp) / 1000000.0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
x[j] = frameCache[j].timestamp;
|
x[byteNum][j] = frameCache[j].timestamp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
x[j] = j;
|
x[byteNum][j] = j;
|
||||||
}
|
}
|
||||||
|
|
||||||
y[j] = tempVal;
|
y[byteNum][j] = tempVal;
|
||||||
if (y[j] < minval) minval = y[j];
|
if (y[byteNum][j] < minval) minval = y[byteNum][j];
|
||||||
if (y[j] > maxval) maxval = y[j];
|
if (y[byteNum][j] > maxval) maxval = y[byteNum][j];
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->graphView->addGraph();
|
graphRef[byteNum] = ui->graphView->addGraph();
|
||||||
ui->graphView->graph()->setName(QString("Graph %1").arg(ui->graphView->graphCount()-1));
|
ui->graphView->graph()->setName(QString("Graph %1").arg(ui->graphView->graphCount()-1));
|
||||||
ui->graphView->graph()->setData(x,y);
|
ui->graphView->graph()->setData(x[byteNum],y[byteNum]);
|
||||||
ui->graphView->graph()->setLineStyle(QCPGraph::lsLine); //connect points with lines
|
ui->graphView->graph()->setLineStyle(QCPGraph::lsLine); //connect points with lines
|
||||||
QPen graphPen;
|
QPen graphPen;
|
||||||
graphPen.setColor(graphColors[byteNum]);
|
graphPen.setColor(graphColors[byteNum]);
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ private:
|
|||||||
bool playbackForward;
|
bool playbackForward;
|
||||||
static const QColor graphColors[8];
|
static const QColor graphColors[8];
|
||||||
bool secondsMode;
|
bool secondsMode;
|
||||||
|
QVector<double> x[8], y[8];
|
||||||
|
QCPGraph *graphRef[8];
|
||||||
|
|
||||||
void refreshIDList();
|
void refreshIDList();
|
||||||
void updateFrameLabel();
|
void updateFrameLabel();
|
||||||
|
|||||||
@@ -400,10 +400,12 @@ void FramePlaybackWindow::btnLoadLive()
|
|||||||
|
|
||||||
void FramePlaybackWindow::btnBackOneClick()
|
void FramePlaybackWindow::btnBackOneClick()
|
||||||
{
|
{
|
||||||
|
sendingBuffer.clear();
|
||||||
playbackTimer->stop(); //pushing this button halts automatic playback
|
playbackTimer->stop(); //pushing this button halts automatic playback
|
||||||
playbackActive = false;
|
playbackActive = false;
|
||||||
|
|
||||||
updatePosition(false);
|
updatePosition(false);
|
||||||
|
emit sendFrameBatch(&sendingBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramePlaybackWindow::btnPauseClick()
|
void FramePlaybackWindow::btnPauseClick()
|
||||||
@@ -450,9 +452,11 @@ void FramePlaybackWindow::btnPlayClick()
|
|||||||
|
|
||||||
void FramePlaybackWindow::btnFwdOneClick()
|
void FramePlaybackWindow::btnFwdOneClick()
|
||||||
{
|
{
|
||||||
|
sendingBuffer.clear();
|
||||||
playbackTimer->stop();
|
playbackTimer->stop();
|
||||||
playbackActive = false;
|
playbackActive = false;
|
||||||
updatePosition(true);
|
updatePosition(true);
|
||||||
|
emit sendFrameBatch(&sendingBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramePlaybackWindow::changePlaybackSpeed(int newSpeed)
|
void FramePlaybackWindow::changePlaybackSpeed(int newSpeed)
|
||||||
|
|||||||
+8
-2
@@ -142,6 +142,7 @@ void GraphingWindow::updatedFrames(int numFrames)
|
|||||||
}
|
}
|
||||||
else //just got some new frames. See if they are relevant.
|
else //just got some new frames. See if they are relevant.
|
||||||
{
|
{
|
||||||
|
bool appendedToGraph = false;
|
||||||
if (numFrames > modelFrames->count()) return;
|
if (numFrames > modelFrames->count()) return;
|
||||||
for (int i = modelFrames->count() - numFrames; i < modelFrames->count(); i++)
|
for (int i = modelFrames->count() - numFrames; i < modelFrames->count(); i++)
|
||||||
{
|
{
|
||||||
@@ -151,12 +152,19 @@ void GraphingWindow::updatedFrames(int numFrames)
|
|||||||
if (graphParams[j].ID == thisFrame.ID)
|
if (graphParams[j].ID == thisFrame.ID)
|
||||||
{
|
{
|
||||||
appendToGraph(graphParams[j], thisFrame);
|
appendToGraph(graphParams[j], thisFrame);
|
||||||
|
appendedToGraph = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (appendedToGraph) {
|
||||||
|
for (int j = 0; j < graphParams.count(); j++)
|
||||||
|
{
|
||||||
|
graphParams[j].ref->setData(graphParams[j].x, graphParams[j].y);
|
||||||
|
}
|
||||||
ui->graphingView->replot();
|
ui->graphingView->replot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GraphingWindow::plottableDoubleClick(QCPAbstractPlottable* plottable, QMouseEvent* event)
|
void GraphingWindow::plottableDoubleClick(QCPAbstractPlottable* plottable, QMouseEvent* event)
|
||||||
{
|
{
|
||||||
@@ -931,8 +939,6 @@ void GraphingWindow::appendToGraph(GraphParams ¶ms, CANFrame &frame)
|
|||||||
params.x.append(frame.timestamp - params.xbias);
|
params.x.append(frame.timestamp - params.xbias);
|
||||||
}
|
}
|
||||||
params.y.append((tempVal * params.scale) + params.bias);
|
params.y.append((tempVal * params.scale) + params.bias);
|
||||||
|
|
||||||
params.ref->setData(params.x,params.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphingWindow::createGraph(GraphParams ¶ms, bool createGraphParam)
|
void GraphingWindow::createGraph(GraphParams ¶ms, bool createGraphParam)
|
||||||
|
|||||||
Reference in New Issue
Block a user