mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-04 02:09:30 +02:00
Add CAN log replay based battery tests
This commit is contained in:
parent
7f8f48756d
commit
fd9d1ec714
9 changed files with 281 additions and 1 deletions
98
test/can_log_based/utils.cpp
Normal file
98
test/can_log_based/utils.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
#include "utils.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
bool ends_with(const std::string& str, const std::string& suffix) {
|
||||
return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
|
||||
}
|
||||
|
||||
void print_frame(const CAN_frame& frame) {
|
||||
std::cout << "ID: " << std::hex << frame.ID << ", DLC: " << (int)frame.DLC << ", Data: ";
|
||||
for (int i = 0; i < frame.DLC; ++i) {
|
||||
std::cout << std::hex << (int)frame.data.u8[i] << " ";
|
||||
}
|
||||
std::cout << std::dec << "\n";
|
||||
}
|
||||
|
||||
CAN_frame parse_can_log_line(const std::string& logLine) {
|
||||
std::stringstream ss(logLine);
|
||||
CAN_frame frame = {};
|
||||
char dummy;
|
||||
|
||||
double timestamp;
|
||||
std::string interfaceName;
|
||||
|
||||
// timestamp and interface name are parsed but not used
|
||||
ss >> dummy >> timestamp >> dummy;
|
||||
ss >> interfaceName;
|
||||
|
||||
// parse hexadecimal CAN ID
|
||||
ss >> std::hex >> frame.ID;
|
||||
if (ss.fail()) {
|
||||
throw std::runtime_error("Invalid format: Failed to parse CAN ID.");
|
||||
}
|
||||
// check whether the ID is in the extended range
|
||||
frame.ext_ID = (frame.ID > 0x7FF);
|
||||
|
||||
// parse the data length
|
||||
int dlc_val;
|
||||
ss >> dummy; // Consume '['
|
||||
if (ss.fail() || dummy != '[') {
|
||||
throw std::runtime_error("Invalid format: Missing opening bracket for data length.");
|
||||
}
|
||||
ss >> dlc_val;
|
||||
frame.DLC = static_cast<uint8_t>(dlc_val);
|
||||
ss >> dummy; // Consume ']'
|
||||
if (ss.fail() || dummy != ']') {
|
||||
throw std::runtime_error("Invalid format: Missing closing bracket for data length.");
|
||||
}
|
||||
// crudely assume CAN FD if DLC > 8
|
||||
frame.FD = (frame.DLC > 8);
|
||||
|
||||
// parse the actual data bytes
|
||||
unsigned int byte;
|
||||
for (int i = 0; i < frame.DLC; ++i) {
|
||||
ss >> std::hex >> byte;
|
||||
if (ss.fail()) {
|
||||
throw std::runtime_error("Fewer data bytes than specified by data length.");
|
||||
}
|
||||
frame.data.u8[i] = static_cast<uint8_t>(byte);
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
std::vector<CAN_frame> parse_can_log_file(const fs::path& filePath) {
|
||||
std::ifstream logFile(filePath);
|
||||
if (!logFile.is_open()) {
|
||||
std::cerr << "Error: Could not open file " << filePath << std::endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<CAN_frame> frames;
|
||||
std::string line;
|
||||
int lineNumber = 0;
|
||||
|
||||
// read the file line by line
|
||||
while (std::getline(logFile, line)) {
|
||||
lineNumber++;
|
||||
if (line.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[0] == '#' || line[0] == ';') {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
try {
|
||||
frames.push_back(parse_can_log_line(line));
|
||||
} catch (const std::runtime_error& e) {
|
||||
std::cerr << "Warning: Skipping malformed line " << lineNumber << " in " << filePath.filename()
|
||||
<< ". Reason: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue