Merge branch 'master' of github.com:collin80/SavvyCAN into WIP

Conflicts:
	README.md
	serialworker.cpp
This commit is contained in:
Collin Kidder
2016-05-31 19:33:26 -04:00
8 changed files with 185 additions and 41 deletions
+33 -3
View File
@@ -50,6 +50,36 @@ http://www.qcustomplot.com/
However, this source code is integrated into the source for SavvyCAN and one isn't required to download it separately. However, this source code is integrated into the source for SavvyCAN and one isn't required to download it separately.
The project now requires (yes, requires) at least QT 5.6.0 because of This project will soon require 5.6.0 or higher because of an upcoming dependency on QSerialBus but currently
a dependency on QtSerialBus which is still an optional feature. You should compile with QT 5.5
will need to download it when installing QT.
Instructions for compiling with Ubuntu:
sudo apt-get install qt5-default qtdeclarative5-dev libqt5serialport5-dev libudev-dev
download and extract QScintilla (see above for link), assume it is extracted in QScintilla-gpl-2.9.1
cd ~/QScintilla-gpl-2.9.1/Qt4Qt5
qmake qscintilla.pro
make
sudo make install
Optionally remove ~/QScintilla-gpl-2.9.1
cd ~
git clone https://github.com/collin80/SavvyCAN.git
cd SavvyCAN
qmake
make
Now run SavvyCAN
./SavvyCAN
+4 -1
View File
@@ -764,8 +764,11 @@ 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)
+6 -4
View File
@@ -48,10 +48,12 @@ void DBCLoadSaveWindow::newFile()
void DBCLoadSaveWindow::loadFile() void DBCLoadSaveWindow::loadFile()
{ {
DBCFile *file = dbcHandler->loadDBCFile(-1); DBCFile *file = dbcHandler->loadDBCFile(-1);
int idx = ui->tableFiles->rowCount(); if(file) {
ui->tableFiles->insertRow(ui->tableFiles->rowCount()); int idx = ui->tableFiles->rowCount();
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(file->getFullFilename())); ui->tableFiles->insertRow(ui->tableFiles->rowCount());
ui->tableFiles->setItem(idx, 1, new QTableWidgetItem("-1")); ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(file->getFullFilename()));
ui->tableFiles->setItem(idx, 1, new QTableWidgetItem("-1"));
}
} }
void DBCLoadSaveWindow::saveFile() void DBCLoadSaveWindow::saveFile()
+13 -10
View File
@@ -382,16 +382,19 @@ 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);
DBC_MESSAGE *message = dbcFile->messageHandler->findMsgByID(Utility::ParseStringToNum(idString)); if(msg) {
sigEditor->setMessageRef(message); QString idString = msg->text();
sigEditor->setFileIdx(fileIdx); DBC_MESSAGE *message = dbcFile->messageHandler->findMsgByID(Utility::ParseStringToNum(idString));
sigEditor->exec(); //blocks this window from being active until we're done sigEditor->setMessageRef(message);
//now update the displayed # of signals sigEditor->setFileIdx(fileIdx);
inhibitCellChanged = true; sigEditor->exec(); //blocks this window from being active until we're done
QTableWidgetItem *replacement = new QTableWidgetItem(QString::number(message->sigHandler->getCount())); //now update the displayed # of signals
ui->MessagesTable->setItem(row, col, replacement); inhibitCellChanged = true;
inhibitCellChanged = false; QTableWidgetItem *replacement = new QTableWidgetItem(QString::number(message->sigHandler->getCount()));
ui->MessagesTable->setItem(row, col, replacement);
inhibitCellChanged = false;
}
} }
} }
+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
@@ -3,6 +3,8 @@
#include <QMessageBox> #include <QMessageBox>
#include <QProgressDialog> #include <QProgressDialog>
#include <iostream>
FrameFileIO::FrameFileIO() FrameFileIO::FrameFileIO()
{ {
@@ -123,6 +125,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);
@@ -151,6 +154,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();
@@ -1335,6 +1339,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)
{ {
QStringList temp; QStringList temp;
+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);
+12
View File
@@ -478,6 +478,18 @@ void SerialWorker::handleTick()
} }
} }
int elapsed = elapsedTime->elapsed();
if(elapsed) {
framesPerSec += gotFrames * 1000 / elapsed - (framesPerSec / 4);
elapsedTime->restart();
}
else
framesPerSec = 0;
emit frameUpdateTick(framesPerSec / 4, gotFrames); //sends stats to interested parties
canModel->sendBulkRefresh(gotFrames);
gotFrames = 0;
if (doValidation && serial && serial->isOpen()) sendCommValidation(); if (doValidation && serial && serial->isOpen()) sendCommValidation();
} }