|
|
@ -1,9 +1,12 @@ |
|
|
|
#include "tools/cabana/streams/pandastream.h" |
|
|
|
#include "tools/cabana/streams/pandastream.h" |
|
|
|
|
|
|
|
|
|
|
|
#include <QFormLayout> |
|
|
|
#include <QLabel> |
|
|
|
#include <QMessageBox> |
|
|
|
#include <QMessageBox> |
|
|
|
|
|
|
|
#include <QPushButton> |
|
|
|
#include <QVBoxLayout> |
|
|
|
#include <QVBoxLayout> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "selfdrive/ui/qt/util.h" |
|
|
|
|
|
|
|
|
|
|
|
PandaStream::PandaStream(QObject *parent, PandaStreamConfig config_) : config(config_), LiveStream(parent) { |
|
|
|
PandaStream::PandaStream(QObject *parent, PandaStreamConfig config_) : config(config_), LiveStream(parent) { |
|
|
|
if (config.serial.isEmpty()) { |
|
|
|
if (config.serial.isEmpty()) { |
|
|
|
auto serials = Panda::list(); |
|
|
|
auto serials = Panda::list(); |
|
|
@ -97,16 +100,105 @@ OpenPandaWidget::OpenPandaWidget(AbstractStream **stream) : AbstractOpenStreamWi |
|
|
|
main_layout->addStretch(1); |
|
|
|
main_layout->addStretch(1); |
|
|
|
|
|
|
|
|
|
|
|
QFormLayout *form_layout = new QFormLayout(); |
|
|
|
QFormLayout *form_layout = new QFormLayout(); |
|
|
|
form_layout->addRow(tr("Serial"), serial_edit = new QLineEdit(this)); |
|
|
|
|
|
|
|
serial_edit->setPlaceholderText(tr("Leave empty to use default serial")); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QHBoxLayout *serial_layout = new QHBoxLayout(); |
|
|
|
|
|
|
|
serial_edit = new QComboBox(); |
|
|
|
|
|
|
|
serial_edit->setFixedWidth(300); |
|
|
|
|
|
|
|
serial_layout->addWidget(serial_edit); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QPushButton *refresh = new QPushButton(tr("Refresh")); |
|
|
|
|
|
|
|
refresh->setFixedWidth(100); |
|
|
|
|
|
|
|
serial_layout->addWidget(refresh); |
|
|
|
|
|
|
|
form_layout->addRow(tr("Serial"), serial_layout); |
|
|
|
main_layout->addLayout(form_layout); |
|
|
|
main_layout->addLayout(form_layout); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
config_layout = new QFormLayout(); |
|
|
|
|
|
|
|
main_layout->addLayout(config_layout); |
|
|
|
|
|
|
|
|
|
|
|
main_layout->addStretch(1); |
|
|
|
main_layout->addStretch(1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QObject::connect(refresh, &QPushButton::clicked, this, &OpenPandaWidget::refreshSerials); |
|
|
|
|
|
|
|
QObject::connect(serial_edit, &QComboBox::currentTextChanged, this, &OpenPandaWidget::buildConfigForm); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Populate serials
|
|
|
|
|
|
|
|
refreshSerials(); |
|
|
|
|
|
|
|
buildConfigForm(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void OpenPandaWidget::refreshSerials() { |
|
|
|
|
|
|
|
serial_edit->clear(); |
|
|
|
|
|
|
|
for (auto serial : Panda::list()) { |
|
|
|
|
|
|
|
serial_edit->addItem(QString::fromStdString(serial)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void OpenPandaWidget::buildConfigForm() { |
|
|
|
|
|
|
|
clearLayout(config_layout); |
|
|
|
|
|
|
|
QString serial = serial_edit->currentText(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool has_fd = false; |
|
|
|
|
|
|
|
bool has_panda = !serial.isEmpty(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (has_panda) { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
Panda panda = Panda(serial.toStdString()); |
|
|
|
|
|
|
|
has_fd = (panda.hw_type == cereal::PandaState::PandaType::RED_PANDA) || (panda.hw_type == cereal::PandaState::PandaType::RED_PANDA_V2); |
|
|
|
|
|
|
|
} catch (const std::exception& e) { |
|
|
|
|
|
|
|
has_panda = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (has_panda) { |
|
|
|
|
|
|
|
config.serial = serial; |
|
|
|
|
|
|
|
config.bus_config.resize(3); |
|
|
|
|
|
|
|
for (int i = 0; i < config.bus_config.size(); i++) { |
|
|
|
|
|
|
|
QHBoxLayout *bus_layout = new QHBoxLayout; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// CAN Speed
|
|
|
|
|
|
|
|
bus_layout->addWidget(new QLabel(tr("CAN Speed (kbps):"))); |
|
|
|
|
|
|
|
QComboBox *can_speed = new QComboBox; |
|
|
|
|
|
|
|
for (int j = 0; j < std::size(speeds); j++) { |
|
|
|
|
|
|
|
can_speed->addItem(QString::number(speeds[j])); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (data_speeds[j] == config.bus_config[i].can_speed_kbps) { |
|
|
|
|
|
|
|
can_speed->setCurrentIndex(j); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
QObject::connect(can_speed, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {config.bus_config[i].can_speed_kbps = speeds[index];}); |
|
|
|
|
|
|
|
bus_layout->addWidget(can_speed); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// CAN-FD Speed
|
|
|
|
|
|
|
|
if (has_fd) { |
|
|
|
|
|
|
|
QCheckBox *enable_fd = new QCheckBox("CAN-FD"); |
|
|
|
|
|
|
|
bus_layout->addWidget(enable_fd); |
|
|
|
|
|
|
|
bus_layout->addWidget(new QLabel(tr("Data Speed (kbps):"))); |
|
|
|
|
|
|
|
QComboBox *data_speed = new QComboBox; |
|
|
|
|
|
|
|
for (int j = 0; j < std::size(data_speeds); j++) { |
|
|
|
|
|
|
|
data_speed->addItem(QString::number(data_speeds[j])); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (data_speeds[j] == config.bus_config[i].data_speed_kbps) { |
|
|
|
|
|
|
|
data_speed->setCurrentIndex(j); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data_speed->setEnabled(false); |
|
|
|
|
|
|
|
bus_layout->addWidget(data_speed); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QObject::connect(data_speed, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {config.bus_config[i].data_speed_kbps = data_speeds[index];}); |
|
|
|
|
|
|
|
QObject::connect(enable_fd, &QCheckBox::stateChanged, data_speed, &QComboBox::setEnabled); |
|
|
|
|
|
|
|
QObject::connect(enable_fd, &QCheckBox::stateChanged, [=](int state) {config.bus_config[i].can_fd = (bool)state;}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
config_layout->addRow(tr("Bus %1:").arg(i), bus_layout); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
config.serial = ""; |
|
|
|
|
|
|
|
config_layout->addWidget(new QLabel(tr("No panda found"))); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool OpenPandaWidget::open() { |
|
|
|
bool OpenPandaWidget::open() { |
|
|
|
try { |
|
|
|
try { |
|
|
|
PandaStreamConfig config = {.serial = serial_edit->text()}; |
|
|
|
|
|
|
|
*stream = new PandaStream(qApp, config); |
|
|
|
*stream = new PandaStream(qApp, config); |
|
|
|
} catch (std::exception &e) { |
|
|
|
} catch (std::exception &e) { |
|
|
|
QMessageBox::warning(nullptr, tr("Warning"), tr("Failed to connect to panda: '%1'").arg(e.what())); |
|
|
|
QMessageBox::warning(nullptr, tr("Warning"), tr("Failed to connect to panda: '%1'").arg(e.what())); |
|
|
|