Merge pull request #52 from canpadawan/master

a few bug fixes and initial support for candump/kayak log file format
This commit is contained in:
Collin Kidder
2016-05-31 18:32:08 -04:00
7 changed files with 148 additions and 40 deletions
+4 -1
View File
@@ -764,10 +764,13 @@ DBCFile* DBCHandler::loadDBCFile(int idx)
DBCFile newFile; DBCFile newFile;
newFile.loadFile(filename); newFile.loadFile(filename);
loadedFiles.append(newFile); loadedFiles.append(newFile);
}
return &loadedFiles.last(); return &loadedFiles.last();
} }
return NULL;
}
void DBCHandler::removeDBCFile(int idx) void DBCHandler::removeDBCFile(int idx)
{ {
if (loadedFiles.count() == 0) return; if (loadedFiles.count() == 0) return;
+2
View File
@@ -48,11 +48,13 @@ void DBCLoadSaveWindow::newFile()
void DBCLoadSaveWindow::loadFile() void DBCLoadSaveWindow::loadFile()
{ {
DBCFile *file = dbcHandler->loadDBCFile(-1); DBCFile *file = dbcHandler->loadDBCFile(-1);
if(file) {
int idx = ui->tableFiles->rowCount(); int idx = ui->tableFiles->rowCount();
ui->tableFiles->insertRow(ui->tableFiles->rowCount()); ui->tableFiles->insertRow(ui->tableFiles->rowCount());
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(file->getFullFilename())); ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(file->getFullFilename()));
ui->tableFiles->setItem(idx, 1, new QTableWidgetItem("-1")); ui->tableFiles->setItem(idx, 1, new QTableWidgetItem("-1"));
} }
}
void DBCLoadSaveWindow::saveFile() void DBCLoadSaveWindow::saveFile()
{ {
+4 -1
View File
@@ -382,7 +382,9 @@ void DBCMainEditor::onCellClickedMessage(int row, int col)
{ {
if (col == 3) //3 is the signals field. If clicked we go to the signals dialog if (col == 3) //3 is the signals field. If clicked we go to the signals dialog
{ {
QString idString = ui->MessagesTable->item(row, 0)->text(); QTableWidgetItem* msg = ui->MessagesTable->item(row, 0);
if(msg) {
QString idString = msg->text();
DBC_MESSAGE *message = dbcFile->messageHandler->findMsgByID(Utility::ParseStringToNum(idString)); DBC_MESSAGE *message = dbcFile->messageHandler->findMsgByID(Utility::ParseStringToNum(idString));
sigEditor->setMessageRef(message); sigEditor->setMessageRef(message);
sigEditor->setFileIdx(fileIdx); sigEditor->setFileIdx(fileIdx);
@@ -394,6 +396,7 @@ void DBCMainEditor::onCellClickedMessage(int row, int col)
inhibitCellChanged = false; inhibitCellChanged = false;
} }
} }
}
void DBCMainEditor::refreshNodesTable() void DBCMainEditor::refreshNodesTable()
{ {
+34 -23
View File
@@ -172,7 +172,7 @@ DBCSignalEditor::DBCSignalEditor(DBCHandler *handler, QWidget *parent) :
connect(ui->rbMultiplexed, &QRadioButton::toggled, connect(ui->rbMultiplexed, &QRadioButton::toggled,
[=](bool state) [=](bool state)
{ {
if (state) //signal is now set as a multiplexed signal if (state && currentSignal) //signal is now set as a multiplexed signal
{ {
currentSignal->isMultiplexed = true; currentSignal->isMultiplexed = true;
currentSignal->isMultiplexor = false; currentSignal->isMultiplexor = false;
@@ -184,7 +184,7 @@ DBCSignalEditor::DBCSignalEditor(DBCHandler *handler, QWidget *parent) :
connect(ui->rbMultiplexor, &QRadioButton::toggled, connect(ui->rbMultiplexor, &QRadioButton::toggled,
[=](bool state) [=](bool state)
{ {
if (state) //signal is now set as a multiplexed signal if (state && currentSignal) //signal is now set as a multiplexed signal
{ {
//don't allow this signal to be a multiplexor if there is already one for this message. //don't allow this signal to be a multiplexor if there is already one for this message.
//if (dbcMessage->multiplexorSignal != currentSignal && dbcMessage->multiplexorSignal != NULL) return; //I spoke too soon above... //if (dbcMessage->multiplexorSignal != currentSignal && dbcMessage->multiplexorSignal != NULL) return; //I spoke too soon above...
@@ -198,7 +198,7 @@ DBCSignalEditor::DBCSignalEditor(DBCHandler *handler, QWidget *parent) :
connect(ui->rbNotMulti, &QRadioButton::toggled, connect(ui->rbNotMulti, &QRadioButton::toggled,
[=](bool state) [=](bool state)
{ {
if (state) //signal is now set as a multiplexed signal if (state && currentSignal) //signal is now set as a multiplexed signal
{ {
currentSignal->isMultiplexed = false; currentSignal->isMultiplexed = false;
currentSignal->isMultiplexor = false; currentSignal->isMultiplexor = false;
@@ -260,19 +260,14 @@ void DBCSignalEditor::showEvent(QShowEvent* event)
{ {
QDialog::showEvent(event); QDialog::showEvent(event);
refreshSignalsList();
currentSignal = NULL; currentSignal = NULL;
if (dbcMessage->sigHandler->getCount() > 0) refreshSignalsList();
{
currentSignal = dbcMessage->sigHandler->findSignalByIdx(0);
fillSignalForm(currentSignal);
fillValueTable(currentSignal);
}
} }
void DBCSignalEditor::onValuesCellChanged(int row,int col) void DBCSignalEditor::onValuesCellChanged(int row,int col)
{ {
if (inhibitCellChanged) return; if (inhibitCellChanged) return;
if (row == ui->valuesTable->rowCount() - 1) if (row == ui->valuesTable->rowCount() - 1)
{ {
DBC_VAL newVal; DBC_VAL newVal;
@@ -340,9 +335,14 @@ void DBCSignalEditor::addNewSignal()
newSig.isMultiplexor = false; newSig.isMultiplexor = false;
newSig.multiplexValue = 0; newSig.multiplexValue = 0;
newSig.parentMessage = dbcMessage; newSig.parentMessage = dbcMessage;
ui->signalsList->addItem(newName);
dbcMessage->sigHandler->addSignal(newSig); dbcMessage->sigHandler->addSignal(newSig);
if (dbcMessage->sigHandler->getCount() == 1) clickSignalList(0);
/* add item at the end of the list and select it */
/* this will call clickSignalList */
ui->signalsList->addItem(newName);
ui->signalsList->setCurrentRow(ui->signalsList->count()-1);
} }
void DBCSignalEditor::deleteCurrentSignal() void DBCSignalEditor::deleteCurrentSignal()
@@ -353,10 +353,6 @@ void DBCSignalEditor::deleteCurrentSignal()
delete(ui->signalsList->item(currIdx)); delete(ui->signalsList->item(currIdx));
dbcMessage->sigHandler->removeSignal(currIdx); dbcMessage->sigHandler->removeSignal(currIdx);
currentSignal = NULL; currentSignal = NULL;
currIdx = ui->signalsList->currentRow();
if (currIdx > -1) currentSignal = dbcMessage->sigHandler->findSignalByIdx(currIdx);
fillSignalForm(currentSignal);
fillValueTable(currentSignal);
} }
} }
@@ -373,21 +369,30 @@ void DBCSignalEditor::deleteCurrentValue()
void DBCSignalEditor::refreshSignalsList() void DBCSignalEditor::refreshSignalsList()
{ {
ui->signalsList->clear(); ui->signalsList->clear();
for (int x = 0; x < dbcMessage->sigHandler->getCount(); x++) for (int x = 0; x < dbcMessage->sigHandler->getCount(); x++)
{ {
DBC_SIGNAL *sig = dbcMessage->sigHandler->findSignalByIdx(x); DBC_SIGNAL *sig = dbcMessage->sigHandler->findSignalByIdx(x);
ui->signalsList->addItem(sig->name); ui->signalsList->addItem(sig->name);
} }
if( ui->signalsList->count()>0 ) {
/* click first element */
ui->signalsList->setCurrentRow(0);
}
else
clickSignalList(-1);
} }
/* fillSignalForm also handles group "enabled" state */
/* WARNING: fillSignalForm can be called recursively since it is in the listener of cbIntelFormat */
void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig) void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
{ {
unsigned char bitpattern[8]; unsigned char bitpattern[8];
generateUsedBits(); if (sig == NULL) {
ui->groupBox->setEnabled(false);
if (sig == NULL)
{
ui->txtName->setText(""); ui->txtName->setText("");
ui->txtBias->setText(""); ui->txtBias->setText("");
ui->txtBitLength->setText(""); ui->txtBitLength->setText("");
@@ -408,6 +413,10 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
return; return;
} }
/* we have a signal */
ui->groupBox->setEnabled(true);
generateUsedBits();
ui->txtName->setText(sig->name); ui->txtName->setText(sig->name);
ui->txtBias->setText(QString::number(sig->bias)); ui->txtBias->setText(QString::number(sig->bias));
ui->txtBitLength->setText(QString::number(sig->signalSize)); ui->txtBitLength->setText(QString::number(sig->signalSize));
@@ -489,6 +498,7 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
} }
} }
/* fillValueTable also handles "enabled" state */
void DBCSignalEditor::fillValueTable(DBC_SIGNAL *sig) void DBCSignalEditor::fillValueTable(DBC_SIGNAL *sig)
{ {
int rowIdx; int rowIdx;
@@ -499,10 +509,13 @@ void DBCSignalEditor::fillValueTable(DBC_SIGNAL *sig)
ui->valuesTable->setRowCount(0); ui->valuesTable->setRowCount(0);
if (sig == NULL) { if (sig == NULL) {
ui->valuesTable->setEnabled(false);
inhibitCellChanged = false; inhibitCellChanged = false;
return; return;
} }
ui->valuesTable->setEnabled(true);
for (int i = 0; i < sig->valList.count(); i++) for (int i = 0; i < sig->valList.count(); i++)
{ {
QTableWidgetItem *val = new QTableWidgetItem(Utility::formatNumber(sig->valList[i].value)); QTableWidgetItem *val = new QTableWidgetItem(Utility::formatNumber(sig->valList[i].value));
@@ -521,11 +534,9 @@ void DBCSignalEditor::fillValueTable(DBC_SIGNAL *sig)
void DBCSignalEditor::clickSignalList(int row) void DBCSignalEditor::clickSignalList(int row)
{ {
if (row < 0) return;
//qDebug() << ui->signalsList->item(row)->text(); //qDebug() << ui->signalsList->item(row)->text();
DBC_SIGNAL *thisSig = dbcMessage->sigHandler->findSignalByName(ui->signalsList->item(row)->text()); DBC_SIGNAL *thisSig = (row<0) ? NULL : dbcMessage->sigHandler->findSignalByName(ui->signalsList->item(row)->text());
if (thisSig == NULL) return;
currentSignal = thisSig; currentSignal = thisSig;
fillSignalForm(thisSig); fillSignalForm(thisSig);
fillValueTable(thisSig); fillValueTable(thisSig);
+82
View File
@@ -2,6 +2,8 @@
#include <QProgressDialog> #include <QProgressDialog>
#include <iostream>
FrameFileIO::FrameFileIO() FrameFileIO::FrameFileIO()
{ {
@@ -122,6 +124,7 @@ bool FrameFileIO::loadFrameFile(QString &fileName, QVector<CANFrame>* frameCache
filters.append(QString(tr("IXXAT MiniLog (*.csv *.CSV)"))); filters.append(QString(tr("IXXAT MiniLog (*.csv *.CSV)")));
filters.append(QString(tr("CAN-DO Log (*.avc *.can *.evc *.qcc *.AVC *.CAN *.EVC *.QCC)"))); filters.append(QString(tr("CAN-DO Log (*.avc *.can *.evc *.qcc *.AVC *.CAN *.EVC *.QCC)")));
filters.append(QString(tr("Vehicle Spy (*.csv *.CSV)"))); filters.append(QString(tr("Vehicle Spy (*.csv *.CSV)")));
filters.append(QString(tr("Candump/Kayak (*.log *.LOG)")));
dialog.setFileMode(QFileDialog::ExistingFile); dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilters(filters); dialog.setNameFilters(filters);
@@ -150,6 +153,7 @@ bool FrameFileIO::loadFrameFile(QString &fileName, QVector<CANFrame>* frameCache
if (dialog.selectedNameFilter() == filters[6]) result = loadIXXATFile(filename, frameCache); if (dialog.selectedNameFilter() == filters[6]) result = loadIXXATFile(filename, frameCache);
if (dialog.selectedNameFilter() == filters[7]) result = loadCANDOFile(filename, frameCache); if (dialog.selectedNameFilter() == filters[7]) result = loadCANDOFile(filename, frameCache);
if (dialog.selectedNameFilter() == filters[8]) result = loadVehicleSpyFile(filename, frameCache); if (dialog.selectedNameFilter() == filters[8]) result = loadVehicleSpyFile(filename, frameCache);
if (dialog.selectedNameFilter() == filters[9]) result = loadCanDumpFile(filename, frameCache);
progress.cancel(); progress.cancel();
@@ -1264,6 +1268,84 @@ bool FrameFileIO::saveTraceFile(QString filename, const QVector<CANFrame> * fram
return true; return true;
} }
/* (0.003800) vcan0 164#0000c01aa8000013 */
bool FrameFileIO::loadCanDumpFile(QString filename, QVector<CANFrame>* frames)
{
QFile *inFile = new QFile(filename);
CANFrame thisFrame;
QByteArray line;
int lineCounter = 0;
int pos = 0;
bool ret;
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
{
delete inFile;
return false;
}
while (!inFile->atEnd()) {
lineCounter++;
if (lineCounter > 100)
{
qApp->processEvents();
lineCounter = 0;
}
line = inFile->readLine().toUpper();
if (line.length() > 1)
{
/* tokenize */
QList<QByteArray> tokens = line.split(' ');
if(tokens.count()<3) continue;
/* timestamp */
QRegExp timeExp("^\\((\\S+)\\)$");
ret = timeExp.exactMatch(tokens[0]);
if(!ret) continue;
thisFrame.timestamp = timeExp.cap(1).toDouble(&ret) * 1000000;
if(!ret) continue;
/* ID & value */
QRegExp IdValExp("^(\\S+)#(\\S+)\n$");
qDebug() << tokens[2];
ret = IdValExp.exactMatch(tokens[2]);
if(!ret) continue;
/* ID */
qDebug() << IdValExp.cap(1);
thisFrame.ID = IdValExp.cap(1).toInt(&ret, 16);
if(!ret) continue;
QString val= IdValExp.cap(2);
QRegExp valExp("(\\S{2})");
/* val byte per byte */
pos = 0;
thisFrame.len = 0;
while ((pos = valExp.indexIn(val, pos)) != -1)
{
thisFrame.data[thisFrame.len] = valExp.cap(1).toInt(&ret, 16);
if(!ret) continue;
thisFrame.len++;
pos += valExp.matchedLength();
}
/*NB: should we make sure len <= 8? */
thisFrame.extended = false;
thisFrame.isReceived = true;
thisFrame.bus = 0;
}
frames->append(thisFrame);
}
inFile->close();
delete inFile;
return true;
}
QString FrameFileIO::unQuote(QString inStr) QString FrameFileIO::unQuote(QString inStr)
{ {
return inStr.split('\"')[1]; return inStr.split('\"')[1];
+1
View File
@@ -42,6 +42,7 @@ public:
static bool saveVehicleSpyFile(QString, const QVector<CANFrame>*); static bool saveVehicleSpyFile(QString, const QVector<CANFrame>*);
static bool loadFrameFile(QString &, QVector<CANFrame>*); static bool loadFrameFile(QString &, QVector<CANFrame>*);
static bool saveFrameFile(QString &, const QVector<CANFrame>*); static bool saveFrameFile(QString &, const QVector<CANFrame>*);
static bool loadCanDumpFile(QString, QVector<CANFrame>*);
private: private:
static QString unQuote(QString); static QString unQuote(QString);
+7 -1
View File
@@ -447,8 +447,14 @@ void SerialWorker::handleTick()
} }
} }
framesPerSec += gotFrames * 1000 / elapsedTime->elapsed() - (framesPerSec / 4); int elapsed = elapsedTime->elapsed();
if(elapsed) {
framesPerSec += gotFrames * 1000 / elapsed - (framesPerSec / 4);
elapsedTime->restart(); elapsedTime->restart();
}
else
framesPerSec = 0;
emit frameUpdateTick(framesPerSec / 4, gotFrames); //sends stats to interested parties emit frameUpdateTick(framesPerSec / 4, gotFrames); //sends stats to interested parties
canModel->sendBulkRefresh(gotFrames); canModel->sendBulkRefresh(gotFrames);
gotFrames = 0; gotFrames = 0;