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.
 
 
 
 
 
 

178 lines
4.8 KiB

#include "tools/cabana/dbc/dbcmanager.h"
#include <QSet>
#include <algorithm>
#include <numeric>
bool DBCManager::open(const SourceSet &sources, const QString &dbc_file_name, QString *error) {
try {
auto it = std::find_if(dbc_files.begin(), dbc_files.end(),
[&](auto &f) { return f.second && f.second->filename == dbc_file_name; });
auto file = (it != dbc_files.end()) ? it->second : std::make_shared<DBCFile>(dbc_file_name);
for (auto s : sources) {
dbc_files[s] = file;
}
} catch (std::exception &e) {
if (error) *error = e.what();
return false;
}
emit DBCFileChanged();
return true;
}
bool DBCManager::open(const SourceSet &sources, const QString &name, const QString &content, QString *error) {
try {
auto file = std::make_shared<DBCFile>(name, content);
for (auto s : sources) {
dbc_files[s] = file;
}
} catch (std::exception &e) {
if (error) *error = e.what();
return false;
}
emit DBCFileChanged();
return true;
}
void DBCManager::close(const SourceSet &sources) {
for (auto s : sources) {
dbc_files[s] = nullptr;
}
emit DBCFileChanged();
}
void DBCManager::close(DBCFile *dbc_file) {
for (auto &[_, f] : dbc_files) {
if (f.get() == dbc_file) f = nullptr;
}
emit DBCFileChanged();
}
void DBCManager::closeAll() {
dbc_files.clear();
emit DBCFileChanged();
}
void DBCManager::addSignal(const MessageId &id, const cabana::Signal &sig) {
if (auto m = msg(id)) {
if (auto s = m->addSignal(sig)) {
emit signalAdded(id, s);
emit maskUpdated();
}
}
}
void DBCManager::updateSignal(const MessageId &id, const QString &sig_name, const cabana::Signal &sig) {
if (auto m = msg(id)) {
if (auto s = m->updateSignal(sig_name, sig)) {
emit signalUpdated(s);
emit maskUpdated();
}
}
}
void DBCManager::removeSignal(const MessageId &id, const QString &sig_name) {
if (auto m = msg(id)) {
if (auto s = m->sig(sig_name)) {
emit signalRemoved(s);
m->removeSignal(sig_name);
emit maskUpdated();
}
}
}
void DBCManager::updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &node, const QString &comment) {
auto dbc_file = findDBCFile(id);
assert(dbc_file); // This should be impossible
dbc_file->updateMsg(id, name, size, node, comment);
emit msgUpdated(id);
}
void DBCManager::removeMsg(const MessageId &id) {
auto dbc_file = findDBCFile(id);
assert(dbc_file); // This should be impossible
dbc_file->removeMsg(id);
emit msgRemoved(id);
emit maskUpdated();
}
QString DBCManager::newMsgName(const MessageId &id) {
return QString("NEW_MSG_") + QString::number(id.address, 16).toUpper();
}
QString DBCManager::newSignalName(const MessageId &id) {
auto m = msg(id);
return m ? m->newSignalName() : "";
}
const std::map<uint32_t, cabana::Msg> &DBCManager::getMessages(uint8_t source) {
static std::map<uint32_t, cabana::Msg> empty_msgs;
auto dbc_file = findDBCFile(source);
return dbc_file ? dbc_file->getMessages() : empty_msgs;
}
cabana::Msg *DBCManager::msg(const MessageId &id) {
auto dbc_file = findDBCFile(id);
return dbc_file ? dbc_file->msg(id) : nullptr;
}
cabana::Msg *DBCManager::msg(uint8_t source, const QString &name) {
auto dbc_file = findDBCFile(source);
return dbc_file ? dbc_file->msg(name) : nullptr;
}
QStringList DBCManager::signalNames() {
// Used for autocompletion
QSet<QString> names;
for (auto &f : allDBCFiles()) {
for (auto &[_, m] : f->getMessages()) {
for (auto sig : m.getSignals()) {
names.insert(sig->name);
}
}
}
QStringList ret = names.values();
ret.sort();
return ret;
}
int DBCManager::nonEmptyDBCCount() {
auto files = allDBCFiles();
return std::count_if(files.cbegin(), files.cend(), [](auto &f) { return !f->isEmpty(); });
}
DBCFile *DBCManager::findDBCFile(const uint8_t source) {
// Find DBC file that matches id.source, fall back to SOURCE_ALL if no specific DBC is found
auto it = dbc_files.count(source) ? dbc_files.find(source) : dbc_files.find(-1);
return it != dbc_files.end() ? it->second.get() : nullptr;
}
std::set<DBCFile *> DBCManager::allDBCFiles() {
std::set<DBCFile *> files;
for (const auto &[_, f] : dbc_files) {
if (f) files.insert(f.get());
}
return files;
}
const SourceSet DBCManager::sources(const DBCFile *dbc_file) const {
SourceSet sources;
for (auto &[s, f] : dbc_files) {
if (f.get() == dbc_file) sources.insert(s);
}
return sources;
}
QString toString(const SourceSet &ss) {
return std::accumulate(ss.cbegin(), ss.cend(), QString(), [](QString str, int source) {
if (!str.isEmpty()) str += ", ";
return str + (source == -1 ? QStringLiteral("all") : QString::number(source));
});
}
DBCManager *dbc() {
static DBCManager dbc_manager(nullptr);
return &dbc_manager;
}