mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-01 03:43:46 +08:00
openpilot v0.8.8 release
This commit is contained in:
+11
-5
@@ -63,7 +63,6 @@ if arch != 'aarch64' and GetOption('setup'):
|
||||
asset_obj = qt_env.Object("assets", assets)
|
||||
|
||||
qt_env.Program("qt/setup/reset", ["qt/setup/reset.cc"], LIBS=qt_libs)
|
||||
qt_env.Program("qt/setup/wifi", ["qt/setup/wifi.cc"], LIBS=qt_libs + ['common', 'json11'])
|
||||
qt_env.Program("qt/setup/updater", ["qt/setup/updater.cc", asset_obj], LIBS=qt_libs)
|
||||
qt_env.Program("qt/setup/setup", ["qt/setup/setup.cc", asset_obj],
|
||||
LIBS=qt_libs + ['curl', 'common', 'json11'])
|
||||
@@ -71,14 +70,21 @@ if arch != 'aarch64' and GetOption('setup'):
|
||||
senv = qt_env.Clone()
|
||||
senv['LINKFLAGS'].append('-Wl,-strip-debug')
|
||||
installers = [
|
||||
("openpilot", "release3-staging"),
|
||||
("openpilot", "release3"),
|
||||
("openpilot_test", "release3-staging"),
|
||||
("openpilot_nightly", "master-ci"),
|
||||
("openpilot_internal", "master"),
|
||||
("dashcam", "dashcam3-staging"),
|
||||
("dashcam", "dashcam3"),
|
||||
("dashcam_test", "dashcam3-staging"),
|
||||
]
|
||||
|
||||
cont = {}
|
||||
for brand in ("openpilot", "dashcam"):
|
||||
cont[brand] = senv.Command(f"qt/setup/continue_{brand}.o", f"#installer/continue_{brand}.sh",
|
||||
"ld -r -b binary -o $TARGET $SOURCE")
|
||||
for name, branch in installers:
|
||||
d = {'BRANCH': f"'\"{branch}\"'"}
|
||||
brand = "dashcam" if "dashcam" in branch else "openpilot"
|
||||
d = {'BRANCH': f"'\"{branch}\"'", 'BRAND': f"'\"{brand}\"'"}
|
||||
if "internal" in name:
|
||||
d['INTERNAL'] = "1"
|
||||
|
||||
@@ -87,7 +93,7 @@ if arch != 'aarch64' and GetOption('setup'):
|
||||
r.raise_for_status()
|
||||
d['SSH_KEYS'] = f'\\"{r.text.strip()}\\"'
|
||||
obj = senv.Object(f"qt/setup/installer_{name}.o", ["qt/setup/installer.cc"], CPPDEFINES=d)
|
||||
f = senv.Program(f"qt/setup/installer_{name}", obj, LIBS=qt_libs)
|
||||
f = senv.Program(f"qt/setup/installer_{name}", [obj, cont[brand]], LIBS=qt_libs)
|
||||
# keep installers small
|
||||
assert f[0].get_size() < 300*1e3
|
||||
|
||||
|
||||
@@ -67,15 +67,15 @@ static void ui_draw_circle_image(const UIState *s, int center_x, int center_y, i
|
||||
ui_draw_circle_image(s, center_x, center_y, radius, image, nvgRGBA(0, 0, 0, (255 * bg_alpha)), img_alpha);
|
||||
}
|
||||
|
||||
static void draw_lead(UIState *s, const cereal::RadarState::LeadData::Reader &lead_data, const vertex_data &vd) {
|
||||
static void draw_lead(UIState *s, const cereal::ModelDataV2::LeadDataV3::Reader &lead_data, const vertex_data &vd) {
|
||||
// Draw lead car indicator
|
||||
auto [x, y] = vd;
|
||||
|
||||
float fillAlpha = 0;
|
||||
float speedBuff = 10.;
|
||||
float leadBuff = 40.;
|
||||
float d_rel = lead_data.getDRel();
|
||||
float v_rel = lead_data.getVRel();
|
||||
float d_rel = lead_data.getX()[0];
|
||||
float v_rel = lead_data.getV()[0];
|
||||
if (d_rel < leadBuff) {
|
||||
fillAlpha = 255*(1.0-(d_rel/leadBuff));
|
||||
if (v_rel < 0) {
|
||||
@@ -167,13 +167,12 @@ static void ui_draw_world(UIState *s) {
|
||||
|
||||
// Draw lead indicators if openpilot is handling longitudinal
|
||||
if (s->scene.longitudinal_control) {
|
||||
auto radar_state = (*s->sm)["radarState"].getRadarState();
|
||||
auto lead_one = radar_state.getLeadOne();
|
||||
auto lead_two = radar_state.getLeadTwo();
|
||||
if (lead_one.getStatus()) {
|
||||
auto lead_one = (*s->sm)["modelV2"].getModelV2().getLeadsV3()[0];
|
||||
auto lead_two = (*s->sm)["modelV2"].getModelV2().getLeadsV3()[1];
|
||||
if (lead_one.getProb() > .5) {
|
||||
draw_lead(s, lead_one, s->scene.lead_vertices[0]);
|
||||
}
|
||||
if (lead_two.getStatus() && (std::abs(lead_one.getDRel() - lead_two.getDRel()) > 3.0)) {
|
||||
if (lead_two.getProb() > .5 && (std::abs(lead_one.getX()[0] - lead_two.getX()[0]) > 3.0)) {
|
||||
draw_lead(s, lead_two, s->scene.lead_vertices[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,15 +14,12 @@
|
||||
#include "selfdrive/common/params.h"
|
||||
#include "selfdrive/common/util.h"
|
||||
#include "selfdrive/hardware/hw.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
|
||||
namespace CommaApi {
|
||||
|
||||
const std::string private_key_path =
|
||||
Hardware::PC() ? util::getenv_default("HOME", "/.comma/persist/comma/id_rsa", "/persist/comma/id_rsa")
|
||||
: "/persist/comma/id_rsa";
|
||||
|
||||
QByteArray rsa_sign(const QByteArray &data) {
|
||||
auto file = QFile(private_key_path.c_str());
|
||||
auto file = QFile(Path::rsa_file().c_str());
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qDebug() << "No RSA private key found, please run manager.py or registration.py";
|
||||
return QByteArray();
|
||||
@@ -48,9 +45,8 @@ QByteArray rsa_sign(const QByteArray &data) {
|
||||
QString create_jwt(const QJsonObject &payloads, int expiry) {
|
||||
QJsonObject header = {{"alg", "RS256"}};
|
||||
|
||||
QString dongle_id = QString::fromStdString(Params().get("DongleId"));
|
||||
auto t = QDateTime::currentSecsSinceEpoch();
|
||||
QJsonObject payload = {{"identity", dongle_id}, {"nbf", t}, {"iat", t}, {"exp", t + expiry}};
|
||||
QJsonObject payload = {{"identity", getDongleId().value_or("")}, {"nbf", t}, {"iat", t}, {"exp", t + expiry}};
|
||||
for (auto it = payloads.begin(); it != payloads.end(); ++it) {
|
||||
payload.insert(it.key(), it.value());
|
||||
}
|
||||
@@ -89,7 +85,7 @@ void HttpRequest::sendRequest(const QString &requestURL, const HttpRequest::Meth
|
||||
if(create_jwt) {
|
||||
token = CommaApi::create_jwt();
|
||||
} else {
|
||||
QString token_json = QString::fromStdString(util::read_file(util::getenv_default("HOME", "/.comma/auth.json", "/.comma/auth.json")));
|
||||
QString token_json = QString::fromStdString(util::read_file(util::getenv("HOME") + "/.comma/auth.json"));
|
||||
QJsonDocument json_d = QJsonDocument::fromJson(token_json.toUtf8());
|
||||
token = json_d["access_token"].toString();
|
||||
}
|
||||
|
||||
@@ -5,8 +5,11 @@
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
|
||||
#include "selfdrive/common/util.h"
|
||||
|
||||
namespace CommaApi {
|
||||
|
||||
const QString BASE_URL = util::getenv("API_HOST", "https://api.commadotai.com").c_str();
|
||||
QByteArray rsa_sign(const QByteArray &data);
|
||||
QString create_jwt(const QJsonObject &payloads = {}, int expiry = 3600);
|
||||
|
||||
|
||||
@@ -158,10 +158,10 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
|
||||
font-size: 55px;
|
||||
}
|
||||
)");
|
||||
refresh();
|
||||
}
|
||||
|
||||
void OffroadHome::showEvent(QShowEvent *event) {
|
||||
refresh();
|
||||
timer->start(10 * 1000);
|
||||
}
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ void MapWindow::timerUpdate() {
|
||||
|
||||
if (localizer_valid) {
|
||||
auto pos = location.getPositionGeodetic();
|
||||
auto orientation = location.getOrientationNED();
|
||||
auto orientation = location.getCalibratedOrientationNED();
|
||||
|
||||
float velocity = location.getVelocityCalibrated().getValue()[0];
|
||||
float bearing = RAD2DEG(orientation.getValue()[2]);
|
||||
@@ -198,7 +198,7 @@ void MapWindow::timerUpdate() {
|
||||
}
|
||||
|
||||
// Transition to next route segment
|
||||
if (distance_to_maneuver < -MANEUVER_TRANSITION_THRESHOLD) {
|
||||
if (!shouldRecompute() && (distance_to_maneuver < -MANEUVER_TRANSITION_THRESHOLD)) {
|
||||
auto next_segment = segment.nextRouteSegment();
|
||||
if (next_segment.isValid()) {
|
||||
segment = next_segment;
|
||||
|
||||
@@ -17,7 +17,7 @@ QMapbox::CoordinatesCollections model_to_collection(
|
||||
|
||||
Eigen::Vector3d ecef(positionECEF.getValue()[0], positionECEF.getValue()[1], positionECEF.getValue()[2]);
|
||||
Eigen::Vector3d orient(calibratedOrientationECEF.getValue()[0], calibratedOrientationECEF.getValue()[1], calibratedOrientationECEF.getValue()[2]);
|
||||
Eigen::Matrix3d ecef_from_local = euler2rot(orient).transpose();
|
||||
Eigen::Matrix3d ecef_from_local = euler2rot(orient);
|
||||
|
||||
QMapbox::Coordinates coordinates;
|
||||
auto x = line.getX();
|
||||
|
||||
@@ -93,19 +93,18 @@ MapPanel::MapPanel(QWidget* parent) : QWidget(parent) {
|
||||
|
||||
clear();
|
||||
|
||||
std::string dongle_id = params.get("DongleId");
|
||||
if (util::is_valid_dongle_id(dongle_id)) {
|
||||
if (auto dongle_id = getDongleId()) {
|
||||
// Fetch favorite and recent locations
|
||||
{
|
||||
std::string url = "https://api.commadotai.com/v1/navigation/" + dongle_id + "/locations";
|
||||
RequestRepeater* repeater = new RequestRepeater(this, QString::fromStdString(url), "ApiCache_NavDestinations", 30, true);
|
||||
QString url = CommaApi::BASE_URL + "/v1/navigation/" + *dongle_id + "/locations";
|
||||
RequestRepeater* repeater = new RequestRepeater(this, url, "ApiCache_NavDestinations", 30, true);
|
||||
QObject::connect(repeater, &RequestRepeater::receivedResponse, this, &MapPanel::parseResponse);
|
||||
QObject::connect(repeater, &RequestRepeater::failedResponse, this, &MapPanel::failedResponse);
|
||||
}
|
||||
|
||||
// Destination set while offline
|
||||
{
|
||||
QString url = QString::fromStdString("https://api.commadotai.com/v1/navigation/" + dongle_id + "/next");
|
||||
QString url = CommaApi::BASE_URL + "/v1/navigation/" + *dongle_id + "/next";
|
||||
RequestRepeater* repeater = new RequestRepeater(this, url, "", 10, true);
|
||||
HttpRequest* deleter = new HttpRequest(this);
|
||||
|
||||
|
||||
@@ -72,8 +72,8 @@ private:
|
||||
QRect(303, 755, 718, 189),
|
||||
};
|
||||
|
||||
const QString IMG_PATH = vwp_w == 2160 ? "../assets/training_wide/" : "../assets/training/";
|
||||
const QVector<QRect> boundingRect = vwp_w == 2160 ? boundingRectWide : boundingRectStandard;
|
||||
const QString IMG_PATH = WIDE_UI ? "../assets/training_wide/" : "../assets/training/";
|
||||
const QVector<QRect> boundingRect = WIDE_UI ? boundingRectWide : boundingRectStandard;
|
||||
|
||||
signals:
|
||||
void completedTraining();
|
||||
|
||||
@@ -96,9 +96,7 @@ TogglesPanel::TogglesPanel(QWidget *parent) : QWidget(parent) {
|
||||
DevicePanel::DevicePanel(QWidget* parent) : QWidget(parent) {
|
||||
QVBoxLayout *main_layout = new QVBoxLayout(this);
|
||||
Params params = Params();
|
||||
|
||||
QString dongle = QString::fromStdString(params.get("DongleId", false));
|
||||
main_layout->addWidget(new LabelControl("Dongle ID", dongle));
|
||||
main_layout->addWidget(new LabelControl("Dongle ID", getDongleId().value_or("N/A")));
|
||||
main_layout->addWidget(horizontal_line());
|
||||
|
||||
QString serial = QString::fromStdString(params.get("HardwareSerial", false));
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "selfdrive/common/params.h"
|
||||
#include "selfdrive/common/swaglog.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
|
||||
template <typename T>
|
||||
T get_response(QDBusMessage response) {
|
||||
@@ -35,9 +36,8 @@ WifiManager::WifiManager(QWidget* parent) : QWidget(parent) {
|
||||
|
||||
// Set tethering ssid as "weedle" + first 4 characters of a dongle id
|
||||
tethering_ssid = "weedle";
|
||||
std::string bytes = Params().get("DongleId");
|
||||
if (bytes.length() >= 4) {
|
||||
tethering_ssid += "-" + QString::fromStdString(bytes.substr(0,4));
|
||||
if (auto dongle_id = getDongleId()) {
|
||||
tethering_ssid += "-" + dongle_id->left(4);
|
||||
}
|
||||
|
||||
adapter = getAdapter();
|
||||
|
||||
@@ -19,11 +19,12 @@ const QString ASSET_PATH = ":/";
|
||||
const QString ASSET_PATH = "../assets/";
|
||||
#endif
|
||||
|
||||
const int vwp_w = (Hardware::TICI() || (getenv("WIDE_UI") != NULL)) ? 2160 : 1920;
|
||||
const bool WIDE_UI = Hardware::TICI() || getenv("WIDE_UI") != nullptr;
|
||||
const int vwp_w = WIDE_UI ? 2160 : 1920;
|
||||
const int vwp_h = 1080;
|
||||
|
||||
inline void setMainWindow(QWidget *w) {
|
||||
const float scale = getenv("SCALE") != NULL ? std::stof(getenv("SCALE")) : 1.0;
|
||||
const float scale = util::getenv("SCALE", 1.0f);
|
||||
w->setFixedSize(vwp_w*scale, vwp_h*scale);
|
||||
w->show();
|
||||
|
||||
|
||||
+19
-31
@@ -2,9 +2,6 @@
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "selfdrive/ui/qt/qt_window.h"
|
||||
#include "selfdrive/common/util.h"
|
||||
#include "selfdrive/hardware/hw.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
|
||||
void Sidebar::drawMetric(QPainter &p, const QString &label, const QString &val, QColor c, int y) {
|
||||
@@ -41,9 +38,9 @@ Sidebar::Sidebar(QWidget *parent) : QFrame(parent) {
|
||||
|
||||
connect(this, &Sidebar::valueChanged, [=] { update(); });
|
||||
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
setFixedWidth(300);
|
||||
setMinimumHeight(vwp_h);
|
||||
setStyleSheet("background-color: rgb(57, 57, 57);");
|
||||
}
|
||||
|
||||
void Sidebar::mouseReleaseEvent(QMouseEvent *event) {
|
||||
@@ -60,42 +57,31 @@ void Sidebar::updateState(const UIState &s) {
|
||||
int strength = (int)deviceState.getNetworkStrength();
|
||||
setProperty("netStrength", strength > 0 ? strength + 1 : 0);
|
||||
|
||||
ItemStatus connectstatus;
|
||||
auto last_ping = deviceState.getLastAthenaPingTime();
|
||||
if (last_ping == 0) {
|
||||
if (params.getBool("PrimeRedirected")) {
|
||||
setProperty("connectStr", "NO\nPRIME");
|
||||
setProperty("connectStatus", danger_color);
|
||||
} else {
|
||||
setProperty("connectStr", "CONNECT\nOFFLINE");
|
||||
setProperty("connectStatus", warning_color);
|
||||
}
|
||||
connectstatus = params.getBool("PrimeRedirected") ? ItemStatus{"NO\nPRIME", danger_color} : ItemStatus{"CONNECT\nOFFLINE", warning_color};
|
||||
} else {
|
||||
bool online = nanos_since_boot() - last_ping < 80e9;
|
||||
setProperty("connectStr", (online ? "CONNECT\nONLINE" : "CONNECT\nERROR"));
|
||||
setProperty("connectStatus", online ? good_color : danger_color);
|
||||
connectstatus = nanos_since_boot() - last_ping < 80e9 ? ItemStatus{"CONNECT\nONLINE", good_color} : ItemStatus{"CONNECT\nERROR", danger_color};
|
||||
}
|
||||
setProperty("connectStatus", QVariant::fromValue(connectstatus));
|
||||
|
||||
QColor tempStatus = danger_color;
|
||||
QColor tempColor = danger_color;
|
||||
auto ts = deviceState.getThermalStatus();
|
||||
if (ts == cereal::DeviceState::ThermalStatus::GREEN) {
|
||||
tempStatus = good_color;
|
||||
tempColor = good_color;
|
||||
} else if (ts == cereal::DeviceState::ThermalStatus::YELLOW) {
|
||||
tempStatus = warning_color;
|
||||
tempColor = warning_color;
|
||||
}
|
||||
setProperty("tempStatus", tempStatus);
|
||||
setProperty("tempVal", (int)deviceState.getAmbientTempC());
|
||||
setProperty("tempStatus", QVariant::fromValue(ItemStatus{QString("%1°C").arg((int)deviceState.getAmbientTempC()), tempColor}));
|
||||
|
||||
QString pandaStr = "VEHICLE\nONLINE";
|
||||
QColor pandaStatus = good_color;
|
||||
ItemStatus pandaStatus = {"VEHICLE\nONLINE", good_color};
|
||||
if (s.scene.pandaType == cereal::PandaState::PandaType::UNKNOWN) {
|
||||
pandaStatus = danger_color;
|
||||
pandaStr = "NO\nPANDA";
|
||||
pandaStatus = {"NO\nPANDA", danger_color};
|
||||
} else if (s.scene.started && !sm["liveLocationKalman"].getLiveLocationKalman().getGpsOK()) {
|
||||
pandaStatus = warning_color;
|
||||
pandaStr = "GPS\nSEARCHING";
|
||||
pandaStatus = {"GPS\nSEARCHING", warning_color};
|
||||
}
|
||||
setProperty("pandaStr", pandaStr);
|
||||
setProperty("pandaStatus", pandaStatus);
|
||||
setProperty("pandaStatus", QVariant::fromValue(pandaStatus));
|
||||
}
|
||||
|
||||
void Sidebar::paintEvent(QPaintEvent *event) {
|
||||
@@ -103,6 +89,8 @@ void Sidebar::paintEvent(QPaintEvent *event) {
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
p.fillRect(rect(), QColor(57, 57, 57));
|
||||
|
||||
// static imgs
|
||||
p.setOpacity(0.65);
|
||||
p.drawImage(settings_btn.x(), settings_btn.y(), settings_img);
|
||||
@@ -124,7 +112,7 @@ void Sidebar::paintEvent(QPaintEvent *event) {
|
||||
p.drawText(r, Qt::AlignCenter, net_type);
|
||||
|
||||
// metrics
|
||||
drawMetric(p, "TEMP", QString("%1°C").arg(temp_val), temp_status, 338);
|
||||
drawMetric(p, panda_str, "", panda_status, 518);
|
||||
drawMetric(p, connect_str, "", connect_status, 676);
|
||||
drawMetric(p, "TEMP", temp_status.first, temp_status.second, 338);
|
||||
drawMetric(p, panda_status.first, "", panda_status.second, 518);
|
||||
drawMetric(p, connect_status.first, "", connect_status.second, 676);
|
||||
}
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
#include "selfdrive/common/params.h"
|
||||
#include "selfdrive/ui/ui.h"
|
||||
|
||||
typedef QPair<QString, QColor> ItemStatus;
|
||||
Q_DECLARE_METATYPE(ItemStatus);
|
||||
|
||||
class Sidebar : public QFrame {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString connectStr MEMBER connect_str NOTIFY valueChanged);
|
||||
Q_PROPERTY(QColor connectStatus MEMBER connect_status NOTIFY valueChanged);
|
||||
Q_PROPERTY(QString pandaStr MEMBER panda_str NOTIFY valueChanged);
|
||||
Q_PROPERTY(QColor pandaStatus MEMBER panda_status NOTIFY valueChanged);
|
||||
Q_PROPERTY(int tempVal MEMBER temp_val NOTIFY valueChanged);
|
||||
Q_PROPERTY(QColor tempStatus MEMBER temp_status NOTIFY valueChanged);
|
||||
Q_PROPERTY(ItemStatus connectStatus MEMBER connect_status NOTIFY valueChanged);
|
||||
Q_PROPERTY(ItemStatus pandaStatus MEMBER panda_status NOTIFY valueChanged);
|
||||
Q_PROPERTY(ItemStatus tempStatus MEMBER temp_status NOTIFY valueChanged);
|
||||
Q_PROPERTY(QString netType MEMBER net_type NOTIFY valueChanged);
|
||||
Q_PROPERTY(int netStrength MEMBER net_strength NOTIFY valueChanged);
|
||||
|
||||
@@ -30,8 +30,6 @@ public slots:
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
void drawMetric(QPainter &p, const QString &label, const QString &val, QColor c, int y);
|
||||
|
||||
QImage home_img, settings_img;
|
||||
@@ -51,12 +49,7 @@ private:
|
||||
const QColor danger_color = QColor(201, 34, 49);
|
||||
|
||||
Params params;
|
||||
QString connect_str = "OFFLINE";
|
||||
QColor connect_status = warning_color;
|
||||
QString panda_str = "NO\nPANDA";
|
||||
QColor panda_status = warning_color;
|
||||
int temp_val = 0;
|
||||
QColor temp_status = warning_color;
|
||||
ItemStatus connect_status, panda_status, temp_status;
|
||||
QString net_type;
|
||||
int net_strength = 0;
|
||||
};
|
||||
|
||||
@@ -15,20 +15,24 @@
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
|
||||
TrackWidget::TrackWidget(QWidget *parent) : QWidget(parent) {
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
setFixedSize(spinner_size);
|
||||
setAutoFillBackground(true);
|
||||
setPalette(Qt::black);
|
||||
|
||||
// pre-compute all the track imgs. make this a gif instead?
|
||||
QPixmap comma_img = QPixmap("../assets/img_spinner_comma.png").scaled(spinner_size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
QTransform transform(1, 0, 0, 1, width() / 2, height() / 2);
|
||||
QPixmap track_img = QPixmap("../assets/img_spinner_track.png").scaled(spinner_size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
for (QPixmap &img : track_imgs) {
|
||||
img = comma_img;
|
||||
QPainter p(&img);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
|
||||
QTransform transform(1, 0, 0, 1, width() / 2, height() / 2);
|
||||
QPixmap pm(spinner_size);
|
||||
QPainter p(&pm);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
for (int i = 0; i < track_imgs.size(); ++i) {
|
||||
p.resetTransform();
|
||||
p.fillRect(0, 0, spinner_size.width(), spinner_size.height(), Qt::black);
|
||||
p.drawPixmap(0, 0, comma_img);
|
||||
p.setTransform(transform.rotate(360 / spinner_fps));
|
||||
p.drawPixmap(-width() / 2, -height() / 2, track_img);
|
||||
track_imgs[i] = pm.copy();
|
||||
}
|
||||
|
||||
m_anim.setDuration(1000);
|
||||
|
||||
+16
-6
@@ -16,6 +16,16 @@ QString getBrandVersion() {
|
||||
return getBrand() + " v" + QString::fromStdString(Params().get("Version")).left(14).trimmed();
|
||||
}
|
||||
|
||||
std::optional<QString> getDongleId() {
|
||||
std::string id = Params().get("DongleId");
|
||||
|
||||
if (!id.empty() && (id != "UnregisteredDevice")) {
|
||||
return QString::fromStdString(id);
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
void configFont(QPainter &p, const QString &family, int size, const QString &style) {
|
||||
QFont f(family);
|
||||
f.setPixelSize(size);
|
||||
@@ -95,12 +105,12 @@ void ClickableWidget::paintEvent(QPaintEvent *) {
|
||||
|
||||
void swagLogMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
|
||||
static std::map<QtMsgType, int> levels = {
|
||||
{QtMsgType::QtDebugMsg, 10},
|
||||
{QtMsgType::QtInfoMsg, 20},
|
||||
{QtMsgType::QtWarningMsg, 30},
|
||||
{QtMsgType::QtCriticalMsg, 40},
|
||||
{QtMsgType::QtSystemMsg, 40},
|
||||
{QtMsgType::QtFatalMsg, 50},
|
||||
{QtMsgType::QtDebugMsg, CLOUDLOG_DEBUG},
|
||||
{QtMsgType::QtInfoMsg, CLOUDLOG_INFO},
|
||||
{QtMsgType::QtWarningMsg, CLOUDLOG_WARNING},
|
||||
{QtMsgType::QtCriticalMsg, CLOUDLOG_ERROR},
|
||||
{QtMsgType::QtSystemMsg, CLOUDLOG_ERROR},
|
||||
{QtMsgType::QtFatalMsg, CLOUDLOG_CRITICAL},
|
||||
};
|
||||
|
||||
std::string file, function;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QLayout>
|
||||
#include <QMouseEvent>
|
||||
@@ -9,6 +11,7 @@
|
||||
|
||||
QString getBrand();
|
||||
QString getBrandVersion();
|
||||
std::optional<QString> getDongleId();
|
||||
void configFont(QPainter &p, const QString &family, int size, const QString &style);
|
||||
void clearLayout(QLayout* layout);
|
||||
void setQtSurfaceFormat();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "selfdrive/common/params.h"
|
||||
#include "selfdrive/ui/qt/request_repeater.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
|
||||
const double MILE_TO_KM = 1.60934;
|
||||
|
||||
@@ -46,10 +47,9 @@ DriveStats::DriveStats(QWidget* parent) : QFrame(parent) {
|
||||
main_layout->addStretch();
|
||||
add_stats_layouts("PAST WEEK", week_);
|
||||
|
||||
std::string dongle_id = Params().get("DongleId");
|
||||
if (util::is_valid_dongle_id(dongle_id)) {
|
||||
std::string url = "https://api.commadotai.com/v1.1/devices/" + dongle_id + "/stats";
|
||||
RequestRepeater* repeater = new RequestRepeater(this, QString::fromStdString(url), "ApiCache_DriveStats", 30);
|
||||
if (auto dongleId = getDongleId()) {
|
||||
QString url = CommaApi::BASE_URL + "/v1.1/devices/" + *dongleId + "/stats";
|
||||
RequestRepeater* repeater = new RequestRepeater(this, url, "ApiCache_DriveStats", 30);
|
||||
QObject::connect(repeater, &RequestRepeater::receivedResponse, this, &DriveStats::parseResponse);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <QrCode.hpp>
|
||||
|
||||
#include "selfdrive/ui/qt/request_repeater.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
|
||||
using qrcodegen::QrCode;
|
||||
|
||||
@@ -109,10 +110,9 @@ PrimeUserWidget::PrimeUserWidget(QWidget* parent) : QWidget(parent) {
|
||||
mainLayout->addStretch();
|
||||
|
||||
// set up API requests
|
||||
std::string dongleId = Params().get("DongleId");
|
||||
if (util::is_valid_dongle_id(dongleId)) {
|
||||
std::string url = "https://api.commadotai.com/v1/devices/" + dongleId + "/owner";
|
||||
RequestRepeater *repeater = new RequestRepeater(this, QString::fromStdString(url), "ApiCache_Owner", 6);
|
||||
if (auto dongleId = getDongleId()) {
|
||||
QString url = CommaApi::BASE_URL + "/v1/devices/" + *dongleId + "/owner";
|
||||
RequestRepeater *repeater = new RequestRepeater(this, url, "ApiCache_Owner", 6);
|
||||
QObject::connect(repeater, &RequestRepeater::receivedResponse, this, &PrimeUserWidget::replyFinished);
|
||||
}
|
||||
}
|
||||
@@ -255,10 +255,9 @@ SetupWidget::SetupWidget(QWidget* parent) : QFrame(parent) {
|
||||
setSizePolicy(sp_retain);
|
||||
|
||||
// set up API requests
|
||||
std::string dongleId = Params().get("DongleId");
|
||||
if (util::is_valid_dongle_id(dongleId)) {
|
||||
std::string url = "https://api.commadotai.com/v1.1/devices/" + dongleId + "/";
|
||||
RequestRepeater* repeater = new RequestRepeater(this, QString::fromStdString(url), "ApiCache_Device", 5);
|
||||
if (auto dongleId = getDongleId()) {
|
||||
QString url = CommaApi::BASE_URL + "/v1.1/devices/" + *dongleId + "/";
|
||||
RequestRepeater* repeater = new RequestRepeater(this, url, "ApiCache_Device", 5);
|
||||
|
||||
QObject::connect(repeater, &RequestRepeater::receivedResponse, this, &SetupWidget::replyFinished);
|
||||
QObject::connect(repeater, &RequestRepeater::failedResponse, this, &SetupWidget::parseError);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
cd "$(dirname "$0")"
|
||||
export LD_LIBRARY_PATH="/system/lib64:$LD_LIBRARY_PATH"
|
||||
exec ./_soundd
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/sh
|
||||
cd "$(dirname "$0")"
|
||||
export LD_LIBRARY_PATH="/system/lib64:$LD_LIBRARY_PATH"
|
||||
export QT_PLUGIN_PATH="../../phonelibs/qt-plugins/$(uname -m)"
|
||||
exec ./_ui
|
||||
|
||||
+36
-29
@@ -63,13 +63,13 @@ static int get_path_length_idx(const cereal::ModelDataV2::XYZTData::Reader &line
|
||||
return max_idx;
|
||||
}
|
||||
|
||||
static void update_leads(UIState *s, const cereal::RadarState::Reader &radar_state, std::optional<cereal::ModelDataV2::XYZTData::Reader> line) {
|
||||
static void update_leads(UIState *s, const cereal::ModelDataV2::Reader &model) {
|
||||
auto leads = model.getLeadsV3();
|
||||
auto model_position = model.getPosition();
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
auto lead_data = (i == 0) ? radar_state.getLeadOne() : radar_state.getLeadTwo();
|
||||
if (lead_data.getStatus()) {
|
||||
float z = line ? (*line).getZ()[get_path_length_idx(*line, lead_data.getDRel())] : 0.0;
|
||||
// negative because radarState uses left positive convention
|
||||
calib_frame_to_full_frame(s, lead_data.getDRel(), -lead_data.getYRel(), z + 1.22, &s->scene.lead_vertices[i]);
|
||||
if (leads[i].getProb() > 0.5) {
|
||||
float z = model_position.getZ()[get_path_length_idx(model_position, leads[i].getX()[0])];
|
||||
calib_frame_to_full_frame(s, leads[i].getX()[0], leads[i].getY()[0], z + 1.22, &s->scene.lead_vertices[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,9 +112,9 @@ static void update_model(UIState *s, const cereal::ModelDataV2::Reader &model) {
|
||||
}
|
||||
|
||||
// update path
|
||||
auto lead_one = (*s->sm)["radarState"].getRadarState().getLeadOne();
|
||||
if (lead_one.getStatus()) {
|
||||
const float lead_d = lead_one.getDRel() * 2.;
|
||||
auto lead_one = model.getLeadsV3()[0];
|
||||
if (lead_one.getProb() > 0.5) {
|
||||
const float lead_d = lead_one.getX()[0] * 2.;
|
||||
max_distance = std::clamp((float)(lead_d - fmin(lead_d * 0.35, 10.)), 0.0f, max_distance);
|
||||
}
|
||||
max_idx = get_path_length_idx(model_position, max_distance);
|
||||
@@ -134,12 +134,10 @@ static void update_state(UIState *s) {
|
||||
scene.engageable = sm["controlsState"].getControlsState().getEngageable();
|
||||
scene.dm_active = sm["driverMonitoringState"].getDriverMonitoringState().getIsActiveMode();
|
||||
}
|
||||
if (sm.updated("radarState") && s->vg) {
|
||||
std::optional<cereal::ModelDataV2::XYZTData::Reader> line;
|
||||
if (sm.rcv_frame("modelV2") > 0) {
|
||||
line = sm["modelV2"].getModelV2().getPosition();
|
||||
}
|
||||
update_leads(s, sm["radarState"].getRadarState(), line);
|
||||
if (sm.updated("modelV2") && s->vg) {
|
||||
auto model = sm["modelV2"].getModelV2();
|
||||
update_model(s, model);
|
||||
update_leads(s, model);
|
||||
}
|
||||
if (sm.updated("liveCalibration")) {
|
||||
scene.world_objects_visible = true;
|
||||
@@ -158,9 +156,6 @@ static void update_state(UIState *s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sm.updated("modelV2") && s->vg) {
|
||||
update_model(s, sm["modelV2"].getModelV2());
|
||||
}
|
||||
if (sm.updated("pandaState")) {
|
||||
auto pandaState = sm["pandaState"].getPandaState();
|
||||
scene.pandaType = pandaState.getPandaType();
|
||||
@@ -189,15 +184,17 @@ static void update_state(UIState *s) {
|
||||
if (sm.updated("roadCameraState")) {
|
||||
auto camera_state = sm["roadCameraState"].getRoadCameraState();
|
||||
|
||||
float max_lines = Hardware::EON() ? 5408 : 1757;
|
||||
float gain = camera_state.getGain();
|
||||
float max_lines = Hardware::EON() ? 5408 : 1904;
|
||||
float max_gain = Hardware::EON() ? 1.0: 10.0;
|
||||
float max_ev = max_lines * max_gain;
|
||||
|
||||
if (Hardware::TICI()) {
|
||||
// Max gain is 4 * 2.5 (High Conversion Gain)
|
||||
gain /= 10.0;
|
||||
if (Hardware::TICI) {
|
||||
max_ev /= 6;
|
||||
}
|
||||
|
||||
scene.light_sensor = std::clamp<float>((1023.0 / max_lines) * (max_lines - camera_state.getIntegLines() * gain), 0.0, 1023.0);
|
||||
float ev = camera_state.getGain() * float(camera_state.getIntegLines());
|
||||
|
||||
scene.light_sensor = std::clamp<float>(1.0 - (ev / max_ev), 0.0, 1.0);
|
||||
}
|
||||
scene.started = sm["deviceState"].getDeviceState().getStarted() && scene.ignition;
|
||||
}
|
||||
@@ -273,7 +270,7 @@ static void update_status(UIState *s) {
|
||||
|
||||
QUIState::QUIState(QObject *parent) : QObject(parent) {
|
||||
ui_state.sm = std::make_unique<SubMaster, const std::initializer_list<const char *>>({
|
||||
"modelV2", "controlsState", "liveCalibration", "radarState", "deviceState", "roadCameraState",
|
||||
"modelV2", "controlsState", "liveCalibration", "deviceState", "roadCameraState",
|
||||
"pandaState", "carParams", "driverMonitoringState", "sensorEvents", "carState", "liveLocationKalman",
|
||||
});
|
||||
|
||||
@@ -305,7 +302,7 @@ void QUIState::update() {
|
||||
started_prev = ui_state.scene.started;
|
||||
emit offroadTransition(!ui_state.scene.started);
|
||||
|
||||
// Change timeout to 0 when onroad, this will call update continously.
|
||||
// Change timeout to 0 when onroad, this will call update continuously.
|
||||
// This puts visionIPC in charge of update frequency, reducing video latency
|
||||
timer->start(ui_state.scene.started ? 0 : 1000 / UI_FREQ);
|
||||
}
|
||||
@@ -339,9 +336,19 @@ void Device::setAwake(bool on, bool reset) {
|
||||
}
|
||||
|
||||
void Device::updateBrightness(const UIState &s) {
|
||||
float brightness_b = 10;
|
||||
float brightness_m = 0.1;
|
||||
float clipped_brightness = std::min(100.0f, (s.scene.light_sensor * brightness_m) + brightness_b);
|
||||
// Scale to 0% to 100%
|
||||
float clipped_brightness = 100.0 * s.scene.light_sensor;
|
||||
|
||||
// CIE 1931 - https://www.photonstophotos.net/GeneralTopics/Exposure/Psychometric_Lightness_and_Gamma.htm
|
||||
if (clipped_brightness <= 8) {
|
||||
clipped_brightness = (clipped_brightness / 903.3);
|
||||
} else {
|
||||
clipped_brightness = std::pow((clipped_brightness + 16.0) / 116.0, 3.0);
|
||||
}
|
||||
|
||||
// Scale back to 10% to 100%
|
||||
clipped_brightness = std::clamp(100.0f * clipped_brightness, 10.0f, 100.0f);
|
||||
|
||||
if (!s.scene.started) {
|
||||
clipped_brightness = BACKLIGHT_OFFROAD;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user