Properly hooked up multiplexed signals. They now show up correctly

when "Interpret Frames" is selected on the main screen. Fixed some
bugs related to the new DBC code.
This commit is contained in:
Collin Kidder
2016-01-10 21:54:33 -05:00
parent 81e97e8803
commit 62e168905a
5 changed files with 115 additions and 8 deletions
+5 -2
View File
@@ -202,12 +202,15 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
tempString.append(msg->name + " " + msg->comment + "\r\n");
for (int j = 0; j < msg->msgSignals.length(); j++)
{
tempString.append(dbcHandler->processSignal(thisFrame, msg->msgSignals.at(j)));
QString sigString = dbcHandler->processSignal(thisFrame, msg->msgSignals.at(j));
if (sigString.length() > 1) //weeds out signals that don't actually exist in this message (due to multiplexing)
{
tempString.append(sigString);
tempString.append("\r\n");
}
}
}
}
return tempString;
break;
default:
+3
View File
@@ -54,6 +54,8 @@ public:
QList<DBC_ATTRIBUTE> attributes;
};
class DBC_MESSAGE; //forward reference so that DBC_SIGNAL can compile before we get to real definition of DBC_MESSAGE
class DBC_SIGNAL
{
public:
@@ -70,6 +72,7 @@ public:
double min;
double max;
DBC_NODE *receiver;
DBC_MESSAGE *parentMessage;
QString unitName;
QString comment;
QList<DBC_ATTRIBUTE> attributes;
+95 -4
View File
@@ -67,6 +67,10 @@ void DBCHandler::loadDBCFile(QString filename)
bool isMultiplexed = false;
DBC_SIGNAL sig;
sig.multiplexValue = 0;
sig.isMultiplexed = false;
sig.isMultiplexor = false;
qDebug() << "Found a SG line";
regex.setPattern("^SG\\_ *(\\w+) *M *: *(\\d+)\\|(\\d+)@(\\d+)([\\+|\\-]) \\(([0-9.+\\-eE]+),([0-9.+\\-eE]+)\\) \\[([0-9.+\\-eE]+)\\|([0-9.+\\-eE]+)\\] \\\"(.*)\\\" (.*)");
@@ -93,6 +97,8 @@ void DBCHandler::loadDBCFile(QString filename)
{
regex.setPattern("^SG\\_ *(\\w+) *: *(\\d+)\\|(\\d+)@(\\d+)([\\+|\\-]) \\(([0-9.+\\-eE]+),([0-9.+\\-eE]+)\\) \\[([0-9.+\\-eE]+)\\|([0-9.+\\-eE]+)\\] \\\"(.*)\\\" (.*)");
match = regex.match(line);
sig.isMultiplexed = false;
sig.isMultiplexor = false;
}
}
@@ -149,6 +155,7 @@ void DBCHandler::loadDBCFile(QString filename)
sig.receiver = findNodeByName(tmp);
}
else sig.receiver = findNodeByName(match.captured(11 + offset));
sig.parentMessage = currentMessage;
currentMessage->msgSignals.append(sig);
if (isMultiplexor) currentMessage->multiplexorSignal = &currentMessage->msgSignals.last();
}
@@ -606,6 +613,18 @@ QString DBCHandler::processSignal(const CANFrame &frame, const DBC_SIGNAL &sig)
return buildString;
}
//if this is a multiplexed signal then we have to see if it is even found in the current message
if (sig.isMultiplexed)
{
if (sig.parentMessage->multiplexorSignal != NULL)
{
int val;
if (!processSignalInt(frame, *sig.parentMessage->multiplexorSignal, val)) return "";
if (val != sig.multiplexValue) return ""; //signal not found in this message
}
else return "";
}
if (sig.valType == SIGNED_INT) isSigned = true;
if (sig.valType == SIGNED_INT || sig.valType == UNSIGNED_INT)
{
@@ -653,14 +672,28 @@ QString DBCHandler::processSignal(const CANFrame &frame, const DBC_SIGNAL &sig)
//Works quite a bit like the above version but this one is cut down and only will return int32_t which is perfect for
//uses like calculating a multiplexor value or if you know you are going to get an integer returned
//from a signal and you want to use it as-is and not have to convert back from a string. Use with caution though
//as this basically assumes the signal is an integer. If it isn't you get -1 back.
int32_t processSignalInt(const CANFrame &frame, const DBC_SIGNAL &sig)
//as this basically assumes the signal is an integer.
//The call syntax is different from the more generic processSignal. Instead of returning the value we return
//true or false to show whether the function succeeded. The variable to fill out is passed by reference.
bool DBCHandler::processSignalInt(const CANFrame &frame, const DBC_SIGNAL &sig, int32_t &outValue)
{
int32_t result = 0;
bool isSigned = false;
if (sig.valType == STRING || sig.valType == SP_FLOAT || sig.valType == DP_FLOAT)
{
return -1; //I warned you!
return false;
}
//if this is a multiplexed signal then we have to see if it is even found in the current message
if (sig.isMultiplexed)
{
if (sig.parentMessage->multiplexorSignal != NULL)
{
int val;
if (!processSignalInt(frame, *sig.parentMessage->multiplexorSignal, val)) return false;
if (val != sig.multiplexValue) return false; //signal not found in this message
}
else return false;
}
if (sig.valType == SIGNED_INT) isSigned = true;
@@ -669,7 +702,65 @@ int32_t processSignalInt(const CANFrame &frame, const DBC_SIGNAL &sig)
double endResult = ((double)result * sig.factor) + sig.bias;
result = (int32_t)endResult;
return result;
outValue = result;
return true;
}
//Another cut down version that will only return double precision data. This can be used on any of the types
//except STRING. Useful for when you know you'll need floating point data and don't want to incur a conversion
//back and forth to double or float. Such a use is the graphing window.
//Similar syntax to processSignalInt but with double instead.
bool DBCHandler::processSignalDouble(const CANFrame &frame, const DBC_SIGNAL &sig, double &outValue)
{
int64_t result = 0;
bool isSigned = false;
double endResult;
if (sig.valType == STRING)
{
return false;
}
//if this is a multiplexed signal then we have to see if it is even found in the current message
if (sig.isMultiplexed)
{
if (sig.parentMessage->multiplexorSignal != NULL)
{
int val;
if (!processSignalInt(frame, *sig.parentMessage->multiplexorSignal, val)) return false;
if (val != sig.multiplexValue) return false; //signal not found in this message
}
else return false;
}
if (sig.valType == SIGNED_INT) isSigned = true;
if (sig.valType == SIGNED_INT || sig.valType == UNSIGNED_INT)
{
result = Utility::processIntegerSignal(frame.data, sig.startBit, sig.signalSize, sig.intelByteOrder, isSigned);
endResult = ((double)result * sig.factor) + sig.bias;
result = (int64_t)endResult;
}
else if (sig.valType == SP_FLOAT)
{
//The theory here is that we force the integer signal code to treat this as
//a 32 bit unsigned integer. This integer is then cast into a float in such a way
//that the bytes that make up the integer are instead treated as having made up
//a 32 bit single precision float. That's evil incarnate but it is very fast and small
//in terms of new code.
result = Utility::processIntegerSignal(frame.data, sig.startBit, 32, false, false);
endResult = (*((float *)(&result)) * sig.factor) + sig.bias;
}
else //double precision float
{
//like the above, this is rotten and evil and wrong in so many ways. Force
//calculation of a 64 bit integer and then cast it into a double.
result = Utility::processIntegerSignal(frame.data, 0, 64, false, false);
endResult = (*((double *)(&result)) * sig.factor) + sig.bias;
}
outValue = endResult;
return true;
}
//given a byte it will reverse the bit order in that byte
+2 -1
View File
@@ -19,7 +19,8 @@ public:
void saveDBCFile(QString);
void listDebugging();
QString processSignal(const CANFrame &frame, const DBC_SIGNAL &sig);
int32_t processSignalInt(const CANFrame &frame, const DBC_SIGNAL &sig);
bool processSignalInt(const CANFrame &frame, const DBC_SIGNAL &sig, int32_t &outValue);
bool processSignalDouble(const CANFrame &frame, const DBC_SIGNAL &sig, double &outValue);
DBC_NODE *findNodeByName(QString name);
DBC_NODE *findNodeByIdx(int idx);
+9
View File
@@ -181,6 +181,8 @@ DBCSignalEditor::DBCSignalEditor(DBCHandler *handler, QWidget *parent) :
{
currentSignal->isMultiplexed = true;
currentSignal->isMultiplexor = false;
//if the set multiplexor for the message was this signal then clear it
if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = NULL;
}
});
@@ -189,8 +191,12 @@ DBCSignalEditor::DBCSignalEditor(DBCHandler *handler, QWidget *parent) :
{
if (state) //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.
//if (dbcMessage->multiplexorSignal != currentSignal && dbcMessage->multiplexorSignal != NULL) return; //I spoke too soon above...
currentSignal->isMultiplexed = false;
currentSignal->isMultiplexor = true;
//we just set that this is the multiplexor so update the message to show that as well.
dbcMessage->multiplexorSignal = currentSignal;
}
});
@@ -201,6 +207,7 @@ DBCSignalEditor::DBCSignalEditor(DBCHandler *handler, QWidget *parent) :
{
currentSignal->isMultiplexed = false;
currentSignal->isMultiplexor = false;
if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = NULL;
}
});
}
@@ -326,6 +333,7 @@ void DBCSignalEditor::addNewSignal()
newSig.isMultiplexed = false;
newSig.isMultiplexor = false;
newSig.multiplexValue = 0;
newSig.parentMessage = dbcMessage;
ui->signalsList->addItem(newName);
dbcMessage->msgSignals.append(newSig);
if (dbcMessage->msgSignals.count() == 1) clickSignalList(0);
@@ -406,6 +414,7 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
ui->rbMultiplexed->setChecked(sig->isMultiplexed);
ui->rbMultiplexor->setChecked(sig->isMultiplexor);
ui->rbNotMulti->setChecked( !(sig->isMultiplexor | sig->isMultiplexed) );
qDebug() << sig->isMultiplexor << "*" << sig->isMultiplexed;
memset(bitpattern, 0, 8); //clear it out first.