openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

117 lines
3.1 KiB

#include "tools/cabana/dbcmanager.h"
#include <QVector>
DBCManager::DBCManager(QObject *parent) : QObject(parent) {}
DBCManager::~DBCManager() {}
void DBCManager::open(const QString &dbc_file_name) {
dbc_name = dbc_file_name;
dbc = const_cast<DBC *>(dbc_lookup(dbc_name.toStdString()));
msg_map.clear();
for (auto &msg : dbc->msgs) {
msg_map[msg.address] = &msg;
}
emit DBCFileChanged();
}
void save(const QString &dbc_file_name) {
// TODO: save DBC to file
}
void DBCManager::updateMsg(const QString &id, const QString &name, uint32_t size) {
auto m = const_cast<Msg *>(msg(id));
if (m) {
m->name = name.toStdString();
m->size = size;
} else {
uint32_t address = addressFromId(id);
dbc->msgs.push_back({.address = address, .name = name.toStdString(), .size = size});
msg_map[address] = &dbc->msgs.back();
}
emit msgUpdated(id);
}
void DBCManager::addSignal(const QString &id, const Signal &sig) {
if (Msg *m = const_cast<Msg *>(msg(id))) {
m->sigs.push_back(sig);
emit signalAdded(id, QString::fromStdString(sig.name));
}
}
void DBCManager::updateSignal(const QString &id, const QString &sig_name, const Signal &sig) {
if (Signal *s = const_cast<Signal *>(signal(id, sig_name))) {
*s = sig;
emit signalUpdated(id, sig_name);
}
}
void DBCManager::removeSignal(const QString &id, const QString &sig_name) {
if (Msg *m = const_cast<Msg *>(msg(id))) {
auto it = std::find_if(m->sigs.begin(), m->sigs.end(), [=](auto &sig) { return sig_name == sig.name.c_str(); });
if (it != m->sigs.end()) {
m->sigs.erase(it);
emit signalRemoved(id, sig_name);
}
}
}
const Signal *DBCManager::signal(const QString &id, const QString &sig_name) const {
if (auto m = msg(id)) {
auto it = std::find_if(m->sigs.begin(), m->sigs.end(), [&](auto &s) { return sig_name == s.name.c_str(); });
if (it != m->sigs.end())
return &(*it);
}
return nullptr;
}
uint32_t DBCManager::addressFromId(const QString &id) {
return id.mid(id.indexOf(':') + 1).toUInt(nullptr, 16);
}
DBCManager *dbc() {
static DBCManager dbc_manager(nullptr);
return &dbc_manager;
}
// helper functions
static QVector<int> BIG_ENDIAN_START_BITS = []() {
QVector<int> ret;
for (int i = 0; i < 64; i++)
for (int j = 7; j >= 0; j--)
ret.push_back(j + i * 8);
return ret;
}();
int bigEndianStartBitsIndex(int start_bit) {
return BIG_ENDIAN_START_BITS[start_bit];
}
int bigEndianBitIndex(int index) {
return BIG_ENDIAN_START_BITS.indexOf(index);
}
double get_raw_value(uint8_t *data, size_t data_size, const Signal &sig) {
int64_t val = 0;
int i = sig.msb / 8;
int bits = sig.size;
while (i >= 0 && i < data_size && bits > 0) {
int lsb = (int)(sig.lsb / 8) == i ? sig.lsb : i * 8;
int msb = (int)(sig.msb / 8) == i ? sig.msb : (i + 1) * 8 - 1;
int size = msb - lsb + 1;
uint64_t d = (data[i] >> (lsb - (i * 8))) & ((1ULL << size) - 1);
val |= d << (bits - size);
bits -= size;
i = sig.is_little_endian ? i - 1 : i + 1;
}
if (sig.is_signed) {
val -= ((val >> (sig.size - 1)) & 0x1) ? (1ULL << sig.size) : 0;
}
double value = val * sig.factor + sig.offset;
return value;
}