diff --git a/selfdrive/athena/athenad.py b/selfdrive/athena/athenad.py index 28ddbb1998..1659b692c4 100755 --- a/selfdrive/athena/athenad.py +++ b/selfdrive/athena/athenad.py @@ -25,7 +25,7 @@ from common.api import Api from common.basedir import PERSIST from common.params import Params from common.realtime import sec_since_boot -from selfdrive.hardware import HARDWARE, PC +from selfdrive.hardware import HARDWARE, PC, TICI from selfdrive.loggerd.config import ROOT from selfdrive.loggerd.xattr_cache import getxattr, setxattr from selfdrive.swaglog import cloudlog, SWAGLOG_DIR @@ -450,6 +450,21 @@ def backoff(retries): return random.randrange(0, min(128, int(2 ** retries))) +def manage_tokens(api): + if not TICI: + return + + try: + params = Params() + mapbox = api.get(f"/v1/tokens/mapbox/{api.dongle_id}/", timeout=5.0, access_token=api.get_token()) + if mapbox.status_code == 200: + params.put("MapboxToken", mapbox.json()["token"]) + else: + params.delete("MapboxToken") + except Exception: + cloudlog.exception("Failed to update tokens") + + def main(): params = Params() dongle_id = params.get("DongleId", encoding='utf-8') @@ -465,8 +480,11 @@ def main(): cookie="jwt=" + api.get_token(), enable_multithread=True, timeout=1.0) - cloudlog.event("athenad.main.connected_ws", ws_uri=ws_uri) ws.settimeout(1) + cloudlog.event("athenad.main.connected_ws", ws_uri=ws_uri) + + manage_tokens(api) + conn_retries = 0 handle_long_poll(ws) except (KeyboardInterrupt, SystemExit): diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc index c9d12db199..bdda7f91b7 100644 --- a/selfdrive/ui/qt/home.cc +++ b/selfdrive/ui/qt/home.cc @@ -31,7 +31,7 @@ HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) { slayout->addWidget(onroad); QObject::connect(this, &HomeWindow::update, onroad, &OnroadWindow::update); - QObject::connect(this, &HomeWindow::offroadTransitionSignal, onroad, &OnroadWindow::offroadTransition); + QObject::connect(this, &HomeWindow::offroadTransitionSignal, onroad, &OnroadWindow::offroadTransitionSignal); home = new OffroadHome(); slayout->addWidget(home); @@ -50,9 +50,6 @@ void HomeWindow::offroadTransition(bool offroad) { if (offroad) { slayout->setCurrentWidget(home); } else { - if (onroad->map != nullptr){ - onroad->map->setVisible(!Params().get("NavDestination").empty()); - } slayout->setCurrentWidget(onroad); } sidebar->setVisible(offroad); @@ -72,6 +69,8 @@ void HomeWindow::showDriverView(bool show) { void HomeWindow::mousePressEvent(QMouseEvent* e) { // Handle sidebar collapsing if (onroad->isVisible() && (!sidebar->isVisible() || e->x() > sidebar->width())) { + + // TODO: Handle this without exposing pointer to map widget // Hide map first if visible, then hide sidebar if (onroad->map != nullptr && onroad->map->isVisible()){ onroad->map->setVisible(false); diff --git a/selfdrive/ui/qt/maps/map.cc b/selfdrive/ui/qt/maps/map.cc index bdbca570d1..9456e0e7ee 100644 --- a/selfdrive/ui/qt/maps/map.cc +++ b/selfdrive/ui/qt/maps/map.cc @@ -31,6 +31,10 @@ MapWindow::MapWindow(const QMapboxGLSettings &settings) : m_settings(settings) { timer = new QTimer(this); QObject::connect(timer, SIGNAL(timeout()), this, SLOT(timerUpdate())); + recompute_timer = new QTimer(this); + recompute_timer->start(1000); + QObject::connect(recompute_timer, SIGNAL(timeout()), this, SLOT(recomputeRoute())); + // Instructions map_instructions = new MapInstructions(this); connect(this, SIGNAL(instructionsChanged(QMap)), @@ -153,18 +157,6 @@ void MapWindow::timerUpdate() { } } - // Recompute route if needed - if (sm->frame % 10 == 0) { - if (recompute_countdown == 0 && shouldRecompute()) { - recompute_countdown = std::pow(2, recompute_backoff); - recompute_backoff = std::min(7, recompute_backoff + 1); - calculateRoute(nav_destination); - } else { - recompute_countdown = std::max(0, recompute_countdown - 1); - } - } - - // Show route instructions if (segment.isValid()) { auto cur_maneuver = segment.maneuver(); @@ -244,7 +236,36 @@ void MapWindow::paintGL() { } +void MapWindow::recomputeRoute() { + bool should_recompute = shouldRecompute(); + auto new_destination = coordinate_from_param("NavDestination"); + + if (!new_destination) { + clearRoute(); + return; + } + + if (*new_destination != nav_destination){ + setVisible(true); // Show map on destination set/change + should_recompute = true; + } + + if (!gps_ok && segment.isValid()) return; // Don't recompute when gps drifts in tunnels + + // Only do API request when map is loaded + if (!m_map.isNull()) { + if (recompute_countdown == 0 && should_recompute) { + recompute_countdown = std::pow(2, recompute_backoff); + recompute_backoff = std::min(7, recompute_backoff + 1); + calculateRoute(*new_destination); + } else { + recompute_countdown = std::max(0, recompute_countdown - 1); + } + } +} + void MapWindow::calculateRoute(QMapbox::Coordinate destination) { + nav_destination = destination; QGeoRouteRequest request(to_QGeoCoordinate(last_position), to_QGeoCoordinate(destination)); request.setFeatureWeight(QGeoRouteRequest::TrafficFeature, QGeoRouteRequest::AvoidFeatureWeight); routing_manager->calculateRoute(request); @@ -269,27 +290,17 @@ void MapWindow::routeCalculated(QGeoRouteReply *reply) { } void MapWindow::clearRoute() { - segment = QGeoRouteSegment(); // Clear route - m_map->setLayoutProperty("navLayer", "visibility", "none"); - m_map->setPitch(MIN_PITCH); -} - + segment = QGeoRouteSegment(); + nav_destination = QMapbox::Coordinate(); -bool MapWindow::shouldRecompute(){ - auto new_destination = coordinate_from_param("NavDestination"); - if (!new_destination) { - clearRoute(); - return false; + if (!m_map.isNull()) { + m_map->setLayoutProperty("navLayer", "visibility", "none"); + m_map->setPitch(MIN_PITCH); } +} - if (!gps_ok && segment.isValid()) return false; // Don't recompute when gps drifts in tunnels - - if (*new_destination != nav_destination){ - nav_destination = *new_destination; - setVisible(true); // Show map on destination set/change - return true; - } +bool MapWindow::shouldRecompute(){ if (!segment.isValid()){ return true; } @@ -301,6 +312,9 @@ bool MapWindow::shouldRecompute(){ for (size_t i = 0; i < path.size() - 1; i++){ auto a = path[i]; auto b = path[i+1]; + if (a.distanceTo(b) < 1.0) { + continue; + } min_d = std::min(min_d, minimum_distance(a, b, cur)); } return min_d > REROUTE_DISTANCE; @@ -364,6 +378,13 @@ void MapWindow::pinchTriggered(QPinchGesture *gesture) { } } +void MapWindow::offroadTransition(bool offroad) { + if (!offroad) { + auto dest = coordinate_from_param("NavDestination"); + setVisible(dest.has_value()); + } +} + MapInstructions::MapInstructions(QWidget * parent) : QWidget(parent){ QHBoxLayout *layout_outer = new QHBoxLayout; layout_outer->setContentsMargins(11, 50, 11, 11); diff --git a/selfdrive/ui/qt/maps/map.h b/selfdrive/ui/qt/maps/map.h index 1d80ff5b52..a7fe527b57 100644 --- a/selfdrive/ui/qt/maps/map.h +++ b/selfdrive/ui/qt/maps/map.h @@ -68,6 +68,7 @@ private: double last_maneuver_distance = 1000; // Route recompute + QTimer* recompute_timer; int recompute_backoff = 0; int recompute_countdown = 0; void calculateRoute(QMapbox::Coordinate destination); @@ -77,6 +78,10 @@ private: private slots: void timerUpdate(); void routeCalculated(QGeoRouteReply *reply); + void recomputeRoute(); + +public slots: + void offroadTransition(bool offroad); signals: void distanceChanged(float distance); diff --git a/selfdrive/ui/qt/onroad.cc b/selfdrive/ui/qt/onroad.cc index 1404379088..e26aff7bc9 100644 --- a/selfdrive/ui/qt/onroad.cc +++ b/selfdrive/ui/qt/onroad.cc @@ -19,22 +19,11 @@ OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent) { nvg = new NvgWindow(this); QObject::connect(this, &OnroadWindow::update, nvg, &NvgWindow::update); - QHBoxLayout* split = new QHBoxLayout(); + split = new QHBoxLayout(); split->setContentsMargins(0, 0, 0, 0); split->setSpacing(0); split->addWidget(nvg); -#ifdef ENABLE_MAPS - QString token = QString::fromStdString(Params().get("MapboxToken")); - if (!token.isEmpty()){ - QMapboxGLSettings settings; - settings.setCacheDatabasePath("/tmp/mbgl-cache.db"); - settings.setCacheDatabaseMaximumSize(20 * 1024 * 1024); - settings.setAccessToken(token.trimmed()); - map = new MapWindow(settings); - split->addWidget(map); - } -#endif QWidget * split_wrapper = new QWidget; split_wrapper->setLayout(split); @@ -43,7 +32,8 @@ OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent) { alerts = new OnroadAlerts(this); alerts->setAttribute(Qt::WA_TransparentForMouseEvents, true); QObject::connect(this, &OnroadWindow::update, alerts, &OnroadAlerts::updateState); - QObject::connect(this, &OnroadWindow::offroadTransition, alerts, &OnroadAlerts::offroadTransition); + QObject::connect(this, &OnroadWindow::offroadTransitionSignal, alerts, &OnroadAlerts::offroadTransition); + QObject::connect(this, &OnroadWindow::offroadTransitionSignal, this, &OnroadWindow::offroadTransition); layout->addWidget(alerts); // setup stacking order @@ -53,6 +43,28 @@ OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent) { setAttribute(Qt::WA_OpaquePaintEvent); } + +void OnroadWindow::offroadTransition(bool offroad) { +#ifdef ENABLE_MAPS + if (!offroad) { + QString token = QString::fromStdString(Params().get("MapboxToken")); + if (map == nullptr && !token.isEmpty()){ + QMapboxGLSettings settings; + settings.setCacheDatabasePath("/data/mbgl-cache.db"); + settings.setCacheDatabaseMaximumSize(20 * 1024 * 1024); + settings.setAccessToken(token.trimmed()); + + MapWindow * m = new MapWindow(settings); + QObject::connect(this, &OnroadWindow::offroadTransitionSignal, m, &MapWindow::offroadTransition); + split->addWidget(m); + + map = m; + } + + } +#endif +} + // ***** onroad widgets ***** OnroadAlerts::OnroadAlerts(QWidget *parent) : QWidget(parent) { diff --git a/selfdrive/ui/qt/onroad.h b/selfdrive/ui/qt/onroad.h index 776030a61a..c3baf01033 100644 --- a/selfdrive/ui/qt/onroad.h +++ b/selfdrive/ui/qt/onroad.h @@ -87,8 +87,12 @@ private: OnroadAlerts *alerts; NvgWindow *nvg; QStackedLayout *layout; + QHBoxLayout* split; signals: void update(const UIState &s); + void offroadTransitionSignal(bool offroad); + +private slots: void offroadTransition(bool offroad); };