First pass implementing support for extended multiplexing.

This causes significant changes to the DBC interface. Things are
probably a bit broken right now. Committing to get it on record
before further large changes are done.
This commit is contained in:
Collin Kidder
2021-02-23 21:22:56 -05:00
parent 4d4dc687aa
commit e00aa1150a
10 changed files with 351 additions and 101 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef CONFIG #ifndef CONFIG
#define CONFIG #define CONFIG
#define VERSION 202 #define VERSION 203
//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
+7
View File
@@ -23,12 +23,19 @@ DBC_SIGNAL::DBC_SIGNAL()
factor = 1.0; factor = 1.0;
intelByteOrder = false; intelByteOrder = false;
parentMessage = nullptr; parentMessage = nullptr;
multiplexParent = nullptr;
receiver = nullptr; receiver = nullptr;
signalSize = 1; signalSize = 1;
startBit = 1; startBit = 1;
valType = DBC_SIG_VAL_TYPE::UNSIGNED_INT; valType = DBC_SIG_VAL_TYPE::UNSIGNED_INT;
} }
DBC_MULTIPLEX::DBC_MULTIPLEX()
{
lowerBound = 0;
upperBound = 0;
sig = nullptr;
}
/* /*
The way that the DBC file format works is kind of weird... For intel format signals you count up The way that the DBC file format works is kind of weird... For intel format signals you count up
+21 -8
View File
@@ -26,18 +26,19 @@ enum DBC_SIG_VAL_TYPE
enum DBC_ATTRIBUTE_VAL_TYPE enum DBC_ATTRIBUTE_VAL_TYPE
{ {
QINT, ATTR_INT,
QFLOAT, ATTR_FLOAT,
QSTRING, ATTR_STRING,
ENUM ATTR_ENUM,
}; };
enum DBC_ATTRIBUTE_TYPE enum DBC_ATTRIBUTE_TYPE
{ {
GENERAL, ATTR_TYPE_GENERAL,
NODE, ATTR_TYPE_NODE,
MESSAGE, ATTR_TYPE_MESSAGE,
SIG ATTR_TYPE_SIG,
ATTR_TYPE_ANY
}; };
class DBC_ATTRIBUTE class DBC_ATTRIBUTE
@@ -82,6 +83,16 @@ public:
}; };
class DBC_MESSAGE; //forward reference so that DBC_SIGNAL can compile before we get to real definition of DBC_MESSAGE class DBC_MESSAGE; //forward reference so that DBC_SIGNAL can compile before we get to real definition of DBC_MESSAGE
class DBC_SIGNAL;
class DBC_MULTIPLEX
{
public:
int lowerBound, upperBound;
DBC_SIGNAL *sig;
DBC_MULTIPLEX();
};
class DBC_SIGNAL class DBC_SIGNAL
{ {
@@ -105,6 +116,8 @@ public: //TODO: this is sloppy. It shouldn't all be public!
QVariant cachedValue; QVariant cachedValue;
QList<DBC_ATTRIBUTE_VALUE> attributes; QList<DBC_ATTRIBUTE_VALUE> attributes;
QList<DBC_VAL_ENUM_ENTRY> valList; QList<DBC_VAL_ENUM_ENTRY> valList;
QList<DBC_MULTIPLEX> multiplexedChildren;
DBC_SIGNAL *multiplexParent;
DBC_SIGNAL(); DBC_SIGNAL();
bool processAsText(const CANFrame &frame, QString &outString, bool outputName = true); bool processAsText(const CANFrame &frame, QString &outString, bool outputName = true);
+141 -53
View File
@@ -373,12 +373,12 @@ void DBCFile::setAssocBus(int bus)
assocBuses = bus; assocBuses = bus;
} }
DBC_ATTRIBUTE *DBCFile::findAttributeByName(QString name) DBC_ATTRIBUTE *DBCFile::findAttributeByName(QString name, DBC_ATTRIBUTE_TYPE type)
{ {
if (dbc_attributes.length() == 0) return nullptr; if (dbc_attributes.length() == 0) return nullptr;
for (int i = 0; i < dbc_attributes.length(); i++) for (int i = 0; i < dbc_attributes.length(); i++)
{ {
if (dbc_attributes[i].name.compare(name, Qt::CaseInsensitive) == 0) if (dbc_attributes[i].name.compare(name, Qt::CaseInsensitive) == 0 && ((type == dbc_attributes[i].attrType) || (type == ATTR_TYPE_ANY) ) )
{ {
return &dbc_attributes[i]; return &dbc_attributes[i];
} }
@@ -480,6 +480,18 @@ DBC_SIGNAL* DBCFile::parseSignalLine(QString line, DBC_MESSAGE *msg)
offset = 1; offset = 1;
} }
else else
{
regex.setPattern("^SG\\_ *(\\w+) +m(\\d+)M *: *(\\d+)\\|(\\d+)@(\\d+)([\\+|\\-]) \\(([0-9.+\\-eE]+),([0-9.+\\-eE]+)\\) \\[([0-9.+\\-eE]+)\\|([0-9.+\\-eE]+)\\] \\\"(.*)\\\" (.*)");
match = regex.match(line);
if (match.hasMatch())
{
qDebug() << "Extended Multiplexor Signal";
sig.isMultiplexor = true; //we don't set the local isMultiplexor variable because this isn't the top level multiplexor
sig.isMultiplexed = true; //but, it is both a multiplexor and multiplexed
sig.multiplexValue = match.captured(2).toInt();
offset = 1;
}
else
{ {
qDebug() << "standard signal"; qDebug() << "standard signal";
regex.setPattern("^SG\\_ *(\\w+) *: *(\\d+)\\|(\\d+)@(\\d+)([\\+|\\-]) \\(([0-9.+\\-eE]+),([0-9.+\\-eE]+)\\) \\[([0-9.+\\-eE]+)\\|([0-9.+\\-eE]+)\\] \\\"(.*)\\\" (.*)"); regex.setPattern("^SG\\_ *(\\w+) *: *(\\d+)\\|(\\d+)@(\\d+)([\\+|\\-]) \\(([0-9.+\\-eE]+),([0-9.+\\-eE]+)\\) \\[([0-9.+\\-eE]+)\\|([0-9.+\\-eE]+)\\] \\\"(.*)\\\" (.*)");
@@ -488,6 +500,7 @@ DBC_SIGNAL* DBCFile::parseSignalLine(QString line, DBC_MESSAGE *msg)
sig.isMultiplexor = false; sig.isMultiplexor = false;
} }
} }
}
//captured 1 is the signal name //captured 1 is the signal name
//captured 2 would be multiplex value if this is a multiplex signal. Then offset the rest of these by 1 //captured 2 would be multiplex value if this is a multiplex signal. Then offset the rest of these by 1
@@ -566,6 +579,46 @@ DBC_SIGNAL* DBCFile::parseSignalLine(QString line, DBC_MESSAGE *msg)
return nullptr; return nullptr;
} }
//SG_MUL_VAL_ 2024 S1_PID_0D_VehicleSpeed S1 13-13;
bool DBCFile::parseSignalMultiplexValueLine(QString line)
{
QRegularExpression regex;
QRegularExpressionMatch match;
qDebug() << "Found a multiplex definition line";
regex.setPattern("^SG\\_MUL\\_VAL\\_ (\\d+) (\\w+) (\\w+) (\\d+)\\-(\\d+);");
match = regex.match(line);
//captured 1 is message ID
//Captured 2 is signal name
//Captured 3 is parent multiplexor
//captured 4 is the lower bound
//captured 5 is the upper bound
if (match.hasMatch())
{
DBC_MESSAGE *msg = messageHandler->findMsgByID(match.captured(1).toUInt());
if (msg != nullptr)
{
DBC_SIGNAL *thisSignal = msg->sigHandler->findSignalByName(match.captured(2));
if (thisSignal != nullptr)
{
DBC_SIGNAL *parentSignal = msg->sigHandler->findSignalByName(match.captured(3));
if (parentSignal != nullptr)
{
//now need to add "thisSignal" to the children multiplexed signals of "parentSignal"
DBC_MULTIPLEX mx;
mx.lowerBound = match.captured(4).toInt();
mx.upperBound = match.captured(5).toInt();
mx.sig = thisSignal;
parentSignal->multiplexedChildren.append(mx);
thisSignal->multiplexParent = parentSignal;
return true;
}
}
}
}
return false;
}
bool DBCFile::parseValueLine(QString line) bool DBCFile::parseValueLine(QString line)
{ {
QRegularExpression regex; QRegularExpression regex;
@@ -732,16 +785,16 @@ bool DBCFile::parseDefaultAttrLine(QString line)
{ {
switch (found->valType) switch (found->valType)
{ {
case QSTRING: case ATTR_STRING:
found->defaultValue = match.captured(2); found->defaultValue = match.captured(2);
break; break;
case QFLOAT: case ATTR_FLOAT:
found->defaultValue = match.captured(2).toFloat(); found->defaultValue = match.captured(2).toFloat();
break; break;
case QINT: case ATTR_INT:
found->defaultValue = match.captured(2).toInt(); found->defaultValue = match.captured(2).toInt();
break; break;
case ENUM: case ATTR_ENUM:
QString temp = match.captured(2); QString temp = match.captured(2);
found->defaultValue = 0; found->defaultValue = 0;
for (int x = 0; x < found->enumVals.count(); x++) for (int x = 0; x < found->enumVals.count(); x++)
@@ -825,6 +878,12 @@ bool DBCFile::loadFile(QString fileName)
{ {
if (!parseSignalLine(line, currentMessage)) numSigFaults++; if (!parseSignalLine(line, currentMessage)) numSigFaults++;
} }
if (line.startsWith("SG_MUL_VAL_ ")) //defines a signal multiplexing value definition
{
if (!parseSignalMultiplexValueLine(line)) numSigFaults++;
}
if (line.startsWith("BU_:")) //line specifies the nodes on this canbus if (line.startsWith("BU_:")) //line specifies the nodes on this canbus
{ {
qDebug() << "Found a BU line"; qDebug() << "Found a BU line";
@@ -917,33 +976,46 @@ bool DBCFile::loadFile(QString fileName)
if (parseAttribute(line.right(line.length() - 12), attr)) if (parseAttribute(line.right(line.length() - 12), attr))
{ {
//qDebug() << "Success"; //qDebug() << "Success";
attr.attrType = SIG; attr.attrType = ATTR_TYPE_SIG;
dbc_attributes.append(attr); dbc_attributes.append(attr);
} }
} }
if (line.startsWith("BA_DEF_ BO_ ")) //definition of a message attribute else if (line.startsWith("BA_DEF_ BO_ ")) //definition of a message attribute
{ {
qDebug() << "Found a BO attribute line"; qDebug() << "Found a BO attribute line";
if (parseAttribute(line.right(line.length() - 12), attr)) if (parseAttribute(line.right(line.length() - 12), attr))
{ {
qDebug() << "Success"; qDebug() << "Success";
attr.attrType = MESSAGE; attr.attrType = ATTR_TYPE_MESSAGE;
dbc_attributes.append(attr); dbc_attributes.append(attr);
} }
} }
if (line.startsWith("BA_DEF_ BU_ ")) //definition of a node attribute else if (line.startsWith("BA_DEF_ BU_ ")) //definition of a node attribute
{ {
qDebug() << "Found a BU attribute line"; qDebug() << "Found a BU attribute line";
if (parseAttribute(line.right(line.length() - 12), attr)) if (parseAttribute(line.right(line.length() - 12), attr))
{ {
//qDebug() << "Success"; //qDebug() << "Success";
attr.attrType = NODE; attr.attrType = ATTR_TYPE_NODE;
dbc_attributes.append(attr); dbc_attributes.append(attr);
} }
} }
else if (line.startsWith("BA_DEF_ ")) //definition of a root attribute
{
qDebug() << "Found a BU attribute line";
if (parseAttribute(line.right(line.length() - 9), attr))
{
//qDebug() << "Success";
attr.attrType = ATTR_TYPE_GENERAL;
dbc_attributes.append(attr);
}
}
if (line.startsWith("BA_DEF_DEF_ ")) //definition of default value for an attribute if (line.startsWith("BA_DEF_DEF_ ")) //definition of default value for an attribute
{ {
parseDefaultAttrLine(line); parseDefaultAttrLine(line);
@@ -961,13 +1033,13 @@ bool DBCFile::loadFile(QString fileName)
DBC_ATTRIBUTE *bgAttr = findAttributeByName("GenMsgBackgroundColor"); DBC_ATTRIBUTE *bgAttr = findAttributeByName("GenMsgBackgroundColor");
if (!bgAttr) if (!bgAttr)
{ {
attr.attrType = MESSAGE; attr.attrType = ATTR_TYPE_MESSAGE;
attr.defaultValue = QApplication::palette().color(QPalette::Base).name(); attr.defaultValue = QApplication::palette().color(QPalette::Base).name();
attr.enumVals.clear(); attr.enumVals.clear();
attr.lower = 0; attr.lower = 0;
attr.upper = 0; attr.upper = 0;
attr.name = "GenMsgBackgroundColor"; attr.name = "GenMsgBackgroundColor";
attr.valType = QSTRING; attr.valType = ATTR_STRING;
dbc_attributes.append(attr); dbc_attributes.append(attr);
bgAttr = findAttributeByName("GenMsgBackgroundColor"); bgAttr = findAttributeByName("GenMsgBackgroundColor");
} }
@@ -975,13 +1047,13 @@ bool DBCFile::loadFile(QString fileName)
DBC_ATTRIBUTE *fgAttr = findAttributeByName("GenMsgForegroundColor"); DBC_ATTRIBUTE *fgAttr = findAttributeByName("GenMsgForegroundColor");
if (!fgAttr) if (!fgAttr)
{ {
attr.attrType = MESSAGE; attr.attrType = ATTR_TYPE_MESSAGE;
attr.defaultValue = QApplication::palette().color(QPalette::WindowText).name(); attr.defaultValue = QApplication::palette().color(QPalette::WindowText).name();
attr.enumVals.clear(); attr.enumVals.clear();
attr.lower = 0; attr.lower = 0;
attr.upper = 0; attr.upper = 0;
attr.name = "GenMsgForegroundColor"; attr.name = "GenMsgForegroundColor";
attr.valType = QSTRING; attr.valType = ATTR_STRING;
dbc_attributes.append(attr); dbc_attributes.append(attr);
fgAttr = findAttributeByName("GenMsgForegroundColor"); fgAttr = findAttributeByName("GenMsgForegroundColor");
} }
@@ -1021,6 +1093,22 @@ bool DBCFile::loadFile(QString fileName)
thisFG = msg->findAttrValByName("GenMsgForegroundColor"); thisFG = msg->findAttrValByName("GenMsgForegroundColor");
if (thisBG) msg->bgColor = QColor(thisBG->value.toString()); if (thisBG) msg->bgColor = QColor(thisBG->value.toString());
if (thisFG) msg->fgColor = QColor(thisFG->value.toString()); if (thisFG) msg->fgColor = QColor(thisFG->value.toString());
for (int y = 0; y < msg->sigHandler->getCount(); y++)
{
DBC_SIGNAL *sig = msg->sigHandler->findSignalByIdx(y);
//if this doesn't have a multiplex parent set but is multiplexed then it must have used
//simple multiplexing instead of any extended specification. So, fill in the multiplexor signal here
//and also write the extended entry for it too.
if (sig->isMultiplexed && (sig->multiplexParent == nullptr) )
{
sig->multiplexParent = msg->multiplexorSignal;
DBC_MULTIPLEX mlt;
mlt.sig = sig;
mlt.lowerBound = sig->multiplexValue;
mlt.upperBound = mlt.lowerBound;
msg->multiplexorSignal->multiplexedChildren.append(mlt);
}
}
} }
if (numSigFaults > 0 || numMsgFaults > 0) if (numSigFaults > 0 || numMsgFaults > 0)
@@ -1049,14 +1137,14 @@ QVariant DBCFile::processAttributeVal(QString input, DBC_ATTRIBUTE_VAL_TYPE typ)
QVariant out; QVariant out;
switch (typ) switch (typ)
{ {
case QSTRING: case ATTR_STRING:
out = input; out = input;
break; break;
case QFLOAT: case ATTR_FLOAT:
out = input.toFloat(); out = input.toFloat();
break; break;
case QINT: case ATTR_INT:
case ENUM: case ATTR_ENUM:
out = input.toInt(); out = input.toInt();
break; break;
} }
@@ -1080,14 +1168,14 @@ bool DBCFile::parseAttribute(QString inpString, DBC_ATTRIBUTE &attr)
qDebug() << "Parsing an attribute with low/high values"; qDebug() << "Parsing an attribute with low/high values";
attr.name = match.captured(1); attr.name = match.captured(1);
QString typ = match.captured(2); QString typ = match.captured(2);
attr.attrType = SIG; attr.attrType = ATTR_TYPE_SIG;
attr.lower = 0; attr.lower = 0;
attr.upper = 0; attr.upper = 0;
attr.valType = QSTRING; attr.valType = ATTR_STRING;
if (!typ.compare("INT", Qt::CaseInsensitive)) if (!typ.compare("INT", Qt::CaseInsensitive))
{ {
qDebug() << "INT attribute named " << attr.name; qDebug() << "INT attribute named " << attr.name;
attr.valType = QINT; attr.valType = ATTR_INT;
attr.lower = match.captured(3).toInt(); attr.lower = match.captured(3).toInt();
attr.upper = match.captured(4).toInt(); attr.upper = match.captured(4).toInt();
goodAttr = true; goodAttr = true;
@@ -1095,7 +1183,7 @@ bool DBCFile::parseAttribute(QString inpString, DBC_ATTRIBUTE &attr)
if (!typ.compare("FLOAT", Qt::CaseInsensitive)) if (!typ.compare("FLOAT", Qt::CaseInsensitive))
{ {
qDebug() << "FLOAT attribute named " << attr.name; qDebug() << "FLOAT attribute named " << attr.name;
attr.valType = QFLOAT; attr.valType = ATTR_FLOAT;
attr.lower = match.captured(3).toDouble(); attr.lower = match.captured(3).toDouble();
attr.upper = match.captured(4).toDouble(); attr.upper = match.captured(4).toDouble();
goodAttr = true; goodAttr = true;
@@ -1103,7 +1191,7 @@ bool DBCFile::parseAttribute(QString inpString, DBC_ATTRIBUTE &attr)
if (!typ.compare("STRING", Qt::CaseInsensitive)) if (!typ.compare("STRING", Qt::CaseInsensitive))
{ {
qDebug() << "STRING attribute named " << attr.name; qDebug() << "STRING attribute named " << attr.name;
attr.valType = QSTRING; attr.valType = ATTR_STRING;
goodAttr = true; goodAttr = true;
} }
} }
@@ -1119,26 +1207,26 @@ bool DBCFile::parseAttribute(QString inpString, DBC_ATTRIBUTE &attr)
QString typ = match.captured(2); QString typ = match.captured(2);
attr.lower = 0; attr.lower = 0;
attr.upper = 0; attr.upper = 0;
attr.attrType = SIG; attr.attrType = ATTR_TYPE_SIG;
if (!typ.compare("INT", Qt::CaseInsensitive)) if (!typ.compare("INT", Qt::CaseInsensitive))
{ {
qDebug() << "INT attribute named " << attr.name; qDebug() << "INT attribute named " << attr.name;
attr.valType = QINT; attr.valType = ATTR_INT;
goodAttr = true; goodAttr = true;
} }
if (!typ.compare("FLOAT", Qt::CaseInsensitive)) if (!typ.compare("FLOAT", Qt::CaseInsensitive))
{ {
qDebug() << "FLOAT attribute named " << attr.name; qDebug() << "FLOAT attribute named " << attr.name;
attr.valType = QFLOAT; attr.valType = ATTR_FLOAT;
goodAttr = true; goodAttr = true;
} }
if (!typ.compare("STRING", Qt::CaseInsensitive)) if (!typ.compare("STRING", Qt::CaseInsensitive))
{ {
qDebug() << "STRING attribute named " << attr.name; qDebug() << "STRING attribute named " << attr.name;
attr.valType = QSTRING; attr.valType = ATTR_STRING;
goodAttr = true; goodAttr = true;
} }
@@ -1151,7 +1239,7 @@ bool DBCFile::parseAttribute(QString inpString, DBC_ATTRIBUTE &attr)
attr.enumVals.append(Utility::unQuote(enumStr)); attr.enumVals.append(Utility::unQuote(enumStr));
qDebug() << "Enum value: " << enumStr; qDebug() << "Enum value: " << enumStr;
} }
attr.valType = ENUM; attr.valType = ATTR_ENUM;
goodAttr = true; goodAttr = true;
} }
} }
@@ -1378,15 +1466,15 @@ bool DBCFile::saveFile(QString fileName)
msgOutput.append("BA_DEF_ "); msgOutput.append("BA_DEF_ ");
switch (dbc_attributes[x].attrType) switch (dbc_attributes[x].attrType)
{ {
case GENERAL: case ATTR_TYPE_GENERAL:
break; break;
case NODE: case ATTR_TYPE_NODE:
msgOutput.append("BU_ "); msgOutput.append("BU_ ");
break; break;
case MESSAGE: case ATTR_TYPE_MESSAGE:
msgOutput.append("BO_ "); msgOutput.append("BO_ ");
break; break;
case SIG: case ATTR_TYPE_SIG:
msgOutput.append("SG_ "); msgOutput.append("SG_ ");
break; break;
} }
@@ -1395,16 +1483,16 @@ bool DBCFile::saveFile(QString fileName)
switch (dbc_attributes[x].valType) switch (dbc_attributes[x].valType)
{ {
case QINT: case ATTR_INT:
msgOutput.append("INT " + QString::number(dbc_attributes[x].lower) + " " + QString::number(dbc_attributes[x].upper)); msgOutput.append("INT " + QString::number(dbc_attributes[x].lower) + " " + QString::number(dbc_attributes[x].upper));
break; break;
case QFLOAT: case ATTR_FLOAT:
msgOutput.append("FLOAT " + QString::number(dbc_attributes[x].lower) + " " + QString::number(dbc_attributes[x].upper)); msgOutput.append("FLOAT " + QString::number(dbc_attributes[x].lower) + " " + QString::number(dbc_attributes[x].upper));
break; break;
case QSTRING: case ATTR_STRING:
msgOutput.append("STRING "); msgOutput.append("STRING ");
break; break;
case ENUM: case ATTR_ENUM:
msgOutput.append("ENUM "); msgOutput.append("ENUM ");
foreach (QString str, dbc_attributes[x].enumVals) foreach (QString str, dbc_attributes[x].enumVals)
{ {
@@ -1424,14 +1512,14 @@ bool DBCFile::saveFile(QString fileName)
defaultsOutput.append("BA_DEF_DEF_ \"" + dbc_attributes[x].name + "\" "); defaultsOutput.append("BA_DEF_DEF_ \"" + dbc_attributes[x].name + "\" ");
switch (dbc_attributes[x].valType) switch (dbc_attributes[x].valType)
{ {
case QSTRING: case ATTR_STRING:
defaultsOutput.append("\"" + dbc_attributes[x].defaultValue.toString() + "\";\n"); defaultsOutput.append("\"" + dbc_attributes[x].defaultValue.toString() + "\";\n");
break; break;
case ENUM: case ATTR_ENUM:
defaultsOutput.append("\"" + dbc_attributes[x].enumVals[dbc_attributes[x].defaultValue.toInt()] + "\";\n"); defaultsOutput.append("\"" + dbc_attributes[x].enumVals[dbc_attributes[x].defaultValue.toInt()] + "\";\n");
break; break;
case QINT: case ATTR_INT:
case QFLOAT: case ATTR_FLOAT:
defaultsOutput.append(dbc_attributes[x].defaultValue.toString() + ";\n"); defaultsOutput.append(dbc_attributes[x].defaultValue.toString() + ";\n");
break; break;
} }
@@ -1496,42 +1584,42 @@ int DBCHandler::createBlankFile()
DBC_ATTRIBUTE attr; DBC_ATTRIBUTE attr;
//add our custom attributes to the new file so that we know they're already there. //add our custom attributes to the new file so that we know they're already there.
attr.attrType = MESSAGE; attr.attrType = ATTR_TYPE_MESSAGE;
attr.defaultValue = QApplication::palette().color(QPalette::Base).name(); attr.defaultValue = QApplication::palette().color(QPalette::Base).name();
qDebug() << attr.defaultValue; qDebug() << attr.defaultValue;
attr.enumVals.clear(); attr.enumVals.clear();
attr.lower = 0; attr.lower = 0;
attr.upper = 0; attr.upper = 0;
attr.name = "GenMsgBackgroundColor"; attr.name = "GenMsgBackgroundColor";
attr.valType = QSTRING; attr.valType = ATTR_STRING;
newFile.dbc_attributes.append(attr); newFile.dbc_attributes.append(attr);
attr.attrType = MESSAGE; attr.attrType = ATTR_TYPE_MESSAGE;
attr.defaultValue = QApplication::palette().color(QPalette::WindowText).name(); attr.defaultValue = QApplication::palette().color(QPalette::WindowText).name();
qDebug() << attr.defaultValue; qDebug() << attr.defaultValue;
attr.enumVals.clear(); attr.enumVals.clear();
attr.lower = 0; attr.lower = 0;
attr.upper = 0; attr.upper = 0;
attr.name = "GenMsgForegroundColor"; attr.name = "GenMsgForegroundColor";
attr.valType = QSTRING; attr.valType = ATTR_STRING;
newFile.dbc_attributes.append(attr); newFile.dbc_attributes.append(attr);
attr.attrType = MESSAGE; attr.attrType = ATTR_TYPE_MESSAGE;
attr.defaultValue = 0; attr.defaultValue = 0;
attr.enumVals.clear(); attr.enumVals.clear();
attr.lower = 0; attr.lower = 0;
attr.upper = 0; attr.upper = 0;
attr.name = "matchingcriteria"; attr.name = "matchingcriteria";
attr.valType = QINT; attr.valType = ATTR_INT;
newFile.dbc_attributes.append(attr); newFile.dbc_attributes.append(attr);
attr.attrType = MESSAGE; attr.attrType = ATTR_TYPE_MESSAGE;
attr.defaultValue = 0; attr.defaultValue = 0;
attr.enumVals.clear(); attr.enumVals.clear();
attr.lower = 0; attr.lower = 0;
attr.upper = 0; attr.upper = 0;
attr.name = "filterlabeling"; attr.name = "filterlabeling";
attr.valType = QINT; attr.valType = ATTR_INT;
newFile.dbc_attributes.append(attr); newFile.dbc_attributes.append(attr);
DBC_NODE falseNode; DBC_NODE falseNode;
@@ -1870,24 +1958,24 @@ DBCHandler::DBCHandler()
DBC_ATTRIBUTE attr; DBC_ATTRIBUTE attr;
attr.attrType = MESSAGE; attr.attrType = ATTR_TYPE_MESSAGE;
attr.defaultValue = matchingCriteria; attr.defaultValue = matchingCriteria;
attr.enumVals.clear(); attr.enumVals.clear();
attr.lower = 0; attr.lower = 0;
attr.upper = 0; attr.upper = 0;
attr.name = "matchingcriteria"; attr.name = "matchingcriteria";
attr.valType = QINT; attr.valType = ATTR_INT;
file->dbc_attributes.append(attr); file->dbc_attributes.append(attr);
file->messageHandler->setMatchingCriteria(matchingCriteria); file->messageHandler->setMatchingCriteria(matchingCriteria);
bool filterLabeling = settings.value("DBC/FilterLabeling_" + QString(i),0).toBool(); bool filterLabeling = settings.value("DBC/FilterLabeling_" + QString(i),0).toBool();
attr.attrType = MESSAGE; attr.attrType = ATTR_TYPE_MESSAGE;
attr.defaultValue = filterLabeling; attr.defaultValue = filterLabeling;
attr.enumVals.clear(); attr.enumVals.clear();
attr.lower = 0; attr.lower = 0;
attr.upper = 0; attr.upper = 0;
attr.name = "filterlabeling"; attr.name = "filterlabeling";
attr.valType = QINT; attr.valType = ATTR_INT;
file->dbc_attributes.append(attr); file->dbc_attributes.append(attr);
file->messageHandler->setFilterLabeling(filterLabeling); file->messageHandler->setFilterLabeling(filterLabeling);
+2 -1
View File
@@ -73,7 +73,7 @@ public:
DBCFile& operator=(const DBCFile& cpy); DBCFile& operator=(const DBCFile& cpy);
DBC_NODE *findNodeByName(QString name); DBC_NODE *findNodeByName(QString name);
DBC_NODE *findNodeByIdx(int idx); DBC_NODE *findNodeByIdx(int idx);
DBC_ATTRIBUTE *findAttributeByName(QString name); DBC_ATTRIBUTE *findAttributeByName(QString name, DBC_ATTRIBUTE_TYPE type = ATTR_TYPE_ANY);
DBC_ATTRIBUTE *findAttributeByIdx(int idx); DBC_ATTRIBUTE *findAttributeByIdx(int idx);
void findAttributesByType(DBC_ATTRIBUTE_TYPE typ, QList<DBC_ATTRIBUTE> *list); void findAttributesByType(DBC_ATTRIBUTE_TYPE typ, QList<DBC_ATTRIBUTE> *list);
bool saveFile(QString); bool saveFile(QString);
@@ -99,6 +99,7 @@ private:
bool parseAttribute(QString inpString, DBC_ATTRIBUTE &attr); bool parseAttribute(QString inpString, DBC_ATTRIBUTE &attr);
QVariant processAttributeVal(QString input, DBC_ATTRIBUTE_VAL_TYPE typ); QVariant processAttributeVal(QString input, DBC_ATTRIBUTE_VAL_TYPE typ);
DBC_SIGNAL* parseSignalLine(QString line, DBC_MESSAGE *msg); DBC_SIGNAL* parseSignalLine(QString line, DBC_MESSAGE *msg);
bool parseSignalMultiplexValueLine(QString line);
DBC_MESSAGE* parseMessageLine(QString line); DBC_MESSAGE* parseMessageLine(QString line);
bool parseValueLine(QString line); bool parseValueLine(QString line);
bool parseAttributeLine(QString line); bool parseAttributeLine(QString line);
+7 -7
View File
@@ -35,7 +35,7 @@ DBCLoadSaveWindow::DBCLoadSaveWindow(const QVector<CANFrame> *frames, QWidget *p
{ {
DBCFile * file = dbcHandler->getFileByIdx(idx); DBCFile * file = dbcHandler->getFileByIdx(idx);
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->getFilename()));
QString bus = QString::number(file->getAssocBus() ); QString bus = QString::number(file->getAssocBus() );
ui->tableFiles->setItem(idx, 1, new QTableWidgetItem(bus)); ui->tableFiles->setItem(idx, 1, new QTableWidgetItem(bus));
@@ -189,7 +189,7 @@ void DBCLoadSaveWindow::loadFile()
inhibitCellProcessing=true; inhibitCellProcessing=true;
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->getFilename()));
ui->tableFiles->setItem(idx, 1, new QTableWidgetItem("-1")); ui->tableFiles->setItem(idx, 1, new QTableWidgetItem("-1"));
DBC_ATTRIBUTE *attr = file->findAttributeByName("matchingcriteria"); DBC_ATTRIBUTE *attr = file->findAttributeByName("matchingcriteria");
@@ -227,7 +227,7 @@ void DBCLoadSaveWindow::saveFile()
if (idx < 0) return; if (idx < 0) return;
dbcHandler->saveDBCFile(idx); dbcHandler->saveDBCFile(idx);
//then update the list to show the new file name (if it changed) //then update the list to show the new file name (if it changed)
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(dbcHandler->getFileByIdx(idx)->getFullFilename())); ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(dbcHandler->getFileByIdx(idx)->getFilename()));
} }
void DBCLoadSaveWindow::removeFile() void DBCLoadSaveWindow::removeFile()
@@ -305,13 +305,13 @@ void DBCLoadSaveWindow::matchingCriteriaChanged(int index)
{ {
DBC_ATTRIBUTE attr; DBC_ATTRIBUTE attr;
attr.attrType = MESSAGE; attr.attrType = ATTR_TYPE_MESSAGE;
attr.defaultValue = matchingCriteria; attr.defaultValue = matchingCriteria;
attr.enumVals.clear(); attr.enumVals.clear();
attr.lower = 0; attr.lower = 0;
attr.upper = 0; attr.upper = 0;
attr.name = "matchingcriteria"; attr.name = "matchingcriteria";
attr.valType = QINT; attr.valType = ATTR_INT;
file->dbc_attributes.append(attr); file->dbc_attributes.append(attr);
file->messageHandler->setMatchingCriteria(matchingCriteria); file->messageHandler->setMatchingCriteria(matchingCriteria);
} }
@@ -351,13 +351,13 @@ void DBCLoadSaveWindow::cellChanged(int row, int col)
{ {
DBC_ATTRIBUTE attr; DBC_ATTRIBUTE attr;
attr.attrType = MESSAGE; attr.attrType = ATTR_TYPE_MESSAGE;
attr.defaultValue = labelFilters ? 1 : 0; attr.defaultValue = labelFilters ? 1 : 0;
attr.enumVals.clear(); attr.enumVals.clear();
attr.lower = 0; attr.lower = 0;
attr.upper = 0; attr.upper = 0;
attr.name = "labelfilters"; attr.name = "labelfilters";
attr.valType = QINT; attr.valType = ATTR_INT;
file->dbc_attributes.append(attr); file->dbc_attributes.append(attr);
file->messageHandler->setFilterLabeling(labelFilters); file->messageHandler->setFilterLabeling(labelFilters);
} }
+57 -15
View File
@@ -230,6 +230,19 @@ void DBCMainEditor::currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem
} }
} }
uint32_t DBCMainEditor::getParentMessageID(QTreeWidgetItem *cell)
{
if (cell->data(0, Qt::UserRole) == 2)
{
return static_cast<uint32_t>(Utility::ParseStringToNum(cell->text(0).split(" ")[0]));
}
else
{
if (cell->parent()) return getParentMessageID(cell->parent());
else return 0;
}
}
//Double clicking is interpreted as a desire to edit the given item. //Double clicking is interpreted as a desire to edit the given item.
void DBCMainEditor::onTreeDoubleClicked(const QModelIndex &index) void DBCMainEditor::onTreeDoubleClicked(const QModelIndex &index)
{ {
@@ -266,16 +279,21 @@ void DBCMainEditor::onTreeDoubleClicked(const QModelIndex &index)
msgEditor->show(); //show allows the rest of the forms to keep going msgEditor->show(); //show allows the rest of the forms to keep going
break; break;
case 3: //a signal case 3: //a signal
idString = firstCol->parent()->text(0).split(" ")[0]; msgID = getParentMessageID(firstCol);
msgID = static_cast<uint32_t>(Utility::ParseStringToNum(idString));
msg = dbcFile->messageHandler->findMsgByID(msgID); msg = dbcFile->messageHandler->findMsgByID(msgID);
sig = msg->sigHandler->findSignalByName(firstCol->text(0).split(" ")[0]); QString nameString = firstCol->text(0);
if (nameString.contains("(")) nameString = nameString.split(" ")[1];
else nameString = nameString.split(" ")[0];
sig = msg->sigHandler->findSignalByName(nameString);
if (sig)
{
sigEditor->setSignalRef(sig); sigEditor->setSignalRef(sig);
sigEditor->setMessageRef(msg); sigEditor->setMessageRef(msg);
sigEditor->setFileIdx(fileIdx); sigEditor->setFileIdx(fileIdx);
//sigEditor->setWindowModality(Qt::WindowModal); //sigEditor->setWindowModality(Qt::WindowModal);
sigEditor->refreshView(); sigEditor->refreshView();
sigEditor->show(); sigEditor->show();
}
break; break;
} }
} }
@@ -330,16 +348,8 @@ void DBCMainEditor::refreshTree()
for (int i = 0; i < msg->sigHandler->getCount(); i++) for (int i = 0; i < msg->sigHandler->getCount(); i++)
{ {
DBC_SIGNAL *sig = msg->sigHandler->findSignalByIdx(i); DBC_SIGNAL *sig = msg->sigHandler->findSignalByIdx(i);
QTreeWidgetItem *sigItem = new QTreeWidgetItem(msgItem); //only process signals here which are "top" level
QString sigInfo = sig->name; if (sig->multiplexParent == nullptr) processSignalToTree(msgItem, sig);
if (sig->comment.count() > 0) sigInfo.append(" - ").append(sig->comment);
sigItem->setText(0, sigInfo);
if (sig->isMultiplexed) sigItem->setIcon(0, multiplexedSignalIcon);
else if (sig->isMultiplexor) sigItem->setIcon(0, multiplexorSignalIcon);
else sigItem->setIcon(0, signalIcon);
sigItem->setData(0, Qt::UserRole, 3);
signalToItem.insert(sig, sigItem);
itemToSignal.insert(sigItem, sig);
} }
} }
} }
@@ -348,6 +358,39 @@ void DBCMainEditor::refreshTree()
ui->treeDBC->sortItems(0, Qt::SortOrder::AscendingOrder); //sort the display list for ease in viewing by mere mortals, helps me a lot. ui->treeDBC->sortItems(0, Qt::SortOrder::AscendingOrder); //sort the display list for ease in viewing by mere mortals, helps me a lot.
} }
QString DBCMainEditor::createSignalText(DBC_SIGNAL *sig)
{
QString sigInfo;
if (sig->isMultiplexed)
{
sigInfo = "(" + QString::number(sig->multiplexValue) + ") ";
}
sigInfo.append(sig->name);
if (sig->comment.count() > 0) sigInfo.append(" - ").append(sig->comment);
return sigInfo;
}
//Signals can have a hierarchial relationship with other signals so this function is separate and calls itself recursively to build the tree
void DBCMainEditor::processSignalToTree(QTreeWidgetItem *parent, DBC_SIGNAL *sig)
{
QTreeWidgetItem *sigItem = new QTreeWidgetItem(parent);
QString sigInfo = createSignalText(sig);
sigItem->setText(0, sigInfo);
if (sig->isMultiplexor) sigItem->setIcon(0, multiplexorSignalIcon);
else if (sig->isMultiplexed) sigItem->setIcon(0, multiplexedSignalIcon);
else sigItem->setIcon(0, signalIcon);
sigItem->setData(0, Qt::UserRole, 3);
signalToItem.insert(sig, sigItem);
itemToSignal.insert(sigItem, sig);
if (sig->multiplexedChildren.count() > 0)
{
for (int i = 0; i < sig->multiplexedChildren.count(); i++)
{
processSignalToTree(sigItem, sig->multiplexedChildren[i].sig);
}
}
}
void DBCMainEditor::updatedNode(DBC_NODE *node) void DBCMainEditor::updatedNode(DBC_NODE *node)
{ {
if (nodeToItem.contains(node)) if (nodeToItem.contains(node))
@@ -403,8 +446,7 @@ void DBCMainEditor::updatedSignal(DBC_SIGNAL *sig)
if (signalToItem.contains(sig)) if (signalToItem.contains(sig))
{ {
QTreeWidgetItem *item = signalToItem.value(sig); QTreeWidgetItem *item = signalToItem.value(sig);
QString sigInfo = sig->name; QString sigInfo = createSignalText(sig);
if (sig->comment.count() > 0) sigInfo.append(" - ").append(sig->comment);
item->setText(0, sigInfo); item->setText(0, sigInfo);
} }
else qDebug() << "That signal doesn't exist. That's a bug dude."; else qDebug() << "That signal doesn't exist. That's a bug dude.";
+3
View File
@@ -76,6 +76,9 @@ private:
void readSettings(); void readSettings();
void writeSettings(); void writeSettings();
void refreshTree(); void refreshTree();
void processSignalToTree(QTreeWidgetItem *parent, DBC_SIGNAL *sig);
uint32_t getParentMessageID(QTreeWidgetItem *cell);
QString createSignalText(DBC_SIGNAL *sig);
}; };
#endif // DBCMAINEDITOR_H #endif // DBCMAINEDITOR_H
+79
View File
@@ -190,6 +190,22 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
//TODO: could look up the multiplexor and ensure that the value is within a range that the multiplexor could return //TODO: could look up the multiplexor and ensure that the value is within a range that the multiplexor could return
currentSignal->multiplexValue = temp; currentSignal->multiplexValue = temp;
}); });
connect(ui->rbExtended, &QRadioButton::toggled,
[=](bool state)
{
if (state && currentSignal) //signal is now set as an extended multiplex/multiplexor
{
currentSignal->isMultiplexed = true;
currentSignal->isMultiplexor = true;
//an extended multi signal cannot be the root multiplexor for a message so make sure to remove it if it was.
if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr;
}
ui->txtMultiplexValue->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
dbcFile->setDirtyFlag();
});
connect(ui->rbMultiplexed, &QRadioButton::toggled, connect(ui->rbMultiplexed, &QRadioButton::toggled,
[=](bool state) [=](bool state)
{ {
@@ -200,6 +216,8 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
//if the set multiplexor for the message was this signal then clear it //if the set multiplexor for the message was this signal then clear it
if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr; if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr;
} }
ui->txtMultiplexValue->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
dbcFile->setDirtyFlag(); dbcFile->setDirtyFlag();
}); });
@@ -215,6 +233,8 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
//we just set that this is the multiplexor so update the message to show that as well. //we just set that this is the multiplexor so update the message to show that as well.
dbcMessage->multiplexorSignal = currentSignal; dbcMessage->multiplexorSignal = currentSignal;
} }
ui->txtMultiplexValue->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
dbcFile->setDirtyFlag(); dbcFile->setDirtyFlag();
}); });
@@ -227,9 +247,42 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
currentSignal->isMultiplexor = false; currentSignal->isMultiplexor = false;
if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr; if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr;
} }
ui->txtMultiplexValue->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
dbcFile->setDirtyFlag(); dbcFile->setDirtyFlag();
}); });
connect(ui->cbMultiplexParent, &QComboBox::currentTextChanged,
[=]()
{
//try to look up the signal that we're set to now, remove this signal from existing children list
//add it to this one, update this signal's parent multiplexor
DBC_SIGNAL *newSig = dbcMessage->sigHandler->findSignalByName(ui->cbMultiplexParent->currentText());
DBC_SIGNAL *oldParent = currentSignal->multiplexParent;
int low = currentSignal->multiplexValue;
int high = low;
if (newSig)
{
for (int i = 0; i < oldParent->multiplexedChildren.count(); i++)
{
if (oldParent->multiplexedChildren[i].sig == currentSignal)
{
low = oldParent->multiplexedChildren[i].lowerBound;
high = oldParent->multiplexedChildren[i].upperBound;
oldParent->multiplexedChildren.removeAt(i);
break;
}
}
currentSignal->multiplexParent = newSig;
DBC_MULTIPLEX mlt;
mlt.lowerBound = low;
mlt.upperBound = high;
mlt.sig = currentSignal;
newSig->multiplexedChildren.append(mlt);
dbcFile->setDirtyFlag();
}
});
installEventFilter(this); installEventFilter(this);
} }
@@ -413,11 +466,37 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
ui->txtMinVal->setText(QString::number(sig->min)); ui->txtMinVal->setText(QString::number(sig->min));
ui->txtScale->setText(QString::number(sig->factor)); ui->txtScale->setText(QString::number(sig->factor));
ui->txtUnitName->setText(sig->unitName); ui->txtUnitName->setText(sig->unitName);
if (sig->isMultiplexed && sig->isMultiplexor)
{
ui->rbMultiplexed->setChecked(false);
ui->rbMultiplexor->setChecked(false);
ui->rbNotMulti->setChecked(false);
ui->rbExtended->setChecked(true);
}
else
{
ui->rbMultiplexed->setChecked(sig->isMultiplexed); ui->rbMultiplexed->setChecked(sig->isMultiplexed);
ui->rbMultiplexor->setChecked(sig->isMultiplexor); ui->rbMultiplexor->setChecked(sig->isMultiplexor);
ui->rbNotMulti->setChecked( !(sig->isMultiplexor | sig->isMultiplexed) ); ui->rbNotMulti->setChecked( !(sig->isMultiplexor | sig->isMultiplexed) );
}
qDebug() << sig->isMultiplexor << "*" << sig->isMultiplexed; qDebug() << sig->isMultiplexor << "*" << sig->isMultiplexed;
ui->cbMultiplexParent->clear();
int numSigs = dbcMessage->sigHandler->getCount();
for (int i = 0; i < numSigs; i++)
{
DBC_SIGNAL *sig_iter = dbcMessage->sigHandler->findSignalByIdx(i);
if (sig_iter->isMultiplexor && (sig_iter != sig))
{
ui->cbMultiplexParent->addItem(sig_iter->name);
if (sig->multiplexParent == sig_iter) ui->cbMultiplexParent->setCurrentIndex(ui->cbMultiplexParent->count() - 1);
}
}
ui->txtMultiplexValue->setEnabled(sig->isMultiplexed);
ui->cbMultiplexParent->setEnabled(sig->isMultiplexed);
memset(bitpattern, 0, 8); //clear it out first. memset(bitpattern, 0, 8); //clear it out first.
int startBit, endBit; int startBit, endBit;
+20 -3
View File
@@ -160,7 +160,7 @@
<item> <item>
<widget class="QRadioButton" name="rbNotMulti"> <widget class="QRadioButton" name="rbNotMulti">
<property name="text"> <property name="text">
<string>Not multiplexed</string> <string>None</string>
</property> </property>
</widget> </widget>
</item> </item>
@@ -178,6 +178,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QRadioButton" name="rbExtended">
<property name="text">
<string>Extended</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item row="10" column="0"> <item row="10" column="0">
@@ -190,16 +197,26 @@
<item row="10" column="1"> <item row="10" column="1">
<widget class="QLineEdit" name="txtMultiplexValue"/> <widget class="QLineEdit" name="txtMultiplexValue"/>
</item> </item>
<item row="11" column="0"> <item row="12" column="0">
<widget class="QLabel" name="label_13"> <widget class="QLabel" name="label_13">
<property name="text"> <property name="text">
<string>Comment:</string> <string>Comment:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="1"> <item row="12" column="1">
<widget class="QLineEdit" name="txtComment"/> <widget class="QLineEdit" name="txtComment"/>
</item> </item>
<item row="11" column="1">
<widget class="QComboBox" name="cbMultiplexParent"/>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Multiplex Parent</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>