Added the ability to track which direction frames are coming from

(from us or to us), import that detail from file formats that support
it, save it to file formats that support it. Also some bug fixes.
This commit is contained in:
Collin Kidder
2015-12-01 20:25:52 -05:00
parent 0ff076de3a
commit f6b5db9617
8 changed files with 111 additions and 39 deletions
+1
View File
@@ -9,6 +9,7 @@ public:
int ID;
int bus;
bool extended;
bool isReceived; //did we receive this or send it?
int len;
unsigned char data[8];
uint64_t timestamp;
+24 -11
View File
@@ -17,7 +17,7 @@ int CANFrameModel::totalFrameCount()
int CANFrameModel::columnCount(const QModelIndex &index) const
{
Q_UNUSED(index);
return 6;
return 7;
}
CANFrameModel::CANFrameModel(QObject *parent)
@@ -159,7 +159,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
if (!index.isValid())
return QVariant();
if (index.row() >= filteredFrames.count())
if (index.row() >= (filteredFrames.count()))
return QVariant();
if (role == Qt::DisplayRole) {
@@ -168,7 +168,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
{
case 0: //timestamp
if (!timeSeconds) return QString::number(thisFrame.timestamp);
else return QString::number(thisFrame.timestamp / 1000000.0f);
else return QString::number((double)thisFrame.timestamp / 1000000.0, 'f', 6);
break;
case 1: //id
return Utility::formatNumber(thisFrame.ID);
@@ -176,13 +176,17 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
case 2: //ext
return QString::number(thisFrame.extended);
break;
case 3: //bus
case 3: //direction
if (thisFrame.isReceived) return QString(tr("Rx"));
else return QString(tr("Tx"));
break;
case 4: //bus
return QString::number(thisFrame.bus);
break;
case 4: //len
case 5: //len
return QString::number(thisFrame.len);
break;
case 5: //data
case 6: //data
for (int i = 0; i < thisFrame.len; i++)
{
tempString.append(Utility::formatNumber(thisFrame.data[i]));
@@ -234,12 +238,15 @@ QVariant CANFrameModel::headerData(int section, Qt::Orientation orientation,
return QString(tr("Ext"));
break;
case 3:
return QString(tr("Bus"));
return QString(tr("Dir"));
break;
case 4:
return QString(tr("Len"));
return QString(tr("Bus"));
break;
case 5:
return QString(tr("Len"));
break;
case 6:
return QString(tr("Data"));
break;
}
@@ -385,6 +392,11 @@ void CANFrameModel::clearFrames()
*/
void CANFrameModel::insertFrames(const QVector<CANFrame> &newFrames)
{
//not resetting the model here because the serial worker automatically does a bulk refresh every 1/4 second
//and that refresh will cause the view to update. If you do both it usually ends up thinking you have
//double the number of frames.
//beginResetModel();
mutex.lock();
int insertedFiltered = 0;
for (int i = 0; i < newFrames.count(); i++)
{
@@ -400,9 +412,10 @@ void CANFrameModel::insertFrames(const QVector<CANFrame> &newFrames)
filteredFrames.append(newFrames[i]);
}
}
beginInsertRows(QModelIndex(), filteredFrames.count() + 1, filteredFrames.count() + insertedFiltered);
endInsertRows();
mutex.unlock();
//endResetModel();
//beginInsertRows(QModelIndex(), filteredFrames.count() + 1, filteredFrames.count() + insertedFiltered);
//endInsertRows();
if (needFilterRefresh) emit updatedFiltersList();
}
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef CONFIG
#define CONFIG
#define VERSION 142
#define VERSION 143
//try to keep this in sync.
//SavvyCAN will complain if you connect a GVRET board with a revision
+51 -18
View File
@@ -94,7 +94,7 @@ bool FrameFileIO::loadCRTDFile(QString filename, QVector<CANFrame>* frames)
return false;
}
line = inFile->readLine(); //read out the header first and discard it.
line = inFile->readLine().toUpper(); //read out the header first and discard it.
while (!inFile->atEnd()) {
lineCounter++;
@@ -121,11 +121,14 @@ bool FrameFileIO::loadCRTDFile(QString filename, QVector<CANFrame>* frames)
}
//qDebug() << "decimal places " << decimalPlaces;
thisFrame.timestamp = (int64_t)(tokens[0].toDouble() * multiplier);
if (tokens[1] == "R11" || tokens[1] == "R29")
char firstChar = tokens[1].left(1)[0];
if (firstChar == 'R' || firstChar == 'T')
{
thisFrame.ID = tokens[2].toInt(NULL, 16);
if (tokens[1] == "R29") thisFrame.extended = true;
if (tokens[1] == "R29" || tokens[1] == "T29") thisFrame.extended = true;
else thisFrame.extended = false;
if (firstChar == 'T') thisFrame.isReceived = false;
else thisFrame.isReceived = true;
thisFrame.bus = 0;
thisFrame.len = tokens.length() - 3;
for (int d = 0; d < thisFrame.len; d++)
@@ -171,11 +174,15 @@ bool FrameFileIO::saveCRTDFile(QString filename, const QVector<CANFrame>* frames
outFile->write(QString::number(frames->at(c).timestamp / 1000000.0, 'f', 6).toUtf8());
outFile->putChar(' ');
if (frames->at(c).isReceived) outFile->putChar('R');
else outFile->putChar('T');
if (frames->at(c).extended)
{
outFile->write("R29 ");
outFile->write("29 ");
}
else outFile->write("R11 ");
else outFile->write("11 ");
outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
outFile->putChar(' ');
@@ -199,6 +206,7 @@ bool FrameFileIO::loadNativeCSVFile(QString filename, QVector<CANFrame>* frames)
QFile *inFile = new QFile(filename);
CANFrame thisFrame;
QByteArray line;
int fileVersion = 1;
long long timeStamp = Utility::GetTimeMS();
int lineCounter = 0;
@@ -208,7 +216,8 @@ bool FrameFileIO::loadNativeCSVFile(QString filename, QVector<CANFrame>* frames)
return false;
}
line = inFile->readLine(); //read out the header first and discard it.
line = inFile->readLine().toUpper(); //read out the header first and discard it.
if (line.at(23) == 'D') fileVersion = 2; //Dir is found starting at position 23 if this is a V2 file
while (!inFile->atEnd()) {
lineCounter++;
@@ -236,11 +245,27 @@ bool FrameFileIO::loadNativeCSVFile(QString filename, QVector<CANFrame>* frames)
thisFrame.ID = tokens[1].toInt(NULL, 16);
if (tokens[2].toUpper().contains("TRUE")) thisFrame.extended = 1;
else thisFrame.extended = 0;
thisFrame.bus = tokens[3].toInt();
thisFrame.len = tokens[4].toInt();
for (int c = 0; c < 8; c++) thisFrame.data[c] = 0;
for (int d = 0; d < thisFrame.len; d++)
thisFrame.data[d] = tokens[5 + d].toInt(NULL, 16);
if (fileVersion == 1)
{
thisFrame.isReceived = true;
thisFrame.bus = tokens[3].toInt();
thisFrame.len = tokens[4].toInt();
for (int c = 0; c < 8; c++) thisFrame.data[c] = 0;
for (int d = 0; d < thisFrame.len; d++)
thisFrame.data[d] = tokens[5 + d].toInt(NULL, 16);
}
else if (fileVersion == 2)
{
if (tokens[3].at(0) == 'R') thisFrame.isReceived = true;
else thisFrame.isReceived = false;
thisFrame.bus = tokens[4].toInt();
thisFrame.len = tokens[5].toInt();
for (int c = 0; c < 8; c++) thisFrame.data[c] = 0;
for (int d = 0; d < thisFrame.len; d++)
thisFrame.data[d] = tokens[6 + d].toInt(NULL, 16);
}
frames->append(thisFrame);
}
}
@@ -260,7 +285,7 @@ bool FrameFileIO::saveNativeCSVFile(QString filename, const QVector<CANFrame>* f
return false;
}
outFile->write("Time Stamp,ID,Extended,Bus,LEN,D1,D2,D3,D4,D5,D6,D7,D8");
outFile->write("Time Stamp,ID,Extended,Dir,Bus,LEN,D1,D2,D3,D4,D5,D6,D7,D8");
outFile->write("\n");
for (int c = 0; c < frames->count(); c++)
@@ -281,6 +306,9 @@ bool FrameFileIO::saveNativeCSVFile(QString filename, const QVector<CANFrame>* f
if (frames->at(c).extended) outFile->write("true,");
else outFile->write("false,");
if (frames->at(c).isReceived) outFile->write("Rx,");
else outFile->write("Tx,");
outFile->write(QString::number(frames->at(c).bus).toUtf8());
outFile->putChar(44);
@@ -449,7 +477,7 @@ bool FrameFileIO::loadLogFile(QString filename, QVector<CANFrame>* frames)
lineCounter = 0;
}
line = inFile->readLine();
line = inFile->readLine().toUpper();
if (line.startsWith("***")) continue;
if (line.length() > 1)
{
@@ -458,6 +486,8 @@ bool FrameFileIO::loadLogFile(QString filename, QVector<CANFrame>* frames)
timeStamp = (timeToks[0].toInt() * (1000ul * 1000ul * 60ul * 60ul)) + (timeToks[1].toInt() * (1000ul * 1000ul * 60ul))
+ (timeToks[2].toInt() * (1000ul * 1000ul)) + (timeToks[3].toInt() * 100ul);
thisFrame.timestamp = timeStamp;
if (tokens[1].at(0) == 'R') thisFrame.isReceived = true;
else thisFrame.isReceived = false;
thisFrame.ID = tokens[3].right(tokens[3].length() - 2).toInt(NULL, 16);
if (tokens[4] == "s") thisFrame.extended = false;
else thisFrame.extended = true;
@@ -513,7 +543,8 @@ bool FrameFileIO::saveLogFile(QString filename, const QVector<CANFrame>* frames)
tempStamp = timestamp.addMSecs(frames->at(c).timestamp / 1000);
outFile->write(tempStamp.toString("h:m:s:z").toUtf8());
outFile->write(" Rx ");
if (frames->at(c).isReceived) outFile->write(" Rx ");
else outFile->write(" Tx ");
outFile->write(QString::number(frames->at(c).bus).toUtf8() + " ");
outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
if (frames->at(c).extended) outFile->write(" x ");
@@ -549,7 +580,7 @@ bool FrameFileIO::loadMicrochipFile(QString filename, QVector<CANFrame>* frames)
CANFrame thisFrame;
QByteArray line;
bool inComment = false;
long long timeStamp = Utility::GetTimeMS();
long long timeStamp;
int lineCounter = 0;
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
@@ -580,9 +611,10 @@ bool FrameFileIO::loadMicrochipFile(QString filename, QVector<CANFrame>* frames)
if (!inComment)
{
QList<QByteArray> tokens = line.split(';');
timeStamp += 5;
timeStamp = tokens[0].toInt() * 1000;
thisFrame.timestamp = timeStamp;
if (tokens[1].at(0) == 'R') thisFrame.isReceived = true;
else thisFrame.isReceived = false;
thisFrame.ID = Utility::ParseStringToNum(tokens[2]);
if (thisFrame.ID <= 0x7FF) thisFrame.extended = false;
else thisFrame.extended = true;
@@ -643,7 +675,8 @@ bool FrameFileIO::saveMicrochipFile(QString filename, const QVector<CANFrame>* f
}
outFile->write(QString::number((int)(frames->at(c).timestamp / 1000)).toUtf8());
outFile->write(";RX;");
if (frames->at(c).isReceived) outFile->write(";RX;");
else outFile->write(";TX;");
outFile->write("0x" + QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8() + ";");
outFile->write(QString::number(frames->at(c).len).toUtf8() + ";");
+2 -5
View File
@@ -49,15 +49,13 @@ MainWindow::MainWindow(QWidget *parent) :
readSettings();
QStringList headers;
headers << "Timestamp" << "ID" << "Ext" << "Bus" << "Len" << "Data";
//model->setHorizontalHeaderLabels(headers);
ui->canFramesView->setColumnWidth(0, 110);
ui->canFramesView->setColumnWidth(1, 70);
ui->canFramesView->setColumnWidth(2, 40);
ui->canFramesView->setColumnWidth(3, 40);
ui->canFramesView->setColumnWidth(4, 40);
ui->canFramesView->setColumnWidth(5, 275);
ui->canFramesView->setColumnWidth(5, 40);
ui->canFramesView->setColumnWidth(6, 275);
QHeaderView *HorzHdr = ui->canFramesView->horizontalHeader();
HorzHdr->setStretchLastSection(true); //causes the data column to automatically fill the tableview
//enabling the below line kills performance in every way imaginable. Left here as a warning. Do not do this.
@@ -500,7 +498,6 @@ void MainWindow::handleLoadFile()
if (result)
{
model->insertFrames(tempFrames);
QStringList fileList = filename.split('/');
loadedFileName = fileList[fileList.length() - 1];
+20 -1
View File
@@ -58,8 +58,14 @@ void ScriptContainer::setErrorWidget(QListWidget *list)
void ScriptContainer::setFilter(QJSValue id, QJSValue mask, QJSValue bus)
{
uint32_t idVal = id.toUInt();
uint32_t maskVal = mask.toUInt();
int busVal = bus.toInt();
qDebug() << "Called set filter";
qDebug() << id.toInt() << "*" << mask.toInt() << "*" << bus.toInt();
qDebug() << idVal << "*" << maskVal << "*" << busVal;
CANFilter filter;
filter.setFilter(idVal, maskVal, busVal);
filters.append(filter);
}
void ScriptContainer::setTickInterval(QJSValue interval)
@@ -77,6 +83,7 @@ void ScriptContainer::setTickInterval(QJSValue interval)
void ScriptContainer::clearFilters()
{
qDebug() << "Called clear filters";
filters.clear();
}
void ScriptContainer::sendFrame(QJSValue id, QJSValue length, QJSValue data)
@@ -84,6 +91,18 @@ void ScriptContainer::sendFrame(QJSValue id, QJSValue length, QJSValue data)
qDebug() << "called send frame";
}
void ScriptContainer::gotFrame(const CANFrame &frame)
{
for (int i = 0; i < filters.length(); i++)
{
if (filters[i].checkFilter(frame.ID, frame.bus))
{
return; //as soon as one filter matches we jump out
}
}
}
void ScriptContainer::tick()
{
if (tickFunction.isCallable())
+6
View File
@@ -1,6 +1,9 @@
#ifndef SCRIPTCONTAINER_H
#define SCRIPTCONTAINER_H
#include "can_structs.h"
#include "canfilter.h"
#include <QJSEngine>
#include <QTimer>
#include <qlistwidget.h>
@@ -11,6 +14,8 @@ class ScriptContainer : public QObject
public:
ScriptContainer();
void gotFrame(const CANFrame &frame);
QString fileName;
QString filePath;
QString scriptText;
@@ -34,6 +39,7 @@ private:
QJSValue tickFunction;
QTimer timer;
QListWidget *errorWidget;
QList<CANFilter> filters;
};
#endif // SCRIPTCONTAINER_H
+5 -2
View File
@@ -155,11 +155,13 @@ void SerialWorker::sendFrame(const CANFrame *frame, int bus = 0)
QByteArray buffer;
int c;
int ID;
CANFrame tempFrame = *frame;
tempFrame.isReceived = false;
//qDebug() << "Sending out frame with id " << frame->ID;
//show our sent frames in the list too. This happens even if we're not connected.
canModel->addFrame(*frame, false);
canModel->addFrame(tempFrame, false);
gotFrames++;
if (!connected) return;
@@ -310,6 +312,7 @@ void SerialWorker::procRXChar(unsigned char c)
//qDebug() << "emit from serial handler to main form id: " << buildFrame->ID;
if (capturing)
{
buildFrame->isReceived = true;
canModel->addFrame(*buildFrame, false);
gotFrames++;
if (buildFrame->ID == targetID) emit gotTargettedFrame(canModel->rowCount() - 1);
@@ -445,7 +448,7 @@ void SerialWorker::handleTick()
emit frameUpdateTick(framesPerSec / 4, gotFrames); //sends stats to interested parties
canModel->sendBulkRefresh(gotFrames);
gotFrames = 0;
if (doValidation && connected) sendCommValidation();
if (doValidation && serial) sendCommValidation();
}
void SerialWorker::handleReconnect()