File indexing completed on 2024-10-06 06:35:10
0001 /* 0002 File : BLFFilterTest.cpp 0003 Project : LabPlot 0004 Description : Tests for the BLF Filter 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2023 Martin Marmsoler <martin.marmsoler@gmail.com> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "BLFFilterTest.h" 0012 #include "backend/datasources/filters/CANFilterPrivate.h" 0013 #include "backend/datasources/filters/VectorBLFFilter.h" 0014 #include "backend/spreadsheet/Spreadsheet.h" 0015 #include "qtestcase.h" 0016 #include <math.h> 0017 0018 #ifdef HAVE_VECTOR_BLF 0019 0020 #include <Vector/BLF.h> 0021 0022 static const std::string PRIMITIVE_DBC = 0023 R"(VERSION "1.0.0" 0024 0025 NS_ : 0026 0027 BS_: 0028 0029 BU_: DBG DRIVER IO MOTOR SENSOR 0030 0031 )"; 0032 0033 // ########################################################################################################## 0034 // ##### Helper functions ################################################################################### 0035 // ########################################################################################################## 0036 void BLFFilterTest::createDBCFile(const QString& filename, const std::string& content) { 0037 auto* file = std::fopen(filename.toStdString().c_str(), "w"); 0038 QVERIFY(file); 0039 std::fputs(PRIMITIVE_DBC.c_str(), file); 0040 std::fputs(content.c_str(), file); 0041 std::fclose(file); 0042 } 0043 0044 Vector::BLF::CanMessage2* BLFFilterTest::createCANMessage(uint32_t id, uint64_t timestamp, const std::vector<uint8_t>& data) { 0045 auto* canMessage = new Vector::BLF::CanMessage2(); 0046 canMessage->channel = 1; 0047 canMessage->flags = 1; // TX 0048 canMessage->dlc = std::min<uint8_t>(data.size(), 8); 0049 canMessage->id = id; 0050 canMessage->objectTimeStamp = timestamp; 0051 canMessage->objectFlags = Vector::BLF::ObjectHeader::ObjectFlags::TimeOneNans; 0052 if (canMessage->data.size() < canMessage->dlc) 0053 canMessage->data.resize(canMessage->dlc); 0054 0055 for (int i = 0; i < canMessage->dlc; i++) { 0056 canMessage->data[i] = data.at(i); 0057 } 0058 return canMessage; 0059 } 0060 0061 void BLFFilterTest::createBLFFile(const QString& filename, QVector<Vector::BLF::CanMessage2*> messages) { 0062 Vector::BLF::File blfFile; 0063 blfFile.open(filename.toStdString().c_str(), std::ios_base::out); 0064 QVERIFY(blfFile.is_open()); 0065 0066 for (auto msg : messages) { 0067 blfFile.write(msg); 0068 } 0069 // Finish creating files 0070 blfFile.close(); 0071 } 0072 0073 // ########################################################################################################## 0074 // ##### Test functions ##################################################################################### 0075 // ########################################################################################################## 0076 void BLFFilterTest::testInvalidBLF() { 0077 VectorBLFFilter filter; 0078 QCOMPARE(filter.isValid(QStringLiteral("UnavailableBLFFile.blf")), false); // File not available 0079 0080 // Create invalid blf file 0081 QTemporaryFile invalidBLFFile; 0082 QVERIFY(invalidBLFFile.open()); 0083 QFile f(invalidBLFFile.fileName()); 0084 QVERIFY(f.open(QIODevice::WriteOnly)); 0085 f.write(QStringLiteral("InvalidFile.blf").toStdString().c_str()); 0086 f.close(); 0087 QCOMPARE(filter.isValid(invalidBLFFile.fileName()), false); 0088 } 0089 0090 void BLFFilterTest::testNotFoundBLF() { 0091 VectorBLFFilter filter; 0092 QCOMPARE(filter.isValid(QStringLiteral("UnavailableBLFFile.blf")), false); // File not available 0093 } 0094 0095 void BLFFilterTest::testInvalidDBC() { 0096 /* open file for writing */ 0097 QTemporaryFile blfFileName(QStringLiteral("XXXXXX.blf")); 0098 QVERIFY(blfFileName.open()); 0099 std::vector<uint8_t> data{0x01, 0x02}; 0100 QVector<Vector::BLF::CanMessage2*> messages{createCANMessage(234, 5, data)}; 0101 createBLFFile(blfFileName.fileName(), messages); 0102 0103 QTemporaryFile dbcFile(QStringLiteral("XXXXXX.dbc")); 0104 QVERIFY(dbcFile.open()); 0105 const auto dbcContent = R"(BO_ 234 MSG1: 8 Vector__XXX 0106 SG_ Sig1 : 0|8@0- (0.1,0) [-3276.8|-3276.7] "C" Vector__XXX 0107 SG_ Sig2 : 8|8@0- (0.1,0) [-3276.8|-3276.7] "C" Vector__XXX 0108 )"; 0109 createDBCFile(dbcFile.fileName(), dbcContent); 0110 0111 // Start Test 0112 0113 VectorBLFFilter filter; 0114 QCOMPARE(filter.isValid(blfFileName.fileName()), true); 0115 0116 // File is valid, but dbc file not 0117 Spreadsheet s(QStringLiteral("TestSpreadsheet"), false); 0118 filter.readDataFromFile(blfFileName.fileName(), &s); 0119 QCOMPARE(s.columnCount(), 2); // column count not changed means no data was added 0120 } 0121 0122 void BLFFilterTest::testValidBLFValidDBCSingleMessageBigEndian() { 0123 /* open file for writing */ 0124 QTemporaryFile blfFileName(QStringLiteral("XXXXXX.blf")); 0125 QVERIFY(blfFileName.open()); 0126 std::vector<uint8_t> data{0x01, 0x02}; 0127 QVector<Vector::BLF::CanMessage2*> messages{createCANMessage(234, 5, data)}; // time is in nanoseconds 0128 createBLFFile(blfFileName.fileName(), messages); 0129 0130 QTemporaryFile dbcFile(QStringLiteral("XXXXXX.dbc")); 0131 QVERIFY(dbcFile.open()); 0132 const auto dbcContent = R"(BO_ 234 MSG1: 8 Vector__XXX 0133 SG_ Sig1 : 7|8@0- (0.1,0) [-3276.8|-3276.7] "C" Vector__XXX 0134 SG_ Sig2 : 15|8@0- (0.1,0) [-3276.8|-3276.7] "C" Vector__XXX 0135 )"; 0136 createDBCFile(dbcFile.fileName(), dbcContent); 0137 0138 // Start Test 0139 0140 VectorBLFFilter filter; 0141 QCOMPARE(filter.isValid(blfFileName.fileName()), true); 0142 0143 // Valid blf and valid dbc 0144 filter.setDBCFile(dbcFile.fileName()); 0145 Spreadsheet s(QStringLiteral("TestSpreadsheet"), false); 0146 filter.readDataFromFile(blfFileName.fileName(), &s); 0147 QCOMPARE(s.columnCount(), 3); // time + Sig1 + Sig2 0148 0149 { 0150 // Time 0151 const auto* c = s.column(0); 0152 QCOMPARE(c->rowCount(), 1); 0153 QCOMPARE(c->valueAt(0), 5e-9); // nanoseconds 0154 } 0155 0156 { 0157 // Sig1 0158 const auto* c = s.column(1); 0159 QCOMPARE(c->rowCount(), 1); 0160 QCOMPARE(c->valueAt(0), 0x01 * 0.1); 0161 } 0162 0163 { 0164 // Sig2 0165 const auto* c = s.column(2); 0166 QCOMPARE(c->rowCount(), 1); 0167 QCOMPARE(c->valueAt(0), 0x02 * 0.1); 0168 } 0169 } 0170 0171 // Use the previous value if there is no value at the current timestamp 0172 void BLFFilterTest::testUsePreviousValueBigEndian() { 0173 /* open file for writing */ 0174 QTemporaryFile blfFileName(QStringLiteral("XXXXXX.blf")); 0175 QVERIFY(blfFileName.open()); 0176 QVector<Vector::BLF::CanMessage2*> messages{ 0177 createCANMessage(532, 5, {2, 62, 1, 161, 39, 6, 0, 214}), 0178 createCANMessage(565, 6, {0, 0, 0, 0, 0, 0, 0, 245}), 0179 createCANMessage(565, 8, {0, 0, 0, 0, 0, 0, 0, 148}), 0180 createCANMessage(532, 10, {2, 62, 1, 161, 39, 6, 0, 205}), 0181 createCANMessage(532, 12, {2, 62, 1, 161, 39, 6, 0, 206}), 0182 createCANMessage(532, 14, {2, 62, 1, 161, 39, 6, 0, 207}), 0183 }; // time is in nanoseconds 0184 createBLFFile(blfFileName.fileName(), messages); 0185 0186 QTemporaryFile dbcFile(QStringLiteral("XXXXXX.dbc")); 0187 QVERIFY(dbcFile.open()); 0188 const auto dbcContent = R"(BO_ 532 MSG1: 8 BMS1 0189 SG_ MSG1Sig1 : 39|16@0+ (0.01,0) [0|0] "%" Vector__XXX 0190 SG_ MSG1Sig2 : 23|16@0+ (0.1,0) [0|6553.5] "V" Vector__XXX 0191 SG_ MSG1Sig3 : 55|16@0- (0.1,0) [0|0] "" Vector__XXX 0192 SG_ MSG1Sig4 : 7|16@0+ (0.1,0) [0|6553.5] "V" Vector__XXX 0193 BO_ 565 MSG2: 8 Vector__XXX 0194 SG_ MSG2Sig1 : 55|16@0- (0.1,0) [0|0] "" Vector__XXX 0195 )"; 0196 createDBCFile(dbcFile.fileName(), dbcContent); 0197 0198 // Start Test 0199 0200 VectorBLFFilter filter; 0201 filter.setTimeHandlingMode(CANFilter::TimeHandling::ConcatPrevious); 0202 QCOMPARE(filter.isValid(blfFileName.fileName()), true); 0203 0204 // Valid blf and valid dbc 0205 filter.setDBCFile(dbcFile.fileName()); 0206 Spreadsheet s(QStringLiteral("TestSpreadsheet"), false); 0207 filter.readDataFromFile(blfFileName.fileName(), &s); 0208 QCOMPARE(s.columnCount(), 6); // time + Msg1Sig1 + Msg1Sig2 + Msg1Sig3 + Msg1Sig4 + Msg2Sig1 0209 0210 { 0211 const auto* c = s.column(0); 0212 QCOMPARE(c->name(), QStringLiteral("Time_s")); 0213 QCOMPARE(c->rowCount(), 6); 0214 0215 QVector<double> refData{5e-9, 6e-9, 8e-9, 10e-9, 12e-9, 14e-9}; 0216 QCOMPARE(refData.size(), 6); 0217 for (int i = 0; i < c->rowCount(); i++) { 0218 QCOMPARE(c->valueAt(i), refData.at(i)); 0219 } 0220 } 0221 0222 { 0223 const auto* c = s.column(1); 0224 QCOMPARE(c->name(), QStringLiteral("MSG1Sig1_%")); 0225 QCOMPARE(c->rowCount(), 6); 0226 0227 QVector<double> refData{99.90, 99.90, 99.90, 99.90, 99.90, 99.90}; 0228 QCOMPARE(refData.size(), 6); 0229 for (int i = 0; i < c->rowCount(); i++) { 0230 QCOMPARE(c->valueAt(i), refData.at(i)); 0231 } 0232 } 0233 0234 { 0235 const auto* c = s.column(2); 0236 QCOMPARE(c->name(), QStringLiteral("MSG1Sig2_V")); 0237 QCOMPARE(c->rowCount(), 6); 0238 0239 QVector<double> refData{41.7, 41.7, 41.7, 41.7, 41.7, 41.7}; 0240 QCOMPARE(refData.size(), 6); 0241 for (int i = 0; i < c->rowCount(); i++) { 0242 QCOMPARE(c->valueAt(i), refData.at(i)); 0243 } 0244 } 0245 0246 { 0247 const auto* c = s.column(3); 0248 QCOMPARE(c->name(), QStringLiteral("MSG1Sig3_")); 0249 QCOMPARE(c->rowCount(), 6); 0250 0251 QVector<double> refData{21.4, 21.4, 21.4, 20.5, 20.6, 20.7}; 0252 QCOMPARE(refData.size(), 6); 0253 for (int i = 0; i < c->rowCount(); i++) { 0254 QCOMPARE(c->valueAt(i), refData.at(i)); 0255 } 0256 } 0257 0258 { 0259 const auto* c = s.column(4); 0260 QCOMPARE(c->name(), QStringLiteral("MSG1Sig4_V")); 0261 QCOMPARE(c->rowCount(), 6); 0262 0263 QVector<double> refData{57.4, 57.4, 57.4, 57.4, 57.4, 57.4}; 0264 QCOMPARE(refData.size(), 6); 0265 for (int i = 0; i < c->rowCount(); i++) { 0266 QCOMPARE(c->valueAt(i), refData.at(i)); 0267 } 0268 } 0269 0270 { 0271 const auto* c = s.column(5); 0272 QCOMPARE(c->name(), QStringLiteral("MSG2Sig1_")); 0273 QCOMPARE(c->rowCount(), 6); 0274 0275 QVector<double> refData{std::nan(""), 24.5, 14.8, 14.8, 14.8, 14.8}; 0276 QCOMPARE(refData.size(), 6); 0277 for (int i = 0; i < c->rowCount(); i++) { 0278 QCOMPARE(c->valueAt(i), refData.at(i)); 0279 } 0280 } 0281 } 0282 0283 // Use NAN if the current message does not contain no value for the signal 0284 void BLFFilterTest::testUseNANBigEndian() { 0285 /* open file for writing */ 0286 QTemporaryFile blfFileName(QStringLiteral("XXXXXX.blf")); 0287 QVERIFY(blfFileName.open()); 0288 QVector<Vector::BLF::CanMessage2*> messages{ 0289 createCANMessage(234, 5, {0x01, 0x02}), 0290 createCANMessage(123, 6, {0xFF, 0xA2}), 0291 createCANMessage(123, 8, {0x23, 0xE2}), 0292 createCANMessage(234, 10, {0xD3, 0xB2}), 0293 createCANMessage(234, 12, {0xE1, 0xC7}), 0294 createCANMessage(234, 14, {0xD1, 0xC7}), 0295 }; // time is in nanoseconds 0296 createBLFFile(blfFileName.fileName(), messages); 0297 0298 QTemporaryFile dbcFile(QStringLiteral("XXXXXX.dbc")); 0299 QVERIFY(dbcFile.open()); 0300 const auto dbcContent = R"(BO_ 234 MSG1: 8 Vector__XXX 0301 SG_ Msg1Sig1 : 7|8@0+ (1,0) [-3276.8|-3276.7] "C" Vector__XXX 0302 SG_ Msg1Sig2 : 15|8@0+ (1,0) [-3276.8|-3276.7] "km/h" Vector__XXX 0303 BO_ 123 MSG2: 8 Vector__XXX 0304 SG_ Msg2Sig1 : 7|8@0+ (1,0) [-3276.8|-3276.7] "mm" Vector__XXX 0305 SG_ Msg2Sig2 : 15|8@0+ (1,0) [-3276.8|-3276.7] "m" Vector__XXX 0306 )"; 0307 createDBCFile(dbcFile.fileName(), dbcContent); 0308 0309 // Start Test 0310 0311 VectorBLFFilter filter; 0312 filter.setConvertTimeToSeconds(true); 0313 filter.setTimeHandlingMode(CANFilter::TimeHandling::ConcatNAN); 0314 QCOMPARE(filter.isValid(blfFileName.fileName()), true); 0315 0316 // Valid blf and valid dbc 0317 filter.setDBCFile(dbcFile.fileName()); 0318 Spreadsheet s(QStringLiteral("TestSpreadsheet"), false); 0319 filter.readDataFromFile(blfFileName.fileName(), &s); 0320 QCOMPARE(s.columnCount(), 5); // time + Msg1Sig1 + Msg1Sig2 + Msg2Sig1 + Msg2Sig2 0321 0322 { 0323 // Time 0324 const auto* c = s.column(0); 0325 QCOMPARE(c->name(), QStringLiteral("Time_s")); 0326 QCOMPARE(c->rowCount(), 6); 0327 0328 QVector<double> refData{5e-9, 6e-9, 8e-9, 10e-9, 12e-9, 14e-9}; 0329 QCOMPARE(refData.size(), 6); 0330 for (int i = 0; i < c->rowCount(); i++) { 0331 QCOMPARE(c->valueAt(i), refData.at(i)); 0332 } 0333 } 0334 0335 { 0336 // Msg1Sig1 0337 const auto* c = s.column(1); 0338 QCOMPARE(c->name(), QStringLiteral("Msg1Sig1_C")); 0339 QCOMPARE(c->rowCount(), 6); 0340 0341 QVector<double> refData{0x01, NAN, NAN, 0xD3, 0xE1, 0xD1}; 0342 QCOMPARE(refData.size(), 6); 0343 for (int i = 0; i < c->rowCount(); i++) { 0344 QCOMPARE(c->valueAt(i), refData.at(i)); 0345 } 0346 } 0347 0348 { 0349 // Msg1Sig2 0350 const auto* c = s.column(2); 0351 QCOMPARE(c->name(), QStringLiteral("Msg1Sig2_km/h")); 0352 QCOMPARE(c->rowCount(), 6); 0353 0354 QVector<double> refData{0x02, NAN, NAN, 0xB2, 0xC7, 0xC7}; 0355 QCOMPARE(refData.size(), 6); 0356 for (int i = 0; i < c->rowCount(); i++) { 0357 QCOMPARE(c->valueAt(i), refData.at(i)); 0358 } 0359 } 0360 0361 { 0362 // Msg2Sig1 0363 const auto* c = s.column(3); 0364 QCOMPARE(c->name(), QStringLiteral("Msg2Sig1_mm")); 0365 QCOMPARE(c->rowCount(), 6); 0366 0367 QVector<double> refData{NAN, 0xFF, 0x23, NAN, NAN, NAN}; 0368 QCOMPARE(refData.size(), 6); 0369 for (int i = 0; i < c->rowCount(); i++) { 0370 QCOMPARE(c->valueAt(i), refData.at(i)); 0371 } 0372 } 0373 0374 { 0375 // Msg2Sig2 0376 const auto* c = s.column(4); 0377 QCOMPARE(c->name(), QStringLiteral("Msg2Sig2_m")); 0378 QCOMPARE(c->rowCount(), 6); 0379 0380 QVector<double> refData{NAN, 0xA2, 0xE2, NAN, NAN, NAN}; 0381 QCOMPARE(refData.size(), 6); 0382 for (int i = 0; i < c->rowCount(); i++) { 0383 QCOMPARE(c->valueAt(i), refData.at(i)); 0384 } 0385 } 0386 } 0387 0388 void BLFFilterTest::testTimeNative() { 0389 /* open file for writing */ 0390 QTemporaryFile blfFileName(QStringLiteral("XXXXXX.blf")); 0391 QVERIFY(blfFileName.open()); 0392 QVector<Vector::BLF::CanMessage2*> messages{ 0393 createCANMessage(234, 5, {0x01, 0x02}), 0394 createCANMessage(123, 6, {0xFF, 0xA2}), 0395 createCANMessage(123, 8, {0x23, 0xE2}), 0396 createCANMessage(234, 10, {0xD3, 0xB2}), 0397 createCANMessage(234, 12, {0xE1, 0xC7}), 0398 createCANMessage(234, 14, {0xD1, 0xC7}), 0399 }; // time is in nanoseconds 0400 createBLFFile(blfFileName.fileName(), messages); 0401 0402 QTemporaryFile dbcFile(QStringLiteral("XXXXXX.dbc")); 0403 QVERIFY(dbcFile.open()); 0404 const auto dbcContent = R"(BO_ 234 MSG1: 8 Vector__XXX 0405 SG_ Msg1Sig1 : 0|8@0+ (1,0) [-3276.8|-3276.7] "C" Vector__XXX 0406 SG_ Msg1Sig2 : 8|8@0+ (1,0) [-3276.8|-3276.7] "km/h" Vector__XXX 0407 BO_ 123 MSG2: 8 Vector__XXX 0408 SG_ Msg2Sig1 : 0|8@0+ (1,0) [-3276.8|-3276.7] "mm" Vector__XXX 0409 SG_ Msg2Sig2 : 8|8@0+ (1,0) [-3276.8|-3276.7] "m" Vector__XXX 0410 )"; 0411 createDBCFile(dbcFile.fileName(), dbcContent); 0412 0413 // Start Test 0414 0415 VectorBLFFilter filter; 0416 filter.setConvertTimeToSeconds(false); 0417 filter.setTimeHandlingMode(CANFilter::TimeHandling::ConcatNAN); 0418 QCOMPARE(filter.isValid(blfFileName.fileName()), true); 0419 0420 // Valid blf and valid dbc 0421 filter.setDBCFile(dbcFile.fileName()); 0422 Spreadsheet s(QStringLiteral("TestSpreadsheet"), false); 0423 filter.readDataFromFile(blfFileName.fileName(), &s); 0424 QCOMPARE(s.columnCount(), 5); // time + Msg1Sig1 + Msg1Sig2 + Msg2Sig1 + Msg2Sig2 0425 0426 { 0427 // Time 0428 const auto* c = s.column(0); 0429 QCOMPARE(c->name(), QStringLiteral("Time_ns")); 0430 QCOMPARE(c->rowCount(), 6); 0431 0432 QVector<double> refData{5, 6, 8, 10, 12, 14}; 0433 QCOMPARE(refData.size(), 6); 0434 for (int i = 0; i < c->rowCount(); i++) { 0435 QCOMPARE(c->valueAt(i), refData.at(i)); 0436 } 0437 } 0438 } 0439 0440 // Value5 is a value larger than one byte, but not exactly a multiple 0441 // And is not aligned with a complete byte 0442 void BLFFilterTest::testBigNumberNotByteAlignedLittleEndian() { 0443 QTemporaryFile blfFileName(QStringLiteral("XXXXXX.blf")); 0444 QVERIFY(blfFileName.open()); 0445 QVector<Vector::BLF::CanMessage2*> messages{ 0446 createCANMessage(337, 5, {0, 4, 252, 19, 0, 0, 0, 0}), 0447 createCANMessage(337, 10, {47, 4, 60, 29, 0, 0, 0, 0}), 0448 createCANMessage(337, 15, {57, 4, 250, 29, 0, 0, 0, 0}), 0449 }; // time is in nanoseconds 0450 createBLFFile(blfFileName.fileName(), messages); 0451 0452 QTemporaryFile dbcFile(QStringLiteral("XXXXXX.dbc")); 0453 QVERIFY(dbcFile.open()); 0454 const auto dbcContent = R"(BO_ 337 STATUS: 8 Vector__XXX 0455 SG_ Value6 : 27|3@1+ (1,0) [0|7] "" Vector__XXX 0456 SG_ Value5 : 16|11@1+ (0.1,-102) [-102|102] "%" Vector__XXX 0457 SG_ Value2 : 8|2@1+ (1,0) [0|2] "" Vector__XXX 0458 SG_ Value3 : 10|1@1+ (1,0) [0|1] "" Vector__XXX 0459 SG_ Value7 : 30|2@1+ (1,0) [0|3] "" Vector__XXX 0460 SG_ Value4 : 11|4@1+ (1,0) [0|3] "" Vector__XXX 0461 SG_ Value1 : 0|8@1+ (1,0) [0|204] "Km/h" Vector__XXX 0462 )"; 0463 createDBCFile(dbcFile.fileName(), dbcContent); 0464 0465 // Start Test 0466 0467 VectorBLFFilter filter; 0468 filter.setConvertTimeToSeconds(true); 0469 filter.setTimeHandlingMode(CANFilter::TimeHandling::ConcatNAN); 0470 QCOMPARE(filter.isValid(blfFileName.fileName()), true); 0471 0472 // Valid blf and valid dbc 0473 filter.setDBCFile(dbcFile.fileName()); 0474 QCOMPARE(filter.d->readDataFromFile(blfFileName.fileName(), 4), 3); 0475 const auto dc = filter.dataContainer(); 0476 QCOMPARE(dc.size(), 8); // Time + 7 signals 0477 { 0478 // Time 0479 const auto* v = static_cast<QVector<double>*>(dc.at(0)); 0480 QCOMPARE(v->length(), 3); 0481 QCOMPARE(v->at(0), 5e-9); 0482 QCOMPARE(v->at(1), 10e-9); 0483 QCOMPARE(v->at(2), 15e-9); 0484 } 0485 0486 { 0487 // Value6 0488 const auto* v = static_cast<QVector<double>*>(dc.at(1)); 0489 QCOMPARE(v->length(), 3); 0490 QCOMPARE(v->at(0), 2.); 0491 QCOMPARE(v->at(1), 3.); 0492 QCOMPARE(v->at(2), 3.); 0493 } 0494 0495 { 0496 // Value5 0497 const auto* v = static_cast<QVector<double>*>(dc.at(2)); 0498 QCOMPARE(v->length(), 3); 0499 QCOMPARE(v->at(0), 0.); 0500 QCOMPARE(v->at(1), 32.); 0501 QCOMPARE(v->at(2), 51.); 0502 } 0503 0504 { 0505 // Value2 0506 const auto* v = static_cast<QVector<double>*>(dc.at(3)); 0507 QCOMPARE(v->length(), 3); 0508 QCOMPARE(v->at(0), 0.); 0509 QCOMPARE(v->at(1), 0.); 0510 QCOMPARE(v->at(2), 0.); 0511 } 0512 0513 { 0514 // Value3 0515 const auto* v = static_cast<QVector<double>*>(dc.at(4)); 0516 QCOMPARE(v->length(), 3); 0517 QCOMPARE(v->at(0), 1.); 0518 QCOMPARE(v->at(1), 1.); 0519 QCOMPARE(v->at(2), 1.); 0520 } 0521 0522 { 0523 // Value7 0524 const auto* v = static_cast<QVector<double>*>(dc.at(5)); 0525 QCOMPARE(v->length(), 3); 0526 QCOMPARE(v->at(0), 0.); 0527 QCOMPARE(v->at(1), 0.); 0528 QCOMPARE(v->at(2), 0.); 0529 } 0530 0531 { 0532 // Value4 0533 const auto* v = static_cast<QVector<double>*>(dc.at(6)); 0534 QCOMPARE(v->length(), 3); 0535 QCOMPARE(v->at(0), 0.); 0536 QCOMPARE(v->at(1), 0.); 0537 QCOMPARE(v->at(2), 0.); 0538 } 0539 0540 { 0541 // Value1 0542 const auto* v = static_cast<QVector<double>*>(dc.at(7)); 0543 QCOMPARE(v->length(), 3); 0544 QCOMPARE(v->at(0), 0.); 0545 QCOMPARE(v->at(1), 47.); 0546 QCOMPARE(v->at(2), 57.); 0547 } 0548 } 0549 0550 // Use NAN if the current message does not contain no value for the signal 0551 void BLFFilterTest::testUseNANLittleEndian() { 0552 QTemporaryFile blfFileName(QStringLiteral("XXXXXX.blf")); 0553 QVERIFY(blfFileName.open()); 0554 QVector<Vector::BLF::CanMessage2*> messages{ 0555 createCANMessage(337, 5, {0, 4, 252, 19, 0, 0, 0, 0}), 0556 createCANMessage(541, 10, {7, 39, 118, 33, 250, 30, 76, 24}), // 99.91, 85.66, 79.3, 22.2 0557 createCANMessage(337, 15, {47, 4, 60, 29, 0, 0, 0, 0}), 0558 createCANMessage(337, 20, {57, 4, 250, 29, 0, 0, 0, 0}), 0559 createCANMessage(541, 25, {7, 39, 118, 33, 250, 30, 76, 24}), // 99.91, 85.66, 79.3, 22.2 0560 }; // time is in nanoseconds 0561 createBLFFile(blfFileName.fileName(), messages); 0562 0563 QTemporaryFile dbcFile(QStringLiteral("XXXXXX.dbc")); 0564 QVERIFY(dbcFile.open()); 0565 const auto dbcContent = R"(BO_ 337 STATUS: 8 Vector__XXX 0566 SG_ Value6 : 27|3@1+ (1,0) [0|7] "" Vector__XXX 0567 SG_ Value5 : 16|11@1+ (0.1,-102) [-102|102] "%" Vector__XXX 0568 SG_ Value2 : 8|2@1+ (1,0) [0|2] "" Vector__XXX 0569 SG_ Value3 : 10|1@1+ (1,0) [0|1] "" Vector__XXX 0570 SG_ Value7 : 30|2@1+ (1,0) [0|3] "" Vector__XXX 0571 SG_ Value4 : 11|4@1+ (1,0) [0|3] "" Vector__XXX 0572 SG_ Value1 : 0|8@1+ (1,0) [0|204] "Km/h" Vector__XXX" 0573 BO_ 541 MSG2: 8 Vector__XXX 0574 SG_ MSG2Value4 : 48|16@1+ (0.01,-40) [-40|125] "C" Vector__XXX 0575 SG_ MSG2Value1 : 0|16@1+ (0.01,0) [0|100] "%" Vector__XXX 0576 SG_ MSG2Value3 : 32|16@1+ (0.01,0) [0|100] "%" Vector__XXX 0577 SG_ MSG2Value2 : 16|16@1+ (0.01,0) [0|100] "%" Vector__XXX 0578 )"; 0579 createDBCFile(dbcFile.fileName(), dbcContent); 0580 0581 // Start Test 0582 0583 VectorBLFFilter filter; 0584 filter.setConvertTimeToSeconds(true); 0585 filter.setTimeHandlingMode(CANFilter::TimeHandling::ConcatNAN); 0586 QCOMPARE(filter.isValid(blfFileName.fileName()), true); 0587 0588 // Valid blf and valid dbc 0589 filter.setDBCFile(dbcFile.fileName()); 0590 Spreadsheet s(QStringLiteral("TestSpreadsheet"), false); 0591 filter.readDataFromFile(blfFileName.fileName(), &s); 0592 QCOMPARE(s.columnCount(), 12); // time + 7 * Msg1 + 4* Msg2 0593 0594 { 0595 // Time 0596 const auto* c = s.column(0); 0597 QCOMPARE(c->name(), QStringLiteral("Time_s")); 0598 QCOMPARE(c->rowCount(), 5); 0599 0600 QVector<double> refData{5e-9, 10e-9, 15e-9, 20e-9, 25e-9}; 0601 QCOMPARE(refData.size(), 5); 0602 for (int i = 0; i < c->rowCount(); i++) { 0603 QCOMPARE(c->valueAt(i), refData.at(i)); 0604 } 0605 } 0606 0607 { 0608 // Msg1Sig6 0609 const auto* c = s.column(1); 0610 QCOMPARE(c->name(), QStringLiteral("Value6_")); 0611 QCOMPARE(c->rowCount(), 5); 0612 0613 QVector<double> refData{2., std::nan("0"), 3., 3., std::nan("0")}; 0614 QCOMPARE(refData.size(), 5); 0615 for (int i = 0; i < c->rowCount(); i++) { 0616 QCOMPARE(c->valueAt(i), refData.at(i)); 0617 } 0618 } 0619 0620 { 0621 // Msg1Sig5 0622 const auto* c = s.column(2); 0623 QCOMPARE(c->name(), QStringLiteral("Value5_%")); 0624 QCOMPARE(c->rowCount(), 5); 0625 0626 QVector<double> refData{0., std::nan("0"), 32., 51., std::nan("0")}; 0627 QCOMPARE(refData.size(), 5); 0628 for (int i = 0; i < c->rowCount(); i++) { 0629 QCOMPARE(c->valueAt(i), refData.at(i)); 0630 } 0631 } 0632 0633 { 0634 // Msg1Sig2 0635 const auto* c = s.column(3); 0636 QCOMPARE(c->name(), QStringLiteral("Value2_")); 0637 QCOMPARE(c->rowCount(), 5); 0638 0639 QVector<double> refData{0., std::nan("0"), 0., 0., std::nan("0")}; 0640 QCOMPARE(refData.size(), 5); 0641 for (int i = 0; i < c->rowCount(); i++) { 0642 QCOMPARE(c->valueAt(i), refData.at(i)); 0643 } 0644 } 0645 0646 { 0647 // Msg1Sig3 0648 const auto* c = s.column(4); 0649 QCOMPARE(c->name(), QStringLiteral("Value3_")); 0650 QCOMPARE(c->rowCount(), 5); 0651 0652 QVector<double> refData{1., std::nan("0"), 1., 1., std::nan("0")}; 0653 QCOMPARE(refData.size(), 5); 0654 for (int i = 0; i < c->rowCount(); i++) { 0655 QCOMPARE(c->valueAt(i), refData.at(i)); 0656 } 0657 } 0658 0659 { 0660 // Msg1Sig7 0661 const auto* c = s.column(5); 0662 QCOMPARE(c->name(), QStringLiteral("Value7_")); 0663 QCOMPARE(c->rowCount(), 5); 0664 0665 QVector<double> refData{0., std::nan("0"), 0., 0., std::nan("0")}; 0666 QCOMPARE(refData.size(), 5); 0667 for (int i = 0; i < c->rowCount(); i++) { 0668 QCOMPARE(c->valueAt(i), refData.at(i)); 0669 } 0670 } 0671 0672 { 0673 // Msg12Sig4 0674 const auto* c = s.column(6); 0675 QCOMPARE(c->name(), QStringLiteral("Value4_")); 0676 QCOMPARE(c->rowCount(), 5); 0677 0678 QVector<double> refData{0., std::nan("0"), 0., 0., std::nan("0")}; 0679 QCOMPARE(refData.size(), 5); 0680 for (int i = 0; i < c->rowCount(); i++) { 0681 QCOMPARE(c->valueAt(i), refData.at(i)); 0682 } 0683 } 0684 0685 { 0686 // Msg1Sig1 0687 const auto* c = s.column(7); 0688 QCOMPARE(c->name(), QStringLiteral("Value1_Km/h")); 0689 QCOMPARE(c->rowCount(), 5); 0690 0691 QVector<double> refData{0., std::nan("0"), 47., 57., std::nan("0")}; 0692 QCOMPARE(refData.size(), 5); 0693 for (int i = 0; i < c->rowCount(); i++) { 0694 QCOMPARE(c->valueAt(i), refData.at(i)); 0695 } 0696 } 0697 0698 { 0699 // Msg2Sig4 0700 const auto* c = s.column(8); 0701 QCOMPARE(c->name(), QStringLiteral("MSG2Value4_C")); 0702 QCOMPARE(c->rowCount(), 5); 0703 0704 QVector<double> refData{std::nan("0"), 22.2, std::nan("0"), std::nan("0"), 22.2}; 0705 QCOMPARE(refData.size(), 5); 0706 for (int i = 0; i < c->rowCount(); i++) { 0707 VALUES_EQUAL(c->valueAt(i), refData.at(i)); 0708 } 0709 } 0710 0711 { 0712 // Msg2Sig1 0713 const auto* c = s.column(9); 0714 QCOMPARE(c->name(), QStringLiteral("MSG2Value1_%")); 0715 QCOMPARE(c->rowCount(), 5); 0716 0717 QVector<double> refData{std::nan("0"), 99.91, std::nan("0"), std::nan("0"), 99.91}; 0718 QCOMPARE(refData.size(), 5); 0719 for (int i = 0; i < c->rowCount(); i++) { 0720 VALUES_EQUAL(c->valueAt(i), refData.at(i)); 0721 } 0722 } 0723 0724 { 0725 // Msg2Sig3 0726 const auto* c = s.column(10); 0727 QCOMPARE(c->name(), QStringLiteral("MSG2Value3_%")); 0728 QCOMPARE(c->rowCount(), 5); 0729 0730 QVector<double> refData{std::nan("0"), 79.3, std::nan("0"), std::nan("0"), 79.3}; 0731 QCOMPARE(refData.size(), 5); 0732 for (int i = 0; i < c->rowCount(); i++) { 0733 VALUES_EQUAL(c->valueAt(i), refData.at(i)); 0734 } 0735 } 0736 0737 { 0738 // Msg2Sig2 0739 const auto* c = s.column(11); 0740 QCOMPARE(c->name(), QStringLiteral("MSG2Value2_%")); 0741 QCOMPARE(c->rowCount(), 5); 0742 0743 QVector<double> refData{std::nan("0"), 85.66, std::nan("0"), std::nan("0"), 85.66}; 0744 QCOMPARE(refData.size(), 5); 0745 for (int i = 0; i < c->rowCount(); i++) { 0746 VALUES_EQUAL(c->valueAt(i), refData.at(i)); 0747 } 0748 } 0749 } 0750 0751 // Use previous value if the current message does not contain no value for the signal 0752 void BLFFilterTest::testUsePreviousValueLittleEndian() { 0753 QTemporaryFile blfFileName(QStringLiteral("XXXXXX.blf")); 0754 QVERIFY(blfFileName.open()); 0755 QVector<Vector::BLF::CanMessage2*> messages{ 0756 createCANMessage(337, 5, {0, 4, 252, 19, 0, 0, 0, 0}), 0757 createCANMessage(541, 10, {7, 39, 118, 33, 250, 30, 76, 24}), // 99.91, 85.66, 79.3, 22.2 0758 createCANMessage(337, 15, {47, 4, 60, 29, 0, 0, 0, 0}), 0759 createCANMessage(337, 20, {57, 4, 250, 29, 0, 0, 0, 0}), 0760 createCANMessage(541, 25, {7, 39, 118, 33, 250, 30, 76, 24}), // 99.91, 85.66, 79.3, 22.2 0761 }; // time is in nanoseconds 0762 createBLFFile(blfFileName.fileName(), messages); 0763 0764 QTemporaryFile dbcFile(QStringLiteral("XXXXXX.dbc")); 0765 QVERIFY(dbcFile.open()); 0766 const auto dbcContent = R"(BO_ 337 STATUS: 8 Vector__XXX 0767 SG_ Value6 : 27|3@1+ (1,0) [0|7] "" Vector__XXX 0768 SG_ Value5 : 16|11@1+ (0.1,-102) [-102|102] "%" Vector__XXX 0769 SG_ Value2 : 8|2@1+ (1,0) [0|2] "" Vector__XXX 0770 SG_ Value3 : 10|1@1+ (1,0) [0|1] "" Vector__XXX 0771 SG_ Value7 : 30|2@1+ (1,0) [0|3] "" Vector__XXX 0772 SG_ Value4 : 11|4@1+ (1,0) [0|3] "" Vector__XXX 0773 SG_ Value1 : 0|8@1+ (1,0) [0|204] "Km/h" Vector__XXX" 0774 BO_ 541 MSG2: 8 Vector__XXX 0775 SG_ MSG2Value4 : 48|16@1+ (0.01,-40) [-40|125] "C" Vector__XXX 0776 SG_ MSG2Value1 : 0|16@1+ (0.01,0) [0|100] "%" Vector__XXX 0777 SG_ MSG2Value3 : 32|16@1+ (0.01,0) [0|100] "%" Vector__XXX 0778 SG_ MSG2Value2 : 16|16@1+ (0.01,0) [0|100] "%" Vector__XXX 0779 )"; 0780 createDBCFile(dbcFile.fileName(), dbcContent); 0781 0782 // Start Test 0783 0784 VectorBLFFilter filter; 0785 filter.setConvertTimeToSeconds(true); 0786 filter.setTimeHandlingMode(CANFilter::TimeHandling::ConcatPrevious); 0787 QCOMPARE(filter.isValid(blfFileName.fileName()), true); 0788 0789 // Valid blf and valid dbc 0790 filter.setDBCFile(dbcFile.fileName()); 0791 Spreadsheet s(QStringLiteral("TestSpreadsheet"), false); 0792 filter.readDataFromFile(blfFileName.fileName(), &s); 0793 QCOMPARE(s.columnCount(), 12); // time + 7 * Msg1 + 4* Msg2 0794 0795 { 0796 // Time 0797 const auto* c = s.column(0); 0798 QCOMPARE(c->name(), QStringLiteral("Time_s")); 0799 QCOMPARE(c->rowCount(), 5); 0800 0801 QVector<double> refData{5e-9, 10e-9, 15e-9, 20e-9, 25e-9}; 0802 QCOMPARE(refData.size(), 5); 0803 for (int i = 0; i < c->rowCount(); i++) { 0804 QCOMPARE(c->valueAt(i), refData.at(i)); 0805 } 0806 } 0807 0808 { 0809 // Msg1Sig6 0810 const auto* c = s.column(1); 0811 QCOMPARE(c->name(), QStringLiteral("Value6_")); 0812 QCOMPARE(c->rowCount(), 5); 0813 0814 QVector<double> refData{2., 2., 3., 3., 3.}; 0815 QCOMPARE(refData.size(), 5); 0816 for (int i = 0; i < c->rowCount(); i++) { 0817 QCOMPARE(c->valueAt(i), refData.at(i)); 0818 } 0819 } 0820 0821 { 0822 // Msg1Sig5 0823 const auto* c = s.column(2); 0824 QCOMPARE(c->name(), QStringLiteral("Value5_%")); 0825 QCOMPARE(c->rowCount(), 5); 0826 0827 QVector<double> refData{0., 0., 32., 51., 51.}; 0828 QCOMPARE(refData.size(), 5); 0829 for (int i = 0; i < c->rowCount(); i++) { 0830 QCOMPARE(c->valueAt(i), refData.at(i)); 0831 } 0832 } 0833 0834 { 0835 // Msg1Sig2 0836 const auto* c = s.column(3); 0837 QCOMPARE(c->name(), QStringLiteral("Value2_")); 0838 QCOMPARE(c->rowCount(), 5); 0839 0840 QVector<double> refData{0., 0., 0., 0., 0.}; 0841 QCOMPARE(refData.size(), 5); 0842 for (int i = 0; i < c->rowCount(); i++) { 0843 QCOMPARE(c->valueAt(i), refData.at(i)); 0844 } 0845 } 0846 0847 { 0848 // Msg1Sig3 0849 const auto* c = s.column(4); 0850 QCOMPARE(c->name(), QStringLiteral("Value3_")); 0851 QCOMPARE(c->rowCount(), 5); 0852 0853 QVector<double> refData{1., 1., 1., 1., 1.}; 0854 QCOMPARE(refData.size(), 5); 0855 for (int i = 0; i < c->rowCount(); i++) { 0856 QCOMPARE(c->valueAt(i), refData.at(i)); 0857 } 0858 } 0859 0860 { 0861 // Msg1Sig7 0862 const auto* c = s.column(5); 0863 QCOMPARE(c->name(), QStringLiteral("Value7_")); 0864 QCOMPARE(c->rowCount(), 5); 0865 0866 QVector<double> refData{0., 0., 0., 0., 0.}; 0867 QCOMPARE(refData.size(), 5); 0868 for (int i = 0; i < c->rowCount(); i++) { 0869 QCOMPARE(c->valueAt(i), refData.at(i)); 0870 } 0871 } 0872 0873 { 0874 // Msg12Sig4 0875 const auto* c = s.column(6); 0876 QCOMPARE(c->name(), QStringLiteral("Value4_")); 0877 QCOMPARE(c->rowCount(), 5); 0878 0879 QVector<double> refData{0., 0., 0., 0., 0.}; 0880 QCOMPARE(refData.size(), 5); 0881 for (int i = 0; i < c->rowCount(); i++) { 0882 QCOMPARE(c->valueAt(i), refData.at(i)); 0883 } 0884 } 0885 0886 { 0887 // Msg1Sig1 0888 const auto* c = s.column(7); 0889 QCOMPARE(c->name(), QStringLiteral("Value1_Km/h")); 0890 QCOMPARE(c->rowCount(), 5); 0891 0892 QVector<double> refData{0., 0., 47., 57., 57.}; 0893 QCOMPARE(refData.size(), 5); 0894 for (int i = 0; i < c->rowCount(); i++) { 0895 QCOMPARE(c->valueAt(i), refData.at(i)); 0896 } 0897 } 0898 0899 { 0900 // Msg2Sig4 0901 const auto* c = s.column(8); 0902 QCOMPARE(c->name(), QStringLiteral("MSG2Value4_C")); 0903 QCOMPARE(c->rowCount(), 5); 0904 0905 QVector<double> refData{std::nan(""), 22.2, 22.2, 22.2, 22.2}; 0906 QCOMPARE(refData.size(), 5); 0907 for (int i = 0; i < c->rowCount(); i++) { 0908 VALUES_EQUAL(c->valueAt(i), refData.at(i)); 0909 } 0910 } 0911 0912 { 0913 // Msg2Sig1 0914 const auto* c = s.column(9); 0915 QCOMPARE(c->name(), QStringLiteral("MSG2Value1_%")); 0916 QCOMPARE(c->rowCount(), 5); 0917 0918 QVector<double> refData{std::nan(""), 99.91, 99.91, 99.91, 99.91}; 0919 QCOMPARE(refData.size(), 5); 0920 for (int i = 0; i < c->rowCount(); i++) { 0921 VALUES_EQUAL(c->valueAt(i), refData.at(i)); 0922 } 0923 } 0924 0925 { 0926 // Msg2Sig3 0927 const auto* c = s.column(10); 0928 QCOMPARE(c->name(), QStringLiteral("MSG2Value3_%")); 0929 QCOMPARE(c->rowCount(), 5); 0930 0931 QVector<double> refData{std::nan(""), 79.3, 79.3, 79.3, 79.3}; 0932 QCOMPARE(refData.size(), 5); 0933 for (int i = 0; i < c->rowCount(); i++) { 0934 VALUES_EQUAL(c->valueAt(i), refData.at(i)); 0935 } 0936 } 0937 0938 { 0939 // Msg2Sig2 0940 const auto* c = s.column(11); 0941 QCOMPARE(c->name(), QStringLiteral("MSG2Value2_%")); 0942 QCOMPARE(c->rowCount(), 5); 0943 0944 QVector<double> refData{std::nan(""), 85.66, 85.66, 85.66, 85.66}; 0945 QCOMPARE(refData.size(), 5); 0946 for (int i = 0; i < c->rowCount(); i++) { 0947 VALUES_EQUAL(c->valueAt(i), refData.at(i)); 0948 } 0949 } 0950 } 0951 0952 #endif 0953 0954 QTEST_MAIN(BLFFilterTest)