From 02ed9c584c7d04d53d3c0f0955e95ab2a58de5de Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 16 Jun 2024 12:20:15 -0700 Subject: [PATCH 01/36] sim: remove docker script --- tools/sim/start_openpilot_docker.sh | 37 ----------------------------- 1 file changed, 37 deletions(-) delete mode 100755 tools/sim/start_openpilot_docker.sh diff --git a/tools/sim/start_openpilot_docker.sh b/tools/sim/start_openpilot_docker.sh deleted file mode 100755 index 3dce6605795750..00000000000000 --- a/tools/sim/start_openpilot_docker.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" -cd $DIR - -OPENPILOT_DIR="/tmp/openpilot" -if ! [[ -z "$MOUNT_OPENPILOT" ]]; then - OPENPILOT_DIR="$(dirname $(dirname $DIR))" - EXTRA_ARGS="-v $OPENPILOT_DIR:$OPENPILOT_DIR -e PYTHONPATH=$OPENPILOT_DIR:$PYTHONPATH" -fi - -if [[ "$CI" ]]; then - CMD="CI=1 ${OPENPILOT_DIR}/tools/sim/tests/test_metadrive_integration.py" -else - # expose X to the container - xhost +local:root - - docker pull ghcr.io/commaai/openpilot-sim:latest - CMD="./tmux_script.sh $*" - EXTRA_ARGS="${EXTRA_ARGS} -it" -fi - -docker kill openpilot_client || true -docker run --net=host\ - --name openpilot_client \ - --rm \ - --gpus all \ - --device=/dev/dri:/dev/dri \ - --device=/dev/input:/dev/input \ - -v /tmp/.X11-unix:/tmp/.X11-unix \ - --shm-size 1G \ - -e DISPLAY=$DISPLAY \ - -e QT_X11_NO_MITSHM=1 \ - -w "$OPENPILOT_DIR/tools/sim" \ - $EXTRA_ARGS \ - ghcr.io/commaai/openpilot-sim:latest \ - /bin/bash -c "$CMD" From 865b98a5c45335dcdf736ab38e89b5a1dcde2d59 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Mon, 17 Jun 2024 03:32:45 +0800 Subject: [PATCH 02/36] cabana: avoid dead locks and improve responsiveness (#32740) avoid dead locks and improve responsive --- tools/cabana/chart/chart.cc | 2 +- tools/cabana/chart/chartswidget.cc | 24 ++++--- tools/cabana/chart/chartswidget.h | 16 ++--- tools/cabana/mainwin.cc | 1 - tools/cabana/streams/abstractstream.cc | 22 ++++++- tools/cabana/streams/abstractstream.h | 8 ++- tools/cabana/streams/replaystream.cc | 7 +- tools/cabana/streams/replaystream.h | 3 - tools/cabana/videowidget.cc | 23 ++++--- tools/cabana/videowidget.h | 8 +-- tools/replay/camera.cc | 1 - tools/replay/logreader.cc | 6 +- tools/replay/replay.cc | 88 +++++++++++++++----------- tools/replay/replay.h | 11 ++-- tools/replay/util.cc | 36 ++++------- tools/replay/util.h | 2 +- 16 files changed, 135 insertions(+), 123 deletions(-) diff --git a/tools/cabana/chart/chart.cc b/tools/cabana/chart/chart.cc index c8537845b164ff..7a056c7674527b 100644 --- a/tools/cabana/chart/chart.cc +++ b/tools/cabana/chart/chart.cc @@ -513,7 +513,7 @@ void ChartView::mouseReleaseEvent(QMouseEvent *event) { // no rubber dragged, seek to mouse position can->seekTo(min); } else if (rubber->width() > 10 && (max - min) > MIN_ZOOM_SECONDS) { - charts_widget->zoom_undo_stack->push(new ZoomCommand(charts_widget, {min, max})); + charts_widget->zoom_undo_stack->push(new ZoomCommand({min, max})); } else { viewport()->update(); } diff --git a/tools/cabana/chart/chartswidget.cc b/tools/cabana/chart/chartswidget.cc index a7bdd746465ec9..59c188afbcdad8 100644 --- a/tools/cabana/chart/chartswidget.cc +++ b/tools/cabana/chart/chartswidget.cc @@ -103,6 +103,8 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QFrame(parent) { QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &ChartsWidget::removeAll); QObject::connect(can, &AbstractStream::eventsMerged, this, &ChartsWidget::eventsMerged); QObject::connect(can, &AbstractStream::msgsReceived, this, &ChartsWidget::updateState); + QObject::connect(can, &AbstractStream::seeking, this, &ChartsWidget::updateState); + QObject::connect(can, &AbstractStream::timeRangeChanged, this, &ChartsWidget::timeRangeChanged); QObject::connect(range_slider, &QSlider::valueChanged, this, &ChartsWidget::setMaxChartRange); QObject::connect(new_plot_btn, &QToolButton::clicked, this, &ChartsWidget::newChart); QObject::connect(remove_all_btn, &QToolButton::clicked, this, &ChartsWidget::removeAll); @@ -159,16 +161,13 @@ void ChartsWidget::eventsMerged(const MessageEventsMap &new_events) { } } -void ChartsWidget::setZoom(double min, double max) { - zoomed_range = {min, max}; - is_zoomed = zoomed_range != display_range; +void ChartsWidget::timeRangeChanged(const std::optional> &time_range) { updateToolBar(); updateState(); - emit rangeChanged(min, max, is_zoomed); } void ChartsWidget::zoomReset() { - setZoom(display_range.first, display_range.second); + can->setTimeRange(std::nullopt); zoom_undo_stack->clear(); } @@ -186,8 +185,9 @@ void ChartsWidget::showValueTip(double sec) { void ChartsWidget::updateState() { if (charts.isEmpty()) return; + const auto &time_range = can->timeRange(); const double cur_sec = can->currentSec(); - if (!is_zoomed) { + if (!time_range.has_value()) { double pos = (cur_sec - display_range.first) / std::max(1.0, max_chart_range); if (pos < 0 || pos > 0.8) { display_range.first = std::max(0.0, cur_sec - max_chart_range * 0.1); @@ -195,13 +195,9 @@ void ChartsWidget::updateState() { double max_sec = std::min(display_range.first + max_chart_range, can->totalSeconds()); display_range.first = std::max(0.0, max_sec - max_chart_range); display_range.second = display_range.first + max_chart_range; - } else if (cur_sec < (zoomed_range.first - 0.1) || cur_sec >= zoomed_range.second) { - // loop in zoomed range - QTimer::singleShot(0, [ts = zoomed_range.first]() { can->seekTo(ts);}); - return; } - const auto &range = is_zoomed ? zoomed_range : display_range; + const auto &range = time_range ? *time_range : display_range; for (auto c : charts) { c->updatePlot(cur_sec, range.first, range.second); } @@ -217,12 +213,14 @@ void ChartsWidget::updateToolBar() { title_label->setText(tr("Charts: %1").arg(charts.size())); columns_action->setText(tr("Column: %1").arg(column_count)); range_lb->setText(utils::formatSeconds(max_chart_range)); + + bool is_zoomed = can->timeRange().has_value(); range_lb_action->setVisible(!is_zoomed); range_slider_action->setVisible(!is_zoomed); undo_zoom_action->setVisible(is_zoomed); redo_zoom_action->setVisible(is_zoomed); reset_zoom_action->setVisible(is_zoomed); - reset_zoom_btn->setText(is_zoomed ? tr("%1-%2").arg(zoomed_range.first, 0, 'f', 2).arg(zoomed_range.second, 0, 'f', 2) : ""); + reset_zoom_btn->setText(is_zoomed ? tr("%1-%2").arg(can->timeRange()->first, 0, 'f', 2).arg(can->timeRange()->second, 0, 'f', 2) : ""); remove_all_btn->setEnabled(!charts.isEmpty()); dock_btn->setIcon(docking ? "arrow-up-right-square" : "arrow-down-left-square"); dock_btn->setToolTip(docking ? tr("Undock charts") : tr("Dock charts")); @@ -252,7 +250,7 @@ ChartView *ChartsWidget::findChart(const MessageId &id, const cabana::Signal *si } ChartView *ChartsWidget::createChart() { - auto chart = new ChartView(is_zoomed ? zoomed_range : display_range, this); + auto chart = new ChartView(can->timeRange().value_or(display_range), this); chart->setFixedHeight(settings.chart_height); chart->setMinimumWidth(CHART_MIN_WIDTH); chart->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); diff --git a/tools/cabana/chart/chartswidget.h b/tools/cabana/chart/chartswidget.h index a39b4d73a59bf6..a9ac05db23ec29 100644 --- a/tools/cabana/chart/chartswidget.h +++ b/tools/cabana/chart/chartswidget.h @@ -46,11 +46,10 @@ class ChartsWidget : public QFrame { public slots: void setColumnCount(int n); void removeAll(); - void setZoom(double min, double max); + void timeRangeChanged(const std::optional> &time_range); signals: void dock(bool floating); - void rangeChanged(double min, double max, bool is_zommed); void seriesChanged(); private: @@ -102,9 +101,7 @@ public slots: ChartsContainer *charts_container; QScrollArea *charts_scroll; uint32_t max_chart_range = 0; - bool is_zoomed = false; std::pair display_range; - std::pair zoomed_range; QAction *columns_action; int column_count = 1; int current_column_count = 0; @@ -119,12 +116,11 @@ public slots: class ZoomCommand : public QUndoCommand { public: - ZoomCommand(ChartsWidget *charts, std::pair range) : charts(charts), range(range), QUndoCommand() { - prev_range = charts->is_zoomed ? charts->zoomed_range : charts->display_range; + ZoomCommand(std::pair range) : range(range), QUndoCommand() { + prev_range = can->timeRange(); setText(QObject::tr("Zoom to %1-%2").arg(range.first, 0, 'f', 2).arg(range.second, 0, 'f', 2)); } - void undo() override { charts->setZoom(prev_range.first, prev_range.second); } - void redo() override { charts->setZoom(range.first, range.second); } - ChartsWidget *charts; - std::pair prev_range, range; + void undo() override { can->setTimeRange(prev_range); } + void redo() override { can->setTimeRange(range); } + std::optional> prev_range, range; }; diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index e6c9b49ca17a0c..d099fcec9955b3 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -192,7 +192,6 @@ void MainWindow::createDockWidgets() { video_splitter = new QSplitter(Qt::Vertical, this); video_widget = new VideoWidget(this); video_splitter->addWidget(video_widget); - QObject::connect(charts_widget, &ChartsWidget::rangeChanged, video_widget, &VideoWidget::updateTimeRange); video_splitter->addWidget(charts_container); video_splitter->setStretchFactor(1, 1); diff --git a/tools/cabana/streams/abstractstream.cc b/tools/cabana/streams/abstractstream.cc index 2e6ca9662e237a..2584106ce4848b 100644 --- a/tools/cabana/streams/abstractstream.cc +++ b/tools/cabana/streams/abstractstream.cc @@ -92,13 +92,23 @@ void AbstractStream::updateLastMessages() { std::set msgs; { std::lock_guard lk(mutex_); + double max_sec = 0; for (const auto &id : new_msgs_) { const auto &can_data = messages_[id]; - current_sec_ = std::max(current_sec_, can_data.ts); + max_sec = std::max(max_sec, can_data.ts); last_msgs[id] = can_data; sources.insert(id.source); } - msgs = std::move(new_msgs_); + + if (!new_msgs_.empty()) { + msgs = std::move(new_msgs_); + current_sec_ = max_sec; + } + } + + if (time_range_ && (current_sec_ < time_range_->first || current_sec_ >= time_range_->second)) { + seekTo(time_range_->first); + return; } if (sources.size() != prev_src_size) { @@ -108,6 +118,14 @@ void AbstractStream::updateLastMessages() { emit msgsReceived(&msgs, prev_msg_size != last_msgs.size()); } +void AbstractStream::setTimeRange(const std::optional> &range) { + time_range_ = range; + if (time_range_ && (current_sec_ < time_range_->first || current_sec_ >= time_range_->second)) { + seekTo(time_range_->first); + } + emit timeRangeChanged(time_range_); +} + void AbstractStream::updateEvent(const MessageId &id, double sec, const uint8_t *data, uint8_t size) { std::lock_guard lk(mutex_); messages_[id].compute(id, data, size, sec, getSpeed(), masks_[id]); diff --git a/tools/cabana/streams/abstractstream.h b/tools/cabana/streams/abstractstream.h index cfd423b36819fe..822dd03d8478b3 100644 --- a/tools/cabana/streams/abstractstream.h +++ b/tools/cabana/streams/abstractstream.h @@ -3,8 +3,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -77,6 +79,8 @@ class AbstractStream : public QObject { virtual double getSpeed() { return 1; } virtual bool isPaused() const { return false; } virtual void pause(bool pause) {} + void setTimeRange(const std::optional> &range); + const std::optional> &timeRange() const { return time_range_; } inline const std::unordered_map &lastMessages() const { return last_msgs; } inline const MessageEventsMap &eventsMap() const { return events_; } @@ -91,8 +95,9 @@ class AbstractStream : public QObject { signals: void paused(); void resume(); - void seekingTo(double sec); + void seeking(double sec); void seekedTo(double sec); + void timeRangeChanged(const std::optional> &range); void streamStarted(); void eventsMerged(const MessageEventsMap &events_map); void msgsReceived(const std::set *new_msgs, bool has_new_ids); @@ -110,6 +115,7 @@ class AbstractStream : public QObject { std::vector all_events_; double current_sec_ = 0; + std::optional> time_range_; uint64_t lastest_event_ts = 0; private: diff --git a/tools/cabana/streams/replaystream.cc b/tools/cabana/streams/replaystream.cc index 5fda6b04870f6c..5d4925a67ac84e 100644 --- a/tools/cabana/streams/replaystream.cc +++ b/tools/cabana/streams/replaystream.cc @@ -53,9 +53,9 @@ bool ReplayStream::loadRoute(const QString &route, const QString &data_dir, uint {}, nullptr, replay_flags, data_dir, this)); replay->setSegmentCacheLimit(settings.max_cached_minutes); replay->installEventFilter(event_filter, this); + QObject::connect(replay.get(), &Replay::seeking, this, &AbstractStream::seeking); QObject::connect(replay.get(), &Replay::seekedTo, this, &AbstractStream::seekedTo); QObject::connect(replay.get(), &Replay::segmentsMerged, this, &ReplayStream::mergeSegments); - QObject::connect(replay.get(), &Replay::qLogLoaded, this, &ReplayStream::qLogLoaded, Qt::QueuedConnection); return replay->load(); } @@ -92,12 +92,7 @@ bool ReplayStream::eventFilter(const Event *event) { } void ReplayStream::seekTo(double ts) { - // Update timestamp and notify receivers of the time change. current_sec_ = ts; - std::set new_msgs; - msgsReceived(&new_msgs, false); - - // Seek to the specified timestamp replay->seekTo(std::max(double(0), ts), false); } diff --git a/tools/cabana/streams/replaystream.h b/tools/cabana/streams/replaystream.h index 049ccddafb7756..ced78680d1e155 100644 --- a/tools/cabana/streams/replaystream.h +++ b/tools/cabana/streams/replaystream.h @@ -34,9 +34,6 @@ class ReplayStream : public AbstractStream { void pause(bool pause) override; static AbstractOpenStreamWidget *widget(AbstractStream **stream); -signals: - void qLogLoaded(int segnum, std::shared_ptr qlog); - private: void mergeSegments(); std::unique_ptr replay = nullptr; diff --git a/tools/cabana/videowidget.cc b/tools/cabana/videowidget.cc index 7fca45c3936dea..d2f78babc19060 100644 --- a/tools/cabana/videowidget.cc +++ b/tools/cabana/videowidget.cc @@ -38,6 +38,8 @@ VideoWidget::VideoWidget(QWidget *parent) : QFrame(parent) { QObject::connect(can, &AbstractStream::paused, this, &VideoWidget::updatePlayBtnState); QObject::connect(can, &AbstractStream::resume, this, &VideoWidget::updatePlayBtnState); QObject::connect(can, &AbstractStream::msgsReceived, this, &VideoWidget::updateState); + QObject::connect(can, &AbstractStream::seeking, this, &VideoWidget::updateState); + QObject::connect(can, &AbstractStream::timeRangeChanged, this, &VideoWidget::timeRangeChanged); updatePlayBtnState(); setWhatsThis(tr(R"( @@ -150,14 +152,16 @@ QWidget *VideoWidget::createCameraWidget() { setMaximumTime(can->totalSeconds()); QObject::connect(slider, &QSlider::sliderReleased, [this]() { can->seekTo(slider->currentSecond()); }); - QObject::connect(slider, &Slider::updateMaximumTime, this, &VideoWidget::setMaximumTime, Qt::QueuedConnection); QObject::connect(can, &AbstractStream::eventsMerged, this, [this]() { slider->update(); }); - QObject::connect(static_cast(can), &ReplayStream::qLogLoaded, slider, &Slider::parseQLog); QObject::connect(cam_widget, &CameraWidget::clicked, []() { can->pause(!can->isPaused()); }); QObject::connect(cam_widget, &CameraWidget::vipcAvailableStreamsUpdated, this, &VideoWidget::vipcAvailableStreamsUpdated); QObject::connect(camera_tab, &QTabBar::currentChanged, [this](int index) { if (index != -1) cam_widget->setStreamType((VisionStreamType)camera_tab->tabData(index).toInt()); }); + + auto replay = static_cast(can)->getReplay(); + QObject::connect(replay, &Replay::qLogLoaded, slider, &Slider::parseQLog, Qt::QueuedConnection); + QObject::connect(replay, &Replay::totalSecondsUpdated, this, &VideoWidget::setMaximumTime, Qt::QueuedConnection); return w; } @@ -198,13 +202,13 @@ void VideoWidget::setMaximumTime(double sec) { slider->setTimeRange(0, sec); } -void VideoWidget::updateTimeRange(double min, double max, bool is_zoomed) { +void VideoWidget::timeRangeChanged(const std::optional> &time_range) { if (can->liveStreaming()) { - skip_to_end_btn->setEnabled(!is_zoomed); + skip_to_end_btn->setEnabled(!time_range.has_value()); return; } - is_zoomed ? slider->setTimeRange(min, max) - : slider->setTimeRange(0, maximum_time); + time_range ? slider->setTimeRange(time_range->first, time_range->second) + : slider->setTimeRange(0, maximum_time); } QString VideoWidget::formatTime(double sec, bool include_milliseconds) { @@ -255,12 +259,7 @@ void Slider::setTimeRange(double min, double max) { setRange(min * factor, max * factor); } -void Slider::parseQLog(int segnum, std::shared_ptr qlog) { - const auto &segments = qobject_cast(can)->route()->segments(); - if (segments.size() > 0 && segnum == segments.rbegin()->first && !qlog->events.empty()) { - emit updateMaximumTime(qlog->events.back().mono_time / 1e9 - can->routeStartTime()); - } - +void Slider::parseQLog(std::shared_ptr qlog) { std::mutex mutex; QtConcurrent::blockingMap(qlog->events.cbegin(), qlog->events.cend(), [&mutex, this](const Event &e) { if (e.which == cereal::Event::Which::THUMBNAIL) { diff --git a/tools/cabana/videowidget.h b/tools/cabana/videowidget.h index b2039e09a46324..7bd55cbce4103d 100644 --- a/tools/cabana/videowidget.h +++ b/tools/cabana/videowidget.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -40,13 +41,10 @@ class Slider : public QSlider { void setTimeRange(double min, double max); AlertInfo alertInfo(double sec); QPixmap thumbnail(double sec); - void parseQLog(int segnum, std::shared_ptr qlog); + void parseQLog(std::shared_ptr qlog); const double factor = 1000.0; -signals: - void updateMaximumTime(double); - private: void mousePressEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override; @@ -63,11 +61,11 @@ class VideoWidget : public QFrame { public: VideoWidget(QWidget *parnet = nullptr); - void updateTimeRange(double min, double max, bool is_zommed); void setMaximumTime(double sec); protected: QString formatTime(double sec, bool include_milliseconds = false); + void timeRangeChanged(const std::optional> &time_range); void updateState(); void updatePlayBtnState(); QWidget *createCameraWidget(); diff --git a/tools/replay/camera.cc b/tools/replay/camera.cc index 9e711149c5eff4..b6d4ddc3a29c90 100644 --- a/tools/replay/camera.cc +++ b/tools/replay/camera.cc @@ -60,7 +60,6 @@ void CameraServer::cameraThread(Camera &cam) { capnp::FlatArrayMessageReader reader(event->data); auto evt = reader.getRoot(); auto eidx = capnp::AnyStruct::Reader(evt).getPointerSection()[0].getAs(); - if (eidx.getType() != cereal::EncodeIndex::Type::FULL_H_E_V_C) continue; int segment_id = eidx.getSegmentId(); uint32_t frame_id = eidx.getFrameId(); diff --git a/tools/replay/logreader.cc b/tools/replay/logreader.cc index 0f1638145fd424..9b726e067d8515 100644 --- a/tools/replay/logreader.cc +++ b/tools/replay/logreader.cc @@ -42,10 +42,10 @@ bool LogReader::load(const char *data, size_t size, std::atomic *abort) { evt.which == cereal::Event::DRIVER_ENCODE_IDX || evt.which == cereal::Event::WIDE_ROAD_ENCODE_IDX) { auto idx = capnp::AnyStruct::Reader(event).getPointerSection()[0].getAs(); - if (uint64_t sof = idx.getTimestampSof()) { - mono_time = sof; + if (idx.getType() == cereal::EncodeIndex::Type::FULL_H_E_V_C) { + uint64_t sof = idx.getTimestampSof(); + events.emplace_back(which, sof ? sof : mono_time, event_data, idx.getSegmentNum()); } - events.emplace_back(which, mono_time, event_data, idx.getSegmentNum()); } } } catch (const kj::Exception &e) { diff --git a/tools/replay/replay.cc b/tools/replay/replay.cc index 8616437188afa0..c5ad2aa5488b9b 100644 --- a/tools/replay/replay.cc +++ b/tools/replay/replay.cc @@ -55,11 +55,11 @@ void Replay::stop() { rInfo("shutdown: in progress..."); if (stream_thread_ != nullptr) { exit_ = true; - paused_ = true; + pauseStreamThread(); stream_cv_.notify_one(); stream_thread_->quit(); stream_thread_->wait(); - delete stream_thread_; + stream_thread_->deleteLater(); stream_thread_ = nullptr; } timeline_future.waitForFinished(); @@ -104,28 +104,40 @@ void Replay::updateEvents(const std::function &update_events_function) { void Replay::seekTo(double seconds, bool relative) { updateEvents([&]() { - seeking_to_seconds_ = relative ? seconds + currentSeconds() : seconds; - seeking_to_seconds_ = std::max(double(0.0), seeking_to_seconds_); - int target_segment = (int)seeking_to_seconds_ / 60; + double target_time = relative ? seconds + currentSeconds() : seconds; + target_time = std::max(double(0.0), target_time); + int target_segment = (int)target_time / 60; if (segments_.count(target_segment) == 0) { - rWarning("can't seek to %d s segment %d is invalid", (int)seeking_to_seconds_, target_segment); + rWarning("Can't seek to %d s segment %d is invalid", (int)target_time, target_segment); return true; } - rInfo("seeking to %d s, segment %d", (int)seeking_to_seconds_, target_segment); + rInfo("Seeking to %d s, segment %d", (int)target_time, target_segment); current_segment_ = target_segment; - cur_mono_time_ = route_start_ts_ + seeking_to_seconds_ * 1e9; - bool segment_merged = isSegmentMerged(target_segment); - if (segment_merged) { - emit seekedTo(seeking_to_seconds_); - // Reset seeking_to_seconds_ to indicate completion of seek - seeking_to_seconds_ = -1; - } - return segment_merged; + cur_mono_time_ = route_start_ts_ + target_time * 1e9; + seeking_to_ = target_time; + return false; }); + + checkSeekProgress(); updateSegmentsCache(); } +void Replay::checkSeekProgress() { + if (seeking_to_) { + auto it = segments_.find(int(*seeking_to_ / 60)); + if (it != segments_.end() && it->second && it->second->isLoaded()) { + emit seekedTo(*seeking_to_); + seeking_to_ = std::nullopt; + // wake up stream thread + updateEvents([]() { return true; }); + } else { + // Emit signal indicating the ongoing seek operation + emit seeking(*seeking_to_); + } + } +} + void Replay::seekToFlag(FindFlag flag) { if (auto next = find(flag)) { seekTo(*next - 2, false); // seek to 2 seconds before next @@ -150,8 +162,9 @@ void Replay::buildTimeline() { const auto &route_segments = route_->segments(); for (auto it = route_segments.cbegin(); it != route_segments.cend() && !exit_; ++it) { std::shared_ptr log(new LogReader()); - if (!log->load(it->second.qlog.toStdString(), &exit_, !hasFlag(REPLAY_FLAG_NO_FILE_CACHE), 0, 3)) continue; + if (!log->load(it->second.qlog.toStdString(), &exit_, !hasFlag(REPLAY_FLAG_NO_FILE_CACHE), 0, 3) || log->events.empty()) continue; + std::vector> timeline; for (const Event &e : log->events) { if (e.which == cereal::Event::Which::CONTROLS_STATE) { capnp::FlatArrayMessageReader reader(e.data); @@ -160,7 +173,6 @@ void Replay::buildTimeline() { if (engaged != cs.getEnabled()) { if (engaged) { - std::lock_guard lk(timeline_lock); timeline.push_back({toSeconds(engaged_begin), toSeconds(e.mono_time), TimelineType::Engaged}); } engaged_begin = e.mono_time; @@ -169,7 +181,6 @@ void Replay::buildTimeline() { if (alert_type != cs.getAlertType().cStr() || alert_status != cs.getAlertStatus()) { if (!alert_type.empty() && alert_size != cereal::ControlsState::AlertSize::NONE) { - std::lock_guard lk(timeline_lock); timeline.push_back({toSeconds(alert_begin), toSeconds(e.mono_time), timeline_types[(int)alert_status]}); } alert_begin = e.mono_time; @@ -178,12 +189,20 @@ void Replay::buildTimeline() { alert_status = cs.getAlertStatus(); } } else if (e.which == cereal::Event::Which::USER_FLAG) { - std::lock_guard lk(timeline_lock); timeline.push_back({toSeconds(e.mono_time), toSeconds(e.mono_time), TimelineType::UserFlag}); } } - std::sort(timeline.begin(), timeline.end(), [](auto &l, auto &r) { return std::get<2>(l) < std::get<2>(r); }); - emit qLogLoaded(it->first, log); + + { + std::lock_guard lk(timeline_lock); + timeline_.insert(timeline_.end(), timeline.begin(), timeline.end()); + std::sort(timeline_.begin(), timeline_.end(), [](auto &l, auto &r) { return std::get<2>(l) < std::get<2>(r); }); + } + + if (it->first == route_segments.rbegin()->first) { + emit totalSecondsUpdated(toSeconds(log->events.back().mono_time)); + } + emit qLogLoaded(log); } } @@ -260,14 +279,13 @@ void Replay::updateSegmentsCache() { const auto &cur_segment = cur->second; if (stream_thread_ == nullptr && cur_segment->isLoaded()) { startStream(cur_segment.get()); - emit streamStarted(); } } void Replay::loadSegmentInRange(SegmentMap::iterator begin, SegmentMap::iterator cur, SegmentMap::iterator end) { - auto loadNext = [this](auto begin, auto end) { - auto it = std::find_if(begin, end, [](const auto &seg_it) { return !seg_it.second || !seg_it.second->isLoaded(); }); - if (it != end && !it->second) { + auto loadNextSegment = [this](auto first, auto last) { + auto it = std::find_if(first, last, [](const auto &seg_it) { return !seg_it.second || !seg_it.second->isLoaded(); }); + if (it != last && !it->second) { rDebug("loading segment %d...", it->first); it->second = std::make_unique(it->first, route_->at(it->first), flags_, filters_); QObject::connect(it->second.get(), &Segment::loadFinished, this, &Replay::segmentLoadFinished); @@ -276,9 +294,9 @@ void Replay::loadSegmentInRange(SegmentMap::iterator begin, SegmentMap::iterator return false; }; - // Load forward segments, then try reverse - if (!loadNext(cur, end)) { - loadNext(std::make_reverse_iterator(cur), segments_.rend()); + // Try loading forward segments, then reverse segments + if (!loadNextSegment(cur, end)) { + loadNextSegment(std::make_reverse_iterator(cur), std::make_reverse_iterator(begin)); } } @@ -316,15 +334,10 @@ void Replay::mergeSegments(const SegmentMap::iterator &begin, const SegmentMap:: updateEvents([&]() { events_.swap(new_events); merged_segments_ = segments_to_merge; - // Check if seeking is in progress - int target_segment = int(seeking_to_seconds_ / 60); - if (seeking_to_seconds_ >= 0 && segments_to_merge.count(target_segment) > 0) { - emit seekedTo(seeking_to_seconds_); - seeking_to_seconds_ = -1; // Reset seeking_to_seconds_ to indicate completion of seek - } // Wake up the stream thread if the current segment is loaded or invalid. - return isSegmentMerged(current_segment_) || (segments_.count(current_segment_) == 0); + return !seeking_to_ && (isSegmentMerged(current_segment_) || (segments_.count(current_segment_) == 0)); }); + checkSeekProgress(); } void Replay::startStream(const Segment *cur_segment) { @@ -379,6 +392,7 @@ void Replay::startStream(const Segment *cur_segment) { stream_thread_->start(); timeline_future = QtConcurrent::run(this, &Replay::buildTimeline); + emit streamStarted(); } void Replay::publishMessage(const Event *e) { @@ -473,6 +487,7 @@ std::vector::const_iterator Replay::publishEvents(std::vector::con // Skip events if socket is not present if (!sockets_[evt.which]) continue; + cur_mono_time_ = evt.mono_time; const uint64_t current_nanos = nanos_since_boot(); const int64_t time_diff = (evt.mono_time - evt_start_ts) / speed_ - (current_nanos - loop_start_ts); @@ -484,12 +499,11 @@ std::vector::const_iterator Replay::publishEvents(std::vector::con loop_start_ts = current_nanos; prev_replay_speed = speed_; } else if (time_diff > 0) { - precise_nano_sleep(time_diff); + precise_nano_sleep(time_diff, paused_); } if (paused_) break; - cur_mono_time_ = evt.mono_time; if (evt.eidx_segnum == -1) { publishMessage(&evt); } else if (camera_server_) { diff --git a/tools/replay/replay.h b/tools/replay/replay.h index 4adbc14df8558d..8b51ab054d06db 100644 --- a/tools/replay/replay.h +++ b/tools/replay/replay.h @@ -85,14 +85,16 @@ class Replay : public QObject { inline const std::string &carFingerprint() const { return car_fingerprint_; } inline const std::vector> getTimeline() { std::lock_guard lk(timeline_lock); - return timeline; + return timeline_; } signals: void streamStarted(); void segmentsMerged(); + void seeking(double sec); void seekedTo(double sec); - void qLogLoaded(int segnum, std::shared_ptr qlog); + void qLogLoaded(std::shared_ptr qlog); + void totalSecondsUpdated(double sec); protected slots: void segmentLoadFinished(bool success); @@ -112,6 +114,7 @@ protected slots: void publishMessage(const Event *e); void publishFrame(const Event *e); void buildTimeline(); + void checkSeekProgress(); inline bool isSegmentMerged(int n) const { return merged_segments_.count(n) > 0; } pthread_t stream_thread_id = 0; @@ -120,7 +123,7 @@ protected slots: bool user_paused_ = false; std::condition_variable stream_cv_; std::atomic current_segment_ = 0; - double seeking_to_seconds_ = -1; + std::optional seeking_to_; SegmentMap segments_; // the following variables must be protected with stream_lock_ std::atomic exit_ = false; @@ -143,7 +146,7 @@ protected slots: std::mutex timeline_lock; QFuture timeline_future; - std::vector> timeline; + std::vector> timeline_; std::string car_fingerprint_; std::atomic speed_ = 1.0; replayEventFilter event_filter = nullptr; diff --git a/tools/replay/util.cc b/tools/replay/util.cc index c8203fd79d815a..a08b3b3d5eab72 100644 --- a/tools/replay/util.cc +++ b/tools/replay/util.cc @@ -318,33 +318,23 @@ std::string decompressBZ2(const std::byte *in, size_t in_size, std::atomic return {}; } -void precise_nano_sleep(int64_t nanoseconds) { -#ifdef __APPLE__ - const long estimate_ns = 1 * 1e6; // 1ms - struct timespec req = {.tv_nsec = estimate_ns}; - uint64_t start_sleep = nanos_since_boot(); - while (nanoseconds > estimate_ns) { - nanosleep(&req, nullptr); - uint64_t end_sleep = nanos_since_boot(); - nanoseconds -= (end_sleep - start_sleep); - start_sleep = end_sleep; - } - // spin wait - if (nanoseconds > 0) { - while ((nanos_since_boot() - start_sleep) <= nanoseconds) { - std::this_thread::yield(); - } - } -#else +void precise_nano_sleep(int64_t nanoseconds, std::atomic &should_exit) { struct timespec req, rem; - - req.tv_sec = nanoseconds / 1e9; - req.tv_nsec = nanoseconds % (int64_t)1e9; - while (clock_nanosleep(CLOCK_MONOTONIC, 0, &req, &rem) && errno == EINTR) { + req.tv_sec = nanoseconds / 1000000000; + req.tv_nsec = nanoseconds % 1000000000; + while (!should_exit) { +#ifdef __APPLE_ + int ret = nanosleep(&req, &rem); + if (ret == 0 || errno != EINTR) + break; +#else + int ret = clock_nanosleep(CLOCK_MONOTONIC, 0, &req, &rem); + if (ret == 0 || ret != EINTR) + break; +#endif // Retry sleep if interrupted by a signal req = rem; } -#endif } std::string sha256(const std::string &str) { diff --git a/tools/replay/util.h b/tools/replay/util.h index 750c13355520aa..97516e18147600 100644 --- a/tools/replay/util.h +++ b/tools/replay/util.h @@ -37,7 +37,7 @@ class MonotonicBuffer { }; std::string sha256(const std::string &str); -void precise_nano_sleep(int64_t nanoseconds); +void precise_nano_sleep(int64_t nanoseconds, std::atomic &should_exit); std::string decompressBZ2(const std::string &in, std::atomic *abort = nullptr); std::string decompressBZ2(const std::byte *in, size_t in_size, std::atomic *abort = nullptr); std::string getUrlWithoutQuery(const std::string &url); From b99fe718ecfbc6044cb5fa53f34e077b9d9a2a4f Mon Sep 17 00:00:00 2001 From: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Mon, 17 Jun 2024 09:26:22 -0700 Subject: [PATCH 03/36] [bot] Update Python packages and pre-commit hooks (#32770) Update Python packages and pre-commit hooks Co-authored-by: Vehicle Researcher --- .pre-commit-config.yaml | 4 +-- poetry.lock | 56 ++++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 61b78236449c37..d47630cdad8019 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,7 +33,7 @@ repos: - -L bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup,bumb,nd,sie,preints,whit,indexIn - --builtins clear,rare,informal,usage,code,names,en-GB_to_en-US - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.8 + rev: v0.4.9 hooks: - id: ruff exclude: '^(third_party/)|(msgq/)|(panda/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(teleoprtc/)|(teleoprtc_repo/)' @@ -98,6 +98,6 @@ repos: args: - --lock - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.28.4 + rev: 0.28.5 hooks: - id: check-github-workflows diff --git a/poetry.lock b/poetry.lock index 2467d6be2d78af..13d082763cc7df 100644 --- a/poetry.lock +++ b/poetry.lock @@ -7219,28 +7219,28 @@ docs = ["furo (==2024.4.27)", "pyenchant (==3.2.2)", "sphinx (==7.1.2)", "sphinx [[package]] name = "ruff" -version = "0.4.8" +version = "0.4.9" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7663a6d78f6adb0eab270fa9cf1ff2d28618ca3a652b60f2a234d92b9ec89066"}, - {file = "ruff-0.4.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eeceb78da8afb6de0ddada93112869852d04f1cd0f6b80fe464fd4e35c330913"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aad360893e92486662ef3be0a339c5ca3c1b109e0134fcd37d534d4be9fb8de3"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:284c2e3f3396fb05f5f803c9fffb53ebbe09a3ebe7dda2929ed8d73ded736deb"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7354f921e3fbe04d2a62d46707e569f9315e1a613307f7311a935743c51a764"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:72584676164e15a68a15778fd1b17c28a519e7a0622161eb2debdcdabdc71883"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9678d5c9b43315f323af2233a04d747409d1e3aa6789620083a82d1066a35199"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704977a658131651a22b5ebeb28b717ef42ac6ee3b11e91dc87b633b5d83142b"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d05f8d6f0c3cce5026cecd83b7a143dcad503045857bc49662f736437380ad45"}, - {file = "ruff-0.4.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6ea874950daca5697309d976c9afba830d3bf0ed66887481d6bca1673fc5b66a"}, - {file = "ruff-0.4.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fc95aac2943ddf360376be9aa3107c8cf9640083940a8c5bd824be692d2216dc"}, - {file = "ruff-0.4.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:384154a1c3f4bf537bac69f33720957ee49ac8d484bfc91720cc94172026ceed"}, - {file = "ruff-0.4.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e9d5ce97cacc99878aa0d084c626a15cd21e6b3d53fd6f9112b7fc485918e1fa"}, - {file = "ruff-0.4.8-py3-none-win32.whl", hash = "sha256:6d795d7639212c2dfd01991259460101c22aabf420d9b943f153ab9d9706e6a9"}, - {file = "ruff-0.4.8-py3-none-win_amd64.whl", hash = "sha256:e14a3a095d07560a9d6769a72f781d73259655919d9b396c650fc98a8157555d"}, - {file = "ruff-0.4.8-py3-none-win_arm64.whl", hash = "sha256:14019a06dbe29b608f6b7cbcec300e3170a8d86efaddb7b23405cb7f7dcaf780"}, - {file = "ruff-0.4.8.tar.gz", hash = "sha256:16d717b1d57b2e2fd68bd0bf80fb43931b79d05a7131aa477d66fc40fbd86268"}, + {file = "ruff-0.4.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b262ed08d036ebe162123170b35703aaf9daffecb698cd367a8d585157732991"}, + {file = "ruff-0.4.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:98ec2775fd2d856dc405635e5ee4ff177920f2141b8e2d9eb5bd6efd50e80317"}, + {file = "ruff-0.4.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4555056049d46d8a381f746680db1c46e67ac3b00d714606304077682832998e"}, + {file = "ruff-0.4.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e91175fbe48f8a2174c9aad70438fe9cb0a5732c4159b2a10a3565fea2d94cde"}, + {file = "ruff-0.4.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e8e7b95673f22e0efd3571fb5b0cf71a5eaaa3cc8a776584f3b2cc878e46bff"}, + {file = "ruff-0.4.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2d45ddc6d82e1190ea737341326ecbc9a61447ba331b0a8962869fcada758505"}, + {file = "ruff-0.4.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:78de3fdb95c4af084087628132336772b1c5044f6e710739d440fc0bccf4d321"}, + {file = "ruff-0.4.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:06b60f91bfa5514bb689b500a25ba48e897d18fea14dce14b48a0c40d1635893"}, + {file = "ruff-0.4.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88bffe9c6a454bf8529f9ab9091c99490578a593cc9f9822b7fc065ee0712a06"}, + {file = "ruff-0.4.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:673bddb893f21ab47a8334c8e0ea7fd6598ecc8e698da75bcd12a7b9d0a3206e"}, + {file = "ruff-0.4.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8c1aff58c31948cc66d0b22951aa19edb5af0a3af40c936340cd32a8b1ab7438"}, + {file = "ruff-0.4.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:784d3ec9bd6493c3b720a0b76f741e6c2d7d44f6b2be87f5eef1ae8cc1d54c84"}, + {file = "ruff-0.4.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:732dd550bfa5d85af8c3c6cbc47ba5b67c6aed8a89e2f011b908fc88f87649db"}, + {file = "ruff-0.4.9-py3-none-win32.whl", hash = "sha256:8064590fd1a50dcf4909c268b0e7c2498253273309ad3d97e4a752bb9df4f521"}, + {file = "ruff-0.4.9-py3-none-win_amd64.whl", hash = "sha256:e0a22c4157e53d006530c902107c7f550b9233e9706313ab57b892d7197d8e52"}, + {file = "ruff-0.4.9-py3-none-win_arm64.whl", hash = "sha256:5d5460f789ccf4efd43f265a58538a2c24dbce15dbf560676e430375f20a8198"}, + {file = "ruff-0.4.9.tar.gz", hash = "sha256:f1cb0828ac9533ba0135d148d214e284711ede33640465e706772645483427e3"}, ] [[package]] @@ -7727,19 +7727,23 @@ widechars = ["wcwidth"] [[package]] name = "timezonefinder" -version = "6.5.0" +version = "6.5.2" description = "python package for finding the timezone of any point on earth (coordinates) offline" optional = false -python-versions = ">=3.8,<4" +python-versions = "<4,>=3.8" files = [ - {file = "timezonefinder-6.5.0-cp38-cp38-manylinux_2_35_x86_64.whl", hash = "sha256:3c70e1ea468ecac11272aa0a727450fd7cf43039ae2a2c62f7900a0a42efb6d6"}, - {file = "timezonefinder-6.5.0.tar.gz", hash = "sha256:7afdb1516927e7766deb6da80c8bd66734a44ba3d898038fe73aef1e9cd39bb0"}, + {file = "timezonefinder-6.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea7ca91f25d988d69efeae020ed828534ed01f6687646a50e464d82da4704b30"}, + {file = "timezonefinder-6.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4a3bca9933ea165380d54b336227def58e62682968437cd44223a065ecff7e9"}, + {file = "timezonefinder-6.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ac4ef31d379c7ba54710462857bea36a9630ea23550ffb15550322e6988efbd"}, + {file = "timezonefinder-6.5.2-cp38-cp38-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:524ab145a2f4ce5101e52308868ecd9da0cdcc2cb3024c13356616b41a685fd6"}, + {file = "timezonefinder-6.5.2-cp39-cp39-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b93927a4996a5c01f0628eb6858c61b2a7f9f49e02c07bed2a95e96a8dc1b65e"}, + {file = "timezonefinder-6.5.2.tar.gz", hash = "sha256:3279e67d5b1b9a54d1a16f3bd4234169f14e2b90c0f58ed37bcfa7303645d610"}, ] [package.dependencies] cffi = ">=1.15.1,<2" h3 = ">=3.7.6,<4" -numpy = {version = ">=1.23,<2", markers = "python_version >= \"3.9\""} +numpy = {version = ">=1.23,<3", markers = "python_version >= \"3.9\""} setuptools = ">=65.5" [package.extras] @@ -7826,13 +7830,13 @@ files = [ [[package]] name = "urllib3" -version = "2.2.1" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] From a99816a08b3c30b72283a4a7b77415349a539c33 Mon Sep 17 00:00:00 2001 From: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Mon, 17 Jun 2024 09:26:34 -0700 Subject: [PATCH 04/36] [bot] Bump submodules (#32769) bump submodules Co-authored-by: Vehicle Researcher --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index faa18026692f77..7287ff0cbf3ab4 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit faa18026692f7714ee537261fe649dafe4882579 +Subproject commit 7287ff0cbf3ab405a670405f2faca419d524387d From ab96d12f2ee7bc80af3203b732be05a46894a610 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 17 Jun 2024 09:43:36 -0700 Subject: [PATCH 05/36] more fetch depth --- release/check-submodules.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/check-submodules.sh b/release/check-submodules.sh index bff8d7a28fe301..5305cecd3a3889 100755 --- a/release/check-submodules.sh +++ b/release/check-submodules.sh @@ -1,7 +1,7 @@ #!/bin/bash while read hash submodule ref; do - git -C $submodule fetch --depth 2000 origin master + git -C $submodule fetch --depth 3000 origin master git -C $submodule branch -r --contains $hash | grep "origin/master" if [ "$?" -eq 0 ]; then echo "$submodule ok" From 54da59c1feb917896538ce8aa22bf4f12af20824 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Tue, 18 Jun 2024 03:44:31 +0800 Subject: [PATCH 06/36] cabana: improved error messaging (#32768) * check user authenrication * Update tools/cabana/streams/replaystream.cc --------- Co-authored-by: Adeeb Shihadeh --- tools/cabana/streams/replaystream.cc | 27 +++++++++++++++++++++++---- tools/replay/replay.h | 1 + tools/replay/route.cc | 3 +++ tools/replay/route.h | 10 ++++++++++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/tools/cabana/streams/replaystream.cc b/tools/cabana/streams/replaystream.cc index 5d4925a67ac84e..bdb9ebb014f032 100644 --- a/tools/cabana/streams/replaystream.cc +++ b/tools/cabana/streams/replaystream.cc @@ -56,7 +56,28 @@ bool ReplayStream::loadRoute(const QString &route, const QString &data_dir, uint QObject::connect(replay.get(), &Replay::seeking, this, &AbstractStream::seeking); QObject::connect(replay.get(), &Replay::seekedTo, this, &AbstractStream::seekedTo); QObject::connect(replay.get(), &Replay::segmentsMerged, this, &ReplayStream::mergeSegments); - return replay->load(); + bool success = replay->load(); + if (!success) { + if (replay->lastRouteError() == RouteLoadError::AccessDenied) { + auto auth_content = util::read_file(util::getenv("HOME") + "/.comma/auth.json"); + QString message; + if (auth_content.empty()) { + message = "Authentication Required. Please run the following command to authenticate:\n\n" + "python tools/lib/auth.py\n\n" + "This will grant access to routes from your comma account."; + } else { + message = tr("Access Denied. You do not have permission to access route:\n\n%1\n\n" + "This is likely a private route.").arg(route); + } + QMessageBox::warning(nullptr, tr("Access Denied"), message); + } else if (replay->lastRouteError() == RouteLoadError::NetworkError) { + QMessageBox::warning(nullptr, tr("Network Error"), + tr("Unable to load the route:\n\n %1.\n\nPlease check your network connection and try again.").arg(route)); + } else { + QMessageBox::warning(nullptr, tr("Route Load Failed"), tr("Failed to load route: '%1'").arg(route)); + } + } + return success; } void ReplayStream::start() { @@ -144,7 +165,7 @@ OpenReplayWidget::OpenReplayWidget(AbstractStream **stream) : AbstractOpenStream bool OpenReplayWidget::open() { QString route = route_edit->text(); QString data_dir; - if (int idx = route.lastIndexOf('/'); idx != -1) { + if (int idx = route.lastIndexOf('/'); idx != -1 && util::file_exists(route.toStdString())) { data_dir = route.mid(0, idx + 1); route = route.mid(idx + 1); } @@ -161,8 +182,6 @@ bool OpenReplayWidget::open() { if (replay_stream->loadRoute(route, data_dir, flags)) { *stream = replay_stream.release(); - } else { - QMessageBox::warning(nullptr, tr("Warning"), tr("Failed to load route: '%1'").arg(route)); } } return *stream != nullptr; diff --git a/tools/replay/replay.h b/tools/replay/replay.h index 8b51ab054d06db..7e1815ede00a4b 100644 --- a/tools/replay/replay.h +++ b/tools/replay/replay.h @@ -53,6 +53,7 @@ class Replay : public QObject { uint32_t flags = REPLAY_FLAG_NONE, QString data_dir = "", QObject *parent = 0); ~Replay(); bool load(); + RouteLoadError lastRouteError() const { return route_->lastError(); } void start(int seconds = 0); void stop(); void pause(bool pause); diff --git a/tools/replay/route.cc b/tools/replay/route.cc index e8e73459eab4b3..18c962abd5cbfa 100644 --- a/tools/replay/route.cc +++ b/tools/replay/route.cc @@ -74,7 +74,10 @@ bool Route::loadFromServer(int retries) { return loadFromJson(result); } else if (err == QNetworkReply::ContentAccessDenied || err == QNetworkReply::AuthenticationRequiredError) { rWarning(">> Unauthorized. Authenticate with tools/lib/auth.py <<"); + err_ = RouteLoadError::AccessDenied; return false; + } else { + err_ = RouteLoadError::NetworkError; } rWarning("Retrying %d/%d", i, retries); util::sleep_for(3000); diff --git a/tools/replay/route.h b/tools/replay/route.h index f95649780462c7..acc73d509a1f6d 100644 --- a/tools/replay/route.h +++ b/tools/replay/route.h @@ -12,6 +12,14 @@ #include "tools/replay/logreader.h" #include "tools/replay/util.h" +enum class RouteLoadError { + None, + AccessDenied, + NetworkError, + FileNotFound, + UnknownError +}; + struct RouteIdentifier { QString dongle_id; QString timestamp; @@ -33,6 +41,7 @@ class Route { public: Route(const QString &route, const QString &data_dir = {}); bool load(); + RouteLoadError lastError() const { return err_; } inline const QString &name() const { return route_.str; } inline const QDateTime datetime() const { return date_time_; } inline const QString &dir() const { return data_dir_; } @@ -50,6 +59,7 @@ class Route { QString data_dir_; std::map segments_; QDateTime date_time_; + RouteLoadError err_ = RouteLoadError::None; }; class Segment : public QObject { From 3de6ee5ee316980f2dfea5e59c7369ac1f0a83df Mon Sep 17 00:00:00 2001 From: Maxime Desroches Date: Mon, 17 Jun 2024 13:24:04 -0700 Subject: [PATCH 07/36] cabana: include optional (#32772) optional --- tools/cabana/videowidget.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/cabana/videowidget.h b/tools/cabana/videowidget.h index 7bd55cbce4103d..ac34c66007bacf 100644 --- a/tools/cabana/videowidget.h +++ b/tools/cabana/videowidget.h @@ -2,6 +2,7 @@ #include #include +#include #include #include From cb63f101cadec4f2ce4362b3df849a1d2adf9e56 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 17 Jun 2024 19:18:20 -0700 Subject: [PATCH 08/36] Toyota: remove smartDSU support (#32777) --- selfdrive/car/tests/routes.py | 1 - selfdrive/car/toyota/carstate.py | 17 +++----------- selfdrive/car/toyota/interface.py | 37 +++++++++---------------------- selfdrive/car/toyota/values.py | 4 +--- 4 files changed, 14 insertions(+), 45 deletions(-) diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index dd3a8f633d2693..b1156f0e896693 100755 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -225,7 +225,6 @@ class CarTestRoute(NamedTuple): CarTestRoute("cd9cff4b0b26c435|2021-05-13--15-12-39", TOYOTA.TOYOTA_CHR), CarTestRoute("57858ede0369a261|2021-05-18--20-34-20", TOYOTA.TOYOTA_CHR), # hybrid CarTestRoute("ea8fbe72b96a185c|2023-02-08--15-11-46", TOYOTA.TOYOTA_CHR_TSS2), - CarTestRoute("ea8fbe72b96a185c|2023-02-22--09-20-34", TOYOTA.TOYOTA_CHR_TSS2), # openpilot longitudinal, with smartDSU CarTestRoute("6719965b0e1d1737|2023-02-09--22-44-05", TOYOTA.TOYOTA_CHR_TSS2), # hybrid CarTestRoute("6719965b0e1d1737|2023-08-29--06-40-05", TOYOTA.TOYOTA_CHR_TSS2), # hybrid, openpilot longitudinal, radar disabled CarTestRoute("14623aae37e549f3|2021-10-24--01-20-49", TOYOTA.TOYOTA_PRIUS_V), diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index 8315f24ae48d8b..a596881c33d985 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -132,8 +132,7 @@ def update(self, cp, cp_cam): cp_acc = cp_cam if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR) else cp if self.CP.carFingerprint in TSS2_CAR and not self.CP.flags & ToyotaFlags.DISABLE_RADAR.value: - if not (self.CP.flags & ToyotaFlags.SMART_DSU.value): - self.acc_type = cp_acc.vl["ACC_CONTROL"]["ACC_TYPE"] + self.acc_type = cp_acc.vl["ACC_CONTROL"]["ACC_TYPE"] ret.stockFcw = bool(cp_acc.vl["PCS_HUD"]["FCW"]) # some TSS2 cars have low speed lockout permanently set, so ignore on those cars @@ -167,13 +166,11 @@ def update(self, cp, cp_cam): if self.CP.carFingerprint not in UNSUPPORTED_DSU_CAR: self.pcm_follow_distance = cp.vl["PCM_CRUISE_2"]["PCM_FOLLOW_DISTANCE"] - if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR) or (self.CP.flags & ToyotaFlags.SMART_DSU and not self.CP.flags & ToyotaFlags.RADAR_CAN_FILTER): + if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR): # distance button is wired to the ACC module (camera or radar) self.prev_distance_button = self.distance_button if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR): self.distance_button = cp_acc.vl["ACC_CONTROL"]["DISTANCE"] - else: - self.distance_button = cp.vl["SDSU"]["FD_BUTTON"] return ret @@ -208,12 +205,9 @@ def get_can_parser(CP): messages.append(("BSM", 1)) if CP.carFingerprint in RADAR_ACC_CAR and not CP.flags & ToyotaFlags.DISABLE_RADAR.value: - if not CP.flags & ToyotaFlags.SMART_DSU.value: - messages += [ - ("ACC_CONTROL", 33), - ] messages += [ ("PCS_HUD", 1), + ("ACC_CONTROL", 33), ] if CP.carFingerprint not in (TSS2_CAR - RADAR_ACC_CAR) and not CP.enableDsu and not CP.flags & ToyotaFlags.DISABLE_RADAR.value: @@ -221,11 +215,6 @@ def get_can_parser(CP): ("PRE_COLLISION", 33), ] - if CP.flags & ToyotaFlags.SMART_DSU and not CP.flags & ToyotaFlags.RADAR_CAN_FILTER: - messages += [ - ("SDSU", 100), - ] - return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0) @staticmethod diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index 98f63597ec083c..6487257bbc7b1b 100644 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -44,18 +44,9 @@ def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): stop_and_go = candidate in TSS2_CAR - # Detect smartDSU, which intercepts ACC_CMD from the DSU (or radar) allowing openpilot to send it - # 0x2AA is sent by a similar device which intercepts the radar instead of DSU on NO_DSU_CARs - if 0x2FF in fingerprint[0] or (0x2AA in fingerprint[0] and candidate in NO_DSU_CAR): - ret.flags |= ToyotaFlags.SMART_DSU.value - - if 0x2AA in fingerprint[0] and candidate in NO_DSU_CAR: - ret.flags |= ToyotaFlags.RADAR_CAN_FILTER.value - # In TSS2 cars, the camera does long control found_ecus = [fw.ecu for fw in car_fw] - ret.enableDsu = len(found_ecus) > 0 and Ecu.dsu not in found_ecus and candidate not in (NO_DSU_CAR | UNSUPPORTED_DSU_CAR) \ - and not (ret.flags & ToyotaFlags.SMART_DSU) + ret.enableDsu = len(found_ecus) > 0 and Ecu.dsu not in found_ecus and candidate not in (NO_DSU_CAR | UNSUPPORTED_DSU_CAR) if candidate == CAR.TOYOTA_PRIUS: stop_and_go = True @@ -98,7 +89,7 @@ def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): # TODO: these models can do stop and go, but unclear if it requires sDSU or unplugging DSU. # For now, don't list stop and go functionality in the docs if ret.flags & ToyotaFlags.SNG_WITHOUT_DSU: - stop_and_go = stop_and_go or bool(ret.flags & ToyotaFlags.SMART_DSU.value) or (ret.enableDsu and not docs) + stop_and_go = stop_and_go or (ret.enableDsu and not docs) ret.centerToFront = ret.wheelbase * 0.44 @@ -110,28 +101,20 @@ def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): # TODO: make an adas dbc file for dsu-less models ret.radarUnavailable = DBC[candidate]['radar'] is None or candidate in (NO_DSU_CAR - TSS2_CAR) - # if the smartDSU is detected, openpilot can send ACC_CONTROL and the smartDSU will block it from the DSU or radar. # since we don't yet parse radar on TSS2/TSS-P radar-based ACC cars, gate longitudinal behind experimental toggle - use_sdsu = bool(ret.flags & ToyotaFlags.SMART_DSU) if candidate in (RADAR_ACC_CAR | NO_DSU_CAR): - ret.experimentalLongitudinalAvailable = use_sdsu or candidate in RADAR_ACC_CAR + ret.experimentalLongitudinalAvailable = candidate in RADAR_ACC_CAR - if not use_sdsu: - # Disabling radar is only supported on TSS2 radar-ACC cars - if experimental_long and candidate in RADAR_ACC_CAR: - ret.flags |= ToyotaFlags.DISABLE_RADAR.value - else: - use_sdsu = use_sdsu and experimental_long + # Disabling radar is only supported on TSS2 radar-ACC cars + if experimental_long and candidate in RADAR_ACC_CAR: + ret.flags |= ToyotaFlags.DISABLE_RADAR.value # openpilot longitudinal enabled by default: - # - non-(TSS2 radar ACC cars) w/ smartDSU installed # - cars w/ DSU disconnected # - TSS2 cars with camera sending ACC_CONTROL where we can block it # openpilot longitudinal behind experimental long toggle: - # - TSS2 radar ACC cars w/ smartDSU installed - # - TSS2 radar ACC cars w/o smartDSU installed (disables radar) - # - TSS-P DSU-less cars w/ CAN filter installed (no radar parser yet) - ret.openpilotLongitudinalControl = use_sdsu or ret.enableDsu or candidate in (TSS2_CAR - RADAR_ACC_CAR) or bool(ret.flags & ToyotaFlags.DISABLE_RADAR.value) + # - TSS2 radar ACC cars (disables radar) + ret.openpilotLongitudinalControl = ret.enableDsu or candidate in (TSS2_CAR - RADAR_ACC_CAR) or bool(ret.flags & ToyotaFlags.DISABLE_RADAR.value) ret.autoResumeSng = ret.openpilotLongitudinalControl and candidate in NO_STOP_TIMER_CAR if not ret.openpilotLongitudinalControl: @@ -156,7 +139,7 @@ def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): @staticmethod def init(CP, logcan, sendcan): - # disable radar if alpha longitudinal toggled on radar-ACC car without CAN filter/smartDSU + # disable radar if alpha longitudinal toggled on radar-ACC car if CP.flags & ToyotaFlags.DISABLE_RADAR.value: communication_control = bytes([uds.SERVICE_TYPE.COMMUNICATION_CONTROL, uds.CONTROL_TYPE.ENABLE_RX_DISABLE_TX, uds.MESSAGE_TYPE.NORMAL]) disable_ecu(logcan, sendcan, bus=0, addr=0x750, sub_addr=0xf, com_cont_req=communication_control) @@ -165,7 +148,7 @@ def init(CP, logcan, sendcan): def _update(self, c): ret = self.CS.update(self.cp, self.cp_cam) - if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR) or (self.CP.flags & ToyotaFlags.SMART_DSU and not self.CP.flags & ToyotaFlags.RADAR_CAN_FILTER): + if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR): ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) # events diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 2e781ad0aa5827..8022e8b3abdbf7 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -44,9 +44,7 @@ def __init__(self, CP): class ToyotaFlags(IntFlag): # Detected flags HYBRID = 1 - SMART_DSU = 2 DISABLE_RADAR = 4 - RADAR_CAN_FILTER = 1024 # Static flags TSS2 = 8 @@ -56,7 +54,7 @@ class ToyotaFlags(IntFlag): # these cars use the Lane Tracing Assist (LTA) message for lateral control ANGLE_CONTROL = 128 NO_STOP_TIMER = 256 - # these cars are speculated to allow stop and go when the DSU is unplugged or disabled with sDSU + # these cars are speculated to allow stop and go when the DSU is unplugged SNG_WITHOUT_DSU = 512 From 5c4ea14a3cb7bcb443fbee8c5b1d52c10788c9e8 Mon Sep 17 00:00:00 2001 From: Maxime Desroches Date: Mon, 17 Jun 2024 20:30:32 -0700 Subject: [PATCH 09/36] Ubuntu 24.04 (#32624) * noble build * workflow * symlink * map only for noble * sym * add qt to cppcheck * cppcheck noreturn in non void funct * get kaitai header * kaitai header * syntax * try new pyopencl * try this version * install lsb-core manually * support old 20.04 lsb-core * try arm * try latest pyopencl * revert * use pocl icd * no lock * no arm pyopencl * new intel opencl runtime * pin filelock * undo * glsl version * new version * build test * remove test * new metadrive * remove glsl restrictions * * Update .github/workflows/tools_tests.yaml Co-authored-by: Adeeb Shihadeh * cache * new cache --------- Co-authored-by: Adeeb Shihadeh --- .devcontainer/Dockerfile | 4 +- .github/workflows/setup/action.yaml | 2 +- .github/workflows/tools_tests.yaml | 28 ++++++++++++-- .pre-commit-config.yaml | 2 + Dockerfile.openpilot_base | 37 +++++++++++-------- SConstruct | 2 + poetry.lock | 6 +-- pyproject.toml | 2 +- selfdrive/navd/SConscript | 4 +- selfdrive/ui/SConscript | 4 +- selfdrive/ui/qt/maps/map_helpers.cc | 8 ++-- .../x86_64/lib/libQMapLibre.so.3.0.0 | 4 +- tools/README.md | 6 +-- tools/profiling/snapdragon/README.md | 2 +- tools/webcam/README.md | 2 +- 15 files changed, 71 insertions(+), 42 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index af67bdbe5d86d5..1115c375db4647 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,11 +1,11 @@ FROM ghcr.io/commaai/openpilot-base:latest -RUN apt update && apt install -y vim net-tools usbutils htop ripgrep tmux wget mesa-utils xvfb libxtst6 libxv1 libglu1-mesa libegl1-mesa gdb bash-completion +RUN apt update && apt install -y vim net-tools usbutils htop ripgrep tmux wget mesa-utils xvfb libxtst6 libxv1 libglu1-mesa gdb bash-completion RUN pip install ipython jupyter jupyterlab RUN cd /tmp && \ ARCH=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) && \ - curl -L -o virtualgl.deb "https://downloads.sourceforge.net/project/virtualgl/3.1/virtualgl_3.1_$ARCH.deb" && \ + curl -L -o virtualgl.deb "https://github.com/VirtualGL/virtualgl/releases/download/3.1.1/virtualgl_3.1.1_$ARCH.deb" && \ dpkg -i virtualgl.deb RUN usermod -aG video batman diff --git a/.github/workflows/setup/action.yaml b/.github/workflows/setup/action.yaml index 970d62030d56f1..701675942f5f39 100644 --- a/.github/workflows/setup/action.yaml +++ b/.github/workflows/setup/action.yaml @@ -60,4 +60,4 @@ runs: find . -type f -not -executable -not -perm 644 -exec chmod 644 {} \; # build our docker image - shell: bash - run: eval ${{ env.BUILD }} \ No newline at end of file + run: eval ${{ env.BUILD }} diff --git a/.github/workflows/tools_tests.yaml b/.github/workflows/tools_tests.yaml index c2f7d86e694caf..9a26ca9a20936a 100644 --- a/.github/workflows/tools_tests.yaml +++ b/.github/workflows/tools_tests.yaml @@ -39,12 +39,13 @@ jobs: source selfdrive/test/setup_vsound.sh && \ CI=1 pytest tools/sim/tests/test_metadrive_bridge.py" - test_python311: - name: test python3.11 support - runs-on: ubuntu-latest - timeout-minutes: 5 + test_compatibility: + name: test 20.04 + 3.11 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v4 + with: + submodules: true - name: Installing ubuntu dependencies run: INSTALL_EXTRA_PACKAGES=no tools/install_ubuntu_dependencies.sh - name: Installing python @@ -57,6 +58,25 @@ jobs: run: pip install poetry==1.7.0 - name: Installing python dependencies run: poetry install --no-cache --no-root + - name: git LFS + run: git lfs pull + - run: echo "CACHE_COMMIT_DATE=$(git log -1 --pretty='format:%cd' --date=format:'%Y-%m-%d-%H:%M')" >> $GITHUB_ENV + - name: Getting scons cache + uses: 'actions/cache@v4' + with: + path: /tmp/scons_cache + key: scons-${{ runner.arch }}-ubuntu2004-${{ env.CACHE_COMMIT_DATE }}-${{ github.sha }} + restore-keys: | + scons-${{ runner.arch }}-ubuntu2004-${{ env.CACHE_COMMIT_DATE }} + scons-${{ runner.arch }}-ubuntu2004 + - name: Building openpilot + run: poetry run scons -u -j$(nproc) + - name: Saving scons cache + uses: actions/cache/save@v4 + if: github.ref == 'refs/heads/master' + with: + path: /tmp/scons_cache + key: scons-${{ runner.arch }}-ubuntu2004-${{ env.CACHE_COMMIT_DATE }}-${{ github.sha }} devcontainer: name: devcontainer diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d47630cdad8019..ecde9fe7718db2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -62,6 +62,8 @@ repos: - --quiet - --force - -j8 + - --library=qt + - --include=third_party/kaitai/kaitaistream.h - repo: https://github.com/cpplint/cpplint rev: 1.6.1 hooks: diff --git a/Dockerfile.openpilot_base b/Dockerfile.openpilot_base index 45b29bdcb13c6a..7228d16ef93527 100644 --- a/Dockerfile.openpilot_base +++ b/Dockerfile.openpilot_base @@ -1,4 +1,4 @@ -FROM ubuntu:20.04 +FROM ubuntu:24.04 ENV PYTHONUNBUFFERED 1 @@ -15,7 +15,7 @@ ENV LC_ALL en_US.UTF-8 COPY tools/install_ubuntu_dependencies.sh /tmp/tools/ RUN INSTALL_EXTRA_PACKAGES=no /tmp/tools/install_ubuntu_dependencies.sh && \ rm -rf /var/lib/apt/lists/* /tmp/* && \ - cd /usr/lib/gcc/arm-none-eabi/9.2.1 && \ + cd /usr/lib/gcc/arm-none-eabi/* && \ rm -rf arm/ thumb/nofp thumb/v6* thumb/v8* thumb/v7+fp thumb/v7-r+fp.sp # Add OpenCL @@ -30,23 +30,28 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ gcc-arm-none-eabi \ tmux \ vim \ - lsb-core \ libx11-6 \ + wget \ && rm -rf /var/lib/apt/lists/* -ARG INTEL_DRIVER=l_opencl_p_18.1.0.015.tgz -ARG INTEL_DRIVER_URL=https://registrationcenter-download.intel.com/akdlm/irc_nas/vcp/15532 -RUN mkdir -p /tmp/opencl-driver-intel - -RUN cd /tmp/opencl-driver-intel && \ - echo INTEL_DRIVER is $INTEL_DRIVER && \ - curl -O $INTEL_DRIVER_URL/$INTEL_DRIVER && \ - tar -xzf $INTEL_DRIVER && \ - for i in $(basename $INTEL_DRIVER .tgz)/rpm/*.rpm; do alien --to-deb $i; done && \ - dpkg -i *.deb && \ - rm -rf $INTEL_DRIVER $(basename $INTEL_DRIVER .tgz) *.deb && \ +RUN mkdir -p /tmp/opencl-driver-intel && \ + cd /tmp/opencl-driver-intel && \ + wget https://github.com/intel/llvm/releases/download/2024-WW14/oclcpuexp-2024.17.3.0.09_rel.tar.gz && \ + wget https://github.com/oneapi-src/oneTBB/releases/download/v2021.12.0/oneapi-tbb-2021.12.0-lin.tgz && \ + mkdir -p /opt/intel/oclcpuexp_2024.17.3.0.09_rel && \ + cd /opt/intel/oclcpuexp_2024.17.3.0.09_rel && \ + tar -zxvf /tmp/opencl-driver-intel/oclcpuexp-2024.17.3.0.09_rel.tar.gz && \ mkdir -p /etc/OpenCL/vendors && \ - echo /opt/intel/opencl_compilers_and_libraries_18.1.0.015/linux/compiler/lib/intel64_lin/libintelocl.so > /etc/OpenCL/vendors/intel.icd && \ + echo /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64/libintelocl.so > /etc/OpenCL/vendors/intel_expcpu.icd && \ + cd /opt/intel && \ + tar -zxvf /tmp/opencl-driver-intel/oneapi-tbb-2021.12.0-lin.tgz && \ + ln -s /opt/intel/oneapi-tbb-2021.12.0/lib/intel64/gcc4.8/libtbb.so /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 && \ + ln -s /opt/intel/oneapi-tbb-2021.12.0/lib/intel64/gcc4.8/libtbbmalloc.so /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 && \ + ln -s /opt/intel/oneapi-tbb-2021.12.0/lib/intel64/gcc4.8/libtbb.so.12 /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 && \ + ln -s /opt/intel/oneapi-tbb-2021.12.0/lib/intel64/gcc4.8/libtbbmalloc.so.2 /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 && \ + mkdir -p /etc/ld.so.conf.d && \ + echo /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 > /etc/ld.so.conf.d/libintelopenclexp.conf && \ + ldconfig -f /etc/ld.so.conf.d/libintelopenclexp.conf && \ cd / && \ rm -rf /tmp/opencl-driver-intel @@ -57,7 +62,7 @@ ENV QTWEBENGINE_DISABLE_SANDBOX 1 RUN dbus-uuidgen > /etc/machine-id ARG USER=batman -ARG USER_UID=1000 +ARG USER_UID=1001 RUN useradd -m -s /bin/bash -u $USER_UID $USER RUN usermod -aG sudo $USER RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers diff --git a/SConstruct b/SConstruct index 944d650d742d99..f53d8fb7d08d54 100644 --- a/SConstruct +++ b/SConstruct @@ -14,6 +14,8 @@ SCons.Warnings.warningAsException(True) TICI = os.path.isfile('/TICI') AGNOS = TICI +UBUNTU_FOCAL = int(subprocess.check_output('[ -f /etc/os-release ] && . /etc/os-release && [ "$ID" = "ubuntu" ] && [ "$VERSION_ID" = "20.04" ] && echo 1 || echo 0', shell=True, encoding='utf-8').rstrip()) +Export('UBUNTU_FOCAL') Decider('MD5-timestamp') diff --git a/poetry.lock b/poetry.lock index 13d082763cc7df..58fa7dee667abc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2270,8 +2270,8 @@ ros = ["zmq"] [package.source] type = "git" url = "https://github.com/commaai/metadrive.git" -reference = "python3.12" -resolved_reference = "0823c7491a1ab870bcd53d10a41e985a3ad1b968" +reference = "anisotropic_off" +resolved_reference = "1606c844345f98aa79f76177856e328edc6ec428" [[package]] name = "mouseinfo" @@ -8114,4 +8114,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = ">=3.11, <3.13" -content-hash = "83dbbf76ea5f3e1022233a164d6f342706ebf64ad8bbbf742a55d5f49474d863" +content-hash = "32df734a6ad6ad6a665c94c41cd0e3643a48174904faaf6f21c5c84f350f3cec" diff --git a/pyproject.toml b/pyproject.toml index 5353b3988769f0..374b0f46cafaec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -176,7 +176,7 @@ flaky = "*" inputs = "*" lru-dict = "*" matplotlib = "*" -metadrive-simulator = { git = "https://github.com/commaai/metadrive.git", branch = "python3.12", markers = "platform_machine != 'aarch64'" } # no linux/aarch64 wheels for certain dependencies +metadrive-simulator = { git = "https://github.com/commaai/metadrive.git", branch = "anisotropic_off", markers = "platform_machine != 'aarch64'" } # no linux/aarch64 wheels for certain dependencies mpld3 = "*" myst-parser = "*" natsort = "*" diff --git a/selfdrive/navd/SConscript b/selfdrive/navd/SConscript index 295e8127dbc7f6..378e7624942e75 100644 --- a/selfdrive/navd/SConscript +++ b/selfdrive/navd/SConscript @@ -1,4 +1,4 @@ -Import('qt_env', 'arch', 'common', 'messaging', 'visionipc', 'transformations') +Import('qt_env', 'arch', 'common', 'messaging', 'visionipc', 'transformations', 'UBUNTU_FOCAL') map_env = qt_env.Clone() libs = ['qt_widgets', 'qt_util', 'QMapLibre', common, messaging, visionipc, transformations, @@ -6,7 +6,7 @@ libs = ['qt_widgets', 'qt_util', 'QMapLibre', common, messaging, visionipc, tran if arch == 'larch64': libs.append(':libEGL_mesa.so.0') -if arch in ['larch64', 'aarch64', 'x86_64']: +if arch in ['larch64', 'aarch64', 'x86_64'] and not UBUNTU_FOCAL: if arch == 'x86_64': rpath = Dir(f"#third_party/maplibre-native-qt/{arch}/lib").srcnode().abspath map_env["RPATH"] += [rpath, ] diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index e181cb9abdc45f..e4fb32586d2fd9 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -1,6 +1,6 @@ import os import json -Import('qt_env', 'arch', 'common', 'messaging', 'visionipc', 'transformations') +Import('qt_env', 'arch', 'common', 'messaging', 'visionipc', 'transformations', 'UBUNTU_FOCAL') base_libs = [common, messaging, visionipc, transformations, 'm', 'OpenCL', 'ssl', 'crypto', 'pthread'] + qt_env["LIBS"] @@ -8,7 +8,7 @@ base_libs = [common, messaging, visionipc, transformations, if arch == 'larch64': base_libs.append('EGL') -maps = arch in ['larch64', 'aarch64', 'x86_64'] +maps = arch in ['larch64', 'aarch64', 'x86_64'] and not UBUNTU_FOCAL if arch == "Darwin": del base_libs[base_libs.index('OpenCL')] diff --git a/selfdrive/ui/qt/maps/map_helpers.cc b/selfdrive/ui/qt/maps/map_helpers.cc index 16923f7a435c1b..50e14011640b6b 100644 --- a/selfdrive/ui/qt/maps/map_helpers.cc +++ b/selfdrive/ui/qt/maps/map_helpers.cc @@ -143,11 +143,11 @@ std::pair map_format_distance(float d, bool is_metric) { d = std::max(d, 0.0f); if (is_metric) { - return (d > 500) ? std::pair{round_distance(d / 1000), QObject::tr("km")} - : std::pair{QString::number(50 * std::nearbyint(d / 50)), QObject::tr("m")}; + return (d > 500) ? std::pair(round_distance(d / 1000), QObject::tr("km")) + : std::pair(QString::number(50 * std::nearbyint(d / 50)), QObject::tr("m")); } else { float feet = d * METER_TO_FOOT; - return (feet > 500) ? std::pair{round_distance(d * METER_TO_MILE), QObject::tr("mi")} - : std::pair{QString::number(50 * std::nearbyint(d / 50)), QObject::tr("ft")}; + return (feet > 500) ? std::pair(round_distance(d * METER_TO_MILE), QObject::tr("mi")) + : std::pair(QString::number(50 * std::nearbyint(d / 50)), QObject::tr("ft")); } } diff --git a/third_party/maplibre-native-qt/x86_64/lib/libQMapLibre.so.3.0.0 b/third_party/maplibre-native-qt/x86_64/lib/libQMapLibre.so.3.0.0 index f2fcf107bc5bc0..e49d321c7c9376 100755 --- a/third_party/maplibre-native-qt/x86_64/lib/libQMapLibre.so.3.0.0 +++ b/third_party/maplibre-native-qt/x86_64/lib/libQMapLibre.so.3.0.0 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b718e4ea770105893dc41f64be36f806586a9471e2bb9d18d5ad97e906434548 -size 11000296 +oid sha256:d62e192aa7806302ed79866d9e3c51efc4bc315a6fdfe0e58e448dac5b279098 +size 11549728 diff --git a/tools/README.md b/tools/README.md index 361a27deda4214..f465ea12343e5d 100644 --- a/tools/README.md +++ b/tools/README.md @@ -2,11 +2,11 @@ ## System Requirements -openpilot is developed and tested on **Ubuntu 20.04**, which is the primary development target aside from the [supported embedded hardware](https://github.com/commaai/openpilot#running-on-a-dedicated-device-in-a-car). +openpilot is developed and tested on **Ubuntu 24.04**, which is the primary development target aside from the [supported embedded hardware](https://github.com/commaai/openpilot#running-on-a-dedicated-device-in-a-car). Running natively on any other system is not recommended and will require modifications. On Windows you can use WSL, and on macOS or incompatible Linux systems, it is recommended to use the dev containers. -## Native setup on Ubuntu 20.04 +## Native setup on Ubuntu 24.04 **1. Clone openpilot** @@ -55,7 +55,7 @@ GUI apps like `ui` or `cabana` can also run inside the container by leveraging X [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/about) should provide a similar experience to native Ubuntu. [WSL 2](https://docs.microsoft.com/en-us/windows/wsl/compare-versions) specifically has been reported by several users to be a seamless experience. -Follow [these instructions](https://docs.microsoft.com/en-us/windows/wsl/install) to setup the WSL and install the `Ubuntu-20.04` distribution. Once your Ubuntu WSL environment is setup, follow the Linux setup instructions to finish setting up your environment. See [these instructions](https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps) for running GUI apps. +Follow [these instructions](https://docs.microsoft.com/en-us/windows/wsl/install) to setup the WSL and install the `Ubuntu-24.04` distribution. Once your Ubuntu WSL environment is setup, follow the Linux setup instructions to finish setting up your environment. See [these instructions](https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps) for running GUI apps. **NOTE**: If you are running WSL and any GUIs are failing (segfaulting or other strange issues) even after following the steps above, you may need to enable software rendering with `LIBGL_ALWAYS_SOFTWARE=1`, e.g. `LIBGL_ALWAYS_SOFTWARE=1 selfdrive/ui/ui`. diff --git a/tools/profiling/snapdragon/README.md b/tools/profiling/snapdragon/README.md index 664814b6115273..f56ca182a77763 100644 --- a/tools/profiling/snapdragon/README.md +++ b/tools/profiling/snapdragon/README.md @@ -3,7 +3,7 @@ snapdragon profiler * download from https://developer.qualcomm.com/software/snapdragon-profiler/tools-archive (need a qc developer account) - * choose v2021.5 (verified working with 20.04 dev environment) + * choose v2021.5 (verified working with 24.04 dev environment) * unzip to selfdrive/debug/profiling/snapdragon/SnapdragonProfiler * run ```./setup-profiler.sh``` * run ```./setup-agnos.sh``` diff --git a/tools/webcam/README.md b/tools/webcam/README.md index 7334d87b38c167..c756069bb5d683 100644 --- a/tools/webcam/README.md +++ b/tools/webcam/README.md @@ -1,7 +1,7 @@ # Run openpilot with webcam on PC What's needed: -- Ubuntu 20.04 +- Ubuntu 24.04 - GPU (recommended) - Two USB webcams, at least 720p and 78 degrees FOV (e.g. Logitech C920/C615) - [Car harness](https://comma.ai/shop/products/comma-car-harness) with black panda to connect to your car From 987b0d9e030ec2191e422e7ca8d059b8a02ef08a Mon Sep 17 00:00:00 2001 From: royjr Date: Tue, 18 Jun 2024 14:27:28 -0400 Subject: [PATCH 10/36] Ubuntu 24.04 fix setup (#32783) * fix tk-dev * fix missing pip * Update tools/install_python_dependencies.sh --------- Co-authored-by: Adeeb Shihadeh --- tools/install_python_dependencies.sh | 10 +++++++++- tools/install_ubuntu_dependencies.sh | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/install_python_dependencies.sh b/tools/install_python_dependencies.sh index af25ec642481a1..bb00302073ead2 100755 --- a/tools/install_python_dependencies.sh +++ b/tools/install_python_dependencies.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash set -e +# Increase the pip timeout to handle TimeoutError +export PIP_DEFAULT_TIMEOUT=200 + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" ROOT=$DIR/../ cd $ROOT @@ -13,7 +16,7 @@ fi if ! command -v "pyenv" > /dev/null 2>&1; then echo "pyenv install ..." curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash - PYENV_PATH_SETUP="export PATH=\$HOME/.pyenv/bin:\$HOME/.pyenv/shims:\$PATH" + PYENV_PATH_SETUP="export PATH=\$HOME/.pyenv/bin:\$HOME/.pyenv/shims:\$HOME/.pyenv/versions/${PYENV_PYTHON_VERSION}/bin:\$PATH" fi if [ -z "$PYENV_SHELL" ] || [ -n "$PYENV_PATH_SETUP" ]; then @@ -51,7 +54,12 @@ if ! pyenv prefix ${PYENV_PYTHON_VERSION} &> /dev/null; then echo "python ${PYENV_PYTHON_VERSION} install ..." CONFIGURE_OPTS="--enable-shared" pyenv install -f ${PYENV_PYTHON_VERSION} fi + eval "$(pyenv init --path)" +eval "$(pyenv init -)" +eval "$(pyenv virtualenv-init -)" +pyenv local ${PYENV_PYTHON_VERSION} +pyenv rehash echo "update pip" pip install pip==24.0 diff --git a/tools/install_ubuntu_dependencies.sh b/tools/install_ubuntu_dependencies.sh index 1f8ef24eaf81ff..1fc5e4fc8b6f9f 100755 --- a/tools/install_ubuntu_dependencies.sh +++ b/tools/install_ubuntu_dependencies.sh @@ -93,7 +93,8 @@ function install_ubuntu_lts_latest_requirements() { qtchooser \ qt5-qmake \ qtbase5-dev-tools \ - python3-dev + python3-dev \ + tk-dev } # Install Ubuntu 20.04 packages From 151b4530ddae30d9c08b86d104d2997cdd4c35e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20R=C4=85czy?= Date: Tue, 18 Jun 2024 17:28:52 -0700 Subject: [PATCH 11/36] Fix openpilot-prebuilt dockerfile (#32787) * Manually add symlinks to prevent docker for copying duplicate files * Copy everything --- Dockerfile.openpilot | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/Dockerfile.openpilot b/Dockerfile.openpilot index 5d8f958c48017d..e26a427eb1aba9 100644 --- a/Dockerfile.openpilot +++ b/Dockerfile.openpilot @@ -8,23 +8,6 @@ ENV PYTHONPATH ${OPENPILOT_PATH}:${PYTHONPATH} RUN mkdir -p ${OPENPILOT_PATH} WORKDIR ${OPENPILOT_PATH} -COPY SConstruct ${OPENPILOT_PATH} - -COPY ./openpilot ${OPENPILOT_PATH}/openpilot -COPY ./third_party ${OPENPILOT_PATH}/third_party -COPY ./site_scons ${OPENPILOT_PATH}/site_scons -COPY ./rednose ${OPENPILOT_PATH}/rednose -COPY ./rednose_repo/site_scons ${OPENPILOT_PATH}/rednose_repo/site_scons -COPY ./tools ${OPENPILOT_PATH}/tools -COPY ./release ${OPENPILOT_PATH}/release -COPY ./common ${OPENPILOT_PATH}/common -COPY ./opendbc ${OPENPILOT_PATH}/opendbc -COPY ./cereal ${OPENPILOT_PATH}/cereal -COPY ./msgq_repo ${OPENPILOT_PATH}/msgq_repo -COPY ./msgq ${OPENPILOT_PATH}/msgq -COPY ./panda ${OPENPILOT_PATH}/panda -COPY ./selfdrive ${OPENPILOT_PATH}/selfdrive -COPY ./system ${OPENPILOT_PATH}/system -COPY ./body ${OPENPILOT_PATH}/body +COPY . ${OPENPILOT_PATH}/ RUN scons --cache-readonly -j$(nproc) From de75372880cb354df2bcb2e0f36e769213bf7072 Mon Sep 17 00:00:00 2001 From: Maxime Desroches Date: Wed, 19 Jun 2024 09:55:23 -0700 Subject: [PATCH 12/36] Remove pyenv (#32786) * no pyenv * better * check poetry * docker * syntax * manual env * pre-commit * revert * format --- Dockerfile.openpilot_base | 16 ++++---- tools/install_python_dependencies.sh | 60 ++++------------------------ tools/install_ubuntu_dependencies.sh | 2 +- 3 files changed, 16 insertions(+), 62 deletions(-) diff --git a/Dockerfile.openpilot_base b/Dockerfile.openpilot_base index 7228d16ef93527..343fd29c82178a 100644 --- a/Dockerfile.openpilot_base +++ b/Dockerfile.openpilot_base @@ -68,20 +68,18 @@ RUN usermod -aG sudo $USER RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers USER $USER -ENV POETRY_VIRTUALENVS_CREATE=false -ENV PYENV_VERSION=3.12.4 -ENV PYENV_ROOT="/home/$USER/pyenv" -ENV PATH="$PYENV_ROOT/bin:$PYENV_ROOT/shims:$PATH" - COPY --chown=$USER pyproject.toml poetry.lock /tmp/ COPY --chown=$USER tools/install_python_dependencies.sh /tmp/tools/ -RUN cd /tmp && \ +ENV POETRY_VIRTUALENVS_CREATE=false +ENV VIRTUAL_ENV=/home/$USER/venv/.venv +RUN python3 -m venv $VIRTUAL_ENV +ENV PATH="$VIRTUAL_ENV/bin:$PATH" +RUN . $VIRTUAL_ENV/bin/activate && \ + cd /tmp && \ tools/install_python_dependencies.sh && \ rm -rf /tmp/* && \ - rm -rf /home/$USER/.cache && \ - find /home/$USER/pyenv -type d -name ".git" | xargs rm -rf && \ - rm -rf /home/$USER/pyenv/versions/3.12.4/lib/python3.12/test + rm -rf /home/$USER/.cache USER root RUN sudo git config --global --add safe.directory /tmp/openpilot diff --git a/tools/install_python_dependencies.sh b/tools/install_python_dependencies.sh index bb00302073ead2..086fc2d14f8653 100755 --- a/tools/install_python_dependencies.sh +++ b/tools/install_python_dependencies.sh @@ -13,58 +13,15 @@ if [ "$(uname)" == "Darwin" ] && [ $SHELL == "/bin/bash" ]; then RC_FILE="$HOME/.bash_profile" fi -if ! command -v "pyenv" > /dev/null 2>&1; then - echo "pyenv install ..." - curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash - PYENV_PATH_SETUP="export PATH=\$HOME/.pyenv/bin:\$HOME/.pyenv/shims:\$HOME/.pyenv/versions/${PYENV_PYTHON_VERSION}/bin:\$PATH" +if ! command -v "poetry" > /dev/null 2>&1; then + echo "installing poetry..." + curl -sSL https://install.python-poetry.org | python3 - + POETRY_BIN='$HOME/.local/bin' + ADD_PATH_CMD="export PATH=\"$POETRY_BIN:\$PATH\"" + eval $ADD_PATH_CMD + printf "\n#poetry path\n$ADD_PATH_CMD\n" >> $RC_FILE fi -if [ -z "$PYENV_SHELL" ] || [ -n "$PYENV_PATH_SETUP" ]; then - echo "pyenvrc setup ..." - cat < "${HOME}/.pyenvrc" -if [ -z "\$PYENV_ROOT" ]; then - $PYENV_PATH_SETUP - export PYENV_ROOT="\$HOME/.pyenv" - eval "\$(pyenv init -)" - eval "\$(pyenv virtualenv-init -)" -fi -EOF - - SOURCE_PYENVRC="source ~/.pyenvrc" - if ! grep "^$SOURCE_PYENVRC$" $RC_FILE > /dev/null; then - printf "\n$SOURCE_PYENVRC\n" >> $RC_FILE - fi - - eval "$SOURCE_PYENVRC" - # $(pyenv init -) produces a function which is broken on bash 3.2 which ships on macOS - if [ $(uname) == "Darwin" ]; then - unset -f pyenv - fi -fi - -export MAKEFLAGS="-j$(nproc)" - -PYENV_PYTHON_VERSION="3.12.4" -if ! pyenv prefix ${PYENV_PYTHON_VERSION} &> /dev/null; then - # no pyenv update on mac - if [ "$(uname)" == "Linux" ]; then - echo "pyenv update ..." - pyenv update - fi - echo "python ${PYENV_PYTHON_VERSION} install ..." - CONFIGURE_OPTS="--enable-shared" pyenv install -f ${PYENV_PYTHON_VERSION} -fi - -eval "$(pyenv init --path)" -eval "$(pyenv init -)" -eval "$(pyenv virtualenv-init -)" -pyenv local ${PYENV_PYTHON_VERSION} -pyenv rehash - -echo "update pip" -pip install pip==24.0 -pip install poetry==1.7.0 - poetry config virtualenvs.prefer-active-python true --local poetry config virtualenvs.in-project true --local @@ -77,9 +34,8 @@ fi poetry self add poetry-dotenv-plugin@^0.1.0 -echo "pip packages install..." +echo "installing python packages..." poetry install --no-cache --no-root -pyenv rehash [ -n "$POETRY_VIRTUALENVS_CREATE" ] && RUN="" || RUN="poetry run" diff --git a/tools/install_ubuntu_dependencies.sh b/tools/install_ubuntu_dependencies.sh index 1fc5e4fc8b6f9f..5c10bf5438d0d6 100755 --- a/tools/install_ubuntu_dependencies.sh +++ b/tools/install_ubuntu_dependencies.sh @@ -94,7 +94,7 @@ function install_ubuntu_lts_latest_requirements() { qt5-qmake \ qtbase5-dev-tools \ python3-dev \ - tk-dev + python3-venv } # Install Ubuntu 20.04 packages From a89201219d19c544c8b12f8124fdceaadd6b3dca Mon Sep 17 00:00:00 2001 From: Jason Young <46612682+jyoung8607@users.noreply.github.com> Date: Wed, 19 Jun 2024 18:17:25 -0400 Subject: [PATCH 13/36] VW: Rename harnesses (#32779) --- docs/CARS.md | 112 ++++++++++++++--------------- selfdrive/car/docs_definitions.py | 4 +- selfdrive/car/volkswagen/values.py | 4 +- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 43bd8a8b30e414..2c32a77f0c7794 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -11,12 +11,12 @@ A supported vehicle is one that just works when you install a comma device. All |Acura|ILX 2016-19|AcuraWatch Plus|openpilot|25 mph|25 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 Honda Nidec connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Acura|RDX 2016-18|AcuraWatch Plus|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 Honda Nidec connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Acura|RDX 2019-22|All|openpilot available[1](#footnotes)|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Honda Bosch A connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Audi|Q2 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Audi|Q3 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Audi|Q2 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Audi|Q3 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim without Super Cruise Package|openpilot available[1](#footnotes)|3 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 GM connector
- 1 comma 3X
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Chevrolet|Bolt EV 2022-23|2LT Trim with Adaptive Cruise Control Package|openpilot available[1](#footnotes)|3 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 GM connector
- 1 comma 3X
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Chevrolet|Equinox 2019-22|Adaptive Cruise Control (ACC)|openpilot available[1](#footnotes)|3 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 GM connector
- 1 comma 3X
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| @@ -29,7 +29,7 @@ A supported vehicle is one that just works when you install a comma device. All |Chrysler|Pacifica Hybrid 2018|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 FCA connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Chrysler|Pacifica Hybrid 2019-23|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 FCA connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |comma|body|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|None|| -|CUPRA|Ateca 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|CUPRA|Ateca 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Dodge|Durango 2020-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 FCA connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Bronco Sport 2021-23|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Escape 2020-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| @@ -185,8 +185,8 @@ A supported vehicle is one that just works when you install a comma device. All |Lexus|UX Hybrid 2019-23|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Lincoln|Aviator 2020-23|Co-Pilot360 Plus|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Lincoln|Aviator Plug-in Hybrid 2020-23|Co-Pilot360 Plus|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|MAN|eTGE 2020-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|MAN|TGE 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|MAN|eTGE 2020-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|MAN|TGE 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Mazda|CX-5 2022-24|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Mazda connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Mazda|CX-9 2021-23|All|Stock|0 mph|28 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Mazda connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Nissan|Altima 2019-20|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 Nissan B connector
- 1 RJ45 cable (7 ft)
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| @@ -194,8 +194,8 @@ A supported vehicle is one that just works when you install a comma device. All |Nissan|Rogue 2018-20|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 Nissan A connector
- 1 RJ45 cable (7 ft)
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Nissan|X-Trail 2017|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 Nissan A connector
- 1 RJ45 cable (7 ft)
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ram|1500 2019-24|Adaptive Cruise Control (ACC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Ram connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|SEAT|Ateca 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|SEAT|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|SEAT|Ateca 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|SEAT|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Subaru|Ascent 2019-21|All[6](#footnotes)|openpilot available[1,7](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Subaru A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
Tools- 1 Pry Tool
- 1 Socket Wrench 8mm or 5/16" (deep)
|| |Subaru|Crosstrek 2018-19|EyeSight Driver Assistance[6](#footnotes)|openpilot available[1,7](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Subaru A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
Tools- 1 Pry Tool
- 1 Socket Wrench 8mm or 5/16" (deep)
|| |Subaru|Crosstrek 2020-23|EyeSight Driver Assistance[6](#footnotes)|openpilot available[1,7](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Subaru A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
Tools- 1 Pry Tool
- 1 Socket Wrench 8mm or 5/16" (deep)
|| @@ -206,15 +206,15 @@ A supported vehicle is one that just works when you install a comma device. All |Subaru|Outback 2020-22|All[6](#footnotes)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Subaru B connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
Tools- 1 Pry Tool
- 1 Socket Wrench 8mm or 5/16" (deep)
|| |Subaru|XV 2018-19|EyeSight Driver Assistance[6](#footnotes)|openpilot available[1,7](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Subaru A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
Tools- 1 Pry Tool
- 1 Socket Wrench 8mm or 5/16" (deep)
|| |Subaru|XV 2020-21|EyeSight Driver Assistance[6](#footnotes)|openpilot available[1,7](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Subaru A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
Tools- 1 Pry Tool
- 1 Socket Wrench 8mm or 5/16" (deep)
|| -|Škoda|Fabia 2022-23[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
[13](#footnotes)|| -|Škoda|Kamiq 2021-23[9,11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
[13](#footnotes)|| -|Škoda|Karoq 2019-23[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Škoda|Kodiaq 2017-23[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Škoda|Octavia 2015-19[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Škoda|Octavia RS 2016[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Škoda|Octavia Scout 2017-19[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Škoda|Scala 2020-23[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
[13](#footnotes)|| -|Škoda|Superb 2015-22[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Škoda|Fabia 2022-23[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
[13](#footnotes)|| +|Škoda|Kamiq 2021-23[9,11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
[13](#footnotes)|| +|Škoda|Karoq 2019-23[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Škoda|Kodiaq 2017-23[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Škoda|Octavia 2015-19[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Škoda|Octavia RS 2016[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Škoda|Octavia Scout 2017-19[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Škoda|Scala 2020-23[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
[13](#footnotes)|| +|Škoda|Superb 2015-22[11](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Toyota|Alphard 2019-20|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Toyota|Alphard Hybrid 2021|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Toyota|Avalon 2016|Toyota Safety Sense P|openpilot available[2](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| @@ -260,42 +260,42 @@ A supported vehicle is one that just works when you install a comma device. All |Toyota|RAV4 Hybrid 2022|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Toyota|RAV4 Hybrid 2023-24|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Toyota|Sienna 2018-20|All|openpilot available[2](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Arteon 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Arteon eHybrid 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Arteon R 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Arteon Shooting Brake 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Atlas 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Atlas Cross Sport 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|California 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Caravelle 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|CC 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Crafter 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|e-Crafter 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|e-Golf 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Golf 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Golf Alltrack 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Golf GTD 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Golf GTE 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Golf GTI 2015-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Golf R 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Grand California 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Jetta 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Jetta GLI 2021-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Passat 2015-22[10](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Passat Alltrack 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Passat GTE 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Polo 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
[13](#footnotes)|| -|Volkswagen|Polo GTI 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
[13](#footnotes)|| -|Volkswagen|T-Cross 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
[13](#footnotes)|| -|Volkswagen|T-Roc 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Taos 2022-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Teramont 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Teramont Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Teramont X 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Tiguan 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Tiguan eHybrid 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Volkswagen|Touran 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Arteon 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Arteon eHybrid 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Arteon R 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Arteon Shooting Brake 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Atlas 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Atlas Cross Sport 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|California 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Caravelle 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|CC 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Crafter 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|e-Crafter 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|e-Golf 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Golf 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Golf Alltrack 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Golf GTD 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Golf GTE 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Golf GTI 2015-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Golf R 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Grand California 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Jetta 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Jetta GLI 2021-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Passat 2015-22[10](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Passat Alltrack 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Passat GTE 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Polo 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
[13](#footnotes)|| +|Volkswagen|Polo GTI 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
[13](#footnotes)|| +|Volkswagen|T-Cross 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
[13](#footnotes)|| +|Volkswagen|T-Roc 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Taos 2022-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Teramont 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Teramont Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Teramont X 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Tiguan 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Tiguan eHybrid 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Touran 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| ### Footnotes 1openpilot Longitudinal Control (Alpha) is available behind a toggle; the toggle is only available in non-release branches such as `devel` or `master-ci`.
diff --git a/selfdrive/car/docs_definitions.py b/selfdrive/car/docs_definitions.py index 971338e9b57196..a04653c1403c96 100644 --- a/selfdrive/car/docs_definitions.py +++ b/selfdrive/car/docs_definitions.py @@ -91,8 +91,8 @@ class CarHarness(EnumBase): subaru_d = BaseCarHarness("Subaru D connector") fca = BaseCarHarness("FCA connector") ram = BaseCarHarness("Ram connector") - vw = BaseCarHarness("VW connector") - j533 = BaseCarHarness("J533 connector", parts=[Accessory.harness_box, Cable.long_obdc_cable, Cable.usbc_coupler]) + vw_a = BaseCarHarness("VW A connector") + vw_j533 = BaseCarHarness("VW J533 connector", parts=[Accessory.harness_box, Cable.long_obdc_cable, Cable.usbc_coupler]) hyundai_a = BaseCarHarness("Hyundai A connector") hyundai_b = BaseCarHarness("Hyundai B connector") hyundai_c = BaseCarHarness("Hyundai C connector") diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 8b58769b3fd87a..69dd63fefd07a9 100644 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -188,7 +188,7 @@ class Footnote(Enum): @dataclass class VWCarDocs(CarDocs): package: str = "Adaptive Cruise Control (ACC) & Lane Assist" - car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.j533])) + car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.vw_j533])) def init_make(self, CP: car.CarParams): self.footnotes.append(Footnote.VW_EXP_LONG) @@ -196,7 +196,7 @@ def init_make(self, CP: car.CarParams): self.footnotes.append(Footnote.SKODA_HEATED_WINDSHIELD) if CP.carFingerprint in (CAR.VOLKSWAGEN_CRAFTER_MK2, CAR.VOLKSWAGEN_TRANSPORTER_T61): - self.car_parts = CarParts([Device.threex_angled_mount, CarHarness.j533]) + self.car_parts = CarParts([Device.threex_angled_mount, CarHarness.vw_j533]) if abs(CP.minSteerSpeed - CarControllerParams.DEFAULT_MIN_STEER_SPEED) < 1e-3: self.min_steer_speed = 0 From e491c9d964a2aef07eeaa7b47f4aa9f992130482 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 19 Jun 2024 19:14:13 -0700 Subject: [PATCH 14/36] remove navigation (#32773) * remove navigation * lil more * fix cabana * revert for now * fix docs * move that over * lock * rm assets --- .vscode/launch.json | 1 - SConstruct | 9 +- common/params.cc | 6 - docs/c_docs.rst | 2 - poetry.lock | 27 +- pyproject.toml | 2 - selfdrive/SConscript | 1 - selfdrive/assets/img_map.png | 3 - .../assets/navigation/default_marker.svg | 3 - .../assets/navigation/direction_arrive.png | 3 - .../navigation/direction_arrive_left.png | 3 - .../navigation/direction_arrive_right.png | 3 - .../navigation/direction_arrive_straight.png | 3 - .../assets/navigation/direction_close.png | 3 - .../assets/navigation/direction_continue.png | 3 - .../navigation/direction_continue_left.png | 3 - .../navigation/direction_continue_right.png | 3 - .../direction_continue_slight_left.png | 3 - .../direction_continue_slight_right.png | 3 - .../direction_continue_straight.png | 3 - .../navigation/direction_continue_uturn.png | 3 - .../assets/navigation/direction_depart.png | 3 - .../navigation/direction_depart_left.png | 3 - .../navigation/direction_depart_right.png | 3 - .../navigation/direction_depart_straight.png | 3 - .../navigation/direction_end_of_road_left.png | 3 - .../direction_end_of_road_right.png | 3 - .../assets/navigation/direction_flag.png | 3 - .../assets/navigation/direction_fork.png | 3 - .../assets/navigation/direction_fork_left.png | 3 - .../navigation/direction_fork_right.png | 3 - .../navigation/direction_fork_slight_left.png | 3 - .../direction_fork_slight_right.png | 3 - .../navigation/direction_fork_straight.png | 3 - .../assets/navigation/direction_invalid.png | 3 - .../navigation/direction_invalid_left.png | 3 - .../navigation/direction_invalid_right.png | 3 - .../direction_invalid_slight_left.png | 3 - .../direction_invalid_slight_right.png | 3 - .../navigation/direction_invalid_straight.png | 3 - .../navigation/direction_invalid_uturn.png | 3 - .../navigation/direction_merge_left.png | 3 - .../navigation/direction_merge_right.png | 3 - .../direction_merge_slight_left.png | 3 - .../direction_merge_slight_right.png | 3 - .../navigation/direction_merge_straight.png | 3 - .../navigation/direction_new_name_left.png | 3 - .../navigation/direction_new_name_right.png | 3 - .../direction_new_name_sharp_left.png | 3 - .../direction_new_name_sharp_right.png | 3 - .../direction_new_name_slight_left.png | 3 - .../direction_new_name_slight_right.png | 3 - .../direction_new_name_straight.png | 3 - .../direction_notification_left.png | 3 - .../direction_notification_right.png | 3 - .../direction_notification_sharp_left.png | 3 - .../direction_notification_sharp_right.png | 3 - .../direction_notification_slight_left.png | 3 - .../direction_notification_slight_right.png | 3 - .../direction_notification_straight.png | 3 - .../navigation/direction_off_ramp_left.png | 3 - .../navigation/direction_off_ramp_right.png | 3 - .../direction_off_ramp_slight_left.png | 3 - .../direction_off_ramp_slight_right.png | 3 - .../navigation/direction_on_ramp_left.png | 3 - .../navigation/direction_on_ramp_right.png | 3 - .../direction_on_ramp_sharp_left.png | 3 - .../direction_on_ramp_sharp_right.png | 3 - .../direction_on_ramp_slight_left.png | 3 - .../direction_on_ramp_slight_right.png | 3 - .../navigation/direction_on_ramp_straight.png | 3 - .../assets/navigation/direction_rotary.png | 3 - .../navigation/direction_rotary_left.png | 3 - .../navigation/direction_rotary_right.png | 3 - .../direction_rotary_sharp_left.png | 3 - .../direction_rotary_sharp_right.png | 3 - .../direction_rotary_slight_left.png | 3 - .../direction_rotary_slight_right.png | 3 - .../navigation/direction_rotary_straight.png | 3 - .../navigation/direction_roundabout.png | 3 - .../navigation/direction_roundabout_left.png | 3 - .../navigation/direction_roundabout_right.png | 3 - .../direction_roundabout_sharp_left.png | 3 - .../direction_roundabout_sharp_right.png | 3 - .../direction_roundabout_slight_left.png | 3 - .../direction_roundabout_slight_right.png | 3 - .../direction_roundabout_straight.png | 3 - .../assets/navigation/direction_turn_left.png | 3 - .../direction_turn_left_inactive.png | 3 - .../navigation/direction_turn_right.png | 3 - .../direction_turn_right_inactive.png | 3 - .../navigation/direction_turn_sharp_left.png | 3 - .../navigation/direction_turn_sharp_right.png | 3 - .../navigation/direction_turn_slight_left.png | 3 - .../direction_turn_slight_left_inactive.png | 3 - .../direction_turn_slight_right.png | 3 - .../direction_turn_slight_right_inactive.png | 3 - .../navigation/direction_turn_straight.png | 3 - .../direction_turn_straight_inactive.png | 3 - .../navigation/direction_turn_uturn.png | 3 - .../assets/navigation/direction_updown.png | 3 - selfdrive/assets/navigation/home.png | 3 - selfdrive/assets/navigation/home.svg | 3 - selfdrive/assets/navigation/home_inactive.png | 3 - .../assets/navigation/icon_directions.svg | 3 - .../navigation/icon_directions_outlined.svg | 3 - selfdrive/assets/navigation/icon_favorite.svg | 3 - selfdrive/assets/navigation/icon_home.svg | 3 - selfdrive/assets/navigation/icon_recent.svg | 3 - selfdrive/assets/navigation/icon_settings.svg | 3 - selfdrive/assets/navigation/icon_work.svg | 3 - selfdrive/assets/navigation/work.png | 3 - selfdrive/assets/navigation/work.svg | 3 - selfdrive/assets/navigation/work_inactive.png | 3 - selfdrive/assets/offroad/icon_map.png | 3 - selfdrive/assets/offroad/icon_map_speed.png | 3 - selfdrive/navd/.gitignore | 6 - selfdrive/navd/README.md | 24 -- selfdrive/navd/SConscript | 20 - selfdrive/navd/__init__.py | 0 selfdrive/navd/helpers.py | 189 --------- selfdrive/navd/main.cc | 29 -- selfdrive/navd/map_renderer.cc | 338 --------------- selfdrive/navd/map_renderer.h | 61 --- selfdrive/navd/map_renderer.py | 100 ----- selfdrive/navd/navd.py | 368 ----------------- selfdrive/navd/set_destination.py | 33 -- selfdrive/navd/style.json | 1 - selfdrive/navd/tests/test_map_renderer.py | 212 ---------- selfdrive/navd/tests/test_navd.py | 57 --- selfdrive/test/test_onroad.py | 1 - selfdrive/ui/SConscript | 11 +- selfdrive/ui/qt/home.cc | 20 +- selfdrive/ui/qt/maps/map.cc | 390 ------------------ selfdrive/ui/qt/maps/map.h | 86 ---- selfdrive/ui/qt/maps/map_eta.cc | 59 --- selfdrive/ui/qt/maps/map_eta.h | 23 -- selfdrive/ui/qt/maps/map_helpers.cc | 153 ------- selfdrive/ui/qt/maps/map_helpers.h | 32 -- selfdrive/ui/qt/maps/map_instructions.cc | 144 ------- selfdrive/ui/qt/maps/map_instructions.h | 38 -- selfdrive/ui/qt/maps/map_panel.cc | 43 -- selfdrive/ui/qt/maps/map_panel.h | 21 - selfdrive/ui/qt/maps/map_settings.cc | 385 ----------------- selfdrive/ui/qt/maps/map_settings.h | 102 ----- selfdrive/ui/qt/offroad/settings.cc | 14 - selfdrive/ui/qt/onroad/annotated_camera.cc | 9 - selfdrive/ui/qt/onroad/annotated_camera.h | 2 - selfdrive/ui/qt/onroad/buttons.cc | 15 - selfdrive/ui/qt/onroad/buttons.h | 13 - selfdrive/ui/qt/onroad/onroad_home.cc | 53 --- selfdrive/ui/qt/onroad/onroad_home.h | 1 - selfdrive/ui/qt/widgets/prime.cc | 8 +- selfdrive/ui/qt/widgets/prime.h | 1 - selfdrive/ui/translations/main_ar.ts | 104 +---- selfdrive/ui/translations/main_de.ts | 106 +---- selfdrive/ui/translations/main_fr.ts | 104 +---- selfdrive/ui/translations/main_ja.ts | 104 +---- selfdrive/ui/translations/main_ko.ts | 108 +---- selfdrive/ui/translations/main_pt-BR.ts | 108 +---- selfdrive/ui/translations/main_th.ts | 104 +---- selfdrive/ui/translations/main_tr.ts | 102 +---- selfdrive/ui/translations/main_zh-CHS.ts | 108 +---- selfdrive/ui/translations/main_zh-CHT.ts | 108 +---- selfdrive/ui/ui.cc | 4 + selfdrive/ui/watch3.cc | 1 - system/athena/athenad.py | 13 - system/manager/process_config.py | 1 - third_party/maplibre-native-qt/.gitignore | 1 - third_party/maplibre-native-qt/aarch64 | 1 - third_party/maplibre-native-qt/build.sh | 36 -- .../include/conversion_p.hpp | 241 ----------- .../include/export_core.hpp | 20 - .../include/export_location.hpp | 20 - .../include/export_widgets.hpp | 20 - .../maplibre-native-qt/include/geojson_p.hpp | 30 -- .../maplibre-native-qt/include/gl_widget.hpp | 56 --- .../include/gl_widget_p.hpp | 42 -- .../maplibre-native-qt/include/map.hpp | 205 --------- .../include/map_observer_p.hpp | 54 --- .../maplibre-native-qt/include/map_p.hpp | 79 ---- .../include/map_renderer_p.hpp | 63 --- .../maplibre-native-qt/include/qgeomap.hpp | 54 --- .../maplibre-native-qt/include/qgeomap_p.hpp | 93 ----- .../maplibre-native-qt/include/qmaplibre.hpp | 9 - .../include/qmaplibrewidgets.hpp | 6 - .../include/qt_mapping_engine.hpp | 31 -- .../maplibre-native-qt/include/settings.hpp | 125 ------ .../maplibre-native-qt/include/settings_p.hpp | 57 --- .../include/style_change_utils_p.hpp | 34 -- .../include/texture_node.hpp | 42 -- .../maplibre-native-qt/include/types.hpp | 206 --------- .../maplibre-native-qt/include/utils.hpp | 28 -- .../larch64/include/QMapLibre/Export | 1 - .../larch64/include/QMapLibre/LayerParameter | 1 - .../larch64/include/QMapLibre/Map | 1 - .../larch64/include/QMapLibre/QMapLibre | 1 - .../larch64/include/QMapLibre/Settings | 1 - .../larch64/include/QMapLibre/SourceParameter | 1 - .../larch64/include/QMapLibre/StyleParameter | 1 - .../larch64/include/QMapLibre/Types | 1 - .../larch64/include/QMapLibre/Utils | 1 - .../larch64/lib/libQMapLibre.so | 3 - .../larch64/lib/libQMapLibre.so.3.0.0 | 3 - .../x86_64/include/QMapLibre/Export | 1 - .../x86_64/include/QMapLibre/LayerParameter | 1 - .../x86_64/include/QMapLibre/Map | 1 - .../x86_64/include/QMapLibre/QMapLibre | 1 - .../x86_64/include/QMapLibre/Settings | 1 - .../x86_64/include/QMapLibre/SourceParameter | 1 - .../x86_64/include/QMapLibre/StyleParameter | 1 - .../x86_64/include/QMapLibre/Types | 1 - .../x86_64/include/QMapLibre/Utils | 1 - .../x86_64/lib/libQMapLibre.so | 1 - .../x86_64/lib/libQMapLibre.so.3.0.0 | 3 - tools/sim/README.md | 2 +- 216 files changed, 51 insertions(+), 6044 deletions(-) delete mode 100644 selfdrive/assets/img_map.png delete mode 100644 selfdrive/assets/navigation/default_marker.svg delete mode 100644 selfdrive/assets/navigation/direction_arrive.png delete mode 100644 selfdrive/assets/navigation/direction_arrive_left.png delete mode 100644 selfdrive/assets/navigation/direction_arrive_right.png delete mode 100644 selfdrive/assets/navigation/direction_arrive_straight.png delete mode 100644 selfdrive/assets/navigation/direction_close.png delete mode 100644 selfdrive/assets/navigation/direction_continue.png delete mode 100644 selfdrive/assets/navigation/direction_continue_left.png delete mode 100644 selfdrive/assets/navigation/direction_continue_right.png delete mode 100644 selfdrive/assets/navigation/direction_continue_slight_left.png delete mode 100644 selfdrive/assets/navigation/direction_continue_slight_right.png delete mode 100644 selfdrive/assets/navigation/direction_continue_straight.png delete mode 100644 selfdrive/assets/navigation/direction_continue_uturn.png delete mode 100644 selfdrive/assets/navigation/direction_depart.png delete mode 100644 selfdrive/assets/navigation/direction_depart_left.png delete mode 100644 selfdrive/assets/navigation/direction_depart_right.png delete mode 100644 selfdrive/assets/navigation/direction_depart_straight.png delete mode 100644 selfdrive/assets/navigation/direction_end_of_road_left.png delete mode 100644 selfdrive/assets/navigation/direction_end_of_road_right.png delete mode 100644 selfdrive/assets/navigation/direction_flag.png delete mode 100644 selfdrive/assets/navigation/direction_fork.png delete mode 100644 selfdrive/assets/navigation/direction_fork_left.png delete mode 100644 selfdrive/assets/navigation/direction_fork_right.png delete mode 100644 selfdrive/assets/navigation/direction_fork_slight_left.png delete mode 100644 selfdrive/assets/navigation/direction_fork_slight_right.png delete mode 100644 selfdrive/assets/navigation/direction_fork_straight.png delete mode 100644 selfdrive/assets/navigation/direction_invalid.png delete mode 100644 selfdrive/assets/navigation/direction_invalid_left.png delete mode 100644 selfdrive/assets/navigation/direction_invalid_right.png delete mode 100644 selfdrive/assets/navigation/direction_invalid_slight_left.png delete mode 100644 selfdrive/assets/navigation/direction_invalid_slight_right.png delete mode 100644 selfdrive/assets/navigation/direction_invalid_straight.png delete mode 100644 selfdrive/assets/navigation/direction_invalid_uturn.png delete mode 100644 selfdrive/assets/navigation/direction_merge_left.png delete mode 100644 selfdrive/assets/navigation/direction_merge_right.png delete mode 100644 selfdrive/assets/navigation/direction_merge_slight_left.png delete mode 100644 selfdrive/assets/navigation/direction_merge_slight_right.png delete mode 100644 selfdrive/assets/navigation/direction_merge_straight.png delete mode 100644 selfdrive/assets/navigation/direction_new_name_left.png delete mode 100644 selfdrive/assets/navigation/direction_new_name_right.png delete mode 100644 selfdrive/assets/navigation/direction_new_name_sharp_left.png delete mode 100644 selfdrive/assets/navigation/direction_new_name_sharp_right.png delete mode 100644 selfdrive/assets/navigation/direction_new_name_slight_left.png delete mode 100644 selfdrive/assets/navigation/direction_new_name_slight_right.png delete mode 100644 selfdrive/assets/navigation/direction_new_name_straight.png delete mode 100644 selfdrive/assets/navigation/direction_notification_left.png delete mode 100644 selfdrive/assets/navigation/direction_notification_right.png delete mode 100644 selfdrive/assets/navigation/direction_notification_sharp_left.png delete mode 100644 selfdrive/assets/navigation/direction_notification_sharp_right.png delete mode 100644 selfdrive/assets/navigation/direction_notification_slight_left.png delete mode 100644 selfdrive/assets/navigation/direction_notification_slight_right.png delete mode 100644 selfdrive/assets/navigation/direction_notification_straight.png delete mode 100644 selfdrive/assets/navigation/direction_off_ramp_left.png delete mode 100644 selfdrive/assets/navigation/direction_off_ramp_right.png delete mode 100644 selfdrive/assets/navigation/direction_off_ramp_slight_left.png delete mode 100644 selfdrive/assets/navigation/direction_off_ramp_slight_right.png delete mode 100644 selfdrive/assets/navigation/direction_on_ramp_left.png delete mode 100644 selfdrive/assets/navigation/direction_on_ramp_right.png delete mode 100644 selfdrive/assets/navigation/direction_on_ramp_sharp_left.png delete mode 100644 selfdrive/assets/navigation/direction_on_ramp_sharp_right.png delete mode 100644 selfdrive/assets/navigation/direction_on_ramp_slight_left.png delete mode 100644 selfdrive/assets/navigation/direction_on_ramp_slight_right.png delete mode 100644 selfdrive/assets/navigation/direction_on_ramp_straight.png delete mode 100644 selfdrive/assets/navigation/direction_rotary.png delete mode 100644 selfdrive/assets/navigation/direction_rotary_left.png delete mode 100644 selfdrive/assets/navigation/direction_rotary_right.png delete mode 100644 selfdrive/assets/navigation/direction_rotary_sharp_left.png delete mode 100644 selfdrive/assets/navigation/direction_rotary_sharp_right.png delete mode 100644 selfdrive/assets/navigation/direction_rotary_slight_left.png delete mode 100644 selfdrive/assets/navigation/direction_rotary_slight_right.png delete mode 100644 selfdrive/assets/navigation/direction_rotary_straight.png delete mode 100644 selfdrive/assets/navigation/direction_roundabout.png delete mode 100644 selfdrive/assets/navigation/direction_roundabout_left.png delete mode 100644 selfdrive/assets/navigation/direction_roundabout_right.png delete mode 100644 selfdrive/assets/navigation/direction_roundabout_sharp_left.png delete mode 100644 selfdrive/assets/navigation/direction_roundabout_sharp_right.png delete mode 100644 selfdrive/assets/navigation/direction_roundabout_slight_left.png delete mode 100644 selfdrive/assets/navigation/direction_roundabout_slight_right.png delete mode 100644 selfdrive/assets/navigation/direction_roundabout_straight.png delete mode 100644 selfdrive/assets/navigation/direction_turn_left.png delete mode 100644 selfdrive/assets/navigation/direction_turn_left_inactive.png delete mode 100644 selfdrive/assets/navigation/direction_turn_right.png delete mode 100644 selfdrive/assets/navigation/direction_turn_right_inactive.png delete mode 100644 selfdrive/assets/navigation/direction_turn_sharp_left.png delete mode 100644 selfdrive/assets/navigation/direction_turn_sharp_right.png delete mode 100644 selfdrive/assets/navigation/direction_turn_slight_left.png delete mode 100644 selfdrive/assets/navigation/direction_turn_slight_left_inactive.png delete mode 100644 selfdrive/assets/navigation/direction_turn_slight_right.png delete mode 100644 selfdrive/assets/navigation/direction_turn_slight_right_inactive.png delete mode 100644 selfdrive/assets/navigation/direction_turn_straight.png delete mode 100644 selfdrive/assets/navigation/direction_turn_straight_inactive.png delete mode 100644 selfdrive/assets/navigation/direction_turn_uturn.png delete mode 100644 selfdrive/assets/navigation/direction_updown.png delete mode 100644 selfdrive/assets/navigation/home.png delete mode 100644 selfdrive/assets/navigation/home.svg delete mode 100644 selfdrive/assets/navigation/home_inactive.png delete mode 100644 selfdrive/assets/navigation/icon_directions.svg delete mode 100644 selfdrive/assets/navigation/icon_directions_outlined.svg delete mode 100644 selfdrive/assets/navigation/icon_favorite.svg delete mode 100644 selfdrive/assets/navigation/icon_home.svg delete mode 100644 selfdrive/assets/navigation/icon_recent.svg delete mode 100644 selfdrive/assets/navigation/icon_settings.svg delete mode 100644 selfdrive/assets/navigation/icon_work.svg delete mode 100644 selfdrive/assets/navigation/work.png delete mode 100644 selfdrive/assets/navigation/work.svg delete mode 100644 selfdrive/assets/navigation/work_inactive.png delete mode 100644 selfdrive/assets/offroad/icon_map.png delete mode 100644 selfdrive/assets/offroad/icon_map_speed.png delete mode 100644 selfdrive/navd/.gitignore delete mode 100644 selfdrive/navd/README.md delete mode 100644 selfdrive/navd/SConscript delete mode 100644 selfdrive/navd/__init__.py delete mode 100644 selfdrive/navd/helpers.py delete mode 100644 selfdrive/navd/main.cc delete mode 100644 selfdrive/navd/map_renderer.cc delete mode 100644 selfdrive/navd/map_renderer.h delete mode 100755 selfdrive/navd/map_renderer.py delete mode 100755 selfdrive/navd/navd.py delete mode 100755 selfdrive/navd/set_destination.py delete mode 100644 selfdrive/navd/style.json delete mode 100644 selfdrive/navd/tests/test_map_renderer.py delete mode 100644 selfdrive/navd/tests/test_navd.py delete mode 100644 selfdrive/ui/qt/maps/map.cc delete mode 100644 selfdrive/ui/qt/maps/map.h delete mode 100644 selfdrive/ui/qt/maps/map_eta.cc delete mode 100644 selfdrive/ui/qt/maps/map_eta.h delete mode 100644 selfdrive/ui/qt/maps/map_helpers.cc delete mode 100644 selfdrive/ui/qt/maps/map_helpers.h delete mode 100644 selfdrive/ui/qt/maps/map_instructions.cc delete mode 100644 selfdrive/ui/qt/maps/map_instructions.h delete mode 100644 selfdrive/ui/qt/maps/map_panel.cc delete mode 100644 selfdrive/ui/qt/maps/map_panel.h delete mode 100644 selfdrive/ui/qt/maps/map_settings.cc delete mode 100644 selfdrive/ui/qt/maps/map_settings.h delete mode 100644 third_party/maplibre-native-qt/.gitignore delete mode 120000 third_party/maplibre-native-qt/aarch64 delete mode 100755 third_party/maplibre-native-qt/build.sh delete mode 100644 third_party/maplibre-native-qt/include/conversion_p.hpp delete mode 100644 third_party/maplibre-native-qt/include/export_core.hpp delete mode 100644 third_party/maplibre-native-qt/include/export_location.hpp delete mode 100644 third_party/maplibre-native-qt/include/export_widgets.hpp delete mode 100644 third_party/maplibre-native-qt/include/geojson_p.hpp delete mode 100644 third_party/maplibre-native-qt/include/gl_widget.hpp delete mode 100644 third_party/maplibre-native-qt/include/gl_widget_p.hpp delete mode 100644 third_party/maplibre-native-qt/include/map.hpp delete mode 100644 third_party/maplibre-native-qt/include/map_observer_p.hpp delete mode 100644 third_party/maplibre-native-qt/include/map_p.hpp delete mode 100644 third_party/maplibre-native-qt/include/map_renderer_p.hpp delete mode 100644 third_party/maplibre-native-qt/include/qgeomap.hpp delete mode 100644 third_party/maplibre-native-qt/include/qgeomap_p.hpp delete mode 100644 third_party/maplibre-native-qt/include/qmaplibre.hpp delete mode 100644 third_party/maplibre-native-qt/include/qmaplibrewidgets.hpp delete mode 100644 third_party/maplibre-native-qt/include/qt_mapping_engine.hpp delete mode 100644 third_party/maplibre-native-qt/include/settings.hpp delete mode 100644 third_party/maplibre-native-qt/include/settings_p.hpp delete mode 100644 third_party/maplibre-native-qt/include/style_change_utils_p.hpp delete mode 100644 third_party/maplibre-native-qt/include/texture_node.hpp delete mode 100644 third_party/maplibre-native-qt/include/types.hpp delete mode 100644 third_party/maplibre-native-qt/include/utils.hpp delete mode 100644 third_party/maplibre-native-qt/larch64/include/QMapLibre/Export delete mode 100644 third_party/maplibre-native-qt/larch64/include/QMapLibre/LayerParameter delete mode 100644 third_party/maplibre-native-qt/larch64/include/QMapLibre/Map delete mode 100644 third_party/maplibre-native-qt/larch64/include/QMapLibre/QMapLibre delete mode 100644 third_party/maplibre-native-qt/larch64/include/QMapLibre/Settings delete mode 100644 third_party/maplibre-native-qt/larch64/include/QMapLibre/SourceParameter delete mode 100644 third_party/maplibre-native-qt/larch64/include/QMapLibre/StyleParameter delete mode 100644 third_party/maplibre-native-qt/larch64/include/QMapLibre/Types delete mode 100644 third_party/maplibre-native-qt/larch64/include/QMapLibre/Utils delete mode 100755 third_party/maplibre-native-qt/larch64/lib/libQMapLibre.so delete mode 100755 third_party/maplibre-native-qt/larch64/lib/libQMapLibre.so.3.0.0 delete mode 100644 third_party/maplibre-native-qt/x86_64/include/QMapLibre/Export delete mode 100644 third_party/maplibre-native-qt/x86_64/include/QMapLibre/LayerParameter delete mode 100644 third_party/maplibre-native-qt/x86_64/include/QMapLibre/Map delete mode 100644 third_party/maplibre-native-qt/x86_64/include/QMapLibre/QMapLibre delete mode 100644 third_party/maplibre-native-qt/x86_64/include/QMapLibre/Settings delete mode 100644 third_party/maplibre-native-qt/x86_64/include/QMapLibre/SourceParameter delete mode 100644 third_party/maplibre-native-qt/x86_64/include/QMapLibre/StyleParameter delete mode 100644 third_party/maplibre-native-qt/x86_64/include/QMapLibre/Types delete mode 100644 third_party/maplibre-native-qt/x86_64/include/QMapLibre/Utils delete mode 120000 third_party/maplibre-native-qt/x86_64/lib/libQMapLibre.so delete mode 100755 third_party/maplibre-native-qt/x86_64/lib/libQMapLibre.so.3.0.0 diff --git a/.vscode/launch.json b/.vscode/launch.json index 3b3953c3f4bf56..a6b341d9eafbdd 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,7 +7,6 @@ "description": "Select the process to debug", "options": [ "selfdrive/controls/controlsd.py", - "selfdrive/navd/navd.py", "system/timed/timed.py", "tools/sim/run_bridge.py" ] diff --git a/SConstruct b/SConstruct index f53d8fb7d08d54..0c4dbee18e2a15 100644 --- a/SConstruct +++ b/SConstruct @@ -14,8 +14,6 @@ SCons.Warnings.warningAsException(True) TICI = os.path.isfile('/TICI') AGNOS = TICI -UBUNTU_FOCAL = int(subprocess.check_output('[ -f /etc/os-release ] && . /etc/os-release && [ "$ID" = "ubuntu" ] && [ "$VERSION_ID" = "20.04" ] && echo 1 || echo 0', shell=True, encoding='utf-8').rstrip()) -Export('UBUNTU_FOCAL') Decider('MD5-timestamp') @@ -213,8 +211,6 @@ env = Environment( "#cereal", "#msgq", "#opendbc/can", - "#third_party/maplibre-native-qt/include", - f"#third_party/maplibre-native-qt/{arch}/include" ], CC='clang', @@ -279,7 +275,7 @@ Export('envCython') # Qt build environment qt_env = env.Clone() -qt_modules = ["Widgets", "Gui", "Core", "Network", "Concurrent", "Multimedia", "Quick", "Qml", "QuickWidgets", "Location", "Positioning", "DBus", "Xml"] +qt_modules = ["Widgets", "Gui", "Core", "Network", "Concurrent", "Multimedia", "Quick", "Qml", "QuickWidgets", "DBus", "Xml"] qt_libs = [] if arch == "Darwin": @@ -332,8 +328,7 @@ qt_flags = [ "-DQT_MESSAGELOGCONTEXT", ] qt_env['CXXFLAGS'] += qt_flags -qt_env['LIBPATH'] += ['#selfdrive/ui', f"#third_party/maplibre-native-qt/{arch}/lib"] -qt_env['RPATH'] += [Dir(f"#third_party/maplibre-native-qt/{arch}/lib").srcnode().abspath] +qt_env['LIBPATH'] += ['#selfdrive/ui', ] qt_env['LIBS'] = qt_libs if GetOption("clazy"): diff --git a/common/params.cc b/common/params.cc index 2330160173ffb6..6e6bba8867880e 100644 --- a/common/params.cc +++ b/common/params.cc @@ -91,7 +91,6 @@ std::unordered_map keys = { {"AccessToken", CLEAR_ON_MANAGER_START | DONT_LOG}, {"AlwaysOnDM", PERSISTENT}, {"ApiCache_Device", PERSISTENT}, - {"ApiCache_NavDestinations", PERSISTENT}, {"AssistNowToken", PERSISTENT}, {"AthenadPid", PERSISTENT}, {"AthenadUploadQueue", PERSISTENT}, @@ -160,11 +159,6 @@ std::unordered_map keys = { {"LiveParameters", PERSISTENT}, {"LiveTorqueParameters", PERSISTENT | DONT_LOG}, {"LongitudinalPersonality", PERSISTENT}, - {"NavDestination", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION}, - {"NavDestinationWaypoints", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION}, - {"NavPastDestinations", PERSISTENT}, - {"NavSettingLeftSide", PERSISTENT}, - {"NavSettingTime24h", PERSISTENT}, {"NetworkMetered", PERSISTENT}, {"ObdMultiplexingChanged", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION}, {"ObdMultiplexingEnabled", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION}, diff --git a/docs/c_docs.rst b/docs/c_docs.rst index 3b89fe98747200..0d65423c0854ba 100644 --- a/docs/c_docs.rst +++ b/docs/c_docs.rst @@ -50,8 +50,6 @@ qt "" .. autodoxygenindex:: :project: selfdrive_ui_qt_offroad -.. autodoxygenindex:: - :project: selfdrive_ui_qt_maps proclogd ^^^^^^^^ diff --git a/poetry.lock b/poetry.lock index 58fa7dee667abc..d81773b9f286ab 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiohttp" @@ -2730,7 +2730,6 @@ optional = false python-versions = ">=3.6" files = [ {file = "opencv-python-4.10.0.82.tar.gz", hash = "sha256:dbc021eaa310c4145c47cd648cb973db69bb5780d6e635386cd53d3ea76bd2d5"}, - {file = "opencv_python-4.10.0.82-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:5f78652339957ec24b80a782becfb32f822d2008a865512121fad8c3ce233e9a"}, {file = "opencv_python-4.10.0.82-cp37-abi3-macosx_12_0_x86_64.whl", hash = "sha256:e6be19a0615aa8c4e0d34e0c7b133e26e386f4b7e9b557b69479104ab2c133ec"}, {file = "opencv_python-4.10.0.82-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b49e530f7fd86f671514b39ffacdf5d14ceb073bc79d0de46bbb6b0cad78eaf"}, {file = "opencv_python-4.10.0.82-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955c5ce8ac90c9e4636ad7f5c0d9c75b80abbe347182cfd09b0e3eec6e50472c"}, @@ -2740,8 +2739,8 @@ files = [ [package.dependencies] numpy = [ - {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, ] [[package]] @@ -2752,7 +2751,6 @@ optional = false python-versions = ">=3.6" files = [ {file = "opencv-python-headless-4.10.0.82.tar.gz", hash = "sha256:de9e742c1b9540816fbd115b0b03841d41ed0c65566b0d7a5371f98b131b7e6d"}, - {file = "opencv_python_headless-4.10.0.82-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:a09ed50ba21cc5bf5d436cb0e784ad09c692d6b1d1454252772f6c8f2c7b4088"}, {file = "opencv_python_headless-4.10.0.82-cp37-abi3-macosx_12_0_x86_64.whl", hash = "sha256:977a5fd21e1fe0d3d2134887db4441f8725abeae95150126302f31fcd9f548fa"}, {file = "opencv_python_headless-4.10.0.82-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db4ec6755838b0be12510bfc9ffb014779c612418f11f4f7e6f505c36124a3aa"}, {file = "opencv_python_headless-4.10.0.82-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10a37fa5276967ecf6eb297295b16b28b7a2eb3b568ca0ee469fb1a5954de298"}, @@ -2762,8 +2760,8 @@ files = [ [package.dependencies] numpy = [ - {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, ] [[package]] @@ -2927,8 +2925,8 @@ files = [ [package.dependencies] numpy = [ - {version = ">=1.23.2", markers = "python_version == \"3.11\""}, {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -3090,21 +3088,6 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] -[[package]] -name = "polyline" -version = "2.0.2" -description = "A Python implementation of Google's Encoded Polyline Algorithm Format." -optional = false -python-versions = ">=3.7" -files = [ - {file = "polyline-2.0.2-py3-none-any.whl", hash = "sha256:389655c893bdabf2863c6aaa49490cf83dcdcec86ae715f67044ee98be57bef5"}, - {file = "polyline-2.0.2.tar.gz", hash = "sha256:10541e759c5fd51f746ee304e9af94744089a4055b6257b293b3afd1df64e369"}, -] - -[package.extras] -dev = ["pylint (>=3.0.3,<3.1.0)", "pytest (>=7.0,<8.0)", "pytest-cov (>=4.0,<5.0)", "sphinx (>=5.3.0,<5.4.0)", "sphinx-rtd-theme (>=1.2.0,<1.3.0)", "toml (>=0.10.2,<0.11.0)"] -publish = ["build (>=0.8,<1.0)", "twine (>=4.0,<5.0)"] - [[package]] name = "portalocker" version = "2.8.2" @@ -8114,4 +8097,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = ">=3.11, <3.13" -content-hash = "32df734a6ad6ad6a665c94c41cd0e3643a48174904faaf6f21c5c84f350f3cec" +content-hash = "163f468ff6cad9a08ccf51dfad6ef024ecc0037a0fbbcdbf2fb3b4e95ac3e744" diff --git a/pyproject.toml b/pyproject.toml index 374b0f46cafaec..1aa20b5b8e9887 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,6 @@ testpaths = [ "selfdrive/controls", "selfdrive/locationd", "selfdrive/monitoring", - "selfdrive/navd/tests", "selfdrive/test/longitudinal_maneuvers", "selfdrive/test/process_replay/test_fuzzy.py", "system/updated", @@ -183,7 +182,6 @@ natsort = "*" opencv-python-headless = "*" parameterized = "^0.8" #pprofile = "*" -polyline = "*" pyautogui = "*" pygame = "*" pyopencl = { version = "*", markers = "platform_machine != 'aarch64'" } # broken on arm64 diff --git a/selfdrive/SConscript b/selfdrive/SConscript index 52898f758f2ae7..0b49e69116f395 100644 --- a/selfdrive/SConscript +++ b/selfdrive/SConscript @@ -2,6 +2,5 @@ SConscript(['pandad/SConscript']) SConscript(['controls/lib/lateral_mpc_lib/SConscript']) SConscript(['controls/lib/longitudinal_mpc_lib/SConscript']) SConscript(['locationd/SConscript']) -SConscript(['navd/SConscript']) SConscript(['modeld/SConscript']) SConscript(['ui/SConscript']) \ No newline at end of file diff --git a/selfdrive/assets/img_map.png b/selfdrive/assets/img_map.png deleted file mode 100644 index a8646491d721e8..00000000000000 --- a/selfdrive/assets/img_map.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4a197665ae2a7fc05109903474d513379711f7b7f555c4148ca99d589c95baf7 -size 31990 diff --git a/selfdrive/assets/navigation/default_marker.svg b/selfdrive/assets/navigation/default_marker.svg deleted file mode 100644 index 4b11ee7623c8a3..00000000000000 --- a/selfdrive/assets/navigation/default_marker.svg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a950b541c4e676475e3571aaa806060c3309c7f44b08a59f1ada19881b42493d -size 389 diff --git a/selfdrive/assets/navigation/direction_arrive.png b/selfdrive/assets/navigation/direction_arrive.png deleted file mode 100644 index f8c5bdc2d81b56..00000000000000 --- a/selfdrive/assets/navigation/direction_arrive.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ae17f4c1896c88a6d520f1acdca99ab23d4ce1140a500b64bea3185041f8ecd9 -size 1246 diff --git a/selfdrive/assets/navigation/direction_arrive_left.png b/selfdrive/assets/navigation/direction_arrive_left.png deleted file mode 100644 index 6f59ab3711cd97..00000000000000 --- a/selfdrive/assets/navigation/direction_arrive_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:86a2eaf6070d6b93df385945bd7f4a6e9bb78b7cc42eb5b7ef9a9b6c075c80ce -size 1581 diff --git a/selfdrive/assets/navigation/direction_arrive_right.png b/selfdrive/assets/navigation/direction_arrive_right.png deleted file mode 100644 index 318e0413399604..00000000000000 --- a/selfdrive/assets/navigation/direction_arrive_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:398f30c89e396bb4bdbac1ba6dfe292f6e3278923e14113e705f4d0591671f32 -size 1528 diff --git a/selfdrive/assets/navigation/direction_arrive_straight.png b/selfdrive/assets/navigation/direction_arrive_straight.png deleted file mode 100644 index f8c5bdc2d81b56..00000000000000 --- a/selfdrive/assets/navigation/direction_arrive_straight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ae17f4c1896c88a6d520f1acdca99ab23d4ce1140a500b64bea3185041f8ecd9 -size 1246 diff --git a/selfdrive/assets/navigation/direction_close.png b/selfdrive/assets/navigation/direction_close.png deleted file mode 100644 index 0e9e478d455245..00000000000000 --- a/selfdrive/assets/navigation/direction_close.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0e23cac9bec0de20f9632d19618be9b05eedb010c6e23b0ba7a8e3cc8225f64e -size 865 diff --git a/selfdrive/assets/navigation/direction_continue.png b/selfdrive/assets/navigation/direction_continue.png deleted file mode 100644 index ce2c42c43de9c5..00000000000000 --- a/selfdrive/assets/navigation/direction_continue.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:008cf037b8713c710eacd1129973119faa2527ab1c19aee5340a16dc0659df8a -size 1063 diff --git a/selfdrive/assets/navigation/direction_continue_left.png b/selfdrive/assets/navigation/direction_continue_left.png deleted file mode 100644 index 438532ee2995e3..00000000000000 --- a/selfdrive/assets/navigation/direction_continue_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:579d6a27e062779d41beb9320abf5797bc8ec81de1f355a4197c3b3ee0766f28 -size 1400 diff --git a/selfdrive/assets/navigation/direction_continue_right.png b/selfdrive/assets/navigation/direction_continue_right.png deleted file mode 100644 index 4ee7ebc3b4fd2b..00000000000000 --- a/selfdrive/assets/navigation/direction_continue_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a4010c8122af918dbdb50e88629adbf79f7733f022bba263e6f44f6ffae3e7a5 -size 1371 diff --git a/selfdrive/assets/navigation/direction_continue_slight_left.png b/selfdrive/assets/navigation/direction_continue_slight_left.png deleted file mode 100644 index 29f44404608bd3..00000000000000 --- a/selfdrive/assets/navigation/direction_continue_slight_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:89041889817454869d98adfb5a16fae33596c038d5484ec734fe3a5cc532c45c -size 1334 diff --git a/selfdrive/assets/navigation/direction_continue_slight_right.png b/selfdrive/assets/navigation/direction_continue_slight_right.png deleted file mode 100644 index 755935b84c512c..00000000000000 --- a/selfdrive/assets/navigation/direction_continue_slight_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e691dd43947c9430fcd73e6bede94aa5fd8995e9303eba53cc0ac589a7c9f106 -size 1347 diff --git a/selfdrive/assets/navigation/direction_continue_straight.png b/selfdrive/assets/navigation/direction_continue_straight.png deleted file mode 100644 index ce2c42c43de9c5..00000000000000 --- a/selfdrive/assets/navigation/direction_continue_straight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:008cf037b8713c710eacd1129973119faa2527ab1c19aee5340a16dc0659df8a -size 1063 diff --git a/selfdrive/assets/navigation/direction_continue_uturn.png b/selfdrive/assets/navigation/direction_continue_uturn.png deleted file mode 100644 index ff9d97893fb766..00000000000000 --- a/selfdrive/assets/navigation/direction_continue_uturn.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e02ac2720f12f9373ae2d86d91fffb6203e18aba04b493bd6f41d2953a11cbc9 -size 1780 diff --git a/selfdrive/assets/navigation/direction_depart.png b/selfdrive/assets/navigation/direction_depart.png deleted file mode 100644 index aa4e4f7115f30e..00000000000000 --- a/selfdrive/assets/navigation/direction_depart.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8f83214c1fa6aba33ca3e1fe29db09733a275efe19864866b9edecbb59abb171 -size 1234 diff --git a/selfdrive/assets/navigation/direction_depart_left.png b/selfdrive/assets/navigation/direction_depart_left.png deleted file mode 100644 index 76937eb5d36d24..00000000000000 --- a/selfdrive/assets/navigation/direction_depart_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:459fe6410e061542876fa7de93efaf901d15937f891e801e1b93f8270e750130 -size 1613 diff --git a/selfdrive/assets/navigation/direction_depart_right.png b/selfdrive/assets/navigation/direction_depart_right.png deleted file mode 100644 index 149626b17132ed..00000000000000 --- a/selfdrive/assets/navigation/direction_depart_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e3f5fb80d62c92876a5e490917f549e2a443dfc683a6787506747bbbeb75d33b -size 1538 diff --git a/selfdrive/assets/navigation/direction_depart_straight.png b/selfdrive/assets/navigation/direction_depart_straight.png deleted file mode 100644 index aa4e4f7115f30e..00000000000000 --- a/selfdrive/assets/navigation/direction_depart_straight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8f83214c1fa6aba33ca3e1fe29db09733a275efe19864866b9edecbb59abb171 -size 1234 diff --git a/selfdrive/assets/navigation/direction_end_of_road_left.png b/selfdrive/assets/navigation/direction_end_of_road_left.png deleted file mode 100644 index 32a602bdefbb11..00000000000000 --- a/selfdrive/assets/navigation/direction_end_of_road_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b9c86ddd75ea1ed2c49c1bdc2e7f98ed15d12226938073688dda1b0bbdf62308 -size 1439 diff --git a/selfdrive/assets/navigation/direction_end_of_road_right.png b/selfdrive/assets/navigation/direction_end_of_road_right.png deleted file mode 100644 index 68915cee258f52..00000000000000 --- a/selfdrive/assets/navigation/direction_end_of_road_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cc7248e62d11cf36f9a13d408a0954a51ff0eee9b8e03d8910a2eb2cb6a09ffd -size 1456 diff --git a/selfdrive/assets/navigation/direction_flag.png b/selfdrive/assets/navigation/direction_flag.png deleted file mode 100644 index 26e8a220f27c5b..00000000000000 --- a/selfdrive/assets/navigation/direction_flag.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8509bd5dbf96e44f73421dc09ca8f7c1dddf2dc21f3b4b15650472b3e06b3470 -size 658 diff --git a/selfdrive/assets/navigation/direction_fork.png b/selfdrive/assets/navigation/direction_fork.png deleted file mode 100644 index c3019a59910489..00000000000000 --- a/selfdrive/assets/navigation/direction_fork.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5198a3fdb610001358501ca76ab52fe0979b9254ed85cbbb2ce1fab1cb77929a -size 2015 diff --git a/selfdrive/assets/navigation/direction_fork_left.png b/selfdrive/assets/navigation/direction_fork_left.png deleted file mode 100644 index a847257e9bc09f..00000000000000 --- a/selfdrive/assets/navigation/direction_fork_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:752424da0ad8430c619045455a86c640b576f8bbe6d3d8b5b6a599b1c61ef489 -size 1863 diff --git a/selfdrive/assets/navigation/direction_fork_right.png b/selfdrive/assets/navigation/direction_fork_right.png deleted file mode 100644 index 102ddf753c2e2c..00000000000000 --- a/selfdrive/assets/navigation/direction_fork_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b6590df8da1f30ec61b3bdf729fda1956d340c5abab448ea0062105500cc5da5 -size 1841 diff --git a/selfdrive/assets/navigation/direction_fork_slight_left.png b/selfdrive/assets/navigation/direction_fork_slight_left.png deleted file mode 100644 index 945ef744e0a981..00000000000000 --- a/selfdrive/assets/navigation/direction_fork_slight_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b4fbd63acf8f5e7f734b332a96e9ad138ad22ee07000ad425712e71b77ce0728 -size 1800 diff --git a/selfdrive/assets/navigation/direction_fork_slight_right.png b/selfdrive/assets/navigation/direction_fork_slight_right.png deleted file mode 100644 index 65db839df9be08..00000000000000 --- a/selfdrive/assets/navigation/direction_fork_slight_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a7a7f5bcab30ce961ff7e345c460cfbd133e45c66da1fe1f0e7bc7c826b05f30 -size 1805 diff --git a/selfdrive/assets/navigation/direction_fork_straight.png b/selfdrive/assets/navigation/direction_fork_straight.png deleted file mode 100644 index 74528d230c415e..00000000000000 --- a/selfdrive/assets/navigation/direction_fork_straight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:676cbe95f9a663816dd77c55dbcf2c346bfae2454be7832914b5527219aba91f -size 2473 diff --git a/selfdrive/assets/navigation/direction_invalid.png b/selfdrive/assets/navigation/direction_invalid.png deleted file mode 100644 index ce2c42c43de9c5..00000000000000 --- a/selfdrive/assets/navigation/direction_invalid.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:008cf037b8713c710eacd1129973119faa2527ab1c19aee5340a16dc0659df8a -size 1063 diff --git a/selfdrive/assets/navigation/direction_invalid_left.png b/selfdrive/assets/navigation/direction_invalid_left.png deleted file mode 100644 index 438532ee2995e3..00000000000000 --- a/selfdrive/assets/navigation/direction_invalid_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:579d6a27e062779d41beb9320abf5797bc8ec81de1f355a4197c3b3ee0766f28 -size 1400 diff --git a/selfdrive/assets/navigation/direction_invalid_right.png b/selfdrive/assets/navigation/direction_invalid_right.png deleted file mode 100644 index 4ee7ebc3b4fd2b..00000000000000 --- a/selfdrive/assets/navigation/direction_invalid_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a4010c8122af918dbdb50e88629adbf79f7733f022bba263e6f44f6ffae3e7a5 -size 1371 diff --git a/selfdrive/assets/navigation/direction_invalid_slight_left.png b/selfdrive/assets/navigation/direction_invalid_slight_left.png deleted file mode 100644 index 29f44404608bd3..00000000000000 --- a/selfdrive/assets/navigation/direction_invalid_slight_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:89041889817454869d98adfb5a16fae33596c038d5484ec734fe3a5cc532c45c -size 1334 diff --git a/selfdrive/assets/navigation/direction_invalid_slight_right.png b/selfdrive/assets/navigation/direction_invalid_slight_right.png deleted file mode 100644 index 755935b84c512c..00000000000000 --- a/selfdrive/assets/navigation/direction_invalid_slight_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e691dd43947c9430fcd73e6bede94aa5fd8995e9303eba53cc0ac589a7c9f106 -size 1347 diff --git a/selfdrive/assets/navigation/direction_invalid_straight.png b/selfdrive/assets/navigation/direction_invalid_straight.png deleted file mode 100644 index ce2c42c43de9c5..00000000000000 --- a/selfdrive/assets/navigation/direction_invalid_straight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:008cf037b8713c710eacd1129973119faa2527ab1c19aee5340a16dc0659df8a -size 1063 diff --git a/selfdrive/assets/navigation/direction_invalid_uturn.png b/selfdrive/assets/navigation/direction_invalid_uturn.png deleted file mode 100644 index ff9d97893fb766..00000000000000 --- a/selfdrive/assets/navigation/direction_invalid_uturn.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e02ac2720f12f9373ae2d86d91fffb6203e18aba04b493bd6f41d2953a11cbc9 -size 1780 diff --git a/selfdrive/assets/navigation/direction_merge_left.png b/selfdrive/assets/navigation/direction_merge_left.png deleted file mode 100644 index 7812f9eb94a0be..00000000000000 --- a/selfdrive/assets/navigation/direction_merge_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:08245891301f814fc0245133e39df3fb14720025cc3e4bc7131f953ead47edc8 -size 1535 diff --git a/selfdrive/assets/navigation/direction_merge_right.png b/selfdrive/assets/navigation/direction_merge_right.png deleted file mode 100644 index 3c44c8fc75d3be..00000000000000 --- a/selfdrive/assets/navigation/direction_merge_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8c629c7273fe2613538295aba807edfddbbae86ae77d6f9b0b60b0486e3f7ca9 -size 1484 diff --git a/selfdrive/assets/navigation/direction_merge_slight_left.png b/selfdrive/assets/navigation/direction_merge_slight_left.png deleted file mode 100644 index 756fb018539262..00000000000000 --- a/selfdrive/assets/navigation/direction_merge_slight_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:72c1ef39486f3dc3f7a0a97777bce16c7c369cc85bf6c82629d6780803804967 -size 1765 diff --git a/selfdrive/assets/navigation/direction_merge_slight_right.png b/selfdrive/assets/navigation/direction_merge_slight_right.png deleted file mode 100644 index b8d42b741fc9ad..00000000000000 --- a/selfdrive/assets/navigation/direction_merge_slight_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8b8bfd8019320127ed0fe03d4a1bddab57d5c2345b6cdeab66558ea9b53c0266 -size 1699 diff --git a/selfdrive/assets/navigation/direction_merge_straight.png b/selfdrive/assets/navigation/direction_merge_straight.png deleted file mode 100644 index 60035c1f0145cb..00000000000000 --- a/selfdrive/assets/navigation/direction_merge_straight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d10bdde82e7896de072de28da46412d5e2f6c902fd5643c6b48a8fc79ed4232f -size 113 diff --git a/selfdrive/assets/navigation/direction_new_name_left.png b/selfdrive/assets/navigation/direction_new_name_left.png deleted file mode 100644 index 438532ee2995e3..00000000000000 --- a/selfdrive/assets/navigation/direction_new_name_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:579d6a27e062779d41beb9320abf5797bc8ec81de1f355a4197c3b3ee0766f28 -size 1400 diff --git a/selfdrive/assets/navigation/direction_new_name_right.png b/selfdrive/assets/navigation/direction_new_name_right.png deleted file mode 100644 index 4ee7ebc3b4fd2b..00000000000000 --- a/selfdrive/assets/navigation/direction_new_name_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a4010c8122af918dbdb50e88629adbf79f7733f022bba263e6f44f6ffae3e7a5 -size 1371 diff --git a/selfdrive/assets/navigation/direction_new_name_sharp_left.png b/selfdrive/assets/navigation/direction_new_name_sharp_left.png deleted file mode 100644 index ae1f3741ef57d8..00000000000000 --- a/selfdrive/assets/navigation/direction_new_name_sharp_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0457b0597386d0b7d3cc06d961df5fb34211ee575da7fab2f81e424d9954bb42 -size 1549 diff --git a/selfdrive/assets/navigation/direction_new_name_sharp_right.png b/selfdrive/assets/navigation/direction_new_name_sharp_right.png deleted file mode 100644 index 0d8cd3ed530370..00000000000000 --- a/selfdrive/assets/navigation/direction_new_name_sharp_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4f6e1556f0b888afb6856f8cf3e16632959190f88dd66c4d9db4832a8269cbc5 -size 1552 diff --git a/selfdrive/assets/navigation/direction_new_name_slight_left.png b/selfdrive/assets/navigation/direction_new_name_slight_left.png deleted file mode 100644 index 29f44404608bd3..00000000000000 --- a/selfdrive/assets/navigation/direction_new_name_slight_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:89041889817454869d98adfb5a16fae33596c038d5484ec734fe3a5cc532c45c -size 1334 diff --git a/selfdrive/assets/navigation/direction_new_name_slight_right.png b/selfdrive/assets/navigation/direction_new_name_slight_right.png deleted file mode 100644 index 755935b84c512c..00000000000000 --- a/selfdrive/assets/navigation/direction_new_name_slight_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e691dd43947c9430fcd73e6bede94aa5fd8995e9303eba53cc0ac589a7c9f106 -size 1347 diff --git a/selfdrive/assets/navigation/direction_new_name_straight.png b/selfdrive/assets/navigation/direction_new_name_straight.png deleted file mode 100644 index ce2c42c43de9c5..00000000000000 --- a/selfdrive/assets/navigation/direction_new_name_straight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:008cf037b8713c710eacd1129973119faa2527ab1c19aee5340a16dc0659df8a -size 1063 diff --git a/selfdrive/assets/navigation/direction_notification_left.png b/selfdrive/assets/navigation/direction_notification_left.png deleted file mode 100644 index 438532ee2995e3..00000000000000 --- a/selfdrive/assets/navigation/direction_notification_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:579d6a27e062779d41beb9320abf5797bc8ec81de1f355a4197c3b3ee0766f28 -size 1400 diff --git a/selfdrive/assets/navigation/direction_notification_right.png b/selfdrive/assets/navigation/direction_notification_right.png deleted file mode 100644 index 4ee7ebc3b4fd2b..00000000000000 --- a/selfdrive/assets/navigation/direction_notification_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a4010c8122af918dbdb50e88629adbf79f7733f022bba263e6f44f6ffae3e7a5 -size 1371 diff --git a/selfdrive/assets/navigation/direction_notification_sharp_left.png b/selfdrive/assets/navigation/direction_notification_sharp_left.png deleted file mode 100644 index d2f1d491a0d59d..00000000000000 --- a/selfdrive/assets/navigation/direction_notification_sharp_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4f2016b7bac3accf541f100a2c83871618214e1806e95e4d80867d30d1dfcf03 -size 1546 diff --git a/selfdrive/assets/navigation/direction_notification_sharp_right.png b/selfdrive/assets/navigation/direction_notification_sharp_right.png deleted file mode 100644 index f338742e5883c9..00000000000000 --- a/selfdrive/assets/navigation/direction_notification_sharp_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:57dbfdabe88f6abbb8993982eef72803ac504842e9a9d388e7dde1623f69f0d7 -size 1551 diff --git a/selfdrive/assets/navigation/direction_notification_slight_left.png b/selfdrive/assets/navigation/direction_notification_slight_left.png deleted file mode 100644 index 29f44404608bd3..00000000000000 --- a/selfdrive/assets/navigation/direction_notification_slight_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:89041889817454869d98adfb5a16fae33596c038d5484ec734fe3a5cc532c45c -size 1334 diff --git a/selfdrive/assets/navigation/direction_notification_slight_right.png b/selfdrive/assets/navigation/direction_notification_slight_right.png deleted file mode 100644 index 755935b84c512c..00000000000000 --- a/selfdrive/assets/navigation/direction_notification_slight_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e691dd43947c9430fcd73e6bede94aa5fd8995e9303eba53cc0ac589a7c9f106 -size 1347 diff --git a/selfdrive/assets/navigation/direction_notification_straight.png b/selfdrive/assets/navigation/direction_notification_straight.png deleted file mode 100644 index ce2c42c43de9c5..00000000000000 --- a/selfdrive/assets/navigation/direction_notification_straight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:008cf037b8713c710eacd1129973119faa2527ab1c19aee5340a16dc0659df8a -size 1063 diff --git a/selfdrive/assets/navigation/direction_off_ramp_left.png b/selfdrive/assets/navigation/direction_off_ramp_left.png deleted file mode 100644 index d01bb4fce35c7d..00000000000000 --- a/selfdrive/assets/navigation/direction_off_ramp_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6736b6c2123cbaf90d2c8e4da79a4089ba42c0e7a220a596e45afd511166da9b -size 1524 diff --git a/selfdrive/assets/navigation/direction_off_ramp_right.png b/selfdrive/assets/navigation/direction_off_ramp_right.png deleted file mode 100644 index 013ec5a4c9f46e..00000000000000 --- a/selfdrive/assets/navigation/direction_off_ramp_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6a636d33568c658b05e460e05a1eac5c4e1cfced204044657a04191027c44c4c -size 1580 diff --git a/selfdrive/assets/navigation/direction_off_ramp_slight_left.png b/selfdrive/assets/navigation/direction_off_ramp_slight_left.png deleted file mode 100644 index 39497c8d418168..00000000000000 --- a/selfdrive/assets/navigation/direction_off_ramp_slight_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a27d55d704f77bca4beaac30a2c5b5abee304986627d09f971b2a2e0367e8477 -size 1478 diff --git a/selfdrive/assets/navigation/direction_off_ramp_slight_right.png b/selfdrive/assets/navigation/direction_off_ramp_slight_right.png deleted file mode 100644 index a68d28d674d897..00000000000000 --- a/selfdrive/assets/navigation/direction_off_ramp_slight_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e711c8e2184440f4ddead06897c90758470e7475fa7e0cf8b2db567e491c8e57 -size 1519 diff --git a/selfdrive/assets/navigation/direction_on_ramp_left.png b/selfdrive/assets/navigation/direction_on_ramp_left.png deleted file mode 100644 index 438532ee2995e3..00000000000000 --- a/selfdrive/assets/navigation/direction_on_ramp_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:579d6a27e062779d41beb9320abf5797bc8ec81de1f355a4197c3b3ee0766f28 -size 1400 diff --git a/selfdrive/assets/navigation/direction_on_ramp_right.png b/selfdrive/assets/navigation/direction_on_ramp_right.png deleted file mode 100644 index 4ee7ebc3b4fd2b..00000000000000 --- a/selfdrive/assets/navigation/direction_on_ramp_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a4010c8122af918dbdb50e88629adbf79f7733f022bba263e6f44f6ffae3e7a5 -size 1371 diff --git a/selfdrive/assets/navigation/direction_on_ramp_sharp_left.png b/selfdrive/assets/navigation/direction_on_ramp_sharp_left.png deleted file mode 100644 index ae1f3741ef57d8..00000000000000 --- a/selfdrive/assets/navigation/direction_on_ramp_sharp_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0457b0597386d0b7d3cc06d961df5fb34211ee575da7fab2f81e424d9954bb42 -size 1549 diff --git a/selfdrive/assets/navigation/direction_on_ramp_sharp_right.png b/selfdrive/assets/navigation/direction_on_ramp_sharp_right.png deleted file mode 100644 index f338742e5883c9..00000000000000 --- a/selfdrive/assets/navigation/direction_on_ramp_sharp_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:57dbfdabe88f6abbb8993982eef72803ac504842e9a9d388e7dde1623f69f0d7 -size 1551 diff --git a/selfdrive/assets/navigation/direction_on_ramp_slight_left.png b/selfdrive/assets/navigation/direction_on_ramp_slight_left.png deleted file mode 100644 index e640fe3404737c..00000000000000 --- a/selfdrive/assets/navigation/direction_on_ramp_slight_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7b2f19864347794510da5e13ebaed40cc01d45bbd649c3e5097052607af52fa7 -size 1334 diff --git a/selfdrive/assets/navigation/direction_on_ramp_slight_right.png b/selfdrive/assets/navigation/direction_on_ramp_slight_right.png deleted file mode 100644 index d309f2d14e2546..00000000000000 --- a/selfdrive/assets/navigation/direction_on_ramp_slight_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0d2704d4d480568deb63598a48b741b024f4e55f5936e3eeb9cdc3daf6618837 -size 1346 diff --git a/selfdrive/assets/navigation/direction_on_ramp_straight.png b/selfdrive/assets/navigation/direction_on_ramp_straight.png deleted file mode 100644 index ce2c42c43de9c5..00000000000000 --- a/selfdrive/assets/navigation/direction_on_ramp_straight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:008cf037b8713c710eacd1129973119faa2527ab1c19aee5340a16dc0659df8a -size 1063 diff --git a/selfdrive/assets/navigation/direction_rotary.png b/selfdrive/assets/navigation/direction_rotary.png deleted file mode 100644 index 20b405201559e2..00000000000000 --- a/selfdrive/assets/navigation/direction_rotary.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1868ec727cd761aad76fb6cb7705360ed9f70a92aea97f4c3b945b043996d1e2 -size 1906 diff --git a/selfdrive/assets/navigation/direction_rotary_left.png b/selfdrive/assets/navigation/direction_rotary_left.png deleted file mode 100644 index f6105012862592..00000000000000 --- a/selfdrive/assets/navigation/direction_rotary_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b2d41ab080452ce24ce27ed833f24790a6e6218dc4a5df4b35d23d6cfc425fbb -size 1543 diff --git a/selfdrive/assets/navigation/direction_rotary_right.png b/selfdrive/assets/navigation/direction_rotary_right.png deleted file mode 100644 index 9b8ea37ddfd432..00000000000000 --- a/selfdrive/assets/navigation/direction_rotary_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:94251b2485f1f8bd0b22eb32fd59459626229c38e4de9aa538ff249b3cc16505 -size 1743 diff --git a/selfdrive/assets/navigation/direction_rotary_sharp_left.png b/selfdrive/assets/navigation/direction_rotary_sharp_left.png deleted file mode 100644 index cbc08827916a93..00000000000000 --- a/selfdrive/assets/navigation/direction_rotary_sharp_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6fbc14fb3720b7452c34c64af8c9b6ce4c953a5e65f3b28ad1ed17b5b2bc47f0 -size 1532 diff --git a/selfdrive/assets/navigation/direction_rotary_sharp_right.png b/selfdrive/assets/navigation/direction_rotary_sharp_right.png deleted file mode 100644 index c7d4ba3175196d..00000000000000 --- a/selfdrive/assets/navigation/direction_rotary_sharp_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0fe99a15432706ac8bdd5766d3ed4869042b50e0d3c54665b63ba8eb2aaaef20 -size 1855 diff --git a/selfdrive/assets/navigation/direction_rotary_slight_left.png b/selfdrive/assets/navigation/direction_rotary_slight_left.png deleted file mode 100644 index 9b5912030bd243..00000000000000 --- a/selfdrive/assets/navigation/direction_rotary_slight_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:45115d7c0d4a6285406777787b19b5f6f9c8231ba773aaaa86ab62b7f94b1c51 -size 1699 diff --git a/selfdrive/assets/navigation/direction_rotary_slight_right.png b/selfdrive/assets/navigation/direction_rotary_slight_right.png deleted file mode 100644 index bc5e6b0d2e2e34..00000000000000 --- a/selfdrive/assets/navigation/direction_rotary_slight_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9ea0a56d30f763f69ba1c5051f05eac13e61a715ae4d80412b1e0570f3263e27 -size 1821 diff --git a/selfdrive/assets/navigation/direction_rotary_straight.png b/selfdrive/assets/navigation/direction_rotary_straight.png deleted file mode 100644 index ac4eec685e0e52..00000000000000 --- a/selfdrive/assets/navigation/direction_rotary_straight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:77c42dadeda4d9fdc5b8e7915319880908dd61acb46e289e88f8e067b8e57410 -size 1736 diff --git a/selfdrive/assets/navigation/direction_roundabout.png b/selfdrive/assets/navigation/direction_roundabout.png deleted file mode 100644 index 20b405201559e2..00000000000000 --- a/selfdrive/assets/navigation/direction_roundabout.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1868ec727cd761aad76fb6cb7705360ed9f70a92aea97f4c3b945b043996d1e2 -size 1906 diff --git a/selfdrive/assets/navigation/direction_roundabout_left.png b/selfdrive/assets/navigation/direction_roundabout_left.png deleted file mode 100644 index f6105012862592..00000000000000 --- a/selfdrive/assets/navigation/direction_roundabout_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b2d41ab080452ce24ce27ed833f24790a6e6218dc4a5df4b35d23d6cfc425fbb -size 1543 diff --git a/selfdrive/assets/navigation/direction_roundabout_right.png b/selfdrive/assets/navigation/direction_roundabout_right.png deleted file mode 100644 index 9b8ea37ddfd432..00000000000000 --- a/selfdrive/assets/navigation/direction_roundabout_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:94251b2485f1f8bd0b22eb32fd59459626229c38e4de9aa538ff249b3cc16505 -size 1743 diff --git a/selfdrive/assets/navigation/direction_roundabout_sharp_left.png b/selfdrive/assets/navigation/direction_roundabout_sharp_left.png deleted file mode 100644 index 204586589d278c..00000000000000 --- a/selfdrive/assets/navigation/direction_roundabout_sharp_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e7423462cc52bf5d97b6d2e05626f8066a6580b03922bc35589690b15d04a222 -size 1532 diff --git a/selfdrive/assets/navigation/direction_roundabout_sharp_right.png b/selfdrive/assets/navigation/direction_roundabout_sharp_right.png deleted file mode 100644 index c7d4ba3175196d..00000000000000 --- a/selfdrive/assets/navigation/direction_roundabout_sharp_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0fe99a15432706ac8bdd5766d3ed4869042b50e0d3c54665b63ba8eb2aaaef20 -size 1855 diff --git a/selfdrive/assets/navigation/direction_roundabout_slight_left.png b/selfdrive/assets/navigation/direction_roundabout_slight_left.png deleted file mode 100644 index d8b806137c574b..00000000000000 --- a/selfdrive/assets/navigation/direction_roundabout_slight_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2b6cdda3bc23add330fa03095fc46251dbe2516f974d4ae44c321d87dc662d54 -size 1702 diff --git a/selfdrive/assets/navigation/direction_roundabout_slight_right.png b/selfdrive/assets/navigation/direction_roundabout_slight_right.png deleted file mode 100644 index bc5e6b0d2e2e34..00000000000000 --- a/selfdrive/assets/navigation/direction_roundabout_slight_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9ea0a56d30f763f69ba1c5051f05eac13e61a715ae4d80412b1e0570f3263e27 -size 1821 diff --git a/selfdrive/assets/navigation/direction_roundabout_straight.png b/selfdrive/assets/navigation/direction_roundabout_straight.png deleted file mode 100644 index ac4eec685e0e52..00000000000000 --- a/selfdrive/assets/navigation/direction_roundabout_straight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:77c42dadeda4d9fdc5b8e7915319880908dd61acb46e289e88f8e067b8e57410 -size 1736 diff --git a/selfdrive/assets/navigation/direction_turn_left.png b/selfdrive/assets/navigation/direction_turn_left.png deleted file mode 100644 index 438532ee2995e3..00000000000000 --- a/selfdrive/assets/navigation/direction_turn_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:579d6a27e062779d41beb9320abf5797bc8ec81de1f355a4197c3b3ee0766f28 -size 1400 diff --git a/selfdrive/assets/navigation/direction_turn_left_inactive.png b/selfdrive/assets/navigation/direction_turn_left_inactive.png deleted file mode 100644 index 7f461a1967b40b..00000000000000 --- a/selfdrive/assets/navigation/direction_turn_left_inactive.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5229d184ca31e027d8c8d493b7d02a34c8097348aab97e10adc7fd78acf6a7fc -size 7221 diff --git a/selfdrive/assets/navigation/direction_turn_right.png b/selfdrive/assets/navigation/direction_turn_right.png deleted file mode 100644 index 4ee7ebc3b4fd2b..00000000000000 --- a/selfdrive/assets/navigation/direction_turn_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a4010c8122af918dbdb50e88629adbf79f7733f022bba263e6f44f6ffae3e7a5 -size 1371 diff --git a/selfdrive/assets/navigation/direction_turn_right_inactive.png b/selfdrive/assets/navigation/direction_turn_right_inactive.png deleted file mode 100644 index bc0a98dccf08b3..00000000000000 --- a/selfdrive/assets/navigation/direction_turn_right_inactive.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fc6c17196f0e345e7c79b60faadd931755b3d1572125557ff263247e7b3a0b4b -size 7239 diff --git a/selfdrive/assets/navigation/direction_turn_sharp_left.png b/selfdrive/assets/navigation/direction_turn_sharp_left.png deleted file mode 100644 index d2f1d491a0d59d..00000000000000 --- a/selfdrive/assets/navigation/direction_turn_sharp_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4f2016b7bac3accf541f100a2c83871618214e1806e95e4d80867d30d1dfcf03 -size 1546 diff --git a/selfdrive/assets/navigation/direction_turn_sharp_right.png b/selfdrive/assets/navigation/direction_turn_sharp_right.png deleted file mode 100644 index f338742e5883c9..00000000000000 --- a/selfdrive/assets/navigation/direction_turn_sharp_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:57dbfdabe88f6abbb8993982eef72803ac504842e9a9d388e7dde1623f69f0d7 -size 1551 diff --git a/selfdrive/assets/navigation/direction_turn_slight_left.png b/selfdrive/assets/navigation/direction_turn_slight_left.png deleted file mode 100644 index 29f44404608bd3..00000000000000 --- a/selfdrive/assets/navigation/direction_turn_slight_left.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:89041889817454869d98adfb5a16fae33596c038d5484ec734fe3a5cc532c45c -size 1334 diff --git a/selfdrive/assets/navigation/direction_turn_slight_left_inactive.png b/selfdrive/assets/navigation/direction_turn_slight_left_inactive.png deleted file mode 100644 index 7c970ebb81faf9..00000000000000 --- a/selfdrive/assets/navigation/direction_turn_slight_left_inactive.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5ce2ea01f9ed172048c86b93e0ebfa8f468473de49be92ad200fb54d688434cb -size 3696 diff --git a/selfdrive/assets/navigation/direction_turn_slight_right.png b/selfdrive/assets/navigation/direction_turn_slight_right.png deleted file mode 100644 index 755935b84c512c..00000000000000 --- a/selfdrive/assets/navigation/direction_turn_slight_right.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e691dd43947c9430fcd73e6bede94aa5fd8995e9303eba53cc0ac589a7c9f106 -size 1347 diff --git a/selfdrive/assets/navigation/direction_turn_slight_right_inactive.png b/selfdrive/assets/navigation/direction_turn_slight_right_inactive.png deleted file mode 100644 index 15611decaaa201..00000000000000 --- a/selfdrive/assets/navigation/direction_turn_slight_right_inactive.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6c1a3d5ee5f493093848b0b5f09e3572bf3cb8a6f79907fcb1b1bd4d690bc634 -size 3743 diff --git a/selfdrive/assets/navigation/direction_turn_straight.png b/selfdrive/assets/navigation/direction_turn_straight.png deleted file mode 100644 index ce2c42c43de9c5..00000000000000 --- a/selfdrive/assets/navigation/direction_turn_straight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:008cf037b8713c710eacd1129973119faa2527ab1c19aee5340a16dc0659df8a -size 1063 diff --git a/selfdrive/assets/navigation/direction_turn_straight_inactive.png b/selfdrive/assets/navigation/direction_turn_straight_inactive.png deleted file mode 100644 index d864e58bd97acf..00000000000000 --- a/selfdrive/assets/navigation/direction_turn_straight_inactive.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2cd32abafe04c8f79d3249a79a32473102ddab7770cb8be29d51b2743869fdaa -size 5452 diff --git a/selfdrive/assets/navigation/direction_turn_uturn.png b/selfdrive/assets/navigation/direction_turn_uturn.png deleted file mode 100644 index ff9d97893fb766..00000000000000 --- a/selfdrive/assets/navigation/direction_turn_uturn.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e02ac2720f12f9373ae2d86d91fffb6203e18aba04b493bd6f41d2953a11cbc9 -size 1780 diff --git a/selfdrive/assets/navigation/direction_updown.png b/selfdrive/assets/navigation/direction_updown.png deleted file mode 100644 index 3c9e3fe22e019b..00000000000000 --- a/selfdrive/assets/navigation/direction_updown.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:41adb4c64ca3cecf2f6de7dcca8826980369995959ad0eb3d7ec584bbac9b4a6 -size 1327 diff --git a/selfdrive/assets/navigation/home.png b/selfdrive/assets/navigation/home.png deleted file mode 100644 index 321cef4163007d..00000000000000 --- a/selfdrive/assets/navigation/home.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6e2fcc5b07c69bb71506257a37d0fd6abe3bd53892f34d6600a3a09795174da5 -size 6128 diff --git a/selfdrive/assets/navigation/home.svg b/selfdrive/assets/navigation/home.svg deleted file mode 100644 index 9d9c60da391c53..00000000000000 --- a/selfdrive/assets/navigation/home.svg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:62f1548c61503d8fdb03592413c38204834d52b30b6fb18d1a9982229616a97e -size 2713 diff --git a/selfdrive/assets/navigation/home_inactive.png b/selfdrive/assets/navigation/home_inactive.png deleted file mode 100644 index 9ffaf2b87b1702..00000000000000 --- a/selfdrive/assets/navigation/home_inactive.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d5dc1f7709720d51911e1c2bd61a6bed9fe30c48807b9f26f542e280c54c1a74 -size 9165 diff --git a/selfdrive/assets/navigation/icon_directions.svg b/selfdrive/assets/navigation/icon_directions.svg deleted file mode 100644 index c36e27316e1a8f..00000000000000 --- a/selfdrive/assets/navigation/icon_directions.svg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:935cd01600d56350cda1941cf382c7c86cd959fa7a0a574bdba8b3011a350578 -size 466 diff --git a/selfdrive/assets/navigation/icon_directions_outlined.svg b/selfdrive/assets/navigation/icon_directions_outlined.svg deleted file mode 100644 index 356a1e74566654..00000000000000 --- a/selfdrive/assets/navigation/icon_directions_outlined.svg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0e5f0b26a56397872f8ac6085a18b666fba4cdf01299f73d704cb29b22c64606 -size 780 diff --git a/selfdrive/assets/navigation/icon_favorite.svg b/selfdrive/assets/navigation/icon_favorite.svg deleted file mode 100644 index 0eb0e43688fc38..00000000000000 --- a/selfdrive/assets/navigation/icon_favorite.svg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ff184bf0239c54060ffbaf465573f17cbc92bd8d3d38ce10e1bd02cdd2b21575 -size 315 diff --git a/selfdrive/assets/navigation/icon_home.svg b/selfdrive/assets/navigation/icon_home.svg deleted file mode 100644 index ca90cc7bf6747b..00000000000000 --- a/selfdrive/assets/navigation/icon_home.svg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1673f8d46251a05787b60346193852991739345506dc7e9b106dfb370d3611ed -size 489 diff --git a/selfdrive/assets/navigation/icon_recent.svg b/selfdrive/assets/navigation/icon_recent.svg deleted file mode 100644 index 76b5a620b12b29..00000000000000 --- a/selfdrive/assets/navigation/icon_recent.svg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5fbce167d2005d08e8bc2113e0a9d5d3e2ed113db8e2a020df1ee14633cd3eed -size 1279 diff --git a/selfdrive/assets/navigation/icon_settings.svg b/selfdrive/assets/navigation/icon_settings.svg deleted file mode 100644 index 3fd31459c3f147..00000000000000 --- a/selfdrive/assets/navigation/icon_settings.svg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1fa72d94b5e05884129dd502babd5de78666c349bb5d12e19872fdbc9fe2100e -size 910 diff --git a/selfdrive/assets/navigation/icon_work.svg b/selfdrive/assets/navigation/icon_work.svg deleted file mode 100644 index dc18914a3943fa..00000000000000 --- a/selfdrive/assets/navigation/icon_work.svg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7ea949d3b66896ac3404d20aea9445a5cd00fefd18623f1c7160293a1de5f807 -size 364 diff --git a/selfdrive/assets/navigation/work.png b/selfdrive/assets/navigation/work.png deleted file mode 100644 index 589087a8aa197a..00000000000000 --- a/selfdrive/assets/navigation/work.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:49aef21620a5d2666c87975b28c6eb1cc8e613c80e504d97f5278cde25872c9d -size 5570 diff --git a/selfdrive/assets/navigation/work.svg b/selfdrive/assets/navigation/work.svg deleted file mode 100644 index 0f6a9ba65b3291..00000000000000 --- a/selfdrive/assets/navigation/work.svg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d2495943fec4ab00b1df5e4e6227bbec45ec57b19b25be561d616292316212f8 -size 2188 diff --git a/selfdrive/assets/navigation/work_inactive.png b/selfdrive/assets/navigation/work_inactive.png deleted file mode 100644 index c1ce69b0042c4b..00000000000000 --- a/selfdrive/assets/navigation/work_inactive.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:93e6a2b405bbbdf48d54fc7c37612430f6688cf8541ee59b984d6add3b8f02a7 -size 8446 diff --git a/selfdrive/assets/offroad/icon_map.png b/selfdrive/assets/offroad/icon_map.png deleted file mode 100644 index 82c0236a48d28d..00000000000000 --- a/selfdrive/assets/offroad/icon_map.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:57a92adcf88c7223b07697f8c2b315f4f4a34b32a866284610d5250144863c6f -size 28235 diff --git a/selfdrive/assets/offroad/icon_map_speed.png b/selfdrive/assets/offroad/icon_map_speed.png deleted file mode 100644 index 4ed1de314b30d4..00000000000000 --- a/selfdrive/assets/offroad/icon_map_speed.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7e950f121f7ed564b149dd430527c8f0ef976b6d9af66a61fb7b5ebaf7170185 -size 29822 diff --git a/selfdrive/navd/.gitignore b/selfdrive/navd/.gitignore deleted file mode 100644 index 4801d60a2c86c8..00000000000000 --- a/selfdrive/navd/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -moc_* -*.moc - -mapsd -map_renderer -libmap_renderer.so diff --git a/selfdrive/navd/README.md b/selfdrive/navd/README.md deleted file mode 100644 index 81de8ae39f6c09..00000000000000 --- a/selfdrive/navd/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# navigation - -This directory contains two daemons, `navd` and `mapsd`, which support navigation in the openpilot stack. - -### navd - -`navd` takes in a route through the `NavDestination` param and sends out two packets: `navRoute` and `navInstruction`. These packets contain the coordinates of the planned route and turn-by-turn instructions. - -### map renderer - -The map renderer listens for the `navRoute` and publishes a simplified rendered map view over VisionIPC. The rendered maps look like this: - -![](https://i.imgur.com/oZLfmwq.png) - -## development - -Currently, [mapbox](https://www.mapbox.com/) is used for navigation. - -* get an API token: https://docs.mapbox.com/help/glossary/access-token/ -* set an API token using the `MAPBOX_TOKEN` environment variable -* routes/destinations are set through the `NavDestination` param - * use `set_destination.py` for debugging -* edit the map: https://www.mapbox.com/contribute -* mapbox API playground: https://docs.mapbox.com/playground/ diff --git a/selfdrive/navd/SConscript b/selfdrive/navd/SConscript deleted file mode 100644 index 378e7624942e75..00000000000000 --- a/selfdrive/navd/SConscript +++ /dev/null @@ -1,20 +0,0 @@ -Import('qt_env', 'arch', 'common', 'messaging', 'visionipc', 'transformations', 'UBUNTU_FOCAL') - -map_env = qt_env.Clone() -libs = ['qt_widgets', 'qt_util', 'QMapLibre', common, messaging, visionipc, transformations, - 'm', 'OpenCL', 'ssl', 'crypto', 'pthread', 'json11'] + map_env["LIBS"] -if arch == 'larch64': - libs.append(':libEGL_mesa.so.0') - -if arch in ['larch64', 'aarch64', 'x86_64'] and not UBUNTU_FOCAL: - if arch == 'x86_64': - rpath = Dir(f"#third_party/maplibre-native-qt/{arch}/lib").srcnode().abspath - map_env["RPATH"] += [rpath, ] - - style_path = File("style.json").abspath - map_env['CXXFLAGS'].append(f'-DSTYLE_PATH=\\"{style_path}\\"') - - map_env["RPATH"].append(Dir('.').abspath) - map_env["LIBPATH"].append(Dir('.').abspath) - maplib = map_env.SharedLibrary("maprender", ["map_renderer.cc"], LIBS=libs) - # map_env.Program("mapsd", ["main.cc", ], LIBS=[maplib[0].get_path(), ] + libs) diff --git a/selfdrive/navd/__init__.py b/selfdrive/navd/__init__.py deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/selfdrive/navd/helpers.py b/selfdrive/navd/helpers.py deleted file mode 100644 index 0f0410c2c7ccda..00000000000000 --- a/selfdrive/navd/helpers.py +++ /dev/null @@ -1,189 +0,0 @@ -from __future__ import annotations - -import json -import math -from typing import Any, cast - -from openpilot.common.conversions import Conversions -from openpilot.common.numpy_fast import clip -from openpilot.common.params import Params - -DIRECTIONS = ('left', 'right', 'straight') -MODIFIABLE_DIRECTIONS = ('left', 'right') - -EARTH_MEAN_RADIUS = 6371007.2 -SPEED_CONVERSIONS = { - 'km/h': Conversions.KPH_TO_MS, - 'mph': Conversions.MPH_TO_MS, - } - - -class Coordinate: - def __init__(self, latitude: float, longitude: float) -> None: - self.latitude = latitude - self.longitude = longitude - self.annotations: dict[str, float] = {} - - @classmethod - def from_mapbox_tuple(cls, t: tuple[float, float]) -> Coordinate: - return cls(t[1], t[0]) - - def as_dict(self) -> dict[str, float]: - return {'latitude': self.latitude, 'longitude': self.longitude} - - def __str__(self) -> str: - return f'Coordinate({self.latitude}, {self.longitude})' - - def __repr__(self) -> str: - return self.__str__() - - def __eq__(self, other) -> bool: - if not isinstance(other, Coordinate): - return False - return (self.latitude == other.latitude) and (self.longitude == other.longitude) - - def __sub__(self, other: Coordinate) -> Coordinate: - return Coordinate(self.latitude - other.latitude, self.longitude - other.longitude) - - def __add__(self, other: Coordinate) -> Coordinate: - return Coordinate(self.latitude + other.latitude, self.longitude + other.longitude) - - def __mul__(self, c: float) -> Coordinate: - return Coordinate(self.latitude * c, self.longitude * c) - - def dot(self, other: Coordinate) -> float: - return self.latitude * other.latitude + self.longitude * other.longitude - - def distance_to(self, other: Coordinate) -> float: - # Haversine formula - dlat = math.radians(other.latitude - self.latitude) - dlon = math.radians(other.longitude - self.longitude) - - haversine_dlat = math.sin(dlat / 2.0) - haversine_dlat *= haversine_dlat - haversine_dlon = math.sin(dlon / 2.0) - haversine_dlon *= haversine_dlon - - y = haversine_dlat \ - + math.cos(math.radians(self.latitude)) \ - * math.cos(math.radians(other.latitude)) \ - * haversine_dlon - x = 2 * math.asin(math.sqrt(y)) - return x * EARTH_MEAN_RADIUS - - -def minimum_distance(a: Coordinate, b: Coordinate, p: Coordinate): - if a.distance_to(b) < 0.01: - return a.distance_to(p) - - ap = p - a - ab = b - a - t = clip(ap.dot(ab) / ab.dot(ab), 0.0, 1.0) - projection = a + ab * t - return projection.distance_to(p) - - -def distance_along_geometry(geometry: list[Coordinate], pos: Coordinate) -> float: - if len(geometry) <= 2: - return geometry[0].distance_to(pos) - - # 1. Find segment that is closest to current position - # 2. Total distance is sum of distance to start of closest segment - # + all previous segments - total_distance = 0.0 - total_distance_closest = 0.0 - closest_distance = 1e9 - - for i in range(len(geometry) - 1): - d = minimum_distance(geometry[i], geometry[i + 1], pos) - - if d < closest_distance: - closest_distance = d - total_distance_closest = total_distance + geometry[i].distance_to(pos) - - total_distance += geometry[i].distance_to(geometry[i + 1]) - - return total_distance_closest - - -def coordinate_from_param(param: str, params: Params = None) -> Coordinate | None: - if params is None: - params = Params() - - json_str = params.get(param) - if json_str is None: - return None - - pos = json.loads(json_str) - if 'latitude' not in pos or 'longitude' not in pos: - return None - - return Coordinate(pos['latitude'], pos['longitude']) - - -def string_to_direction(direction: str) -> str: - for d in DIRECTIONS: - if d in direction: - if 'slight' in direction and d in MODIFIABLE_DIRECTIONS: - return 'slight' + d.capitalize() - return d - return 'none' - - -def maxspeed_to_ms(maxspeed: dict[str, str | float]) -> float: - unit = cast(str, maxspeed['unit']) - speed = cast(float, maxspeed['speed']) - return SPEED_CONVERSIONS[unit] * speed - - -def field_valid(dat: dict, field: str) -> bool: - return field in dat and dat[field] is not None - - -def parse_banner_instructions(banners: Any, distance_to_maneuver: float = 0.0) -> dict[str, Any] | None: - if not len(banners): - return None - - instruction = {} - - # A segment can contain multiple banners, find one that we need to show now - current_banner = banners[0] - for banner in banners: - if distance_to_maneuver < banner['distanceAlongGeometry']: - current_banner = banner - - # Only show banner when close enough to maneuver - instruction['showFull'] = distance_to_maneuver < current_banner['distanceAlongGeometry'] - - # Primary - p = current_banner['primary'] - if field_valid(p, 'text'): - instruction['maneuverPrimaryText'] = p['text'] - if field_valid(p, 'type'): - instruction['maneuverType'] = p['type'] - if field_valid(p, 'modifier'): - instruction['maneuverModifier'] = p['modifier'] - - # Secondary - if field_valid(current_banner, 'secondary'): - instruction['maneuverSecondaryText'] = current_banner['secondary']['text'] - - # Lane lines - if field_valid(current_banner, 'sub'): - lanes = [] - for component in current_banner['sub']['components']: - if component['type'] != 'lane': - continue - - lane = { - 'active': component['active'], - 'directions': [string_to_direction(d) for d in component['directions']], - } - - if field_valid(component, 'active_direction'): - lane['activeDirection'] = string_to_direction(component['active_direction']) - - lanes.append(lane) - instruction['lanes'] = lanes - - return instruction diff --git a/selfdrive/navd/main.cc b/selfdrive/navd/main.cc deleted file mode 100644 index 2e7b4d3b60fc61..00000000000000 --- a/selfdrive/navd/main.cc +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include - -#include -#include - -#include "common/util.h" -#include "selfdrive/ui/qt/util.h" -#include "selfdrive/ui/qt/maps/map_helpers.h" -#include "selfdrive/navd/map_renderer.h" -#include "system/hardware/hw.h" - -int main(int argc, char *argv[]) { - Hardware::config_cpu_rendering(true); - - qInstallMessageHandler(swagLogMessageHandler); - setpriority(PRIO_PROCESS, 0, -20); - int ret = util::set_core_affinity({0, 1, 2, 3}); - assert(ret == 0); - - QApplication app(argc, argv); - std::signal(SIGINT, sigTermHandler); - std::signal(SIGTERM, sigTermHandler); - - MapRenderer * m = new MapRenderer(get_mapbox_settings()); - assert(m); - - return app.exec(); -} diff --git a/selfdrive/navd/map_renderer.cc b/selfdrive/navd/map_renderer.cc deleted file mode 100644 index 1e57ad3e7c9f88..00000000000000 --- a/selfdrive/navd/map_renderer.cc +++ /dev/null @@ -1,338 +0,0 @@ -#include "selfdrive/navd/map_renderer.h" - -#include -#include -#include -#include - -#include "common/util.h" -#include "common/timing.h" -#include "common/swaglog.h" -#include "selfdrive/ui/qt/maps/map_helpers.h" - -const float DEFAULT_ZOOM = 13.5; // Don't go below 13 or features will start to disappear -const int HEIGHT = 256, WIDTH = 256; -const int NUM_VIPC_BUFFERS = 4; - -const int EARTH_CIRCUMFERENCE_METERS = 40075000; -const int EARTH_RADIUS_METERS = 6378137; -const int PIXELS_PER_TILE = 256; -const int MAP_OFFSET = 128; - -const bool TEST_MODE = getenv("MAP_RENDER_TEST_MODE"); -const int LLK_DECIMATION = TEST_MODE ? 1 : 10; - -float get_zoom_level_for_scale(float lat, float meters_per_pixel) { - float meters_per_tile = meters_per_pixel * PIXELS_PER_TILE; - float num_tiles = cos(DEG2RAD(lat)) * EARTH_CIRCUMFERENCE_METERS / meters_per_tile; - return log2(num_tiles) - 1; -} - -QMapLibre::Coordinate get_point_along_line(float lat, float lon, float bearing, float dist) { - float ang_dist = dist / EARTH_RADIUS_METERS; - float lat1 = DEG2RAD(lat), lon1 = DEG2RAD(lon), bearing1 = DEG2RAD(bearing); - float lat2 = asin(sin(lat1)*cos(ang_dist) + cos(lat1)*sin(ang_dist)*cos(bearing1)); - float lon2 = lon1 + atan2(sin(bearing1)*sin(ang_dist)*cos(lat1), cos(ang_dist)-sin(lat1)*sin(lat2)); - return QMapLibre::Coordinate(RAD2DEG(lat2), RAD2DEG(lon2)); -} - - -MapRenderer::MapRenderer(const QMapLibre::Settings &settings, bool online) : m_settings(settings) { - QSurfaceFormat fmt; - fmt.setRenderableType(QSurfaceFormat::OpenGLES); - - m_settings.setMapMode(QMapLibre::Settings::MapMode::Static); - - ctx = std::make_unique(); - ctx->setFormat(fmt); - ctx->create(); - assert(ctx->isValid()); - - surface = std::make_unique(); - surface->setFormat(ctx->format()); - surface->create(); - - ctx->makeCurrent(surface.get()); - assert(QOpenGLContext::currentContext() == ctx.get()); - - gl_functions.reset(ctx->functions()); - gl_functions->initializeOpenGLFunctions(); - - QOpenGLFramebufferObjectFormat fbo_format; - fbo.reset(new QOpenGLFramebufferObject(WIDTH, HEIGHT, fbo_format)); - - std::string style = util::read_file(STYLE_PATH); - m_map.reset(new QMapLibre::Map(nullptr, m_settings, fbo->size(), 1)); - m_map->setCoordinateZoom(QMapLibre::Coordinate(0, 0), DEFAULT_ZOOM); - m_map->setStyleJson(style.c_str()); - m_map->createRenderer(); - ever_loaded = false; - - m_map->resize(fbo->size()); - m_map->setFramebufferObject(fbo->handle(), fbo->size()); - gl_functions->glViewport(0, 0, WIDTH, HEIGHT); - - QObject::connect(m_map.data(), &QMapLibre::Map::mapChanged, [=](QMapLibre::Map::MapChange change) { - // Ignore expected signals - // https://github.com/mapbox/mapbox-gl-native/blob/cf734a2fec960025350d8de0d01ad38aeae155a0/platform/qt/include/qmapboxgl.hpp#L116 - if (ever_loaded) { - if (change != QMapLibre::Map::MapChange::MapChangeRegionWillChange && - change != QMapLibre::Map::MapChange::MapChangeRegionDidChange && - change != QMapLibre::Map::MapChange::MapChangeWillStartRenderingFrame && - change != QMapLibre::Map::MapChange::MapChangeDidFinishRenderingFrameFullyRendered) { - LOGD("New map state: %d", change); - } - } - }); - - QObject::connect(m_map.data(), &QMapLibre::Map::mapLoadingFailed, [=](QMapLibre::Map::MapLoadingFailure err_code, const QString &reason) { - LOGE("Map loading failed with %d: '%s'\n", err_code, reason.toStdString().c_str()); - }); - - QObject::connect(m_map.data(), &QMapLibre::Map::staticRenderFinished, [=](const QString &error) { - rendering = false; - - if (!error.isEmpty()) { - LOGE("Static map rendering failed with error: '%s'\n", error.toStdString().c_str()); - } else if (vipc_server != nullptr) { - double end_render_t = millis_since_boot(); - publish((end_render_t - start_render_t) / 1000.0, true); - last_llk_rendered = (*sm)["liveLocationKalman"].getLogMonoTime(); - } - }); - - if (online) { - vipc_server.reset(new VisionIpcServer("navd")); - vipc_server->create_buffers(VisionStreamType::VISION_STREAM_MAP, NUM_VIPC_BUFFERS, false, WIDTH, HEIGHT); - vipc_server->start_listener(); - - pm.reset(new PubMaster({"navThumbnail", "mapRenderState"})); - sm.reset(new SubMaster({"liveLocationKalman", "navRoute"}, {"liveLocationKalman"})); - - timer = new QTimer(this); - timer->setSingleShot(true); - QObject::connect(timer, SIGNAL(timeout()), this, SLOT(msgUpdate())); - timer->start(0); - } -} - -void MapRenderer::msgUpdate() { - sm->update(1000); - - if (sm->updated("liveLocationKalman")) { - auto location = (*sm)["liveLocationKalman"].getLiveLocationKalman(); - auto pos = location.getPositionGeodetic(); - auto orientation = location.getCalibratedOrientationNED(); - - if ((sm->rcv_frame("liveLocationKalman") % LLK_DECIMATION) == 0) { - float bearing = RAD2DEG(orientation.getValue()[2]); - updatePosition(get_point_along_line(pos.getValue()[0], pos.getValue()[1], bearing, MAP_OFFSET), bearing); - - if (!rendering) { - update(); - } - - if (!rendered()) { - publish(0, false); - } - } - - - } - - if (sm->updated("navRoute")) { - QList route; - auto coords = (*sm)["navRoute"].getNavRoute().getCoordinates(); - for (auto const &c : coords) { - route.push_back(QGeoCoordinate(c.getLatitude(), c.getLongitude())); - } - updateRoute(route); - } - - // schedule next update - timer->start(0); -} - -void MapRenderer::updatePosition(QMapLibre::Coordinate position, float bearing) { - if (m_map.isNull()) { - return; - } - - // Choose a scale that ensures above 13 zoom level up to and above 75deg of lat - float meters_per_pixel = 2; - float zoom = get_zoom_level_for_scale(position.first, meters_per_pixel); - - m_map->setCoordinate(position); - m_map->setBearing(bearing); - m_map->setZoom(zoom); - if (!rendering) { - update(); - } -} - -bool MapRenderer::loaded() { - return m_map->isFullyLoaded(); -} - -void MapRenderer::update() { - rendering = true; - gl_functions->glClear(GL_COLOR_BUFFER_BIT); - start_render_t = millis_since_boot(); - m_map->startStaticRender(); -} - -void MapRenderer::sendThumbnail(const uint64_t ts, const kj::Array &buf) { - MessageBuilder msg; - auto thumbnaild = msg.initEvent().initNavThumbnail(); - thumbnaild.setFrameId(frame_id); - thumbnaild.setTimestampEof(ts); - thumbnaild.setThumbnail(buf); - pm->send("navThumbnail", msg); -} - -void MapRenderer::publish(const double render_time, const bool loaded) { - QImage cap = fbo->toImage().convertToFormat(QImage::Format_RGB888, Qt::AutoColor); - - auto location = (*sm)["liveLocationKalman"].getLiveLocationKalman(); - bool valid = loaded && (location.getStatus() == cereal::LiveLocationKalman::Status::VALID) && location.getPositionGeodetic().getValid(); - ever_loaded = ever_loaded || loaded; - uint64_t ts = nanos_since_boot(); - VisionBuf* buf = vipc_server->get_buffer(VisionStreamType::VISION_STREAM_MAP); - VisionIpcBufExtra extra = { - .frame_id = frame_id, - .timestamp_sof = (*sm)["liveLocationKalman"].getLogMonoTime(), - .timestamp_eof = ts, - .valid = valid, - }; - - assert(cap.sizeInBytes() >= buf->len); - uint8_t* dst = (uint8_t*)buf->addr; - uint8_t* src = cap.bits(); - - // RGB to greyscale - memset(dst, 128, buf->len); - for (int i = 0; i < WIDTH * HEIGHT; i++) { - dst[i] = src[i * 3]; - } - - vipc_server->send(buf, &extra); - - // Send thumbnail - if (TEST_MODE) { - // Full image in thumbnails in test mode - kj::Array buffer_kj = kj::heapArray((const capnp::byte*)cap.bits(), cap.sizeInBytes()); - sendThumbnail(ts, buffer_kj); - } else if (frame_id % 100 == 0) { - // Write jpeg into buffer - QByteArray buffer_bytes; - QBuffer buffer(&buffer_bytes); - buffer.open(QIODevice::WriteOnly); - cap.save(&buffer, "JPG", 50); - - kj::Array buffer_kj = kj::heapArray((const capnp::byte*)buffer_bytes.constData(), buffer_bytes.size()); - sendThumbnail(ts, buffer_kj); - } - - // Send state msg - MessageBuilder msg; - auto evt = msg.initEvent(); - auto state = evt.initMapRenderState(); - evt.setValid(valid); - state.setLocationMonoTime((*sm)["liveLocationKalman"].getLogMonoTime()); - state.setRenderTime(render_time); - state.setFrameId(frame_id); - pm->send("mapRenderState", msg); - - frame_id++; -} - -uint8_t* MapRenderer::getImage() { - QImage cap = fbo->toImage().convertToFormat(QImage::Format_RGB888, Qt::AutoColor); - - uint8_t* src = cap.bits(); - uint8_t* dst = new uint8_t[WIDTH * HEIGHT]; - - // RGB to greyscale - for (int i = 0; i < WIDTH * HEIGHT; i++) { - dst[i] = src[i * 3]; - } - - return dst; -} - -void MapRenderer::updateRoute(QList coordinates) { - if (m_map.isNull()) return; - initLayers(); - - auto route_points = coordinate_list_to_collection(coordinates); - QMapLibre::Feature feature(QMapLibre::Feature::LineStringType, route_points, {}, {}); - QVariantMap navSource; - navSource["type"] = "geojson"; - navSource["data"] = QVariant::fromValue(feature); - m_map->updateSource("navSource", navSource); - m_map->setLayoutProperty("navLayer", "visibility", "visible"); -} - -void MapRenderer::initLayers() { - if (!m_map->layerExists("navLayer")) { - LOGD("Initializing navLayer"); - QVariantMap nav; - nav["type"] = "line"; - nav["source"] = "navSource"; - m_map->addLayer("navLayer", nav, "road-intersection"); - m_map->setPaintProperty("navLayer", "line-color", QColor("grey")); - m_map->setPaintProperty("navLayer", "line-width", 5); - m_map->setLayoutProperty("navLayer", "line-cap", "round"); - } -} - -MapRenderer::~MapRenderer() { -} - -extern "C" { - MapRenderer* map_renderer_init(char *maps_host = nullptr, char *token = nullptr) { - char *argv[] = { - (char*)"navd", - nullptr - }; - int argc = 0; - QApplication *app = new QApplication(argc, argv); - assert(app); - - QMapLibre::Settings settings; - settings.setProviderTemplate(QMapLibre::Settings::ProviderTemplate::MapboxProvider); - settings.setApiBaseUrl(maps_host == nullptr ? MAPS_HOST : maps_host); - settings.setApiKey(token == nullptr ? get_mapbox_token() : token); - - return new MapRenderer(settings, false); - } - - void map_renderer_update_position(MapRenderer *inst, float lat, float lon, float bearing) { - inst->updatePosition({lat, lon}, bearing); - QApplication::processEvents(); - } - - void map_renderer_update_route(MapRenderer *inst, char* polyline) { - inst->updateRoute(polyline_to_coordinate_list(QString::fromUtf8(polyline))); - } - - void map_renderer_update(MapRenderer *inst) { - inst->update(); - } - - void map_renderer_process(MapRenderer *inst) { - QApplication::processEvents(); - } - - bool map_renderer_loaded(MapRenderer *inst) { - return inst->loaded(); - } - - uint8_t * map_renderer_get_image(MapRenderer *inst) { - return inst->getImage(); - } - - void map_renderer_free_image(MapRenderer *inst, uint8_t * buf) { - delete[] buf; - } -} diff --git a/selfdrive/navd/map_renderer.h b/selfdrive/navd/map_renderer.h deleted file mode 100644 index 956c1d54bc6a43..00000000000000 --- a/selfdrive/navd/map_renderer.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msgq/visionipc/visionipc_server.h" -#include "cereal/messaging/messaging.h" - - -class MapRenderer : public QObject { - Q_OBJECT - -public: - MapRenderer(const QMapLibre::Settings &, bool online=true); - uint8_t* getImage(); - void update(); - bool loaded(); - ~MapRenderer(); - -private: - std::unique_ptr ctx; - std::unique_ptr surface; - std::unique_ptr gl_functions; - std::unique_ptr fbo; - - std::unique_ptr vipc_server; - std::unique_ptr pm; - std::unique_ptr sm; - void publish(const double render_time, const bool loaded); - void sendThumbnail(const uint64_t ts, const kj::Array &buf); - - QMapLibre::Settings m_settings; - QScopedPointer m_map; - - void initLayers(); - - double start_render_t; - uint32_t frame_id = 0; - uint64_t last_llk_rendered = 0; - bool rendering = false; - bool rendered() { - return last_llk_rendered == (*sm)["liveLocationKalman"].getLogMonoTime(); - } - - QTimer* timer; - bool ever_loaded = false; - -public slots: - void updatePosition(QMapLibre::Coordinate position, float bearing); - void updateRoute(QList coordinates); - void msgUpdate(); -}; diff --git a/selfdrive/navd/map_renderer.py b/selfdrive/navd/map_renderer.py deleted file mode 100755 index e44b883436cb0b..00000000000000 --- a/selfdrive/navd/map_renderer.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env python3 -# You might need to uninstall the PyQt5 pip package to avoid conflicts - -import os -import time -import numpy as np -import polyline -from cffi import FFI - -from openpilot.common.ffi_wrapper import suffix -from openpilot.common.basedir import BASEDIR - -HEIGHT = WIDTH = SIZE = 256 -METERS_PER_PIXEL = 2 - - -def get_ffi(): - lib = os.path.join(BASEDIR, "selfdrive", "navd", "libmaprender" + suffix()) - - ffi = FFI() - ffi.cdef(""" -void* map_renderer_init(char *maps_host, char *token); -void map_renderer_update_position(void *inst, float lat, float lon, float bearing); -void map_renderer_update_route(void *inst, char *polyline); -void map_renderer_update(void *inst); -void map_renderer_process(void *inst); -bool map_renderer_loaded(void *inst); -uint8_t* map_renderer_get_image(void *inst); -void map_renderer_free_image(void *inst, uint8_t *buf); -""") - return ffi, ffi.dlopen(lib) - - -def wait_ready(lib, renderer, timeout=None): - st = time.time() - while not lib.map_renderer_loaded(renderer): - lib.map_renderer_update(renderer) - - # The main qt app is not execed, so we need to periodically process events for e.g. network requests - lib.map_renderer_process(renderer) - - time.sleep(0.01) - - if timeout is not None and time.time() - st > timeout: - raise TimeoutError("Timeout waiting for map renderer to be ready") - - -def get_image(lib, renderer): - buf = lib.map_renderer_get_image(renderer) - r = list(buf[0:WIDTH * HEIGHT]) - lib.map_renderer_free_image(renderer, buf) - - # Convert to numpy - r = np.asarray(r) - return r.reshape((WIDTH, HEIGHT)) - - -def navRoute_to_polyline(nr): - coords = [(m.latitude, m.longitude) for m in nr.navRoute.coordinates] - return coords_to_polyline(coords) - - -def coords_to_polyline(coords): - # TODO: where does this factor of 10 come from? - return polyline.encode([(lat * 10., lon * 10.) for lat, lon in coords]) - - -def polyline_to_coords(p): - coords = polyline.decode(p) - return [(lat / 10., lon / 10.) for lat, lon in coords] - - - -if __name__ == "__main__": - import matplotlib.pyplot as plt - - ffi, lib = get_ffi() - renderer = lib.map_renderer_init(ffi.NULL, ffi.NULL) - wait_ready(lib, renderer) - - geometry = r"{yxk}@|obn~Eg@@eCFqc@J{RFw@?kA@gA?q|@Riu@NuJBgi@ZqVNcRBaPBkG@iSD{I@_H@cH?gG@mG@gG?aD@{LDgDDkVVyQLiGDgX@q_@@qI@qKhS{R~[}NtYaDbGoIvLwNfP_b@|f@oFnF_JxHel@bf@{JlIuxAlpAkNnLmZrWqFhFoh@jd@kX|TkJxH_RnPy^|[uKtHoZ~Um`DlkCorC``CuShQogCtwB_ThQcr@fk@sVrWgRhVmSb\\oj@jxA{Qvg@u]tbAyHzSos@xjBeKbWszAbgEc~@~jCuTrl@cYfo@mRn\\_m@v}@ij@jp@om@lk@y|A`pAiXbVmWzUod@xj@wNlTw}@|uAwSn\\kRfYqOdS_IdJuK`KmKvJoOhLuLbHaMzGwO~GoOzFiSrEsOhD}PhCqw@vJmnAxSczA`Vyb@bHk[fFgl@pJeoDdl@}}@zIyr@hG}X`BmUdBcM^aRR}Oe@iZc@mR_@{FScHxAn_@vz@zCzH~GjPxAhDlB~DhEdJlIbMhFfG|F~GlHrGjNjItLnGvQ~EhLnBfOn@p`@AzAAvn@CfC?fc@`@lUrArStCfSxEtSzGxM|ElFlBrOzJlEbDnC~BfDtCnHjHlLvMdTnZzHpObOf^pKla@~G|a@dErg@rCbj@zArYlj@ttJ~AfZh@r]LzYg@`TkDbj@gIdv@oE|i@kKzhA{CdNsEfOiGlPsEvMiDpLgBpHyB`MkB|MmArPg@|N?|P^rUvFz~AWpOCdAkB|PuB`KeFfHkCfGy@tAqC~AsBPkDs@uAiAcJwMe@s@eKkPMoXQux@EuuCoH?eI?Kas@}Dy@wAUkMOgDL" # noqa: E501 - lib.map_renderer_update_route(renderer, geometry.encode()) - - POSITIONS = [ - (32.71569271952601, -117.16384270868463, 0), (32.71569271952601, -117.16384270868463, 45), # San Diego - (52.378641991483136, 4.902623379456488, 0), (52.378641991483136, 4.902623379456488, 45), # Amsterdam - ] - plt.figure() - - for i, pos in enumerate(POSITIONS): - t = time.time() - lib.map_renderer_update_position(renderer, *pos) - wait_ready(lib, renderer) - - print(f"{pos} took {time.time() - t:.2f} s") - - plt.subplot(2, 2, i + 1) - plt.imshow(get_image(lib, renderer), cmap='gray') - - plt.show() diff --git a/selfdrive/navd/navd.py b/selfdrive/navd/navd.py deleted file mode 100755 index 8cfc495f272a40..00000000000000 --- a/selfdrive/navd/navd.py +++ /dev/null @@ -1,368 +0,0 @@ -#!/usr/bin/env python3 -import json -import math -import os -import threading - -import requests - -import cereal.messaging as messaging -from cereal import log -from openpilot.common.api import Api -from openpilot.common.params import Params -from openpilot.common.realtime import Ratekeeper -from openpilot.selfdrive.navd.helpers import (Coordinate, coordinate_from_param, - distance_along_geometry, maxspeed_to_ms, - minimum_distance, - parse_banner_instructions) -from openpilot.common.swaglog import cloudlog - -REROUTE_DISTANCE = 25 -MANEUVER_TRANSITION_THRESHOLD = 10 -REROUTE_COUNTER_MIN = 3 - - -class RouteEngine: - def __init__(self, sm, pm): - self.sm = sm - self.pm = pm - - self.params = Params() - - # Get last gps position from params - self.last_position = coordinate_from_param("LastGPSPosition", self.params) - self.last_bearing = None - - self.gps_ok = False - self.localizer_valid = False - - self.nav_destination = None - self.step_idx = None - self.route = None - self.route_geometry = None - - self.recompute_backoff = 0 - self.recompute_countdown = 0 - - self.ui_pid = None - - self.reroute_counter = 0 - - - self.api = None - self.mapbox_token = None - if "MAPBOX_TOKEN" in os.environ: - self.mapbox_token = os.environ["MAPBOX_TOKEN"] - self.mapbox_host = "https://api.mapbox.com" - else: - self.api = Api(self.params.get("DongleId", encoding='utf8')) - self.mapbox_host = "https://maps.comma.ai" - - def update(self): - self.sm.update(0) - - if self.sm.updated["managerState"]: - ui_pid = [p.pid for p in self.sm["managerState"].processes if p.name == "ui" and p.running] - if ui_pid: - if self.ui_pid and self.ui_pid != ui_pid[0]: - cloudlog.warning("UI restarting, sending route") - threading.Timer(5.0, self.send_route).start() - self.ui_pid = ui_pid[0] - - self.update_location() - try: - self.recompute_route() - self.send_instruction() - except Exception: - cloudlog.exception("navd.failed_to_compute") - - def update_location(self): - location = self.sm['liveLocationKalman'] - self.gps_ok = location.gpsOK - - self.localizer_valid = (location.status == log.LiveLocationKalman.Status.valid) and location.positionGeodetic.valid - - if self.localizer_valid: - self.last_bearing = math.degrees(location.calibratedOrientationNED.value[2]) - self.last_position = Coordinate(location.positionGeodetic.value[0], location.positionGeodetic.value[1]) - - def recompute_route(self): - if self.last_position is None: - return - - new_destination = coordinate_from_param("NavDestination", self.params) - if new_destination is None: - self.clear_route() - self.reset_recompute_limits() - return - - should_recompute = self.should_recompute() - if new_destination != self.nav_destination: - cloudlog.warning(f"Got new destination from NavDestination param {new_destination}") - should_recompute = True - - # Don't recompute when GPS drifts in tunnels - if not self.gps_ok and self.step_idx is not None: - return - - if self.recompute_countdown == 0 and should_recompute: - self.recompute_countdown = 2**self.recompute_backoff - self.recompute_backoff = min(6, self.recompute_backoff + 1) - self.calculate_route(new_destination) - self.reroute_counter = 0 - else: - self.recompute_countdown = max(0, self.recompute_countdown - 1) - - def calculate_route(self, destination): - cloudlog.warning(f"Calculating route {self.last_position} -> {destination}") - self.nav_destination = destination - - lang = self.params.get('LanguageSetting', encoding='utf8') - if lang is not None: - lang = lang.replace('main_', '') - - token = self.mapbox_token - if token is None: - token = self.api.get_token() - - params = { - 'access_token': token, - 'annotations': 'maxspeed', - 'geometries': 'geojson', - 'overview': 'full', - 'steps': 'true', - 'banner_instructions': 'true', - 'alternatives': 'false', - 'language': lang, - } - - # TODO: move waypoints into NavDestination param? - waypoints = self.params.get('NavDestinationWaypoints', encoding='utf8') - waypoint_coords = [] - if waypoints is not None and len(waypoints) > 0: - waypoint_coords = json.loads(waypoints) - - coords = [ - (self.last_position.longitude, self.last_position.latitude), - *waypoint_coords, - (destination.longitude, destination.latitude) - ] - params['waypoints'] = f'0;{len(coords)-1}' - if self.last_bearing is not None: - params['bearings'] = f"{(self.last_bearing + 360) % 360:.0f},90" + (';'*(len(coords)-1)) - - coords_str = ';'.join([f'{lon},{lat}' for lon, lat in coords]) - url = self.mapbox_host + '/directions/v5/mapbox/driving-traffic/' + coords_str - try: - resp = requests.get(url, params=params, timeout=10) - if resp.status_code != 200: - cloudlog.event("API request failed", status_code=resp.status_code, text=resp.text, error=True) - resp.raise_for_status() - - r = resp.json() - if len(r['routes']): - self.route = r['routes'][0]['legs'][0]['steps'] - self.route_geometry = [] - - maxspeed_idx = 0 - maxspeeds = r['routes'][0]['legs'][0]['annotation']['maxspeed'] - - # Convert coordinates - for step in self.route: - coords = [] - - for c in step['geometry']['coordinates']: - coord = Coordinate.from_mapbox_tuple(c) - - # Last step does not have maxspeed - if (maxspeed_idx < len(maxspeeds)): - maxspeed = maxspeeds[maxspeed_idx] - if ('unknown' not in maxspeed) and ('none' not in maxspeed): - coord.annotations['maxspeed'] = maxspeed_to_ms(maxspeed) - - coords.append(coord) - maxspeed_idx += 1 - - self.route_geometry.append(coords) - maxspeed_idx -= 1 # Every segment ends with the same coordinate as the start of the next - - self.step_idx = 0 - else: - cloudlog.warning("Got empty route response") - self.clear_route() - - # clear waypoints to avoid a re-route including past waypoints - # TODO: only clear once we're past a waypoint - self.params.remove('NavDestinationWaypoints') - - except requests.exceptions.RequestException: - cloudlog.exception("failed to get route") - self.clear_route() - - self.send_route() - - def send_instruction(self): - msg = messaging.new_message('navInstruction', valid=True) - - if self.step_idx is None: - msg.valid = False - self.pm.send('navInstruction', msg) - return - - step = self.route[self.step_idx] - geometry = self.route_geometry[self.step_idx] - along_geometry = distance_along_geometry(geometry, self.last_position) - distance_to_maneuver_along_geometry = step['distance'] - along_geometry - - # Banner instructions are for the following maneuver step, don't use empty last step - banner_step = step - if not len(banner_step['bannerInstructions']) and self.step_idx == len(self.route) - 1: - banner_step = self.route[max(self.step_idx - 1, 0)] - - # Current instruction - msg.navInstruction.maneuverDistance = distance_to_maneuver_along_geometry - instruction = parse_banner_instructions(banner_step['bannerInstructions'], distance_to_maneuver_along_geometry) - if instruction is not None: - for k,v in instruction.items(): - setattr(msg.navInstruction, k, v) - - # All instructions - maneuvers = [] - for i, step_i in enumerate(self.route): - if i < self.step_idx: - distance_to_maneuver = -sum(self.route[j]['distance'] for j in range(i+1, self.step_idx)) - along_geometry - elif i == self.step_idx: - distance_to_maneuver = distance_to_maneuver_along_geometry - else: - distance_to_maneuver = distance_to_maneuver_along_geometry + sum(self.route[j]['distance'] for j in range(self.step_idx+1, i+1)) - - instruction = parse_banner_instructions(step_i['bannerInstructions'], distance_to_maneuver) - if instruction is None: - continue - maneuver = {'distance': distance_to_maneuver} - if 'maneuverType' in instruction: - maneuver['type'] = instruction['maneuverType'] - if 'maneuverModifier' in instruction: - maneuver['modifier'] = instruction['maneuverModifier'] - maneuvers.append(maneuver) - - msg.navInstruction.allManeuvers = maneuvers - - # Compute total remaining time and distance - remaining = 1.0 - along_geometry / max(step['distance'], 1) - total_distance = step['distance'] * remaining - total_time = step['duration'] * remaining - - if step['duration_typical'] is None: - total_time_typical = total_time - else: - total_time_typical = step['duration_typical'] * remaining - - # Add up totals for future steps - for i in range(self.step_idx + 1, len(self.route)): - total_distance += self.route[i]['distance'] - total_time += self.route[i]['duration'] - if self.route[i]['duration_typical'] is None: - total_time_typical += self.route[i]['duration'] - else: - total_time_typical += self.route[i]['duration_typical'] - - msg.navInstruction.distanceRemaining = total_distance - msg.navInstruction.timeRemaining = total_time - msg.navInstruction.timeRemainingTypical = total_time_typical - - # Speed limit - closest_idx, closest = min(enumerate(geometry), key=lambda p: p[1].distance_to(self.last_position)) - if closest_idx > 0: - # If we are not past the closest point, show previous - if along_geometry < distance_along_geometry(geometry, geometry[closest_idx]): - closest = geometry[closest_idx - 1] - - if ('maxspeed' in closest.annotations) and self.localizer_valid: - msg.navInstruction.speedLimit = closest.annotations['maxspeed'] - - # Speed limit sign type - if 'speedLimitSign' in step: - if step['speedLimitSign'] == 'mutcd': - msg.navInstruction.speedLimitSign = log.NavInstruction.SpeedLimitSign.mutcd - elif step['speedLimitSign'] == 'vienna': - msg.navInstruction.speedLimitSign = log.NavInstruction.SpeedLimitSign.vienna - - self.pm.send('navInstruction', msg) - - # Transition to next route segment - if distance_to_maneuver_along_geometry < -MANEUVER_TRANSITION_THRESHOLD: - if self.step_idx + 1 < len(self.route): - self.step_idx += 1 - self.reset_recompute_limits() - else: - cloudlog.warning("Destination reached") - - # Clear route if driving away from destination - dist = self.nav_destination.distance_to(self.last_position) - if dist > REROUTE_DISTANCE: - self.params.remove("NavDestination") - self.clear_route() - - def send_route(self): - coords = [] - - if self.route is not None: - for path in self.route_geometry: - coords += [c.as_dict() for c in path] - - msg = messaging.new_message('navRoute', valid=True) - msg.navRoute.coordinates = coords - self.pm.send('navRoute', msg) - - def clear_route(self): - self.route = None - self.route_geometry = None - self.step_idx = None - self.nav_destination = None - - def reset_recompute_limits(self): - self.recompute_backoff = 0 - self.recompute_countdown = 0 - - def should_recompute(self): - if self.step_idx is None or self.route is None: - return True - - # Don't recompute in last segment, assume destination is reached - if self.step_idx == len(self.route) - 1: - return False - - # Compute closest distance to all line segments in the current path - min_d = REROUTE_DISTANCE + 1 - path = self.route_geometry[self.step_idx] - for i in range(len(path) - 1): - a = path[i] - b = path[i + 1] - - if a.distance_to(b) < 1.0: - continue - - min_d = min(min_d, minimum_distance(a, b, self.last_position)) - - if min_d > REROUTE_DISTANCE: - self.reroute_counter += 1 - else: - self.reroute_counter = 0 - return self.reroute_counter > REROUTE_COUNTER_MIN - # TODO: Check for going wrong way in segment - - -def main(): - pm = messaging.PubMaster(['navInstruction', 'navRoute']) - sm = messaging.SubMaster(['liveLocationKalman', 'managerState']) - - rk = Ratekeeper(1.0) - route_engine = RouteEngine(sm, pm) - while True: - route_engine.update() - rk.keep_time() - - -if __name__ == "__main__": - main() diff --git a/selfdrive/navd/set_destination.py b/selfdrive/navd/set_destination.py deleted file mode 100755 index 811aa576d1ef89..00000000000000 --- a/selfdrive/navd/set_destination.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python3 -import json -import sys - -from openpilot.common.params import Params - -if __name__ == "__main__": - params = Params() - - # set from google maps url - if len(sys.argv) > 1: - coords = sys.argv[1].split("/@")[-1].split("/")[0].split(",") - dest = { - "latitude": float(coords[0]), - "longitude": float(coords[1]) - } - params.put("NavDestination", json.dumps(dest)) - params.remove("NavDestinationWaypoints") - else: - print("Setting to Taco Bell") - dest = { - "latitude": 32.71160109904473, - "longitude": -117.12556569985693, - } - params.put("NavDestination", json.dumps(dest)) - - waypoints = [ - (-117.16020713111648, 32.71997612490662), - ] - params.put("NavDestinationWaypoints", json.dumps(waypoints)) - - print(dest) - print(waypoints) diff --git a/selfdrive/navd/style.json b/selfdrive/navd/style.json deleted file mode 100644 index 06bb750d1ffdc6..00000000000000 --- a/selfdrive/navd/style.json +++ /dev/null @@ -1 +0,0 @@ -{"version": 8, "name": "Navigation Model", "metadata": {"mapbox:type": "default", "mapbox:origin": "monochrome-dark-v1", "mapbox:sdk-support": {"android": "10.0.0", "ios": "10.0.0", "js": "2.3.0"}, "mapbox:autocomposite": true, "mapbox:groups": {"Transit, transit-labels": {"name": "Transit, transit-labels", "collapsed": true}, "Administrative boundaries, admin": {"name": "Administrative boundaries, admin", "collapsed": true}, "Transit, bridges": {"name": "Transit, bridges", "collapsed": true}, "Transit, surface": {"name": "Transit, surface", "collapsed": true}, "Road network, bridges": {"name": "Road network, bridges", "collapsed": false}, "Land, water, & sky, water": {"name": "Land, water, & sky, water", "collapsed": true}, "Road network, tunnels": {"name": "Road network, tunnels", "collapsed": false}, "Road network, road-labels": {"name": "Road network, road-labels", "collapsed": true}, "Buildings, built": {"name": "Buildings, built", "collapsed": true}, "Natural features, natural-labels": {"name": "Natural features, natural-labels", "collapsed": true}, "Road network, surface": {"name": "Road network, surface", "collapsed": false}, "Land, water, & sky, built": {"name": "Land, water, & sky, built", "collapsed": true}, "Place labels, place-labels": {"name": "Place labels, place-labels", "collapsed": true}, "Point of interest labels, poi-labels": {"name": "Point of interest labels, poi-labels", "collapsed": true}, "Road network, tunnels-case": {"name": "Road network, tunnels-case", "collapsed": true}, "Transit, built": {"name": "Transit, built", "collapsed": true}, "Road network, surface-icons": {"name": "Road network, surface-icons", "collapsed": false}, "Land, water, & sky, land": {"name": "Land, water, & sky, land", "collapsed": true}}}, "center": [-117.19189443261149, 32.756553679559985], "zoom": 12.932776547838778, "bearing": 0, "pitch": 0.5017568344510897, "sources": {"composite": {"url": "mapbox://mapbox.mapbox-streets-v8", "type": "vector", "maxzoom": 13}}, "sprite": "mapbox://sprites/commaai/ckvmksrpd4n0a14pfdo5heqzr/bkx9h9tjdf3xedbnjvfo5xnbv", "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf", "layers": [{"id": "land", "type": "background", "layout": {"visibility": "none"}, "paint": {"background-color": "rgb(252, 252, 252)"}, "metadata": {"mapbox:featureComponent": "land-and-water", "mapbox:group": "Land, water, & sky, land"}}, {"minzoom": 5, "layout": {"visibility": "none"}, "metadata": {"mapbox:featureComponent": "land-and-water", "mapbox:group": "Land, water, & sky, land"}, "filter": ["==", ["get", "class"], "national_park"], "type": "fill", "source": "composite", "id": "national-park", "paint": {"fill-color": "rgb(240, 240, 240)", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 5, 0, 6, 0.5, 10, 0.5]}, "source-layer": "landuse_overlay"}, {"minzoom": 5, "layout": {"visibility": "none"}, "metadata": {"mapbox:featureComponent": "land-and-water", "mapbox:group": "Land, water, & sky, land"}, "filter": ["match", ["get", "class"], ["park", "airport", "glacier", "pitch", "sand", "facility"], true, false], "type": "fill", "source": "composite", "id": "landuse", "paint": {"fill-color": "rgb(240, 240, 240)", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 5, 0, 6, ["match", ["get", "class"], "glacier", 0.5, 1]]}, "source-layer": "landuse"}, {"id": "waterway-shadow", "type": "line", "source": "composite", "source-layer": "waterway", "minzoom": 8, "layout": {"line-cap": ["step", ["zoom"], "butt", 11, "round"], "line-join": "round", "visibility": "none"}, "paint": {"line-color": "rgb(204, 204, 204)", "line-width": ["interpolate", ["exponential", 1.3], ["zoom"], 9, ["match", ["get", "class"], ["canal", "river"], 0.1, 0], 20, ["match", ["get", "class"], ["canal", "river"], 8, 3]], "line-translate": ["interpolate", ["exponential", 1.2], ["zoom"], 7, ["literal", [0, 0]], 16, ["literal", [-1, -1]]], "line-translate-anchor": "viewport", "line-opacity": ["interpolate", ["linear"], ["zoom"], 8, 0, 8.5, 1]}, "metadata": {"mapbox:featureComponent": "land-and-water", "mapbox:group": "Land, water, & sky, water"}}, {"id": "water-shadow", "type": "fill", "source": "composite", "source-layer": "water", "layout": {"visibility": "none"}, "paint": {"fill-color": "rgb(204, 204, 204)", "fill-translate": ["interpolate", ["exponential", 1.2], ["zoom"], 7, ["literal", [0, 0]], 16, ["literal", [-1, -1]]], "fill-translate-anchor": "viewport"}, "metadata": {"mapbox:featureComponent": "land-and-water", "mapbox:group": "Land, water, & sky, water"}}, {"id": "waterway", "type": "line", "source": "composite", "source-layer": "waterway", "minzoom": 8, "layout": {"line-cap": ["step", ["zoom"], "butt", 11, "round"], "line-join": "round", "visibility": "none"}, "paint": {"line-color": "rgb(224, 224, 224)", "line-width": ["interpolate", ["exponential", 1.3], ["zoom"], 9, ["match", ["get", "class"], ["canal", "river"], 0.1, 0], 20, ["match", ["get", "class"], ["canal", "river"], 8, 3]], "line-opacity": ["interpolate", ["linear"], ["zoom"], 8, 0, 8.5, 1]}, "metadata": {"mapbox:featureComponent": "land-and-water", "mapbox:group": "Land, water, & sky, water"}}, {"id": "water", "type": "fill", "source": "composite", "source-layer": "water", "layout": {"visibility": "none"}, "paint": {"fill-color": "rgb(224, 224, 224)"}, "metadata": {"mapbox:featureComponent": "land-and-water", "mapbox:group": "Land, water, & sky, water"}}, {"minzoom": 13, "layout": {"visibility": "none"}, "metadata": {"mapbox:featureComponent": "land-and-water", "mapbox:group": "Land, water, & sky, built"}, "filter": ["all", ["==", ["geometry-type"], "Polygon"], ["==", ["get", "class"], "land"]], "type": "fill", "source": "composite", "id": "land-structure-polygon", "paint": {"fill-color": "rgb(252, 252, 252)"}, "source-layer": "structure"}, {"minzoom": 13, "layout": {"line-cap": "round", "visibility": "none"}, "metadata": {"mapbox:featureComponent": "land-and-water", "mapbox:group": "Land, water, & sky, built"}, "filter": ["all", ["==", ["geometry-type"], "LineString"], ["==", ["get", "class"], "land"]], "type": "line", "source": "composite", "id": "land-structure-line", "paint": {"line-width": ["interpolate", ["exponential", 1.99], ["zoom"], 14, 0.75, 20, 40], "line-color": "rgb(252, 252, 252)"}, "source-layer": "structure"}, {"minzoom": 11, "layout": {"visibility": "none"}, "metadata": {"mapbox:featureComponent": "transit", "mapbox:group": "Transit, built"}, "filter": ["all", ["==", ["geometry-type"], "Polygon"], ["match", ["get", "type"], ["runway", "taxiway", "helipad"], true, false]], "type": "fill", "source": "composite", "id": "aeroway-polygon", "paint": {"fill-color": "rgb(255, 255, 255)", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 11, 0, 11.5, 1]}, "source-layer": "aeroway"}, {"minzoom": 9, "layout": {"visibility": "none"}, "metadata": {"mapbox:featureComponent": "transit", "mapbox:group": "Transit, built"}, "filter": ["==", ["geometry-type"], "LineString"], "type": "line", "source": "composite", "id": "aeroway-line", "paint": {"line-color": "rgb(255, 255, 255)", "line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 9, ["match", ["get", "type"], "runway", 1, 0.5], 18, ["match", ["get", "type"], "runway", 80, 20]]}, "source-layer": "aeroway"}, {"minzoom": 13, "layout": {"visibility": "none"}, "metadata": {"mapbox:featureComponent": "buildings", "mapbox:group": "Buildings, built"}, "filter": ["all", ["!=", ["get", "type"], "building:part"], ["==", ["get", "underground"], "false"]], "type": "line", "source": "composite", "id": "building-outline", "paint": {"line-color": "rgb(227, 227, 227)", "line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 15, 0.75, 20, 3], "line-opacity": ["interpolate", ["linear"], ["zoom"], 15, 0, 16, 1]}, "source-layer": "building"}, {"minzoom": 13, "layout": {"visibility": "none"}, "metadata": {"mapbox:featureComponent": "buildings", "mapbox:group": "Buildings, built"}, "filter": ["all", ["!=", ["get", "type"], "building:part"], ["==", ["get", "underground"], "false"]], "type": "fill", "source": "composite", "id": "building", "paint": {"fill-color": ["interpolate", ["linear"], ["zoom"], 15, "rgb(242, 242, 242)", 16, "rgb(242, 242, 242)"], "fill-opacity": ["interpolate", ["linear"], ["zoom"], 15, 0, 16, 1], "fill-outline-color": "rgb(227, 227, 227)"}, "source-layer": "building"}, {"minzoom": 13, "layout": {}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, tunnels-case"}, "filter": ["all", ["==", ["get", "structure"], "tunnel"], ["step", ["zoom"], ["match", ["get", "class"], ["street", "street_limited", "primary_link", "track"], true, false], 1, ["match", ["get", "class"], ["street", "street_limited", "track", "primary_link", "secondary_link", "tertiary_link", "service"], true, false]], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "tunnel-street-minor-low", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, ["match", ["get", "class"], ["street", "street_limited", "primary_link"], 2, "track", 1, 0.5], 18, ["match", ["get", "class"], ["street", "street_limited", "primary_link"], 18, 12]], "line-color": "rgb(235, 235, 235)", "line-opacity": ["step", ["zoom"], 1, 14, 0]}, "source-layer": "road"}, {"minzoom": 13, "layout": {}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, tunnels-case"}, "filter": ["all", ["==", ["get", "structure"], "tunnel"], ["step", ["zoom"], ["match", ["get", "class"], ["street", "street_limited", "primary_link", "track"], true, false], 1, ["match", ["get", "class"], ["street", "street_limited", "track", "primary_link", "secondary_link", "tertiary_link", "service"], true, false]], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "tunnel-street-minor-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.75, 20, 2], "line-color": "rgb(255, 255, 255)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, ["match", ["get", "class"], ["street", "street_limited", "primary_link"], 2, "track", 1, 0.5], 18, ["match", ["get", "class"], ["street", "street_limited", "primary_link"], 18, 12]], "line-opacity": ["step", ["zoom"], 0, 14, 1], "line-dasharray": [3, 3]}, "source-layer": "road"}, {"minzoom": 13, "layout": {}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, tunnels-case"}, "filter": ["all", ["==", ["get", "structure"], "tunnel"], ["match", ["get", "class"], ["primary", "secondary", "tertiary"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "tunnel-primary-secondary-tertiary-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 10, ["match", ["get", "class"], "primary", 1, 0.75], 18, 2], "line-color": "rgb(255, 255, 255)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, ["match", ["get", "class"], "primary", 0.75, 0.1], 18, ["match", ["get", "class"], "primary", 32, 26]], "line-dasharray": [3, 3]}, "source-layer": "road"}, {"minzoom": 13, "layout": {}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, tunnels-case"}, "filter": ["all", ["==", ["get", "structure"], "tunnel"], ["match", ["get", "class"], ["motorway_link", "trunk_link"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "tunnel-major-link-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.75, 20, 2], "line-color": "rgb(255, 255, 255)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, 2, 18, 18], "line-dasharray": [3, 3]}, "source-layer": "road"}, {"minzoom": 13, "layout": {}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, tunnels-case"}, "filter": ["all", ["==", ["get", "structure"], "tunnel"], ["match", ["get", "class"], ["motorway", "trunk"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "tunnel-motorway-trunk-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 10, 1, 18, 2], "line-color": "rgb(255, 255, 255)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, 0.75, 18, 32], "line-dasharray": [3, 3]}, "source-layer": "road"}, {"minzoom": 13, "layout": {}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, tunnels-case"}, "filter": ["all", ["==", ["get", "structure"], "tunnel"], ["==", ["get", "class"], "construction"], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "tunnel-construction", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 14, 2, 18, 18], "line-color": "rgb(235, 235, 235)", "line-dasharray": ["step", ["zoom"], ["literal", [0.4, 0.8]], 15, ["literal", [0.3, 0.6]], 16, ["literal", [0.2, 0.3]], 17, ["literal", [0.2, 0.25]], 18, ["literal", [0.15, 0.15]]]}, "source-layer": "road"}, {"minzoom": 13, "layout": {}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, tunnels"}, "filter": ["all", ["==", ["get", "structure"], "tunnel"], ["match", ["get", "class"], ["motorway_link", "trunk_link"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "tunnel-major-link", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, 2, 18, 18], "line-color": "rgb(235, 235, 235)"}, "source-layer": "road"}, {"minzoom": 13, "layout": {}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, tunnels"}, "filter": ["all", ["==", ["get", "structure"], "tunnel"], ["step", ["zoom"], ["match", ["get", "class"], ["street", "street_limited", "primary_link", "track"], true, false], 1, ["match", ["get", "class"], ["street", "street_limited", "track", "primary_link", "secondary_link", "tertiary_link", "service"], true, false]], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "tunnel-street-minor", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, ["match", ["get", "class"], ["street", "street_limited", "primary_link"], 2, "track", 1, 0.5], 18, ["match", ["get", "class"], ["street", "street_limited", "primary_link"], 18, 12]], "line-color": "rgb(235, 235, 235)", "line-opacity": ["step", ["zoom"], 0, 14, 1]}, "source-layer": "road"}, {"minzoom": 13, "layout": {}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, tunnels"}, "filter": ["all", ["==", ["get", "structure"], "tunnel"], ["match", ["get", "class"], ["primary", "secondary", "tertiary"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "tunnel-primary-secondary-tertiary", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, ["match", ["get", "class"], "primary", 0.75, 0.1], 18, ["match", ["get", "class"], "primary", 32, 26]], "line-color": "rgb(235, 235, 235)"}, "source-layer": "road"}, {"minzoom": 13, "layout": {}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, tunnels"}, "filter": ["all", ["==", ["get", "structure"], "tunnel"], ["match", ["get", "class"], ["motorway", "trunk"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "tunnel-motorway-trunk", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, 0.75, 18, 32], "line-color": "rgb(235, 235, 235)"}, "source-layer": "road"}, {"minzoom": 13, "layout": {"icon-image": "turning-circle-outline", "icon-size": ["interpolate", ["exponential", 1.5], ["zoom"], 14, 0.122, 18, 0.969, 20, 1], "icon-allow-overlap": true, "icon-ignore-placement": true, "icon-padding": 0, "icon-rotation-alignment": "map", "visibility": "none"}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["==", ["geometry-type"], "Point"], ["match", ["get", "class"], ["turning_circle", "turning_loop"], true, false]], "type": "symbol", "source": "composite", "id": "turning-feature-outline", "paint": {}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["step", ["zoom"], ["==", ["get", "class"], "track"], 1, ["match", ["get", "class"], ["track", "secondary_link", "tertiary_link", "service"], true, false]], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-minor-low", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 14, ["match", ["get", "class"], "track", 1, 0.5], 18, 12], "line-color": "rgb(255, 255, 255)", "line-opacity": ["step", ["zoom"], 1, 14, 0]}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["step", ["zoom"], ["==", ["get", "class"], "track"], 1, ["match", ["get", "class"], ["track", "secondary_link", "tertiary_link", "service"], true, false]], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-minor-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.75, 20, 2], "line-color": "rgb(242, 242, 242)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 14, ["match", ["get", "class"], "track", 1, 0.5], 18, 12], "line-opacity": ["step", ["zoom"], 0, 14, 1]}, "source-layer": "road"}, {"minzoom": 11, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["match", ["get", "class"], ["street", "street_limited", "primary_link"], true, false], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-street-low", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, 2, 18, 18], "line-color": "rgb(255, 255, 255)", "line-opacity": ["step", ["zoom"], 1, 14, 0]}, "source-layer": "road"}, {"minzoom": 11, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["match", ["get", "class"], ["street", "street_limited", "primary_link"], true, false], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-street-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.75, 20, 2], "line-color": "rgb(242, 242, 242)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, 2, 18, 18], "line-opacity": ["step", ["zoom"], 0, 14, 1]}, "source-layer": "road"}, {"minzoom": 8, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["match", ["get", "class"], ["secondary", "tertiary"], true, false], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-secondary-tertiary-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 10, 0.75, 18, 2], "line-color": "rgb(242, 242, 242)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, 0.1, 18, 26], "line-opacity": ["step", ["zoom"], 0, 10, 1]}, "source-layer": "road"}, {"minzoom": 7, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["==", ["get", "class"], "primary"], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-primary-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 10, 1, 18, 2], "line-color": "rgb(242, 242, 242)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, 0.75, 18, 32], "line-opacity": ["step", ["zoom"], 0, 10, 1]}, "source-layer": "road"}, {"minzoom": 10, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["match", ["get", "class"], ["motorway_link", "trunk_link"], true, false], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-major-link-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.75, 20, 2], "line-color": "rgb(242, 242, 242)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, 2, 18, 18], "line-opacity": ["step", ["zoom"], 0, 11, 1]}, "source-layer": "road"}, {"minzoom": 5, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["match", ["get", "class"], ["motorway", "trunk"], true, false], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-motorway-trunk-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 10, 1, 18, 2], "line-color": "rgb(242, 242, 242)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, 0.75, 18, 32], "line-opacity": ["step", ["zoom"], ["match", ["get", "class"], "motorway", 1, 0], 6, 1]}, "source-layer": "road"}, {"minzoom": 13, "layout": {}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["==", ["get", "class"], "construction"], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-construction", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 14, 2, 18, 18], "line-color": "rgb(255, 255, 255)", "line-dasharray": ["step", ["zoom"], ["literal", [0.4, 0.8]], 15, ["literal", [0.3, 0.6]], 16, ["literal", [0.2, 0.3]], 17, ["literal", [0.2, 0.25]], 18, ["literal", [0.15, 0.15]]]}, "source-layer": "road"}, {"minzoom": 10, "layout": {"line-cap": ["step", ["zoom"], "butt", 13, "round"], "line-join": ["step", ["zoom"], "miter", 13, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["match", ["get", "class"], ["motorway_link", "trunk_link"], true, false], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-major-link", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, 2, 18, 18], "line-color": "rgb(255, 255, 255)"}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["step", ["zoom"], ["==", ["get", "class"], "track"], 1, ["match", ["get", "class"], ["track", "secondary_link", "tertiary_link", "service"], true, false]], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-minor", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 14, ["match", ["get", "class"], "track", 1, 0.5], 18, 12], "line-color": "rgb(255, 255, 255)", "line-opacity": ["step", ["zoom"], 0, 14, 1]}, "source-layer": "road"}, {"minzoom": 11, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["match", ["get", "class"], ["street", "street_limited", "primary_link"], true, false], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-street", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, 2, 18, 18], "line-color": "rgb(255, 255, 255)", "line-opacity": ["step", ["zoom"], 0, 14, 1]}, "source-layer": "road"}, {"minzoom": 8, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["match", ["get", "class"], ["secondary", "tertiary"], true, false], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-secondary-tertiary", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, 0.1, 18, 26], "line-color": "rgb(255, 255, 255)"}, "source-layer": "road"}, {"minzoom": 6, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}, "filter": ["all", ["==", ["get", "class"], "primary"], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "road-primary", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, 0.75, 18, 32], "line-color": "rgb(255, 255, 255)"}, "source-layer": "road"}, {"id": "road-motorway-trunk", "type": "line", "source": "composite", "source-layer": "road", "filter": ["all", ["match", ["get", "class"], ["motorway", "trunk"], true, false], ["match", ["get", "structure"], ["none", "ford"], true, false], ["==", ["geometry-type"], "LineString"]], "layout": {"line-cap": ["step", ["zoom"], "butt", 13, "round"], "line-join": ["step", ["zoom"], "miter", 13, "round"]}, "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, 0.75, 18, 32], "line-color": "rgb(255, 255, 255)"}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface"}}, {"minzoom": 13, "layout": {"line-join": "round", "visibility": "none"}, "metadata": {"mapbox:featureComponent": "transit", "mapbox:group": "Transit, surface"}, "filter": ["all", ["match", ["get", "class"], ["major_rail", "minor_rail"], true, false], ["match", ["get", "structure"], ["none", "ford"], true, false]], "type": "line", "source": "composite", "id": "road-rail", "paint": {"line-color": ["interpolate", ["linear"], ["zoom"], 13, "rgb(242, 242, 242)", 17, "rgb(227, 227, 227)"], "line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 14, 0.5, 20, 1]}, "source-layer": "road"}, {"minzoom": 13, "layout": {"icon-image": "turning-circle", "icon-size": ["interpolate", ["exponential", 1.5], ["zoom"], 14, 0.095, 18, 1], "icon-allow-overlap": true, "icon-ignore-placement": true, "icon-padding": 0, "icon-rotation-alignment": "map", "visibility": "none"}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, surface-icons"}, "filter": ["all", ["==", ["geometry-type"], "Point"], ["match", ["get", "class"], ["turning_circle", "turning_loop"], true, false]], "type": "symbol", "source": "composite", "id": "turning-feature", "paint": {}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], ["step", ["zoom"], ["match", ["get", "class"], ["street", "street_limited", "primary_link", "track"], true, false], 1, ["match", ["get", "class"], ["street", "street_limited", "track", "primary_link", "secondary_link", "tertiary_link", "service"], true, false]], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-street-minor-low", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, ["match", ["get", "class"], ["street", "street_limited", "primary_link"], 2, "track", 1, 0.5], 18, ["match", ["get", "class"], ["street", "street_limited", "primary_link"], 18, 12]], "line-color": "rgb(255, 255, 255)", "line-opacity": ["step", ["zoom"], 1, 14, 0]}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-join": "round"}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], ["step", ["zoom"], ["match", ["get", "class"], ["street", "street_limited", "primary_link", "track"], true, false], 1, ["match", ["get", "class"], ["street", "street_limited", "track", "primary_link", "secondary_link", "tertiary_link", "service"], true, false]], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-street-minor-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.75, 20, 2], "line-color": "rgb(242, 242, 242)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, ["match", ["get", "class"], ["street", "street_limited", "primary_link"], 2, "track", 1, 0.5], 18, ["match", ["get", "class"], ["street", "street_limited", "primary_link"], 18, 12]], "line-opacity": ["step", ["zoom"], 0, 14, 1]}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-join": "round"}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], ["match", ["get", "class"], ["primary", "secondary", "tertiary"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-primary-secondary-tertiary-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 10, ["match", ["get", "class"], "primary", 1, 0.75], 18, 2], "line-color": "rgb(242, 242, 242)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, ["match", ["get", "class"], "primary", 0.75, 0.1], 18, ["match", ["get", "class"], "primary", 32, 26]], "line-opacity": ["step", ["zoom"], 0, 10, 1]}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-join": "round"}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], ["match", ["get", "class"], ["motorway_link", "trunk_link"], true, false], ["<=", ["get", "layer"], 1], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-major-link-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.75, 20, 2], "line-color": "rgb(242, 242, 242)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, 2, 18, 18]}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-join": "round"}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], ["match", ["get", "class"], ["motorway", "trunk"], true, false], ["<=", ["get", "layer"], 1], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-motorway-trunk-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 10, 1, 18, 2], "line-color": "rgb(242, 242, 242)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, 0.75, 18, 32]}, "source-layer": "road"}, {"minzoom": 13, "layout": {}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], ["==", ["get", "class"], "construction"], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-construction", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 14, 2, 18, 18], "line-color": "rgb(255, 255, 255)", "line-dasharray": ["step", ["zoom"], ["literal", [0.4, 0.8]], 15, ["literal", [0.3, 0.6]], 16, ["literal", [0.2, 0.3]], 17, ["literal", [0.2, 0.25]], 18, ["literal", [0.15, 0.15]]]}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-cap": "round", "line-join": "round"}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], ["match", ["get", "class"], ["motorway_link", "trunk_link"], true, false], ["<=", ["get", "layer"], 1], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-major-link", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, 2, 18, 18], "line-color": "rgb(255, 255, 255)"}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], ["step", ["zoom"], ["match", ["get", "class"], ["street", "street_limited", "primary_link", "track"], true, false], 1, ["match", ["get", "class"], ["street", "street_limited", "track", "primary_link", "secondary_link", "tertiary_link", "service"], true, false]], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-street-minor", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, ["match", ["get", "class"], ["street", "street_limited", "primary_link"], 2, "track", 1, 0.5], 18, ["match", ["get", "class"], ["street", "street_limited", "primary_link"], 18, 12]], "line-color": "rgb(255, 255, 255)", "line-opacity": ["step", ["zoom"], 0, 14, 1]}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], ["match", ["get", "class"], ["primary", "secondary", "tertiary"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-primary-secondary-tertiary", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, ["match", ["get", "class"], "primary", 0.75, 0.1], 18, ["match", ["get", "class"], "primary", 32, 26]], "line-color": "rgb(255, 255, 255)"}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-cap": "round", "line-join": "round"}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], ["match", ["get", "class"], ["motorway", "trunk"], true, false], ["<=", ["get", "layer"], 1], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-motorway-trunk", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, 0.75, 18, 32], "line-color": "rgb(255, 255, 255)"}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-join": "round"}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], [">=", ["get", "layer"], 2], ["match", ["get", "class"], ["motorway_link", "trunk_link"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-major-link-2-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.75, 20, 2], "line-color": "rgb(242, 242, 242)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, 2, 18, 18]}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-join": "round"}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], [">=", ["get", "layer"], 2], ["match", ["get", "class"], ["motorway", "trunk"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-motorway-trunk-2-case", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 10, 1, 18, 2], "line-color": "rgb(242, 242, 242)", "line-gap-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, 0.75, 18, 32]}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-cap": "round", "line-join": "round"}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], [">=", ["get", "layer"], 2], ["match", ["get", "class"], ["motorway_link", "trunk_link"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-major-link-2", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 12, 0.5, 14, 2, 18, 18], "line-color": "rgb(255, 255, 255)"}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-cap": ["step", ["zoom"], "butt", 14, "round"], "line-join": ["step", ["zoom"], "miter", 14, "round"]}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], [">=", ["get", "layer"], 2], ["match", ["get", "class"], ["motorway", "trunk"], true, false], ["==", ["geometry-type"], "LineString"]], "type": "line", "source": "composite", "id": "bridge-motorway-trunk-2", "paint": {"line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 5, 0.75, 18, 32], "line-color": "rgb(255, 255, 255)"}, "source-layer": "road"}, {"minzoom": 13, "layout": {"line-join": "round", "visibility": "none"}, "metadata": {"mapbox:featureComponent": "transit", "mapbox:group": "Transit, bridges"}, "filter": ["all", ["==", ["get", "structure"], "bridge"], ["match", ["get", "class"], ["major_rail", "minor_rail"], true, false]], "type": "line", "source": "composite", "id": "bridge-rail", "paint": {"line-color": "rgb(227, 227, 227)", "line-width": ["interpolate", ["exponential", 1.5], ["zoom"], 14, 0.5, 20, 1]}, "source-layer": "road"}, {"minzoom": 7, "layout": {"line-join": "bevel", "visibility": "none"}, "metadata": {"mapbox:featureComponent": "admin-boundaries", "mapbox:group": "Administrative boundaries, admin"}, "filter": ["all", ["==", ["get", "admin_level"], 1], ["==", ["get", "maritime"], "false"], ["match", ["get", "worldview"], ["all", "US"], true, false]], "type": "line", "source": "composite", "id": "admin-1-boundary-bg", "paint": {"line-color": ["interpolate", ["linear"], ["zoom"], 8, "rgb(227, 227, 227)", 16, "rgb(227, 227, 227)"], "line-width": ["interpolate", ["linear"], ["zoom"], 7, 3.75, 12, 5.5], "line-opacity": ["interpolate", ["linear"], ["zoom"], 7, 0, 8, 0.75], "line-dasharray": [1, 0], "line-blur": ["interpolate", ["linear"], ["zoom"], 3, 0, 8, 3]}, "source-layer": "admin"}, {"minzoom": 1, "layout": {"visibility": "none"}, "metadata": {"mapbox:featureComponent": "admin-boundaries", "mapbox:group": "Administrative boundaries, admin"}, "filter": ["all", ["==", ["get", "admin_level"], 0], ["==", ["get", "maritime"], "false"], ["match", ["get", "worldview"], ["all", "US"], true, false]], "type": "line", "source": "composite", "id": "admin-0-boundary-bg", "paint": {"line-width": ["interpolate", ["linear"], ["zoom"], 3, 3.5, 10, 8], "line-color": "rgb(227, 227, 227)", "line-opacity": ["interpolate", ["linear"], ["zoom"], 3, 0, 4, 0.5], "line-blur": ["interpolate", ["linear"], ["zoom"], 3, 0, 10, 2]}, "source-layer": "admin"}, {"minzoom": 2, "layout": {"line-join": "round", "line-cap": "round", "visibility": "none"}, "metadata": {"mapbox:featureComponent": "admin-boundaries", "mapbox:group": "Administrative boundaries, admin"}, "filter": ["all", ["==", ["get", "admin_level"], 1], ["==", ["get", "maritime"], "false"], ["match", ["get", "worldview"], ["all", "US"], true, false]], "type": "line", "source": "composite", "id": "admin-1-boundary", "paint": {"line-dasharray": ["step", ["zoom"], ["literal", [2, 0]], 7, ["literal", [2, 2, 6, 2]]], "line-width": ["interpolate", ["linear"], ["zoom"], 7, 0.75, 12, 1.5], "line-opacity": ["interpolate", ["linear"], ["zoom"], 2, 0, 3, 1], "line-color": ["interpolate", ["linear"], ["zoom"], 3, "rgb(224, 224, 224)", 7, "rgb(184, 184, 184)"]}, "source-layer": "admin"}, {"minzoom": 1, "layout": {"line-join": "round", "line-cap": "round", "visibility": "none"}, "metadata": {"mapbox:featureComponent": "admin-boundaries", "mapbox:group": "Administrative boundaries, admin"}, "filter": ["all", ["==", ["get", "admin_level"], 0], ["==", ["get", "disputed"], "false"], ["==", ["get", "maritime"], "false"], ["match", ["get", "worldview"], ["all", "US"], true, false]], "type": "line", "source": "composite", "id": "admin-0-boundary", "paint": {"line-color": "rgb(184, 184, 184)", "line-width": ["interpolate", ["linear"], ["zoom"], 3, 0.5, 10, 2], "line-dasharray": [10, 0]}, "source-layer": "admin"}, {"minzoom": 1, "layout": {"line-join": "round", "visibility": "none"}, "metadata": {"mapbox:featureComponent": "admin-boundaries", "mapbox:group": "Administrative boundaries, admin"}, "filter": ["all", ["==", ["get", "disputed"], "true"], ["==", ["get", "admin_level"], 0], ["==", ["get", "maritime"], "false"], ["match", ["get", "worldview"], ["all", "US"], true, false]], "type": "line", "source": "composite", "id": "admin-0-boundary-disputed", "paint": {"line-color": "rgb(184, 184, 184)", "line-width": ["interpolate", ["linear"], ["zoom"], 3, 0.5, 10, 2], "line-dasharray": ["step", ["zoom"], ["literal", [3.25, 3.25]], 6, ["literal", [2.5, 2.5]], 7, ["literal", [2, 2.25]], 8, ["literal", [1.75, 2]]]}, "source-layer": "admin"}, {"minzoom": 10, "layout": {"text-size": ["interpolate", ["linear"], ["zoom"], 10, ["match", ["get", "class"], ["motorway", "trunk", "primary", "secondary", "tertiary"], 10, ["motorway_link", "trunk_link", "primary_link", "secondary_link", "tertiary_link", "street", "street_limited"], 9, 6.5], 18, ["match", ["get", "class"], ["motorway", "trunk", "primary", "secondary", "tertiary"], 16, ["motorway_link", "trunk_link", "primary_link", "secondary_link", "tertiary_link", "street", "street_limited"], 14, 13]], "text-max-angle": 30, "text-font": ["DIN Pro Regular", "Arial Unicode MS Regular"], "symbol-placement": "line", "text-padding": 1, "visibility": "none", "text-rotation-alignment": "map", "text-pitch-alignment": "viewport", "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "text-letter-spacing": 0.01}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, road-labels"}, "filter": ["step", ["zoom"], ["match", ["get", "class"], ["motorway", "trunk", "primary", "secondary", "tertiary"], true, false], 1, ["match", ["get", "class"], ["motorway", "trunk", "primary", "secondary", "tertiary", "street", "street_limited"], true, false], 2, ["match", ["get", "class"], ["path", "pedestrian", "golf", "ferry", "aerialway"], false, true]], "type": "symbol", "source": "composite", "id": "road-label", "paint": {"text-color": "rgb(128, 128, 128)", "text-halo-color": "rgb(255, 255, 255)", "text-halo-width": 1, "text-halo-blur": 1}, "source-layer": "road"}, {"minzoom": 13, "layout": {"text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "icon-image": "intersection", "icon-text-fit": "both", "icon-text-fit-padding": [1, 2, 1, 2], "text-size": ["interpolate", ["exponential", 1.2], ["zoom"], 15, 9, 18, 12], "text-font": ["DIN Pro Bold", "Arial Unicode MS Bold"], "visibility": "none"}, "metadata": {"mapbox:featureComponent": "road-network", "mapbox:group": "Road network, road-labels"}, "filter": ["all", ["==", ["get", "class"], "intersection"], ["has", "name"]], "type": "symbol", "source": "composite", "id": "road-intersection", "paint": {"text-color": "rgb(153, 153, 153)"}, "source-layer": "road"}, {"minzoom": 13, "layout": {"text-font": ["DIN Pro Italic", "Arial Unicode MS Regular"], "text-max-angle": 30, "symbol-spacing": ["interpolate", ["linear", 1], ["zoom"], 15, 250, 17, 400], "text-size": ["interpolate", ["linear"], ["zoom"], 13, 12, 18, 16], "symbol-placement": "line", "text-pitch-alignment": "viewport", "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "visibility": "none"}, "metadata": {"mapbox:featureComponent": "natural-features", "mapbox:group": "Natural features, natural-labels"}, "filter": ["all", ["match", ["get", "class"], ["canal", "river", "stream"], ["match", ["get", "worldview"], ["all", "US"], true, false], ["disputed_canal", "disputed_river", "disputed_stream"], ["all", ["==", ["get", "disputed"], "true"], ["match", ["get", "worldview"], ["all", "US"], true, false]], false], ["==", ["geometry-type"], "LineString"]], "type": "symbol", "source": "composite", "id": "waterway-label", "paint": {"text-color": "rgb(150, 150, 150)"}, "source-layer": "natural_label"}, {"minzoom": 4, "layout": {"text-size": ["step", ["zoom"], ["step", ["get", "sizerank"], 18, 5, 12], 17, ["step", ["get", "sizerank"], 18, 13, 12]], "text-max-angle": 30, "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "text-font": ["DIN Pro Medium", "Arial Unicode MS Regular"], "symbol-placement": "line-center", "text-pitch-alignment": "viewport", "visibility": "none"}, "metadata": {"mapbox:featureComponent": "natural-features", "mapbox:group": "Natural features, natural-labels"}, "filter": ["all", ["match", ["get", "class"], ["glacier", "landform"], ["match", ["get", "worldview"], ["all", "US"], true, false], ["disputed_glacier", "disputed_landform"], ["all", ["==", ["get", "disputed"], "true"], ["match", ["get", "worldview"], ["all", "US"], true, false]], false], ["==", ["geometry-type"], "LineString"], ["<=", ["get", "filterrank"], 1]], "type": "symbol", "source": "composite", "id": "natural-line-label", "paint": {"text-halo-width": 0.5, "text-halo-color": "rgb(255, 255, 255)", "text-halo-blur": 0.5, "text-color": "rgb(128, 128, 128)"}, "source-layer": "natural_label"}, {"minzoom": 4, "layout": {"text-size": ["step", ["zoom"], ["step", ["get", "sizerank"], 18, 5, 12], 17, ["step", ["get", "sizerank"], 18, 13, 12]], "icon-image": "", "text-font": ["DIN Pro Medium", "Arial Unicode MS Regular"], "text-offset": ["literal", [0, 0]], "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "visibility": "none"}, "metadata": {"mapbox:featureComponent": "natural-features", "mapbox:group": "Natural features, natural-labels"}, "filter": ["all", ["match", ["get", "class"], ["dock", "glacier", "landform", "water_feature", "wetland"], ["match", ["get", "worldview"], ["all", "US"], true, false], ["disputed_dock", "disputed_glacier", "disputed_landform", "disputed_water_feature", "disputed_wetland"], ["all", ["==", ["get", "disputed"], "true"], ["match", ["get", "worldview"], ["all", "US"], true, false]], false], ["==", ["geometry-type"], "Point"], ["<=", ["get", "filterrank"], 1]], "type": "symbol", "source": "composite", "id": "natural-point-label", "paint": {"icon-opacity": ["step", ["zoom"], ["step", ["get", "sizerank"], 0, 5, 1], 17, ["step", ["get", "sizerank"], 0, 13, 1]], "text-halo-color": "rgb(255, 255, 255)", "text-halo-width": 0.5, "text-halo-blur": 0.5, "text-color": "rgb(128, 128, 128)"}, "source-layer": "natural_label"}, {"id": "water-line-label", "type": "symbol", "metadata": {"mapbox:featureComponent": "natural-features", "mapbox:group": "Natural features, natural-labels"}, "source": "composite", "source-layer": "natural_label", "filter": ["all", ["match", ["get", "class"], ["bay", "ocean", "reservoir", "sea", "water"], ["match", ["get", "worldview"], ["all", "US"], true, false], ["disputed_bay", "disputed_ocean", "disputed_reservoir", "disputed_sea", "disputed_water"], ["all", ["==", ["get", "disputed"], "true"], ["match", ["get", "worldview"], ["all", "US"], true, false]], false], ["==", ["geometry-type"], "LineString"]], "layout": {"text-size": ["interpolate", ["linear"], ["zoom"], 7, ["step", ["get", "sizerank"], 20, 6, 18, 12, 12], 10, ["step", ["get", "sizerank"], 15, 9, 12], 18, ["step", ["get", "sizerank"], 15, 9, 14]], "text-max-angle": 30, "text-letter-spacing": ["match", ["get", "class"], "ocean", 0.25, ["sea", "bay"], 0.15, 0], "text-font": ["DIN Pro Italic", "Arial Unicode MS Regular"], "symbol-placement": "line-center", "text-pitch-alignment": "viewport", "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "visibility": "none"}, "paint": {"text-color": "rgb(150, 150, 150)"}}, {"id": "water-point-label", "type": "symbol", "source": "composite", "source-layer": "natural_label", "filter": ["all", ["match", ["get", "class"], ["bay", "ocean", "reservoir", "sea", "water"], ["match", ["get", "worldview"], ["all", "US"], true, false], ["disputed_bay", "disputed_ocean", "disputed_reservoir", "disputed_sea", "disputed_water"], ["all", ["==", ["get", "disputed"], "true"], ["match", ["get", "worldview"], ["all", "US"], true, false]], false], ["==", ["geometry-type"], "Point"]], "layout": {"text-line-height": 1.3, "text-size": ["interpolate", ["linear"], ["zoom"], 7, ["step", ["get", "sizerank"], 20, 6, 15, 12, 12], 10, ["step", ["get", "sizerank"], 15, 9, 12]], "text-font": ["DIN Pro Italic", "Arial Unicode MS Regular"], "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "text-letter-spacing": ["match", ["get", "class"], "ocean", 0.25, ["bay", "sea"], 0.15, 0.01], "text-max-width": ["match", ["get", "class"], "ocean", 4, "sea", 5, ["bay", "water"], 7, 10], "visibility": "none"}, "paint": {"text-color": "rgb(150, 150, 150)"}, "metadata": {"mapbox:featureComponent": "natural-features", "mapbox:group": "Natural features, natural-labels"}}, {"minzoom": 6, "layout": {"text-size": ["step", ["zoom"], ["step", ["get", "sizerank"], 18, 5, 12], 17, ["step", ["get", "sizerank"], 18, 13, 12]], "icon-image": "", "text-font": ["DIN Pro Medium", "Arial Unicode MS Regular"], "text-offset": [0, 0], "text-anchor": ["step", ["zoom"], ["step", ["get", "sizerank"], "center", 5, "top"], 17, ["step", ["get", "sizerank"], "center", 13, "top"]], "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "visibility": "none"}, "metadata": {"mapbox:featureComponent": "point-of-interest-labels", "mapbox:group": "Point of interest labels, poi-labels"}, "filter": ["<=", ["get", "filterrank"], ["+", ["step", ["zoom"], 1, 2, 3, 4, 5], 1]], "type": "symbol", "source": "composite", "id": "poi-label", "paint": {"text-halo-color": "rgb(255, 255, 255)", "text-halo-width": 0.5, "text-halo-blur": 0.5, "text-color": ["step", ["zoom"], ["step", ["get", "sizerank"], "rgb(184, 184, 184)", 5, "rgb(161, 161, 161)"], 17, ["step", ["get", "sizerank"], "rgb(184, 184, 184)", 13, "rgb(161, 161, 161)"]]}, "source-layer": "poi_label"}, {"minzoom": 8, "layout": {"text-line-height": 1.1, "text-size": ["step", ["get", "sizerank"], 18, 9, 12], "icon-image": ["get", "maki"], "text-font": ["DIN Pro Medium", "Arial Unicode MS Regular"], "visibility": "none", "text-offset": [0, 0.75], "text-rotation-alignment": "viewport", "text-anchor": "top", "text-field": ["step", ["get", "sizerank"], ["coalesce", ["get", "name_en"], ["get", "name"]], 15, ["get", "ref"]], "text-letter-spacing": 0.01, "text-max-width": 9}, "metadata": {"mapbox:featureComponent": "transit", "mapbox:group": "Transit, transit-labels"}, "filter": ["match", ["get", "class"], ["military", "civil"], ["match", ["get", "worldview"], ["all", "US"], true, false], ["disputed_military", "disputed_civil"], ["all", ["==", ["get", "disputed"], "true"], ["match", ["get", "worldview"], ["all", "US"], true, false]], false], "type": "symbol", "source": "composite", "id": "airport-label", "paint": {"text-color": "rgb(128, 128, 128)", "text-halo-color": "rgb(255, 255, 255)", "text-halo-width": 1}, "source-layer": "airport_label"}, {"minzoom": 10, "layout": {"text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "text-transform": "uppercase", "text-font": ["DIN Pro Regular", "Arial Unicode MS Regular"], "text-letter-spacing": ["match", ["get", "type"], "suburb", 0.15, 0.1], "text-max-width": 7, "text-padding": 3, "text-size": ["interpolate", ["cubic-bezier", 0.5, 0, 1, 1], ["zoom"], 11, ["match", ["get", "type"], "suburb", 11, 10.5], 15, ["match", ["get", "type"], "suburb", 15, 14]], "visibility": "none"}, "metadata": {"mapbox:featureComponent": "place-labels", "mapbox:group": "Place labels, place-labels"}, "maxzoom": 15, "filter": ["all", ["match", ["get", "class"], "settlement_subdivision", ["match", ["get", "worldview"], ["all", "US"], true, false], "disputed_settlement_subdivision", ["all", ["==", ["get", "disputed"], "true"], ["match", ["get", "worldview"], ["all", "US"], true, false]], false], ["<=", ["get", "filterrank"], 4]], "type": "symbol", "source": "composite", "id": "settlement-subdivision-label", "paint": {"text-halo-color": "rgb(255, 255, 255)", "text-halo-width": 1, "text-color": "rgb(179, 179, 179)", "text-halo-blur": 0.5}, "source-layer": "place_label"}, {"minzoom": 3, "layout": {"text-line-height": 1.1, "text-size": ["interpolate", ["cubic-bezier", 0.2, 0, 0.9, 1], ["zoom"], 3, ["step", ["get", "symbolrank"], 12, 9, 11, 10, 10.5, 12, 9.5, 14, 8.5, 16, 6.5, 17, 4], 13, ["step", ["get", "symbolrank"], 23, 9, 21, 10, 19, 11, 17, 12, 16, 13, 15, 15, 13]], "text-radial-offset": ["step", ["zoom"], ["match", ["get", "capital"], 2, 0.6, 0.55], 8, 0], "icon-image": ["step", ["zoom"], ["case", ["==", ["get", "capital"], 2], "border-dot-13", ["step", ["get", "symbolrank"], "dot-11", 9, "dot-10", 11, "dot-9"]], 8, ""], "text-font": ["DIN Pro Regular", "Arial Unicode MS Regular"], "text-justify": "auto", "visibility": "none", "text-anchor": ["step", ["zoom"], ["get", "text_anchor"], 8, "center"], "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "text-max-width": 7}, "metadata": {"mapbox:featureComponent": "place-labels", "mapbox:group": "Place labels, place-labels"}, "maxzoom": 13, "filter": ["all", ["<=", ["get", "filterrank"], 3], ["match", ["get", "class"], "settlement", ["match", ["get", "worldview"], ["all", "US"], true, false], "disputed_settlement", ["all", ["==", ["get", "disputed"], "true"], ["match", ["get", "worldview"], ["all", "US"], true, false]], false], ["step", ["zoom"], [">", ["get", "symbolrank"], 6], 1, [">=", ["get", "symbolrank"], 7], 2, [">=", ["get", "symbolrank"], 8], 3, [">=", ["get", "symbolrank"], 10], 4, [">=", ["get", "symbolrank"], 11], 5, [">=", ["get", "symbolrank"], 13], 6, [">=", ["get", "symbolrank"], 15]]], "type": "symbol", "source": "composite", "id": "settlement-minor-label", "paint": {"text-color": ["step", ["get", "symbolrank"], "rgb(128, 128, 128)", 11, "rgb(161, 161, 161)", 16, "rgb(184, 184, 184)"], "text-halo-color": "rgb(255, 255, 255)", "text-halo-width": 1, "text-halo-blur": 1}, "source-layer": "place_label"}, {"minzoom": 3, "layout": {"text-line-height": 1.1, "text-size": ["interpolate", ["cubic-bezier", 0.2, 0, 0.9, 1], ["zoom"], 3, ["step", ["get", "symbolrank"], 13, 6, 12], 6, ["step", ["get", "symbolrank"], 16, 6, 15, 7, 14], 8, ["step", ["get", "symbolrank"], 18, 9, 17, 10, 15], 15, ["step", ["get", "symbolrank"], 23, 9, 22, 10, 20, 11, 18, 12, 16, 13, 15, 15, 13]], "text-radial-offset": ["step", ["zoom"], ["match", ["get", "capital"], 2, 0.6, 0.55], 8, 0], "icon-image": ["step", ["zoom"], ["case", ["==", ["get", "capital"], 2], "border-dot-13", ["step", ["get", "symbolrank"], "dot-11", 9, "dot-10", 11, "dot-9"]], 8, ""], "text-font": ["DIN Pro Medium", "Arial Unicode MS Regular"], "text-justify": ["step", ["zoom"], ["match", ["get", "text_anchor"], ["left", "bottom-left", "top-left"], "left", ["right", "bottom-right", "top-right"], "right", "center"], 8, "center"], "visibility": "none", "text-anchor": ["step", ["zoom"], ["get", "text_anchor"], 8, "center"], "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "text-max-width": 7}, "metadata": {"mapbox:featureComponent": "place-labels", "mapbox:group": "Place labels, place-labels"}, "maxzoom": 15, "filter": ["all", ["<=", ["get", "filterrank"], 3], ["match", ["get", "class"], "settlement", ["match", ["get", "worldview"], ["all", "US"], true, false], "disputed_settlement", ["all", ["==", ["get", "disputed"], "true"], ["match", ["get", "worldview"], ["all", "US"], true, false]], false], ["step", ["zoom"], false, 1, ["<=", ["get", "symbolrank"], 6], 2, ["<", ["get", "symbolrank"], 7], 3, ["<", ["get", "symbolrank"], 8], 4, ["<", ["get", "symbolrank"], 10], 5, ["<", ["get", "symbolrank"], 11], 6, ["<", ["get", "symbolrank"], 13], 7, ["<", ["get", "symbolrank"], 15], 8, [">=", ["get", "symbolrank"], 11], 9, [">=", ["get", "symbolrank"], 15]]], "type": "symbol", "source": "composite", "id": "settlement-major-label", "paint": {"text-color": ["step", ["get", "symbolrank"], "rgb(128, 128, 128)", 11, "rgb(161, 161, 161)", 16, "rgb(184, 184, 184)"], "text-halo-color": "rgb(255, 255, 255)", "text-halo-width": 1, "text-halo-blur": 1}, "source-layer": "place_label"}, {"minzoom": 3, "layout": {"text-size": ["interpolate", ["cubic-bezier", 0.85, 0.7, 0.65, 1], ["zoom"], 4, ["step", ["get", "symbolrank"], 10, 6, 9.5, 7, 9], 9, ["step", ["get", "symbolrank"], 21, 6, 16, 7, 13]], "text-transform": "uppercase", "text-font": ["DIN Pro Bold", "Arial Unicode MS Bold"], "text-field": ["step", ["zoom"], ["step", ["get", "symbolrank"], ["coalesce", ["get", "name_en"], ["get", "name"]], 5, ["coalesce", ["get", "abbr"], ["get", "name_en"], ["get", "name"]]], 5, ["coalesce", ["get", "name_en"], ["get", "name"]]], "text-letter-spacing": 0.15, "text-max-width": 6, "visibility": "none"}, "metadata": {"mapbox:featureComponent": "place-labels", "mapbox:group": "Place labels, place-labels"}, "maxzoom": 9, "filter": ["match", ["get", "class"], "state", ["match", ["get", "worldview"], ["all", "US"], true, false], "disputed_state", ["all", ["==", ["get", "disputed"], "true"], ["match", ["get", "worldview"], ["all", "US"], true, false]], false], "type": "symbol", "source": "composite", "id": "state-label", "paint": {"text-color": "rgb(184, 184, 184)", "text-halo-color": "rgb(255, 255, 255)", "text-halo-width": 1}, "source-layer": "place_label"}, {"minzoom": 1, "layout": {"text-line-height": 1.1, "text-size": ["interpolate", ["cubic-bezier", 0.2, 0, 0.7, 1], ["zoom"], 1, ["step", ["get", "symbolrank"], 11, 4, 9, 5, 8], 9, ["step", ["get", "symbolrank"], 22, 4, 19, 5, 17]], "text-radial-offset": ["step", ["zoom"], 0.6, 8, 0], "icon-image": "", "text-font": ["DIN Pro Medium", "Arial Unicode MS Regular"], "text-justify": ["step", ["zoom"], ["match", ["get", "text_anchor"], ["left", "bottom-left", "top-left"], "left", ["right", "bottom-right", "top-right"], "right", "center"], 7, "auto"], "visibility": "none", "text-field": ["coalesce", ["get", "name_en"], ["get", "name"]], "text-max-width": 6}, "metadata": {"mapbox:featureComponent": "place-labels", "mapbox:group": "Place labels, place-labels"}, "maxzoom": 10, "filter": ["match", ["get", "class"], "country", ["match", ["get", "worldview"], ["all", "US"], true, false], "disputed_country", ["all", ["==", ["get", "disputed"], "true"], ["match", ["get", "worldview"], ["all", "US"], true, false]], false], "type": "symbol", "source": "composite", "id": "country-label", "paint": {"icon-opacity": ["step", ["zoom"], ["case", ["has", "text_anchor"], 1, 0], 7, 0], "text-color": "rgb(128, 128, 128)", "text-halo-color": "rgb(255, 255, 255)", "text-halo-width": 1.25}, "source-layer": "place_label"}], "created": "2021-11-05T16:12:04.822Z", "modified": "2021-11-25T13:58:04.167Z", "id": "ckvmksrpd4n0a14pfdo5heqzr", "owner": "commaai", "visibility": "private", "protected": false, "draft": false} \ No newline at end of file diff --git a/selfdrive/navd/tests/test_map_renderer.py b/selfdrive/navd/tests/test_map_renderer.py deleted file mode 100644 index 04363883b2c0f4..00000000000000 --- a/selfdrive/navd/tests/test_map_renderer.py +++ /dev/null @@ -1,212 +0,0 @@ -import time -import numpy as np -import os -import pytest -import requests -import threading -import http.server -import cereal.messaging as messaging - -from typing import Any -from msgq.visionipc import VisionIpcClient, VisionStreamType -from openpilot.common.mock.generators import LLK_DECIMATION, LOCATION1, LOCATION2, generate_liveLocationKalman -from openpilot.selfdrive.test.helpers import with_processes - -CACHE_PATH = "/data/mbgl-cache-navd.db" - -RENDER_FRAMES = 15 -DEFAULT_ITERATIONS = RENDER_FRAMES * LLK_DECIMATION -LOCATION1_REPEATED = [LOCATION1] * DEFAULT_ITERATIONS -LOCATION2_REPEATED = [LOCATION2] * DEFAULT_ITERATIONS - - -class MapBoxInternetDisabledRequestHandler(http.server.BaseHTTPRequestHandler): - INTERNET_ACTIVE = True - - def do_GET(self): - if not self.INTERNET_ACTIVE: - self.send_response(500) - self.end_headers() - return - - url = f'https://api.mapbox.com{self.path}' - - headers = dict(self.headers) - headers["Host"] = "api.mapbox.com" - - r = requests.get(url, headers=headers, timeout=5) - - self.send_response(r.status_code) - self.end_headers() - self.wfile.write(r.content) - - def log_message(self, *args: Any) -> None: - return - - def log_error(self, *args: Any) -> None: - return - - -class MapBoxInternetDisabledServer(threading.Thread): - def run(self): - self.server = http.server.HTTPServer(("127.0.0.1", 0), MapBoxInternetDisabledRequestHandler) - self.port = self.server.server_port - self.server.serve_forever() - - def stop(self): - self.server.shutdown() - - def disable_internet(self): - MapBoxInternetDisabledRequestHandler.INTERNET_ACTIVE = False - - def enable_internet(self): - MapBoxInternetDisabledRequestHandler.INTERNET_ACTIVE = True - - -@pytest.mark.skip(reason="not used") -class TestMapRenderer: - server: MapBoxInternetDisabledServer - - @classmethod - def setup_class(cls): - assert "MAPBOX_TOKEN" in os.environ - cls.original_token = os.environ["MAPBOX_TOKEN"] - cls.server = MapBoxInternetDisabledServer() - cls.server.start() - time.sleep(0.5) # wait for server to startup - - @classmethod - def teardown_class(cls) -> None: - cls.server.stop() - - def setup_method(self): - self.server.enable_internet() - os.environ['MAPS_HOST'] = f'http://localhost:{self.server.port}' - - self.sm = messaging.SubMaster(['mapRenderState']) - self.pm = messaging.PubMaster(['liveLocationKalman']) - self.vipc = VisionIpcClient("navd", VisionStreamType.VISION_STREAM_MAP, True) - - if os.path.exists(CACHE_PATH): - os.remove(CACHE_PATH) - - def _setup_test(self): - assert self.pm.wait_for_readers_to_update("liveLocationKalman", 10) - - time.sleep(0.5) - - assert VisionIpcClient.available_streams("navd", False) == {VisionStreamType.VISION_STREAM_MAP, } - assert self.vipc.connect(False) - self.vipc.recv() - - def _run_test(self, expect_valid, locations=LOCATION1_REPEATED): - starting_frame_id = None - - render_times = [] - - # run test - prev_frame_id = -1 - for i, location in enumerate(locations): - frame_expected = (i+1) % LLK_DECIMATION == 0 - - if self.sm.logMonoTime['mapRenderState'] == 0: - prev_valid = False - prev_frame_id = -1 - else: - prev_valid = self.sm.valid['mapRenderState'] - prev_frame_id = self.sm['mapRenderState'].frameId - - if starting_frame_id is None: - starting_frame_id = prev_frame_id - - llk = generate_liveLocationKalman(location) - self.pm.send("liveLocationKalman", llk) - self.pm.wait_for_readers_to_update("liveLocationKalman", 10) - self.sm.update(1000 if frame_expected else 0) - assert self.sm.updated['mapRenderState'] == frame_expected, "renderer running at wrong frequency" - - if not frame_expected: - continue - - frames_since_test_start = self.sm['mapRenderState'].frameId - starting_frame_id - - # give a few frames to switch from valid to invalid, or vice versa - invalid_and_not_previously_valid = (expect_valid and not self.sm.valid['mapRenderState'] and not prev_valid) - valid_and_not_previously_invalid = (not expect_valid and self.sm.valid['mapRenderState'] and prev_valid) - - if (invalid_and_not_previously_valid or valid_and_not_previously_invalid) and frames_since_test_start < 20: - continue - - # check output - assert self.sm.valid['mapRenderState'] == expect_valid - assert self.sm['mapRenderState'].frameId == (prev_frame_id + 1) - assert self.sm['mapRenderState'].locationMonoTime == llk.logMonoTime - if not expect_valid: - assert self.sm['mapRenderState'].renderTime == 0. - else: - assert 0. < self.sm['mapRenderState'].renderTime < 0.1 - render_times.append(self.sm['mapRenderState'].renderTime) - - # check vision ipc output - assert self.vipc.recv() is not None - assert self.vipc.valid == expect_valid - assert self.vipc.timestamp_sof == llk.logMonoTime - assert self.vipc.frame_id == self.sm['mapRenderState'].frameId - - assert frames_since_test_start >= RENDER_FRAMES - - return render_times - - @with_processes(["mapsd"]) - def test_with_internet(self): - self._setup_test() - self._run_test(True) - - @with_processes(["mapsd"]) - def test_with_no_internet(self): - self.server.disable_internet() - self._setup_test() - self._run_test(False) - - @with_processes(["mapsd"]) - @pytest.mark.skip(reason="slow, flaky, and unlikely to break") - def test_recover_from_no_internet(self): - self._setup_test() - self._run_test(True) - - self.server.disable_internet() - - # change locations to force mapsd to refetch - self._run_test(False, LOCATION2_REPEATED) - - self.server.enable_internet() - self._run_test(True, LOCATION2_REPEATED) - - @with_processes(["mapsd"]) - @pytest.mark.tici - def test_render_time_distribution(self): - self._setup_test() - # from location1 -> location2 and back - locations = np.array([*np.linspace(LOCATION1, LOCATION2, 2000), *np.linspace(LOCATION2, LOCATION1, 2000)]).tolist() - - render_times = self._run_test(True, locations) - - _min = np.min(render_times) - _max = np.max(render_times) - _mean = np.mean(render_times) - _median = np.median(render_times) - _stddev = np.std(render_times) - - print(f"Stats: min: {_min}, max: {_max}, mean: {_mean}, median: {_median}, stddev: {_stddev}, count: {len(render_times)}") - - def assert_stat(stat, nominal, tol=0.3): - tol = (nominal / (1+tol)), (nominal * (1+tol)) - assert tol[0] < stat < tol[1], f"{stat} not in tolerance {tol}" - - assert_stat(_mean, 0.030) - assert_stat(_median, 0.027) - assert_stat(_stddev, 0.0078) - - assert _max < 0.065 - assert _min > 0.015 - diff --git a/selfdrive/navd/tests/test_navd.py b/selfdrive/navd/tests/test_navd.py deleted file mode 100644 index b6580acff18a7a..00000000000000 --- a/selfdrive/navd/tests/test_navd.py +++ /dev/null @@ -1,57 +0,0 @@ -import json -import random -import numpy as np - -from parameterized import parameterized - -import cereal.messaging as messaging -from openpilot.common.params import Params -from openpilot.system.manager.process_config import managed_processes - - -class TestNavd: - def setup_method(self): - self.params = Params() - self.sm = messaging.SubMaster(['navRoute', 'navInstruction']) - - def teardown_method(self): - managed_processes['navd'].stop() - - def _check_route(self, start, end, check_coords=True): - self.params.put("NavDestination", json.dumps(end)) - self.params.put("LastGPSPosition", json.dumps(start)) - - managed_processes['navd'].start() - for _ in range(30): - self.sm.update(1000) - if all(f > 0 for f in self.sm.recv_frame.values()): - break - else: - raise Exception("didn't get a route") - - assert managed_processes['navd'].proc.is_alive() - managed_processes['navd'].stop() - - # ensure start and end match up - if check_coords: - coords = self.sm['navRoute'].coordinates - assert np.allclose([start['latitude'], start['longitude'], end['latitude'], end['longitude']], - [coords[0].latitude, coords[0].longitude, coords[-1].latitude, coords[-1].longitude], - rtol=1e-3) - - def test_simple(self): - start = { - "latitude": 32.7427228, - "longitude": -117.2321177, - } - end = { - "latitude": 32.7557004, - "longitude": -117.268002, - } - self._check_route(start, end) - - @parameterized.expand([(i,) for i in range(10)]) - def test_random(self, index): - start = {"latitude": random.uniform(-90, 90), "longitude": random.uniform(-180, 180)} - end = {"latitude": random.uniform(-90, 90), "longitude": random.uniform(-180, 180)} - self._check_route(start, end, check_coords=False) diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 7b44a3b80eb8da..7574a5e4abce16 100644 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -60,7 +60,6 @@ "system.timed": 0, "selfdrive.pandad.pandad": 0, "system.statsd": 0.4, - "selfdrive.navd.navd": 0.4, "system.loggerd.uploader": (0.5, 15.0), "system.loggerd.deleter": 0.1, } diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index e4fb32586d2fd9..8b268b9e84878b 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -1,6 +1,6 @@ import os import json -Import('qt_env', 'arch', 'common', 'messaging', 'visionipc', 'transformations', 'UBUNTU_FOCAL') +Import('qt_env', 'arch', 'common', 'messaging', 'visionipc', 'transformations') base_libs = [common, messaging, visionipc, transformations, 'm', 'OpenCL', 'ssl', 'crypto', 'pthread'] + qt_env["LIBS"] @@ -8,8 +8,6 @@ base_libs = [common, messaging, visionipc, transformations, if arch == 'larch64': base_libs.append('EGL') -maps = arch in ['larch64', 'aarch64', 'x86_64'] and not UBUNTU_FOCAL - if arch == "Darwin": del base_libs[base_libs.index('OpenCL')] qt_env['FRAMEWORKS'] += ['OpenCL'] @@ -24,13 +22,6 @@ widgets_src = ["ui.cc", "qt/widgets/input.cc", "qt/widgets/wifi.cc", "qt/widgets/scrollview.cc", "qt/widgets/cameraview.cc", "#third_party/qrcode/QrCode.cc", "qt/request_repeater.cc", "qt/qt_window.cc", "qt/network/networking.cc", "qt/network/wifi_manager.cc"] -qt_env['CPPDEFINES'] = [] -if maps: - base_libs += ['QMapLibre'] - widgets_src += ["qt/maps/map_helpers.cc", "qt/maps/map_settings.cc", "qt/maps/map.cc", "qt/maps/map_panel.cc", - "qt/maps/map_eta.cc", "qt/maps/map_instructions.cc"] - qt_env['CPPDEFINES'] += ["ENABLE_MAPS"] - widgets = qt_env.Library("qt_widgets", widgets_src, LIBS=base_libs) Export('widgets') qt_libs = [widgets, qt_util] + base_libs diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc index 9dbe7cbae39b86..c510087e8e33df 100644 --- a/selfdrive/ui/qt/home.cc +++ b/selfdrive/ui/qt/home.cc @@ -9,10 +9,6 @@ #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/widgets/prime.h" -#ifdef ENABLE_MAPS -#include "selfdrive/ui/qt/maps/map_settings.h" -#endif - // HomeWindow: the container for the offroad and onroad UIs HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) { @@ -145,13 +141,17 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) { home_layout->setContentsMargins(0, 0, 0, 0); home_layout->setSpacing(30); - // left: MapSettings/PrimeAdWidget + // left: PrimeAdWidget QStackedWidget *left_widget = new QStackedWidget(this); -#ifdef ENABLE_MAPS - left_widget->addWidget(new MapSettings); -#else - left_widget->addWidget(new QWidget); -#endif + QVBoxLayout *left_prime_layout = new QVBoxLayout(); + QWidget *prime_user = new PrimeUserWidget(); + prime_user->setStyleSheet(R"( + border-radius: 10px; + background-color: #333333; + )"); + left_prime_layout->addWidget(prime_user); + left_prime_layout->addStretch(); + left_widget->addWidget(new LayoutWidget(left_prime_layout)); left_widget->addWidget(new PrimeAdWidget); left_widget->setStyleSheet("border-radius: 10px;"); diff --git a/selfdrive/ui/qt/maps/map.cc b/selfdrive/ui/qt/maps/map.cc deleted file mode 100644 index 490eb118cad047..00000000000000 --- a/selfdrive/ui/qt/maps/map.cc +++ /dev/null @@ -1,390 +0,0 @@ -#include "selfdrive/ui/qt/maps/map.h" - -#include -#include - -#include - -#include "common/swaglog.h" -#include "selfdrive/ui/qt/maps/map_helpers.h" -#include "selfdrive/ui/qt/util.h" -#include "selfdrive/ui/ui.h" - - -const int INTERACTION_TIMEOUT = 100; - -const float MAX_ZOOM = 17; -const float MIN_ZOOM = 14; -const float MAX_PITCH = 50; -const float MIN_PITCH = 0; -const float MAP_SCALE = 2; - -MapWindow::MapWindow(const QMapLibre::Settings &settings) : m_settings(settings), velocity_filter(0, 10, 0.05, false) { - QObject::connect(uiState(), &UIState::uiUpdate, this, &MapWindow::updateState); - - map_overlay = new QWidget (this); - map_overlay->setAttribute(Qt::WA_TranslucentBackground, true); - QVBoxLayout *overlay_layout = new QVBoxLayout(map_overlay); - overlay_layout->setContentsMargins(0, 0, 0, 0); - - // Instructions - map_instructions = new MapInstructions(this); - map_instructions->setVisible(false); - - map_eta = new MapETA(this); - map_eta->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - map_eta->setFixedHeight(120); - - error = new QLabel(this); - error->setStyleSheet(R"(color:white;padding:50px 11px;font-size: 90px; background-color:rgba(0, 0, 0, 150);)"); - error->setAlignment(Qt::AlignCenter); - - overlay_layout->addWidget(error); - overlay_layout->addWidget(map_instructions); - overlay_layout->addStretch(1); - overlay_layout->addWidget(map_eta); - - last_position = coordinate_from_param("LastGPSPosition"); - grabGesture(Qt::GestureType::PinchGesture); - qDebug() << "MapWindow initialized"; -} - -MapWindow::~MapWindow() { - makeCurrent(); -} - -void MapWindow::initLayers() { - // This doesn't work from initializeGL - if (!m_map->layerExists("modelPathLayer")) { - qDebug() << "Initializing modelPathLayer"; - QVariantMap modelPath; - //modelPath["id"] = "modelPathLayer"; - modelPath["type"] = "line"; - modelPath["source"] = "modelPathSource"; - m_map->addLayer("modelPathLayer", modelPath); - m_map->setPaintProperty("modelPathLayer", "line-color", QColor("red")); - m_map->setPaintProperty("modelPathLayer", "line-width", 5.0); - m_map->setLayoutProperty("modelPathLayer", "line-cap", "round"); - } - if (!m_map->layerExists("navLayer")) { - qDebug() << "Initializing navLayer"; - QVariantMap nav; - nav["type"] = "line"; - nav["source"] = "navSource"; - m_map->addLayer("navLayer", nav, "road-intersection"); - - QVariantMap transition; - transition["duration"] = 400; // ms - m_map->setPaintProperty("navLayer", "line-color", QColor("#31a1ee")); - m_map->setPaintProperty("navLayer", "line-color-transition", transition); - m_map->setPaintProperty("navLayer", "line-width", 7.5); - m_map->setLayoutProperty("navLayer", "line-cap", "round"); - } - if (!m_map->layerExists("pinLayer")) { - qDebug() << "Initializing pinLayer"; - m_map->addImage("default_marker", QImage("../assets/navigation/default_marker.svg")); - QVariantMap pin; - pin["type"] = "symbol"; - pin["source"] = "pinSource"; - m_map->addLayer("pinLayer", pin); - m_map->setLayoutProperty("pinLayer", "icon-pitch-alignment", "viewport"); - m_map->setLayoutProperty("pinLayer", "icon-image", "default_marker"); - m_map->setLayoutProperty("pinLayer", "icon-ignore-placement", true); - m_map->setLayoutProperty("pinLayer", "icon-allow-overlap", true); - m_map->setLayoutProperty("pinLayer", "symbol-sort-key", 0); - m_map->setLayoutProperty("pinLayer", "icon-anchor", "bottom"); - } - if (!m_map->layerExists("carPosLayer")) { - qDebug() << "Initializing carPosLayer"; - m_map->addImage("label-arrow", QImage("../assets/images/triangle.svg")); - - QVariantMap carPos; - carPos["type"] = "symbol"; - carPos["source"] = "carPosSource"; - m_map->addLayer("carPosLayer", carPos); - m_map->setLayoutProperty("carPosLayer", "icon-pitch-alignment", "map"); - m_map->setLayoutProperty("carPosLayer", "icon-image", "label-arrow"); - m_map->setLayoutProperty("carPosLayer", "icon-size", 0.5); - m_map->setLayoutProperty("carPosLayer", "icon-ignore-placement", true); - m_map->setLayoutProperty("carPosLayer", "icon-allow-overlap", true); - // TODO: remove, symbol-sort-key does not seem to matter outside of each layer - m_map->setLayoutProperty("carPosLayer", "symbol-sort-key", 0); - } -} - -void MapWindow::updateState(const UIState &s) { - if (!uiState()->scene.started) { - return; - } - const SubMaster &sm = *(s.sm); - update(); - - // on rising edge of a valid system time, reinitialize the map to set a new token - if (sm.valid("clocks") && !prev_time_valid) { - LOGW("Time is now valid, reinitializing map"); - m_settings.setApiKey(get_mapbox_token()); - initializeGL(); - } - prev_time_valid = sm.valid("clocks"); - - if (sm.updated("liveLocationKalman")) { - auto locationd_location = sm["liveLocationKalman"].getLiveLocationKalman(); - auto locationd_pos = locationd_location.getPositionGeodetic(); - auto locationd_orientation = locationd_location.getCalibratedOrientationNED(); - auto locationd_velocity = locationd_location.getVelocityCalibrated(); - auto locationd_ecef = locationd_location.getPositionECEF(); - - locationd_valid = (locationd_pos.getValid() && locationd_orientation.getValid() && locationd_velocity.getValid() && locationd_ecef.getValid()); - if (locationd_valid) { - // Check std norm - auto pos_ecef_std = locationd_ecef.getStd(); - bool pos_accurate_enough = sqrt(pow(pos_ecef_std[0], 2) + pow(pos_ecef_std[1], 2) + pow(pos_ecef_std[2], 2)) < 100; - locationd_valid = pos_accurate_enough; - } - - if (locationd_valid) { - last_position = QMapLibre::Coordinate(locationd_pos.getValue()[0], locationd_pos.getValue()[1]); - last_bearing = RAD2DEG(locationd_orientation.getValue()[2]); - velocity_filter.update(std::max(10.0, locationd_velocity.getValue()[0])); - } - } - - if (sm.updated("navRoute") && sm["navRoute"].getNavRoute().getCoordinates().size()) { - auto nav_dest = coordinate_from_param("NavDestination"); - bool allow_open = std::exchange(last_valid_nav_dest, nav_dest) != nav_dest && - nav_dest && !isVisible(); - qWarning() << "Got new navRoute from navd. Opening map:" << allow_open; - - // Show map on destination set/change - if (allow_open) { - emit requestSettings(false); - emit requestVisible(true); - } - } - - loaded_once = loaded_once || (m_map && m_map->isFullyLoaded()); - if (!loaded_once) { - setError(tr("Map Loading")); - return; - } - initLayers(); - - if (!locationd_valid) { - setError(tr("Waiting for GPS")); - } else if (routing_problem) { - setError(tr("Waiting for route")); - } else { - setError(""); - } - - if (locationd_valid) { - // Update current location marker - auto point = coordinate_to_collection(*last_position); - QMapLibre::Feature feature1(QMapLibre::Feature::PointType, point, {}, {}); - QVariantMap carPosSource; - carPosSource["type"] = "geojson"; - carPosSource["data"] = QVariant::fromValue(feature1); - m_map->updateSource("carPosSource", carPosSource); - - // Map bearing isn't updated when interacting, keep location marker up to date - if (last_bearing) { - m_map->setLayoutProperty("carPosLayer", "icon-rotate", *last_bearing - m_map->bearing()); - } - } - - if (interaction_counter == 0) { - if (last_position) m_map->setCoordinate(*last_position); - if (last_bearing) m_map->setBearing(*last_bearing); - m_map->setZoom(util::map_val(velocity_filter.x(), 0, 30, MAX_ZOOM, MIN_ZOOM)); - } else { - interaction_counter--; - } - - if (sm.updated("navInstruction")) { - // an invalid navInstruction packet with a nav destination is only possible if: - // - API exception/no internet - // - route response is empty - // - any time navd is waiting for recompute_countdown - routing_problem = !sm.valid("navInstruction") && coordinate_from_param("NavDestination").has_value(); - - if (sm.valid("navInstruction")) { - auto i = sm["navInstruction"].getNavInstruction(); - map_eta->updateETA(i.getTimeRemaining(), i.getTimeRemainingTypical(), i.getDistanceRemaining()); - - if (locationd_valid) { - m_map->setPitch(MAX_PITCH); // TODO: smooth pitching based on maneuver distance - map_instructions->updateInstructions(i); - } - } else { - clearRoute(); - } - } - - if (sm.rcv_frame("navRoute") != route_rcv_frame) { - qWarning() << "Updating navLayer with new route"; - auto route = sm["navRoute"].getNavRoute(); - auto route_points = capnp_coordinate_list_to_collection(route.getCoordinates()); - QMapLibre::Feature feature(QMapLibre::Feature::LineStringType, route_points, {}, {}); - QVariantMap navSource; - navSource["type"] = "geojson"; - navSource["data"] = QVariant::fromValue(feature); - m_map->updateSource("navSource", navSource); - m_map->setLayoutProperty("navLayer", "visibility", "visible"); - - route_rcv_frame = sm.rcv_frame("navRoute"); - updateDestinationMarker(); - } -} - -void MapWindow::setError(const QString &err_str) { - if (err_str != error->text()) { - error->setText(err_str); - error->setVisible(!err_str.isEmpty()); - if (!err_str.isEmpty()) map_instructions->setVisible(false); - } -} - -void MapWindow::resizeGL(int w, int h) { - m_map->resize(size() / MAP_SCALE); - map_overlay->setFixedSize(width(), height()); -} - -void MapWindow::initializeGL() { - m_map.reset(new QMapLibre::Map(this, m_settings, size(), 1)); - - if (last_position) { - m_map->setCoordinateZoom(*last_position, MAX_ZOOM); - } else { - m_map->setCoordinateZoom(QMapLibre::Coordinate(64.31990695292795, -149.79038934046247), MIN_ZOOM); - } - - m_map->setMargins({0, 350, 0, 50}); - m_map->setPitch(MIN_PITCH); - m_map->setStyleUrl("mapbox://styles/commaai/clkqztk0f00ou01qyhsa5bzpj"); - - QObject::connect(m_map.data(), &QMapLibre::Map::mapChanged, [=](QMapLibre::Map::MapChange change) { - // set global animation duration to 0 ms so visibility changes are instant - if (change == QMapLibre::Map::MapChange::MapChangeDidFinishLoadingStyle) { - m_map->setTransitionOptions(0, 0); - } - if (change == QMapLibre::Map::MapChange::MapChangeDidFinishLoadingMap) { - loaded_once = true; - } - }); - - QObject::connect(m_map.data(), &QMapLibre::Map::mapLoadingFailed, [=](QMapLibre::Map::MapLoadingFailure err_code, const QString &reason) { - LOGE("Map loading failed with %d: '%s'\n", err_code, reason.toStdString().c_str()); - }); -} - -void MapWindow::paintGL() { - if (!isVisible() || m_map.isNull()) return; - m_map->render(); -} - -void MapWindow::clearRoute() { - if (!m_map.isNull()) { - m_map->setLayoutProperty("navLayer", "visibility", "none"); - m_map->setPitch(MIN_PITCH); - updateDestinationMarker(); - } - - map_instructions->setVisible(false); - map_eta->setVisible(false); - last_valid_nav_dest = std::nullopt; -} - -void MapWindow::mousePressEvent(QMouseEvent *ev) { - m_lastPos = ev->localPos(); - ev->accept(); -} - -void MapWindow::mouseDoubleClickEvent(QMouseEvent *ev) { - if (last_position) m_map->setCoordinate(*last_position); - if (last_bearing) m_map->setBearing(*last_bearing); - m_map->setZoom(util::map_val(velocity_filter.x(), 0, 30, MAX_ZOOM, MIN_ZOOM)); - update(); - - interaction_counter = 0; -} - -void MapWindow::mouseMoveEvent(QMouseEvent *ev) { - QPointF delta = ev->localPos() - m_lastPos; - - if (!delta.isNull()) { - interaction_counter = INTERACTION_TIMEOUT; - m_map->moveBy(delta / MAP_SCALE); - update(); - } - - m_lastPos = ev->localPos(); - ev->accept(); -} - -void MapWindow::wheelEvent(QWheelEvent *ev) { - if (ev->orientation() == Qt::Horizontal) { - return; - } - - float factor = ev->delta() / 1200.; - if (ev->delta() < 0) { - factor = factor > -1 ? factor : 1 / factor; - } - - m_map->scaleBy(1 + factor, ev->pos() / MAP_SCALE); - update(); - - interaction_counter = INTERACTION_TIMEOUT; - ev->accept(); -} - -bool MapWindow::event(QEvent *event) { - if (event->type() == QEvent::Gesture) { - return gestureEvent(static_cast(event)); - } - - return QWidget::event(event); -} - -bool MapWindow::gestureEvent(QGestureEvent *event) { - if (QGesture *pinch = event->gesture(Qt::PinchGesture)) { - pinchTriggered(static_cast(pinch)); - } - return true; -} - -void MapWindow::pinchTriggered(QPinchGesture *gesture) { - QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags(); - if (changeFlags & QPinchGesture::ScaleFactorChanged) { - // TODO: figure out why gesture centerPoint doesn't work - m_map->scaleBy(gesture->scaleFactor(), {width() / 2.0 / MAP_SCALE, height() / 2.0 / MAP_SCALE}); - update(); - interaction_counter = INTERACTION_TIMEOUT; - } -} - -void MapWindow::offroadTransition(bool offroad) { - if (offroad) { - clearRoute(); - routing_problem = false; - } else { - auto dest = coordinate_from_param("NavDestination"); - emit requestVisible(dest.has_value()); - } - last_bearing = {}; -} - -void MapWindow::updateDestinationMarker() { - auto nav_dest = coordinate_from_param("NavDestination"); - if (nav_dest.has_value()) { - auto point = coordinate_to_collection(*nav_dest); - QMapLibre::Feature feature(QMapLibre::Feature::PointType, point, {}, {}); - QVariantMap pinSource; - pinSource["type"] = "geojson"; - pinSource["data"] = QVariant::fromValue(feature); - m_map->updateSource("pinSource", pinSource); - m_map->setPaintProperty("pinLayer", "visibility", "visible"); - } else { - m_map->setPaintProperty("pinLayer", "visibility", "none"); - } -} diff --git a/selfdrive/ui/qt/maps/map.h b/selfdrive/ui/qt/maps/map.h deleted file mode 100644 index 31a44f27b1ecec..00000000000000 --- a/selfdrive/ui/qt/maps/map.h +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cereal/messaging/messaging.h" -#include "common/params.h" -#include "common/util.h" -#include "selfdrive/ui/ui.h" -#include "selfdrive/ui/qt/maps/map_eta.h" -#include "selfdrive/ui/qt/maps/map_instructions.h" - -class MapWindow : public QOpenGLWidget { - Q_OBJECT - -public: - MapWindow(const QMapLibre::Settings &); - ~MapWindow(); - -private: - void initializeGL() final; - void paintGL() final; - void resizeGL(int w, int h) override; - - QMapLibre::Settings m_settings; - QScopedPointer m_map; - - void initLayers(); - - void mousePressEvent(QMouseEvent *ev) final; - void mouseDoubleClickEvent(QMouseEvent *ev) final; - void mouseMoveEvent(QMouseEvent *ev) final; - void wheelEvent(QWheelEvent *ev) final; - bool event(QEvent *event) final; - bool gestureEvent(QGestureEvent *event); - void pinchTriggered(QPinchGesture *gesture); - void setError(const QString &err_str); - - bool loaded_once = false; - bool prev_time_valid = true; - - // Panning - QPointF m_lastPos; - int interaction_counter = 0; - - // Position - std::optional last_valid_nav_dest; - std::optional last_position; - std::optional last_bearing; - FirstOrderFilter velocity_filter; - bool locationd_valid = false; - bool routing_problem = false; - - QWidget *map_overlay; - QLabel *error; - MapInstructions* map_instructions; - MapETA* map_eta; - - void clearRoute(); - void updateDestinationMarker(); - uint64_t route_rcv_frame = 0; - -private slots: - void updateState(const UIState &s); - -public slots: - void offroadTransition(bool offroad); - -signals: - void requestVisible(bool visible); - void requestSettings(bool settings); -}; diff --git a/selfdrive/ui/qt/maps/map_eta.cc b/selfdrive/ui/qt/maps/map_eta.cc deleted file mode 100644 index 0eb77e36ce6773..00000000000000 --- a/selfdrive/ui/qt/maps/map_eta.cc +++ /dev/null @@ -1,59 +0,0 @@ -#include "selfdrive/ui/qt/maps/map_eta.h" - -#include -#include - -#include "selfdrive/ui/qt/maps/map_helpers.h" -#include "selfdrive/ui/ui.h" - -const float MANEUVER_TRANSITION_THRESHOLD = 10; - -MapETA::MapETA(QWidget *parent) : QWidget(parent) { - setVisible(false); - setAttribute(Qt::WA_TranslucentBackground); - eta_doc.setUndoRedoEnabled(false); - eta_doc.setDefaultStyleSheet("body {font-family:Inter;font-size:70px;color:white;} b{font-weight:600;} td{padding:0 3px;}"); -} - -void MapETA::paintEvent(QPaintEvent *event) { - if (!eta_doc.isEmpty()) { - QPainter p(this); - p.setRenderHint(QPainter::Antialiasing); - p.setPen(Qt::NoPen); - p.setBrush(QColor(0, 0, 0, 255)); - QSizeF txt_size = eta_doc.size(); - p.drawRoundedRect((width() - txt_size.width()) / 2 - UI_BORDER_SIZE, 0, txt_size.width() + UI_BORDER_SIZE * 2, height() + 25, 25, 25); - p.translate((width() - txt_size.width()) / 2, (height() - txt_size.height()) / 2); - eta_doc.drawContents(&p); - } -} - -void MapETA::updateETA(float s, float s_typical, float d) { - // ETA - auto eta_t = QDateTime::currentDateTime().addSecs(s).time(); - auto eta = format_24h ? std::pair{eta_t.toString("HH:mm"), tr("eta")} - : std::pair{eta_t.toString("h:mm a").split(' ')[0], eta_t.toString("a")}; - - // Remaining time - auto remaining = s < 3600 ? std::pair{QString::number(int(s / 60)), tr("min")} - : std::pair{QString("%1:%2").arg((int)s / 3600).arg(((int)s % 3600) / 60, 2, 10, QLatin1Char('0')), tr("hr")}; - QString color = "#25DA6E"; - if (std::abs(s_typical) > 1e-5) { - if (s / s_typical > 1.5) { - color = "#DA3025"; - } else if (s / s_typical > 1.2) { - color = "#DAA725"; - } - } - - // Distance - auto distance = map_format_distance(d, uiState()->scene.is_metric); - - eta_doc.setHtml(QString(R"( - - )") - .arg(eta.first, eta.second, color, remaining.first, remaining.second, distance.first, distance.second)); - - setVisible(d >= MANEUVER_TRANSITION_THRESHOLD); - update(); -} diff --git a/selfdrive/ui/qt/maps/map_eta.h b/selfdrive/ui/qt/maps/map_eta.h deleted file mode 100644 index 6e59837de3d746..00000000000000 --- a/selfdrive/ui/qt/maps/map_eta.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "common/params.h" - -class MapETA : public QWidget { - Q_OBJECT - -public: - MapETA(QWidget * parent=nullptr); - void updateETA(float seconds, float seconds_typical, float distance); - -private: - void paintEvent(QPaintEvent *event) override; - void showEvent(QShowEvent *event) override { format_24h = param.getBool("NavSettingTime24h"); } - - bool format_24h = false; - QTextDocument eta_doc; - Params param; -}; diff --git a/selfdrive/ui/qt/maps/map_helpers.cc b/selfdrive/ui/qt/maps/map_helpers.cc deleted file mode 100644 index 50e14011640b6b..00000000000000 --- a/selfdrive/ui/qt/maps/map_helpers.cc +++ /dev/null @@ -1,153 +0,0 @@ -#include "selfdrive/ui/qt/maps/map_helpers.h" - -#include -#include -#include - -#include -#include - -#include "common/params.h" -#include "system/hardware/hw.h" -#include "selfdrive/ui/qt/api.h" - -QString get_mapbox_token() { - // Valid for 4 weeks since we can't swap tokens on the fly - return MAPBOX_TOKEN.isEmpty() ? CommaApi::create_jwt({}, 4 * 7 * 24 * 3600) : MAPBOX_TOKEN; -} - -QMapLibre::Settings get_mapbox_settings() { - QMapLibre::Settings settings; - settings.setProviderTemplate(QMapLibre::Settings::ProviderTemplate::MapboxProvider); - - if (!Hardware::PC()) { - settings.setCacheDatabasePath(MAPS_CACHE_PATH); - settings.setCacheDatabaseMaximumSize(100 * 1024 * 1024); - } - settings.setApiBaseUrl(MAPS_HOST); - settings.setApiKey(get_mapbox_token()); - - return settings; -} - -QGeoCoordinate to_QGeoCoordinate(const QMapLibre::Coordinate &in) { - return QGeoCoordinate(in.first, in.second); -} - -QMapLibre::CoordinatesCollections model_to_collection( - const cereal::LiveLocationKalman::Measurement::Reader &calibratedOrientationECEF, - const cereal::LiveLocationKalman::Measurement::Reader &positionECEF, - const cereal::XYZTData::Reader &line){ - - 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); - - QMapLibre::Coordinates coordinates; - auto x = line.getX(); - auto y = line.getY(); - auto z = line.getZ(); - for (int i = 0; i < x.size(); i++) { - Eigen::Vector3d point_ecef = ecef_from_local * Eigen::Vector3d(x[i], y[i], z[i]) + ecef; - Geodetic point_geodetic = ecef2geodetic((ECEF){.x = point_ecef[0], .y = point_ecef[1], .z = point_ecef[2]}); - coordinates.push_back({point_geodetic.lat, point_geodetic.lon}); - } - - return {QMapLibre::CoordinatesCollection{coordinates}}; -} - -QMapLibre::CoordinatesCollections coordinate_to_collection(const QMapLibre::Coordinate &c) { - QMapLibre::Coordinates coordinates{c}; - return {QMapLibre::CoordinatesCollection{coordinates}}; -} - -QMapLibre::CoordinatesCollections capnp_coordinate_list_to_collection(const capnp::List::Reader& coordinate_list) { - QMapLibre::Coordinates coordinates; - for (auto const &c : coordinate_list) { - coordinates.push_back({c.getLatitude(), c.getLongitude()}); - } - return {QMapLibre::CoordinatesCollection{coordinates}}; -} - -QMapLibre::CoordinatesCollections coordinate_list_to_collection(const QList &coordinate_list) { - QMapLibre::Coordinates coordinates; - for (auto &c : coordinate_list) { - coordinates.push_back({c.latitude(), c.longitude()}); - } - return {QMapLibre::CoordinatesCollection{coordinates}}; -} - -QList polyline_to_coordinate_list(const QString &polylineString) { - QList path; - if (polylineString.isEmpty()) - return path; - - QByteArray data = polylineString.toLatin1(); - - bool parsingLatitude = true; - - int shift = 0; - int value = 0; - - QGeoCoordinate coord(0, 0); - - for (int i = 0; i < data.length(); ++i) { - unsigned char c = data.at(i) - 63; - - value |= (c & 0x1f) << shift; - shift += 5; - - // another chunk - if (c & 0x20) - continue; - - int diff = (value & 1) ? ~(value >> 1) : (value >> 1); - - if (parsingLatitude) { - coord.setLatitude(coord.latitude() + (double)diff/1e6); - } else { - coord.setLongitude(coord.longitude() + (double)diff/1e6); - path.append(coord); - } - - parsingLatitude = !parsingLatitude; - - value = 0; - shift = 0; - } - - return path; -} - -std::optional coordinate_from_param(const std::string ¶m) { - QString json_str = QString::fromStdString(Params().get(param)); - if (json_str.isEmpty()) return {}; - - QJsonDocument doc = QJsonDocument::fromJson(json_str.toUtf8()); - if (doc.isNull()) return {}; - - QJsonObject json = doc.object(); - if (json["latitude"].isDouble() && json["longitude"].isDouble()) { - QMapLibre::Coordinate coord(json["latitude"].toDouble(), json["longitude"].toDouble()); - return coord; - } else { - return {}; - } -} - -// return {distance, unit} -std::pair map_format_distance(float d, bool is_metric) { - auto round_distance = [](float d) -> QString { - return (d > 10) ? QString::number(std::nearbyint(d)) : QString::number(std::nearbyint(d * 10) / 10.0, 'f', 1); - }; - - d = std::max(d, 0.0f); - if (is_metric) { - return (d > 500) ? std::pair(round_distance(d / 1000), QObject::tr("km")) - : std::pair(QString::number(50 * std::nearbyint(d / 50)), QObject::tr("m")); - } else { - float feet = d * METER_TO_FOOT; - return (feet > 500) ? std::pair(round_distance(d * METER_TO_MILE), QObject::tr("mi")) - : std::pair(QString::number(50 * std::nearbyint(d / 50)), QObject::tr("ft")); - } -} diff --git a/selfdrive/ui/qt/maps/map_helpers.h b/selfdrive/ui/qt/maps/map_helpers.h deleted file mode 100644 index 0f4be674f05633..00000000000000 --- a/selfdrive/ui/qt/maps/map_helpers.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include "common/util.h" -#include "common/transformations/coordinates.hpp" -#include "common/transformations/orientation.hpp" -#include "cereal/messaging/messaging.h" - -const QString MAPBOX_TOKEN = util::getenv("MAPBOX_TOKEN").c_str(); -const QString MAPS_HOST = util::getenv("MAPS_HOST", MAPBOX_TOKEN.isEmpty() ? "https://maps.comma.ai" : "https://api.mapbox.com").c_str(); -const QString MAPS_CACHE_PATH = "/data/mbgl-cache-navd.db"; - -QString get_mapbox_token(); -QMapLibre::Settings get_mapbox_settings(); -QGeoCoordinate to_QGeoCoordinate(const QMapLibre::Coordinate &in); -QMapLibre::CoordinatesCollections model_to_collection( - const cereal::LiveLocationKalman::Measurement::Reader &calibratedOrientationECEF, - const cereal::LiveLocationKalman::Measurement::Reader &positionECEF, - const cereal::XYZTData::Reader &line); -QMapLibre::CoordinatesCollections coordinate_to_collection(const QMapLibre::Coordinate &c); -QMapLibre::CoordinatesCollections capnp_coordinate_list_to_collection(const capnp::List::Reader &coordinate_list); -QMapLibre::CoordinatesCollections coordinate_list_to_collection(const QList &coordinate_list); -QList polyline_to_coordinate_list(const QString &polylineString); -std::optional coordinate_from_param(const std::string ¶m); -std::pair map_format_distance(float d, bool is_metric); diff --git a/selfdrive/ui/qt/maps/map_instructions.cc b/selfdrive/ui/qt/maps/map_instructions.cc deleted file mode 100644 index ba8cb356bd1651..00000000000000 --- a/selfdrive/ui/qt/maps/map_instructions.cc +++ /dev/null @@ -1,144 +0,0 @@ -#include "selfdrive/ui/qt/maps/map_instructions.h" - -#include -#include - -#include "selfdrive/ui/qt/maps/map_helpers.h" -#include "selfdrive/ui/ui.h" - -const QString ICON_SUFFIX = ".png"; - -MapInstructions::MapInstructions(QWidget *parent) : QWidget(parent) { - is_rhd = Params().getBool("IsRhdDetected"); - QVBoxLayout *main_layout = new QVBoxLayout(this); - main_layout->setContentsMargins(11, UI_BORDER_SIZE, 11, 20); - - QHBoxLayout *top_layout = new QHBoxLayout; - top_layout->addWidget(icon_01 = new QLabel, 0, Qt::AlignTop); - - QVBoxLayout *right_layout = new QVBoxLayout; - right_layout->setContentsMargins(9, 9, 9, 0); - right_layout->addWidget(distance = new QLabel); - distance->setStyleSheet(R"(font-size: 90px;)"); - - right_layout->addWidget(primary = new QLabel); - primary->setStyleSheet(R"(font-size: 60px;)"); - primary->setWordWrap(true); - - right_layout->addWidget(secondary = new QLabel); - secondary->setStyleSheet(R"(font-size: 50px;)"); - secondary->setWordWrap(true); - - top_layout->addLayout(right_layout); - - main_layout->addLayout(top_layout); - main_layout->addLayout(lane_layout = new QHBoxLayout); - lane_layout->setAlignment(Qt::AlignHCenter); - lane_layout->setSpacing(10); - - setStyleSheet("color:white"); - QPalette pal = palette(); - pal.setColor(QPalette::Background, QColor(0, 0, 0, 150)); - setAutoFillBackground(true); - setPalette(pal); - - buildPixmapCache(); -} - -void MapInstructions::buildPixmapCache() { - QDir dir("../assets/navigation"); - for (QString fn : dir.entryList({"*" + ICON_SUFFIX}, QDir::Files)) { - QPixmap pm(dir.filePath(fn)); - QString key = fn.left(fn.size() - ICON_SUFFIX.length()); - pm = pm.scaledToWidth(200, Qt::SmoothTransformation); - - // Maneuver icons - pixmap_cache[key] = pm; - // lane direction icons - if (key.contains("turn_")) { - pixmap_cache["lane_" + key] = pm.scaled({125, 125}, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - } - - // for rhd, reflect direction and then flip - if (key.contains("_left")) { - pixmap_cache["rhd_" + key.replace("_left", "_right")] = pm.transformed(QTransform().scale(-1, 1)); - } else if (key.contains("_right")) { - pixmap_cache["rhd_" + key.replace("_right", "_left")] = pm.transformed(QTransform().scale(-1, 1)); - } - } -} - -void MapInstructions::updateInstructions(cereal::NavInstruction::Reader instruction) { - setUpdatesEnabled(false); - - // Show instruction text - QString primary_str = QString::fromStdString(instruction.getManeuverPrimaryText()); - QString secondary_str = QString::fromStdString(instruction.getManeuverSecondaryText()); - - primary->setText(primary_str); - secondary->setVisible(secondary_str.length() > 0); - secondary->setText(secondary_str); - - auto distance_str_pair = map_format_distance(instruction.getManeuverDistance(), uiState()->scene.is_metric); - distance->setText(QString("%1 %2").arg(distance_str_pair.first, distance_str_pair.second)); - - // Show arrow with direction - QString type = QString::fromStdString(instruction.getManeuverType()); - QString modifier = QString::fromStdString(instruction.getManeuverModifier()); - if (!type.isEmpty()) { - QString fn = "direction_" + type; - if (!modifier.isEmpty()) { - fn += "_" + modifier; - } - fn = fn.replace(' ', '_'); - bool rhd = is_rhd && (fn.contains("_left") || fn.contains("_right")); - icon_01->setPixmap(pixmap_cache[!rhd ? fn : "rhd_" + fn]); - icon_01->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); - icon_01->setVisible(true); - } else { - icon_01->setVisible(false); - } - - // Hide distance after arrival - distance->setVisible(type != "arrive" || instruction.getManeuverDistance() > 0); - - // Show lanes - auto lanes = instruction.getLanes(); - for (int i = 0; i < lanes.size(); ++i) { - bool active = lanes[i].getActive(); - const auto active_direction = lanes[i].getActiveDirection(); - - // TODO: Make more images based on active direction and combined directions - QString fn = "lane_direction_"; - - // active direction has precedence - if (active && active_direction != cereal::NavInstruction::Direction::NONE) { - fn += "turn_" + DIRECTIONS[active_direction]; - } else { - for (auto const &direction : lanes[i].getDirections()) { - if (direction != cereal::NavInstruction::Direction::NONE) { - fn += "turn_" + DIRECTIONS[direction]; - break; - } - } - } - - if (!active) { - fn += "_inactive"; - } - - QLabel *label = (i < lane_labels.size()) ? lane_labels[i] : lane_labels.emplace_back(new QLabel); - if (!label->parentWidget()) { - lane_layout->addWidget(label); - } - label->setPixmap(pixmap_cache[fn]); - label->setVisible(true); - } - - for (int i = lanes.size(); i < lane_labels.size(); ++i) { - lane_labels[i]->setVisible(false); - } - - setUpdatesEnabled(true); - setVisible(true); -} diff --git a/selfdrive/ui/qt/maps/map_instructions.h b/selfdrive/ui/qt/maps/map_instructions.h deleted file mode 100644 index 06a943d27fb0a8..00000000000000 --- a/selfdrive/ui/qt/maps/map_instructions.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include - -#include -#include -#include - -#include "cereal/gen/cpp/log.capnp.h" - -static std::map DIRECTIONS = { - {cereal::NavInstruction::Direction::NONE, "none"}, - {cereal::NavInstruction::Direction::LEFT, "left"}, - {cereal::NavInstruction::Direction::RIGHT, "right"}, - {cereal::NavInstruction::Direction::STRAIGHT, "straight"}, - {cereal::NavInstruction::Direction::SLIGHT_LEFT, "slight_left"}, - {cereal::NavInstruction::Direction::SLIGHT_RIGHT, "slight_right"}, -}; - -class MapInstructions : public QWidget { - Q_OBJECT - -private: - QLabel *distance; - QLabel *primary; - QLabel *secondary; - QLabel *icon_01; - QHBoxLayout *lane_layout; - bool is_rhd = false; - std::vector lane_labels; - QHash pixmap_cache; - -public: - MapInstructions(QWidget * parent=nullptr); - void buildPixmapCache(); - void updateInstructions(cereal::NavInstruction::Reader instruction); -}; diff --git a/selfdrive/ui/qt/maps/map_panel.cc b/selfdrive/ui/qt/maps/map_panel.cc deleted file mode 100644 index c4cc20e21d3a75..00000000000000 --- a/selfdrive/ui/qt/maps/map_panel.cc +++ /dev/null @@ -1,43 +0,0 @@ -#include "selfdrive/ui/qt/maps/map_panel.h" - -#include -#include - -#include "selfdrive/ui/qt/maps/map.h" -#include "selfdrive/ui/qt/maps/map_settings.h" -#include "selfdrive/ui/qt/util.h" -#include "selfdrive/ui/ui.h" - -MapPanel::MapPanel(const QMapLibre::Settings &mapboxSettings, QWidget *parent) : QFrame(parent) { - content_stack = new QStackedLayout(this); - content_stack->setContentsMargins(0, 0, 0, 0); - - auto map = new MapWindow(mapboxSettings); - QObject::connect(uiState(), &UIState::offroadTransition, map, &MapWindow::offroadTransition); - QObject::connect(device(), &Device::interactiveTimeout, this, [=]() { - content_stack->setCurrentIndex(0); - }); - QObject::connect(map, &MapWindow::requestVisible, this, [=](bool visible) { - // when we show the map for a new route, signal HomeWindow to hide the sidebar - if (visible) { emit mapPanelRequested(); } - setVisible(visible); - }); - QObject::connect(map, &MapWindow::requestSettings, this, [=](bool settings) { - content_stack->setCurrentIndex(settings ? 1 : 0); - }); - content_stack->addWidget(map); - - auto settings = new MapSettings(true, parent); - QObject::connect(settings, &MapSettings::closeSettings, this, [=]() { - content_stack->setCurrentIndex(0); - }); - content_stack->addWidget(settings); -} - -void MapPanel::toggleMapSettings() { - // show settings if not visible, then toggle between map and settings - int new_index = isVisible() ? (1 - content_stack->currentIndex()) : 1; - content_stack->setCurrentIndex(new_index); - emit mapPanelRequested(); - show(); -} diff --git a/selfdrive/ui/qt/maps/map_panel.h b/selfdrive/ui/qt/maps/map_panel.h deleted file mode 100644 index 190bb634464db5..00000000000000 --- a/selfdrive/ui/qt/maps/map_panel.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -#include -#include - -class MapPanel : public QFrame { - Q_OBJECT - -public: - explicit MapPanel(const QMapLibre::Settings &settings, QWidget *parent = nullptr); - -signals: - void mapPanelRequested(); - -public slots: - void toggleMapSettings(); - -private: - QStackedLayout *content_stack; -}; diff --git a/selfdrive/ui/qt/maps/map_settings.cc b/selfdrive/ui/qt/maps/map_settings.cc deleted file mode 100644 index 4d655be36cd81f..00000000000000 --- a/selfdrive/ui/qt/maps/map_settings.cc +++ /dev/null @@ -1,385 +0,0 @@ -#include "selfdrive/ui/qt/maps/map_settings.h" - -#include - -#include -#include - -#include "common/util.h" -#include "selfdrive/ui/qt/request_repeater.h" -#include "selfdrive/ui/qt/widgets/scrollview.h" - -static void swap(QJsonValueRef v1, QJsonValueRef v2) { std::swap(v1, v2); } - -static bool locationEqual(const QJsonValue &v1, const QJsonValue &v2) { - return v1["latitude"] == v2["latitude"] && v1["longitude"] == v2["longitude"]; -} - -static qint64 convertTimestampToEpoch(const QString ×tamp) { - QDateTime dt = QDateTime::fromString(timestamp, Qt::ISODate); - return dt.isValid() ? dt.toSecsSinceEpoch() : 0; -} - -MapSettings::MapSettings(bool closeable, QWidget *parent) : QFrame(parent) { - setContentsMargins(0, 0, 0, 0); - setAttribute(Qt::WA_NoMousePropagation); - - auto *frame = new QVBoxLayout(this); - frame->setContentsMargins(40, 40, 40, 0); - frame->setSpacing(0); - - auto *heading_frame = new QHBoxLayout; - heading_frame->setContentsMargins(0, 0, 0, 0); - heading_frame->setSpacing(32); - { - if (closeable) { - auto *close_btn = new QPushButton("←"); - close_btn->setStyleSheet(R"( - QPushButton { - color: #FFFFFF; - font-size: 100px; - padding-bottom: 8px; - border 1px grey solid; - border-radius: 70px; - background-color: #292929; - font-weight: 500; - } - QPushButton:pressed { - background-color: #3B3B3B; - } - )"); - close_btn->setFixedSize(140, 140); - QObject::connect(close_btn, &QPushButton::clicked, [=]() { emit closeSettings(); }); - // TODO: read map_on_left from ui state - heading_frame->addWidget(close_btn); - } - - auto *heading = new QVBoxLayout; - heading->setContentsMargins(0, 0, 0, 0); - heading->setSpacing(16); - { - auto *title = new QLabel(tr("NAVIGATION"), this); - title->setStyleSheet("color: #FFFFFF; font-size: 54px; font-weight: 600;"); - heading->addWidget(title); - - auto *subtitle = new QLabel(tr("Manage at connect.comma.ai"), this); - subtitle->setStyleSheet("color: #A0A0A0; font-size: 40px; font-weight: 300;"); - heading->addWidget(subtitle); - } - heading_frame->addLayout(heading, 1); - } - frame->addLayout(heading_frame); - frame->addSpacing(32); - - current_widget = new DestinationWidget(this); - QObject::connect(current_widget, &DestinationWidget::actionClicked, - []() { NavManager::instance()->setCurrentDestination({}); }); - frame->addWidget(current_widget); - frame->addSpacing(32); - - QWidget *destinations_container = new QWidget(this); - destinations_layout = new QVBoxLayout(destinations_container); - destinations_layout->setContentsMargins(0, 32, 0, 32); - destinations_layout->setSpacing(20); - destinations_layout->addWidget(home_widget = new DestinationWidget(this)); - destinations_layout->addWidget(work_widget = new DestinationWidget(this)); - QObject::connect(home_widget, &DestinationWidget::navigateTo, this, &MapSettings::navigateTo); - QObject::connect(work_widget, &DestinationWidget::navigateTo, this, &MapSettings::navigateTo); - destinations_layout->addStretch(); - - ScrollView *destinations_scroller = new ScrollView(destinations_container, this); - destinations_scroller->setFrameShape(QFrame::NoFrame); - frame->addWidget(destinations_scroller); - - setStyleSheet("MapSettings { background-color: #333333; }"); - QObject::connect(NavManager::instance(), &NavManager::updated, this, &MapSettings::refresh); -} - -void MapSettings::showEvent(QShowEvent *event) { - refresh(); -} - -void MapSettings::refresh() { - if (!isVisible()) return; - - setUpdatesEnabled(false); - - auto get_w = [this](int i) { - auto w = i < widgets.size() ? widgets[i] : widgets.emplace_back(new DestinationWidget); - if (!w->parentWidget()) { - destinations_layout->insertWidget(destinations_layout->count() - 1, w); - QObject::connect(w, &DestinationWidget::navigateTo, this, &MapSettings::navigateTo); - } - return w; - }; - - const auto current_dest = NavManager::instance()->currentDestination(); - if (!current_dest.isEmpty()) { - current_widget->set(current_dest, true); - } else { - current_widget->unset("", true); - } - home_widget->unset(NAV_FAVORITE_LABEL_HOME); - work_widget->unset(NAV_FAVORITE_LABEL_WORK); - - int n = 0; - for (auto location : NavManager::instance()->currentLocations()) { - DestinationWidget *w = nullptr; - auto dest = location.toObject(); - if (dest["save_type"].toString() == NAV_TYPE_FAVORITE) { - auto label = dest["label"].toString(); - if (label == NAV_FAVORITE_LABEL_HOME) w = home_widget; - if (label == NAV_FAVORITE_LABEL_WORK) w = work_widget; - } - w = w ? w : get_w(n++); - w->set(dest, false); - w->setVisible(!locationEqual(dest, current_dest)); - } - for (; n < widgets.size(); ++n) widgets[n]->setVisible(false); - - setUpdatesEnabled(true); -} - -void MapSettings::navigateTo(const QJsonObject &place) { - NavManager::instance()->setCurrentDestination(place); - emit closeSettings(); -} - -DestinationWidget::DestinationWidget(QWidget *parent) : QPushButton(parent) { - setContentsMargins(0, 0, 0, 0); - - auto *frame = new QHBoxLayout(this); - frame->setContentsMargins(32, 24, 32, 24); - frame->setSpacing(32); - - icon = new QLabel(this); - icon->setAlignment(Qt::AlignCenter); - icon->setFixedSize(96, 96); - icon->setObjectName("icon"); - frame->addWidget(icon); - - auto *inner_frame = new QVBoxLayout; - inner_frame->setContentsMargins(0, 0, 0, 0); - inner_frame->setSpacing(0); - { - title = new ElidedLabel(this); - title->setAttribute(Qt::WA_TransparentForMouseEvents); - inner_frame->addWidget(title); - - subtitle = new ElidedLabel(this); - subtitle->setAttribute(Qt::WA_TransparentForMouseEvents); - subtitle->setObjectName("subtitle"); - inner_frame->addWidget(subtitle); - } - frame->addLayout(inner_frame, 1); - - action = new QPushButton(this); - action->setFixedSize(96, 96); - action->setObjectName("action"); - action->setStyleSheet("font-size: 65px; font-weight: 600;"); - QObject::connect(action, &QPushButton::clicked, this, &QPushButton::clicked); - QObject::connect(action, &QPushButton::clicked, this, &DestinationWidget::actionClicked); - frame->addWidget(action); - - setFixedHeight(164); - setStyleSheet(R"( - DestinationWidget { background-color: #202123; border-radius: 10px; } - QLabel { color: #FFFFFF; font-size: 48px; font-weight: 400; } - #icon { background-color: #3B4356; border-radius: 48px; } - #subtitle { color: #9BA0A5; } - #action { border: none; border-radius: 48px; color: #FFFFFF; padding-bottom: 4px; } - - /* current destination */ - [current="true"] { background-color: #E8E8E8; } - [current="true"] QLabel { color: #000000; } - [current="true"] #icon { background-color: #42906B; } - [current="true"] #subtitle { color: #333333; } - [current="true"] #action { color: #202123; } - - /* no saved destination */ - [set="false"] QLabel { color: #9BA0A5; } - [current="true"][set="false"] QLabel { color: #A0000000; } - - /* pressed */ - [current="false"]:pressed { background-color: #18191B; } - [current="true"] #action:pressed { background-color: #D6D6D6; } - )"); - QObject::connect(this, &QPushButton::clicked, [this]() { if (!dest.isEmpty()) emit navigateTo(dest); }); -} - -void DestinationWidget::set(const QJsonObject &destination, bool current) { - if (dest == destination) return; - - dest = destination; - setProperty("current", current); - setProperty("set", true); - - auto icon_pixmap = current ? icons().directions : icons().recent; - auto title_text = destination["place_name"].toString(); - auto subtitle_text = destination["place_details"].toString(); - - if (destination["save_type"] == NAV_TYPE_FAVORITE) { - if (destination["label"] == NAV_FAVORITE_LABEL_HOME) { - icon_pixmap = icons().home; - subtitle_text = title_text + ", " + subtitle_text; - title_text = tr("Home"); - } else if (destination["label"] == NAV_FAVORITE_LABEL_WORK) { - icon_pixmap = icons().work; - subtitle_text = title_text + ", " + subtitle_text; - title_text = tr("Work"); - } else { - icon_pixmap = icons().favorite; - } - } - - icon->setPixmap(icon_pixmap); - - title->setText(title_text); - subtitle->setText(subtitle_text); - subtitle->setVisible(true); - - // TODO: use pixmap - action->setAttribute(Qt::WA_TransparentForMouseEvents, !current); - action->setText(current ? "×" : "→"); - action->setVisible(true); - - setStyleSheet(styleSheet()); -} - -void DestinationWidget::unset(const QString &label, bool current) { - dest = {}; - setProperty("current", current); - setProperty("set", false); - - if (label.isEmpty()) { - icon->setPixmap(icons().directions); - title->setText(tr("No destination set")); - } else { - QString title_text = label == NAV_FAVORITE_LABEL_HOME ? tr("home") : tr("work"); - icon->setPixmap(label == NAV_FAVORITE_LABEL_HOME ? icons().home : icons().work); - title->setText(tr("No %1 location set").arg(title_text)); - } - - subtitle->setVisible(false); - action->setVisible(false); - - setStyleSheet(styleSheet()); - setVisible(true); -} - -// singleton NavManager - -NavManager *NavManager::instance() { - static NavManager *request = new NavManager(qApp); - return request; -} - -NavManager::NavManager(QObject *parent) : QObject(parent) { - locations = QJsonDocument::fromJson(params.get("NavPastDestinations").c_str()).array(); - current_dest = QJsonDocument::fromJson(params.get("NavDestination").c_str()).object(); - if (auto dongle_id = getDongleId()) { - { - // Fetch favorite and recent locations - QString url = CommaApi::BASE_URL + "/v1/navigation/" + *dongle_id + "/locations"; - RequestRepeater *repeater = new RequestRepeater(this, url, "ApiCache_NavDestinations", 30, true); - QObject::connect(repeater, &RequestRepeater::requestDone, this, &NavManager::parseLocationsResponse); - } - { - auto param_watcher = new ParamWatcher(this); - QObject::connect(param_watcher, &ParamWatcher::paramChanged, this, &NavManager::updated); - - // Destination set while offline - QString url = CommaApi::BASE_URL + "/v1/navigation/" + *dongle_id + "/next"; - HttpRequest *deleter = new HttpRequest(this); - RequestRepeater *repeater = new RequestRepeater(this, url, "", 10, true); - QObject::connect(repeater, &RequestRepeater::requestDone, [=](const QString &resp, bool success) { - if (success && resp != "null") { - if (params.get("NavDestination").empty()) { - qWarning() << "Setting NavDestination from /next" << resp; - params.put("NavDestination", resp.toStdString()); - } else { - qWarning() << "Got location from /next, but NavDestination already set"; - } - // Send DELETE to clear destination server side - deleter->sendRequest(url, HttpRequest::Method::DELETE); - } - - // athena can set destination at any time - param_watcher->addParam("NavDestination"); - current_dest = QJsonDocument::fromJson(params.get("NavDestination").c_str()).object(); - emit updated(); - }); - } - } -} - -void NavManager::parseLocationsResponse(const QString &response, bool success) { - if (!success || response == prev_response) return; - - prev_response = response; - QJsonDocument doc = QJsonDocument::fromJson(response.trimmed().toUtf8()); - if (doc.isNull()) { - qWarning() << "JSON Parse failed on navigation locations" << response; - return; - } - - // set last activity time. - auto remote_locations = doc.array(); - for (QJsonValueRef loc : remote_locations) { - auto obj = loc.toObject(); - auto serverTime = convertTimestampToEpoch(obj["modified"].toString()); - obj.insert("time", qMax(serverTime, getLastActivity(obj))); - loc = obj; - } - - locations = remote_locations; - sortLocations(); - emit updated(); -} - -void NavManager::sortLocations() { - // Sort: alphabetical FAVORITES, and then most recent. - // We don't need to care about the ordering of HOME and WORK. DestinationWidget always displays them at the top. - std::stable_sort(locations.begin(), locations.end(), [](const QJsonValue &a, const QJsonValue &b) { - if (a["save_type"] == NAV_TYPE_FAVORITE || b["save_type"] == NAV_TYPE_FAVORITE) { - return (std::tuple(a["save_type"].toString(), a["place_name"].toString()) < - std::tuple(b["save_type"].toString(), b["place_name"].toString())); - } else { - return a["time"].toVariant().toLongLong() > b["time"].toVariant().toLongLong(); - } - }); - - write_param_future = std::async(std::launch::async, [destinations = QJsonArray(locations)]() { - Params().put("NavPastDestinations", QJsonDocument(destinations).toJson().toStdString()); - }); -} - -qint64 NavManager::getLastActivity(const QJsonObject &loc) const { - qint64 last_activity = 0; - auto it = std::find_if(locations.begin(), locations.end(), - [&loc](const QJsonValue &l) { return locationEqual(loc, l); }); - if (it != locations.end()) { - auto tm = it->toObject().value("time"); - if (!tm.isUndefined() && !tm.isNull()) { - last_activity = tm.toVariant().toLongLong(); - } - } - return last_activity; -} - -void NavManager::setCurrentDestination(const QJsonObject &loc) { - current_dest = loc; - if (!current_dest.isEmpty()) { - current_dest["time"] = QDateTime::currentSecsSinceEpoch(); - auto it = std::find_if(locations.begin(), locations.end(), - [&loc](const QJsonValue &l) { return locationEqual(loc, l); }); - if (it != locations.end()) { - *it = current_dest; - sortLocations(); - } - params.put("NavDestination", QJsonDocument(current_dest).toJson().toStdString()); - } else { - params.remove("NavDestination"); - } - emit updated(); -} diff --git a/selfdrive/ui/qt/maps/map_settings.h b/selfdrive/ui/qt/maps/map_settings.h deleted file mode 100644 index 0e151df4ad4ccd..00000000000000 --- a/selfdrive/ui/qt/maps/map_settings.h +++ /dev/null @@ -1,102 +0,0 @@ -#pragma once - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "common/params.h" -#include "selfdrive/ui/qt/util.h" -#include "selfdrive/ui/qt/widgets/controls.h" - -const QString NAV_TYPE_FAVORITE = "favorite"; -const QString NAV_TYPE_RECENT = "recent"; - -const QString NAV_FAVORITE_LABEL_HOME = "home"; -const QString NAV_FAVORITE_LABEL_WORK = "work"; - -class DestinationWidget; - -class NavManager : public QObject { - Q_OBJECT - -public: - static NavManager *instance(); - QJsonArray currentLocations() const { return locations; } - QJsonObject currentDestination() const { return current_dest; } - void setCurrentDestination(const QJsonObject &loc); - qint64 getLastActivity(const QJsonObject &loc) const; - -signals: - void updated(); - -private: - NavManager(QObject *parent); - void parseLocationsResponse(const QString &response, bool success); - void sortLocations(); - - Params params; - QString prev_response; - QJsonArray locations; - QJsonObject current_dest; - std::future write_param_future; -}; - -class MapSettings : public QFrame { - Q_OBJECT -public: - explicit MapSettings(bool closeable = false, QWidget *parent = nullptr); - void navigateTo(const QJsonObject &place); - -private: - void showEvent(QShowEvent *event) override; - void refresh(); - - QVBoxLayout *destinations_layout; - DestinationWidget *current_widget; - DestinationWidget *home_widget; - DestinationWidget *work_widget; - std::vector widgets; - -signals: - void closeSettings(); -}; - -class DestinationWidget : public QPushButton { - Q_OBJECT -public: - explicit DestinationWidget(QWidget *parent = nullptr); - void set(const QJsonObject &location, bool current = false); - void unset(const QString &label, bool current = false); - -signals: - void actionClicked(); - void navigateTo(const QJsonObject &destination); - -private: - struct NavIcons { - QPixmap home, work, favorite, recent, directions; - }; - - static NavIcons icons() { - static NavIcons nav_icons { - loadPixmap("../assets/navigation/icon_home.svg", {48, 48}), - loadPixmap("../assets/navigation/icon_work.svg", {48, 48}), - loadPixmap("../assets/navigation/icon_favorite.svg", {48, 48}), - loadPixmap("../assets/navigation/icon_recent.svg", {48, 48}), - loadPixmap("../assets/navigation/icon_directions.svg", {48, 48}), - }; - return nav_icons; - } - -private: - QLabel *icon, *title, *subtitle; - QPushButton *action; - QJsonObject dest; -}; diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 96fe6585cc81e9..dc60d40e4825a9 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -69,20 +69,6 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { tr("Display speed in km/h instead of mph."), "../assets/offroad/icon_metric.png", }, -#ifdef ENABLE_MAPS - { - "NavSettingTime24h", - tr("Show ETA in 24h Format"), - tr("Use 24h format instead of am/pm"), - "../assets/offroad/icon_metric.png", - }, - { - "NavSettingLeftSide", - tr("Show Map on Left Side of UI"), - tr("Show map on left side when in split screen view."), - "../assets/offroad/icon_road.png", - }, -#endif }; diff --git a/selfdrive/ui/qt/onroad/annotated_camera.cc b/selfdrive/ui/qt/onroad/annotated_camera.cc index 241bb6ed343ded..07016ef94ab138 100644 --- a/selfdrive/ui/qt/onroad/annotated_camera.cc +++ b/selfdrive/ui/qt/onroad/annotated_camera.cc @@ -20,9 +20,6 @@ AnnotatedCameraWidget::AnnotatedCameraWidget(VisionStreamType type, QWidget* par experimental_btn = new ExperimentalButton(this); main_layout->addWidget(experimental_btn, 0, Qt::AlignTop | Qt::AlignRight); - map_settings_btn = new MapSettingsButton(this); - main_layout->addWidget(map_settings_btn, 0, Qt::AlignBottom | Qt::AlignRight); - dm_img = loadPixmap("../assets/img_driver_face.png", {img_size + 5, img_size + 5}); } @@ -70,12 +67,6 @@ void AnnotatedCameraWidget::updateState(const UIState &s) { rightHandDM = dm_state.getIsRHD(); // DM icon transition dm_fade_state = std::clamp(dm_fade_state+0.2*(0.5-dmActive), 0.0, 1.0); - - // hide map settings button for alerts and flip for right hand DM - if (map_settings_btn->isEnabled()) { - map_settings_btn->setVisible(!hideBottomIcons); - main_layout->setAlignment(map_settings_btn, (rightHandDM ? Qt::AlignLeft : Qt::AlignRight) | Qt::AlignBottom); - } } void AnnotatedCameraWidget::drawHud(QPainter &p) { diff --git a/selfdrive/ui/qt/onroad/annotated_camera.h b/selfdrive/ui/qt/onroad/annotated_camera.h index 0be4adfffa68dd..1470b85f78592d 100644 --- a/selfdrive/ui/qt/onroad/annotated_camera.h +++ b/selfdrive/ui/qt/onroad/annotated_camera.h @@ -13,8 +13,6 @@ class AnnotatedCameraWidget : public CameraWidget { explicit AnnotatedCameraWidget(VisionStreamType type, QWidget* parent = 0); void updateState(const UIState &s); - MapSettingsButton *map_settings_btn; - private: void drawText(QPainter &p, int x, int y, const QString &text, int alpha = 255); diff --git a/selfdrive/ui/qt/onroad/buttons.cc b/selfdrive/ui/qt/onroad/buttons.cc index 75ec3161740d7a..92bcea11b5c3f4 100644 --- a/selfdrive/ui/qt/onroad/buttons.cc +++ b/selfdrive/ui/qt/onroad/buttons.cc @@ -47,18 +47,3 @@ void ExperimentalButton::paintEvent(QPaintEvent *event) { QPixmap img = experimental_mode ? experimental_img : engage_img; drawIcon(p, QPoint(btn_size / 2, btn_size / 2), img, QColor(0, 0, 0, 166), (isDown() || !engageable) ? 0.6 : 1.0); } - -// MapSettingsButton -MapSettingsButton::MapSettingsButton(QWidget *parent) : QPushButton(parent) { - setFixedSize(btn_size, btn_size); - settings_img = loadPixmap("../assets/navigation/icon_directions_outlined.svg", {img_size, img_size}); - - // hidden by default, made visible if map is created (has prime or mapbox token) - setVisible(false); - setEnabled(false); -} - -void MapSettingsButton::paintEvent(QPaintEvent *event) { - QPainter p(this); - drawIcon(p, QPoint(btn_size / 2, btn_size / 2), settings_img, QColor(0, 0, 0, 166), isDown() ? 0.6 : 1.0); -} diff --git a/selfdrive/ui/qt/onroad/buttons.h b/selfdrive/ui/qt/onroad/buttons.h index b0757795fb56d8..9c91bc3c7b649f 100644 --- a/selfdrive/ui/qt/onroad/buttons.h +++ b/selfdrive/ui/qt/onroad/buttons.h @@ -25,17 +25,4 @@ class ExperimentalButton : public QPushButton { bool engageable; }; - -class MapSettingsButton : public QPushButton { - Q_OBJECT - -public: - explicit MapSettingsButton(QWidget *parent = 0); - -private: - void paintEvent(QPaintEvent *event) override; - - QPixmap settings_img; -}; - void drawIcon(QPainter &p, const QPoint ¢er, const QPixmap &img, const QBrush &bg, float opacity); diff --git a/selfdrive/ui/qt/onroad/onroad_home.cc b/selfdrive/ui/qt/onroad/onroad_home.cc index 66eb1812e63a94..f8c7d8035042a6 100644 --- a/selfdrive/ui/qt/onroad/onroad_home.cc +++ b/selfdrive/ui/qt/onroad/onroad_home.cc @@ -3,11 +3,6 @@ #include #include -#ifdef ENABLE_MAPS -#include "selfdrive/ui/qt/maps/map_helpers.h" -#include "selfdrive/ui/qt/maps/map_panel.h" -#endif - #include "selfdrive/ui/qt/util.h" OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent) { @@ -30,11 +25,6 @@ OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent) { split->insertWidget(0, arCam); } - if (getenv("MAP_RENDER_VIEW")) { - CameraWidget *map_render = new CameraWidget("navd", VISION_STREAM_MAP, false, this); - split->insertWidget(0, map_render); - } - stacked_layout->addWidget(split_wrapper); alerts = new OnroadAlerts(this); @@ -47,7 +37,6 @@ OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent) { setAttribute(Qt::WA_OpaquePaintEvent); QObject::connect(uiState(), &UIState::uiUpdate, this, &OnroadWindow::updateState); QObject::connect(uiState(), &UIState::offroadTransition, this, &OnroadWindow::offroadTransition); - QObject::connect(uiState(), &UIState::primeChanged, this, &OnroadWindow::primeChanged); } void OnroadWindow::updateState(const UIState &s) { @@ -73,56 +62,14 @@ void OnroadWindow::updateState(const UIState &s) { } void OnroadWindow::mousePressEvent(QMouseEvent* e) { -#ifdef ENABLE_MAPS - if (map != nullptr) { - bool sidebarVisible = geometry().x() > 0; - bool show_map = !sidebarVisible; - map->setVisible(show_map && !map->isVisible()); - } -#endif // propagation event to parent(HomeWindow) QWidget::mousePressEvent(e); } -void OnroadWindow::createMapWidget() { -#ifdef ENABLE_MAPS - auto m = new MapPanel(get_mapbox_settings()); - map = m; - QObject::connect(m, &MapPanel::mapPanelRequested, this, &OnroadWindow::mapPanelRequested); - QObject::connect(nvg->map_settings_btn, &MapSettingsButton::clicked, m, &MapPanel::toggleMapSettings); - nvg->map_settings_btn->setEnabled(true); - - m->setFixedWidth(topWidget(this)->width() / 2 - UI_BORDER_SIZE); - split->insertWidget(0, m); - // hidden by default, made visible when navRoute is published - m->setVisible(false); -#endif -} - void OnroadWindow::offroadTransition(bool offroad) { -#ifdef ENABLE_MAPS - if (!offroad) { - if (map == nullptr && (uiState()->hasPrime() || !MAPBOX_TOKEN.isEmpty())) { - createMapWidget(); - } - } -#endif alerts->clear(); } -void OnroadWindow::primeChanged(bool prime) { -#ifdef ENABLE_MAPS - if (map && (!prime && MAPBOX_TOKEN.isEmpty())) { - nvg->map_settings_btn->setEnabled(false); - nvg->map_settings_btn->setVisible(false); - map->deleteLater(); - map = nullptr; - } else if (!map && (prime || !MAPBOX_TOKEN.isEmpty())) { - createMapWidget(); - } -#endif -} - void OnroadWindow::paintEvent(QPaintEvent *event) { QPainter p(this); p.fillRect(rect(), QColor(bg.red(), bg.green(), bg.blue(), 255)); diff --git a/selfdrive/ui/qt/onroad/onroad_home.h b/selfdrive/ui/qt/onroad/onroad_home.h index 4976f56a67cace..e8fa19b04618f3 100644 --- a/selfdrive/ui/qt/onroad/onroad_home.h +++ b/selfdrive/ui/qt/onroad/onroad_home.h @@ -26,6 +26,5 @@ class OnroadWindow : public QWidget { private slots: void offroadTransition(bool offroad); - void primeChanged(bool prime); void updateState(const UIState &s); }; diff --git a/selfdrive/ui/qt/widgets/prime.cc b/selfdrive/ui/qt/widgets/prime.cc index 2621612f67f432..25712c26c71395 100644 --- a/selfdrive/ui/qt/widgets/prime.cc +++ b/selfdrive/ui/qt/widgets/prime.cc @@ -155,7 +155,7 @@ PrimeAdWidget::PrimeAdWidget(QWidget* parent) : QFrame(parent) { main_layout->addWidget(features, 0, Qt::AlignBottom); main_layout->addSpacing(30); - QVector bullets = {tr("Remote access"), tr("24/7 LTE connectivity"), tr("1 year of drive storage"), tr("Turn-by-turn navigation")}; + QVector bullets = {tr("Remote access"), tr("24/7 LTE connectivity"), tr("1 year of drive storage"), tr("Remote snapshots")}; for (auto &b : bullets) { const QString check = " "; QLabel *l = new QLabel(check + b); @@ -225,9 +225,6 @@ SetupWidget::SetupWidget(QWidget* parent) : QFrame(parent) { content_layout->setContentsMargins(0, 0, 0, 0); content_layout->setSpacing(30); - primeUser = new PrimeUserWidget; - content_layout->addWidget(primeUser); - WiFiPromptWidget *wifi_prompt = new WiFiPromptWidget; QObject::connect(wifi_prompt, &WiFiPromptWidget::openSettings, this, &SetupWidget::openSettings); content_layout->addWidget(wifi_prompt); @@ -235,7 +232,6 @@ SetupWidget::SetupWidget(QWidget* parent) : QFrame(parent) { mainLayout->addWidget(content); - primeUser->setVisible(uiState()->hasPrime()); mainLayout->setCurrentIndex(1); setStyleSheet(R"( @@ -277,8 +273,6 @@ void SetupWidget::replyFinished(const QString &response, bool success) { mainLayout->setCurrentIndex(0); } else { popup->reject(); - - primeUser->setVisible(uiState()->hasPrime()); mainLayout->setCurrentIndex(1); } } diff --git a/selfdrive/ui/qt/widgets/prime.h b/selfdrive/ui/qt/widgets/prime.h index 63341c4ceae8d9..eac71bcddb12b7 100644 --- a/selfdrive/ui/qt/widgets/prime.h +++ b/selfdrive/ui/qt/widgets/prime.h @@ -66,7 +66,6 @@ class SetupWidget : public QFrame { private: PairingPopup *popup; QStackedWidget *mainLayout; - PrimeUserWidget *primeUser; private slots: void replyFinished(const QString &response, bool success); diff --git a/selfdrive/ui/translations/main_ar.ts b/selfdrive/ui/translations/main_ar.ts index d8146723a4dc5c..9925a2c7a95dde 100644 --- a/selfdrive/ui/translations/main_ar.ts +++ b/selfdrive/ui/translations/main_ar.ts @@ -136,33 +136,6 @@ رفض، إلغاء التثبيت %1 - - DestinationWidget - - Home - المنزل - - - Work - العمل - - - No destination set - لم يتم ضبط الوجهة - - - home - المنزل - - - work - العمل - - - No %1 location set - لم يتم ضبط %1 موقع - - DevicePanel @@ -349,47 +322,6 @@ جارٍ التثبيت... - - MapETA - - eta - الوصول - - - min - د - - - hr - س - - - - MapSettings - - NAVIGATION - التنقل - - - Manage at connect.comma.ai - الإدارة في connect.comma.ai - - - - MapWindow - - Map Loading - تحميل الخريطة - - - Waiting for GPS - بانتظار GPS - - - Waiting for route - بانتظار الطريق - - MultiOptionDialog @@ -568,8 +500,8 @@ سنة واحدة من تخزين القرص - Turn-by-turn navigation - التنقل خطوة بخطوة + Remote snapshots + @@ -630,22 +562,6 @@ منذ %n يوم - - km - كم - - - m - م - - - mi - ميل - - - ft - قدم - now الآن @@ -1090,22 +1006,6 @@ This may take up to a minute. When enabled, pressing the accelerator pedal will disengage openpilot. عند تمكين هذه الميزة، فإن الضغط على دواسة الوقود سيؤدي إلى فك ارتباط openpilot. - - Show ETA in 24h Format - إظهار الوقت المقدر للوصول بصيغة 24 ساعة - - - Use 24h format instead of am/pm - استخدام صيغة 24 ساعة بدلاً من صباحاً/مساء - - - Show Map on Left Side of UI - عرض الخريطة على الجانب الأيسر من واجهة المستخدم - - - Show map on left side when in split screen view. - عرض الخريطة عل الجانب الأيسر عندما تكون وضعية العرض بطريقة الشاشة المنقسمة. - openpilot Longitudinal Control (Alpha) التحكم الطولي openpilot (ألفا) diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index 010aa4d30485cd..a4f9963d6764e2 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -136,33 +136,6 @@ Ablehnen, deinstallieren %1 - - DestinationWidget - - Home - - - - Work - - - - No destination set - - - - No %1 location set - - - - home - - - - work - - - DevicePanel @@ -345,47 +318,6 @@ Installiere... - - MapETA - - eta - Ankunft - - - min - min - - - hr - std - - - - MapSettings - - NAVIGATION - - - - Manage at connect.comma.ai - - - - - MapWindow - - Map Loading - Karte wird geladen - - - Waiting for GPS - Warten auf GPS - - - Waiting for route - - - MultiOptionDialog @@ -559,11 +491,11 @@ - Turn-by-turn navigation + 1 year of drive storage - 1 year of drive storage + Remote snapshots @@ -613,22 +545,6 @@ vor %n Tagen - - km - km - - - m - m - - - mi - mi - - - ft - fuß - now @@ -1070,24 +986,6 @@ This may take up to a minute. When enabled, pressing the accelerator pedal will disengage openpilot. Wenn aktiviert, deaktiviert sich Openpilot sobald das Gaspedal betätigt wird. - - Use 24h format instead of am/pm - Benutze das 24Stunden Format anstatt am/pm - - - Show Map on Left Side of UI - Too long for UI - Zeige die Karte auf der linken Seite - - - Show map on left side when in split screen view. - Zeige die Karte auf der linken Seite der Benutzeroberfläche bei geteilten Bildschirm. - - - Show ETA in 24h Format - Too long for UI - Zeige die Ankunftszeit im 24 Stunden Format - Experimental Mode Experimenteller Modus diff --git a/selfdrive/ui/translations/main_fr.ts b/selfdrive/ui/translations/main_fr.ts index dde6adadd3ca5a..7f7c07d1bb27f6 100644 --- a/selfdrive/ui/translations/main_fr.ts +++ b/selfdrive/ui/translations/main_fr.ts @@ -136,33 +136,6 @@ Refuser, désinstaller %1 - - DestinationWidget - - Home - Domicile - - - Work - Travail - - - No destination set - Aucune destination définie - - - home - domicile - - - work - travail - - - No %1 location set - Aucun lieu %1 défini - - DevicePanel @@ -345,47 +318,6 @@ Installation... - - MapETA - - eta - eta - - - min - min - - - hr - h - - - - MapSettings - - NAVIGATION - NAVIGATION - - - Manage at connect.comma.ai - Gérer sur connect.comma.ai - - - - MapWindow - - Map Loading - Chargement de la carte - - - Waiting for GPS - En attente du GPS - - - Waiting for route - En attente d'un trajet - - MultiOptionDialog @@ -564,8 +496,8 @@ 1 an de stockage de trajets - Turn-by-turn navigation - Navigation étape par étape + Remote snapshots + @@ -614,22 +546,6 @@ il y a %n jours - - km - km - - - m - m - - - mi - mi - - - ft - ft - now @@ -1090,22 +1006,6 @@ Cela peut prendre jusqu'à une minute. Display speed in km/h instead of mph. Afficher la vitesse en km/h au lieu de mph. - - Show ETA in 24h Format - Afficher l'heure d'arrivée en format 24h - - - Use 24h format instead of am/pm - Utiliser le format 24h plutôt que am/pm - - - Show Map on Left Side of UI - Afficher la carte à gauche de l'interface - - - Show map on left side when in split screen view. - Afficher la carte à gauche en mode écran scindé. - Aggressive Aggressif diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index e0fb60620bc64f..39b018cfba2491 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -136,33 +136,6 @@ 拒否して %1 をアンインストール - - DestinationWidget - - Home - - - - Work - - - - No destination set - - - - No %1 location set - - - - home - - - - work - - - DevicePanel @@ -344,47 +317,6 @@ インストールしています... - - MapETA - - eta - 到着予定時間 - - - min - - - - hr - 時間 - - - - MapSettings - - NAVIGATION - - - - Manage at connect.comma.ai - - - - - MapWindow - - Map Loading - マップを読み込んでいます - - - Waiting for GPS - GPS信号を探しています - - - Waiting for route - - - MultiOptionDialog @@ -558,11 +490,11 @@ - Turn-by-turn navigation + 1 year of drive storage - 1 year of drive storage + Remote snapshots @@ -609,22 +541,6 @@ %n 日前 - - km - キロメートル - - - m - メートル - - - mi - マイル - - - ft - フィート - now @@ -1068,22 +984,6 @@ This may take up to a minute. When enabled, pressing the accelerator pedal will disengage openpilot. この機能を有効化すると、openpilotを利用中にアクセルを踏むとopenpilotによる運転サポートを中断します。 - - Show ETA in 24h Format - 24時間表示 - - - Use 24h format instead of am/pm - AM/PM の代わりに24時間形式を使用します - - - Show Map on Left Side of UI - ディスプレイの左側にマップを表示 - - - Show map on left side when in split screen view. - 分割画面表示の場合、ディスプレイの左側にマップを表示します。 - Experimental Mode 実験モード diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 56fc5014eed4b2..36247a6197f90f 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -136,33 +136,6 @@ 거절, %1 제거 - - DestinationWidget - - Home - - - - Work - 회사 - - - No destination set - 목적지가 설정되지 않았습니다 - - - No %1 location set - %1 위치가 설정되지 않았습니다 - - - home - - - - work - 회사 - - DevicePanel @@ -344,47 +317,6 @@ 설치 중... - - MapETA - - eta - 도착 - - - min - - - - hr - 시간 - - - - MapSettings - - NAVIGATION - 내비게이션 - - - Manage at connect.comma.ai - connect.comma.ai에서 관리하세요 - - - - MapWindow - - Map Loading - 지도 로딩 중 - - - Waiting for GPS - GPS 수신 중 - - - Waiting for route - 경로를 기다리는 중 - - MultiOptionDialog @@ -558,14 +490,14 @@ 24/7 LTE connectivity 항상 LTE 연결 - - Turn-by-turn navigation - 내비게이션 경로안내 - 1 year of drive storage 1년간 드라이브 로그 저장 + + Remote snapshots + + PrimeUserWidget @@ -610,22 +542,6 @@ %n 일 전 - - km - km - - - m - m - - - mi - mi - - - ft - ft - now now @@ -1070,22 +986,6 @@ This may take up to a minute. When enabled, pressing the accelerator pedal will disengage openpilot. 활성화된 경우 가속 페달을 밟으면 openpilot이 해제됩니다. - - Show ETA in 24h Format - 24시간 형식으로 도착 예정 시간 표시 - - - Use 24h format instead of am/pm - 오전/오후 대신 24시간 형식 사용 - - - Show Map on Left Side of UI - UI 왼쪽에 지도 표시 - - - Show map on left side when in split screen view. - 분할 화면 보기에서 지도를 왼쪽에 표시합니다. - Experimental Mode 실험 모드 diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index feaa6e86a14abb..8a71612e3af988 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -136,33 +136,6 @@ Rejeitar, desintalar %1 - - DestinationWidget - - Home - Casa - - - Work - Trabalho - - - No destination set - Nenhum destino definido - - - No %1 location set - Endereço de %1 não definido - - - home - casa - - - work - trabalho - - DevicePanel @@ -345,47 +318,6 @@ Instalando... - - MapETA - - eta - eta - - - min - min - - - hr - hr - - - - MapSettings - - NAVIGATION - NAVEGAÇÃO - - - Manage at connect.comma.ai - Gerencie em connect.comma.ai - - - - MapWindow - - Map Loading - Carregando Mapa - - - Waiting for GPS - Aguardando GPS - - - Waiting for route - Aguardando rota - - MultiOptionDialog @@ -559,14 +491,14 @@ 24/7 LTE connectivity Conectividade LTE (só nos EUA) - - Turn-by-turn navigation - Navegação passo a passo - 1 year of drive storage 1 ano de dados em nuvem + + Remote snapshots + + PrimeUserWidget @@ -614,22 +546,6 @@ há %n dias - - km - km - - - m - m - - - mi - milha - - - ft - pés - now agora @@ -1074,22 +990,6 @@ Isso pode levar até um minuto. When enabled, pressing the accelerator pedal will disengage openpilot. Quando ativado, pressionar o pedal do acelerador desacionará o openpilot. - - Show ETA in 24h Format - Mostrar ETA em Formato 24h - - - Use 24h format instead of am/pm - Use o formato 24h em vez de am/pm - - - Show Map on Left Side of UI - Exibir Mapa no Lado Esquerdo - - - Show map on left side when in split screen view. - Exibir mapa do lado esquerdo quando a tela for dividida. - Experimental Mode Modo Experimental diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts index e594a6975f4c1a..d4a33398bed4b0 100644 --- a/selfdrive/ui/translations/main_th.ts +++ b/selfdrive/ui/translations/main_th.ts @@ -136,33 +136,6 @@ ปฏิเสธ และถอนการติดตั้ง %1 - - DestinationWidget - - Home - บ้าน - - - Work - ที่ทำงาน - - - No destination set - ยังไม่ได้เลือกจุดหมาย - - - home - บ้าน - - - work - ที่ทำงาน - - - No %1 location set - ยังไม่ได้เลือกตำแหน่ง%1 - - DevicePanel @@ -344,47 +317,6 @@ กำลังติดตั้ง... - - MapETA - - eta - eta - - - min - นาที - - - hr - ชม. - - - - MapSettings - - NAVIGATION - การนำทาง - - - Manage at connect.comma.ai - จัดการได้ที่ connect.comma.ai - - - - MapWindow - - Map Loading - กำลังโหลดแผนที่ - - - Waiting for GPS - กำลังรอสัญญาณ GPS - - - Waiting for route - กำลังรอเส้นทาง - - MultiOptionDialog @@ -563,8 +495,8 @@ จัดเก็บข้อมูลการขับขี่นาน 1 ปี - Turn-by-turn navigation - การนำทางแบบเลี้ยวต่อเลี้ยว + Remote snapshots + @@ -610,22 +542,6 @@ %n วันที่แล้ว - - km - กม. - - - m - ม. - - - mi - ไมล์ - - - ft - ฟุต - now ตอนนี้ @@ -1070,22 +986,6 @@ This may take up to a minute. When enabled, pressing the accelerator pedal will disengage openpilot. เมื่อเปิดใช้งาน การกดแป้นคันเร่งจะเป็นการยกเลิกระบบช่วยขับโดย openpilot - - Show ETA in 24h Format - แสดงเวลา ETA ในรูปแบบ 24 ชั่วโมง - - - Use 24h format instead of am/pm - ใช้รูปแบบเวลา 24 ชั่วโมง แทน am/pm - - - Show Map on Left Side of UI - แสดงแผนที่ที่ด้านซ้ายของหน้าจอ - - - Show map on left side when in split screen view. - แสดงแผนที่ด้านซ้ายของหน้าจอเมื่ออยู่ในโหมดแบ่งหน้าจอ - Experimental Mode โหมดทดลอง diff --git a/selfdrive/ui/translations/main_tr.ts b/selfdrive/ui/translations/main_tr.ts index 48615f169933b3..36d11dbe61ebd6 100644 --- a/selfdrive/ui/translations/main_tr.ts +++ b/selfdrive/ui/translations/main_tr.ts @@ -136,33 +136,6 @@ Reddet, Kurulumu kaldır. %1 - - DestinationWidget - - Home - - - - Work - - - - No destination set - - - - home - - - - work - - - - No %1 location set - - - DevicePanel @@ -344,47 +317,6 @@ Yükleniyor... - - MapETA - - eta - tahmini varış süresi - - - min - dk - - - hr - saat - - - - MapSettings - - NAVIGATION - - - - Manage at connect.comma.ai - - - - - MapWindow - - Map Loading - Harita yükleniyor - - - Waiting for GPS - GPS verisi bekleniyor... - - - Waiting for route - - - MultiOptionDialog @@ -562,7 +494,7 @@ - Turn-by-turn navigation + Remote snapshots @@ -609,22 +541,6 @@ %n gün önce - - km - km - - - m - m - - - mi - mil - - - ft - ft - now @@ -1064,22 +980,6 @@ This may take up to a minute. When enabled, pressing the accelerator pedal will disengage openpilot. Aktifleştirilirse eğer gaz pedalına basınca openpilot devre dışı kalır. - - Show ETA in 24h Format - Tahmini varış süresini 24 saat formatı şeklinde göster - - - Use 24h format instead of am/pm - 24 saat formatını kullan - - - Show Map on Left Side of UI - Haritayı arayüzün sol tarafında göster - - - Show map on left side when in split screen view. - Bölünmüş ekran görünümündeyken haritayı sol tarafta göster. - openpilot Longitudinal Control (Alpha) diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 32119ee10f4d78..79a6e95501b791 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -136,33 +136,6 @@ 拒绝并卸载%1 - - DestinationWidget - - Home - 住家 - - - Work - 工作 - - - No destination set - 尚未设置目的地 - - - No %1 location set - 尚未设置 %1 的位置 - - - home - 住家 - - - work - 工作 - - DevicePanel @@ -344,47 +317,6 @@ 正在安装…… - - MapETA - - eta - 抵达 - - - min - 分钟 - - - hr - 小时 - - - - MapSettings - - NAVIGATION - 导航 - - - Manage at connect.comma.ai - 请在 connect.comma.ai 上管理 - - - - MapWindow - - Map Loading - 地图加载中 - - - Waiting for GPS - 等待 GPS - - - Waiting for route - 等待路线 - - MultiOptionDialog @@ -558,14 +490,14 @@ 24/7 LTE connectivity 全天候 LTE 連線 - - Turn-by-turn navigation - 领航功能 - 1 year of drive storage 一年的行驶记录储存空间 + + Remote snapshots + + PrimeUserWidget @@ -610,22 +542,6 @@ %n 天前 - - km - km - - - m - m - - - mi - mi - - - ft - ft - now 现在 @@ -1070,22 +986,6 @@ This may take up to a minute. When enabled, pressing the accelerator pedal will disengage openpilot. 启用后,踩下油门踏板将取消openpilot。 - - Show ETA in 24h Format - 以24小时格式显示预计到达时间 - - - Use 24h format instead of am/pm - 使用24小时制代替am/pm - - - Show Map on Left Side of UI - 在介面左侧显示地图 - - - Show map on left side when in split screen view. - 在分屏模式中,将地图置于屏幕左侧。 - Experimental Mode 测试模式 diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 9d1c16db9f08ad..ec6131892eef58 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -136,33 +136,6 @@ 拒絕並解除安裝 %1 - - DestinationWidget - - Home - 住家 - - - Work - 工作 - - - No destination set - 尚未設定目的地 - - - No %1 location set - 尚未設定 %1 的位置 - - - home - 住家 - - - work - 工作 - - DevicePanel @@ -344,47 +317,6 @@ 安裝中… - - MapETA - - eta - 抵達 - - - min - 分鐘 - - - hr - 小時 - - - - MapSettings - - NAVIGATION - 導航 - - - Manage at connect.comma.ai - 請在 connect.comma.ai 上管理 - - - - MapWindow - - Map Loading - 地圖載入中 - - - Waiting for GPS - 等待 GPS - - - Waiting for route - 等待路線 - - MultiOptionDialog @@ -558,14 +490,14 @@ 24/7 LTE connectivity 24/7 LTE 連線 - - Turn-by-turn navigation - 導航功能 - 1 year of drive storage 一年的行駛記錄儲存空間 + + Remote snapshots + + PrimeUserWidget @@ -610,22 +542,6 @@ %n 天前 - - km - km - - - m - m - - - mi - mi - - - ft - ft - now 現在 @@ -1070,22 +986,6 @@ This may take up to a minute. When enabled, pressing the accelerator pedal will disengage openpilot. 啟用後,踩踏油門將會取消 openpilot 控制。 - - Show ETA in 24h Format - 預計到達時間單位改用 24 小時制 - - - Use 24h format instead of am/pm - 使用 24 小時制。(預設值為 12 小時制) - - - Show Map on Left Side of UI - 將地圖顯示在畫面的左側 - - - Show map on left side when in split screen view. - 進入分割畫面後,地圖將會顯示在畫面的左側。 - Experimental Mode 實驗模式 diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index 06b8b13bc18871..2b415b119789e8 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -265,6 +265,10 @@ void UIState::update() { update_state(this); updateStatus(); + if (std::getenv("PRIME_TYPE")) { + setPrimeType((PrimeType)atoi(std::getenv("PRIME_TYPE"))); + } + if (sm->frame % UI_FREQ == 0) { watchdog_kick(nanos_since_boot()); } diff --git a/selfdrive/ui/watch3.cc b/selfdrive/ui/watch3.cc index ec35c29b6b4c55..c14e03aa6ea70f 100644 --- a/selfdrive/ui/watch3.cc +++ b/selfdrive/ui/watch3.cc @@ -19,7 +19,6 @@ int main(int argc, char *argv[]) { { QHBoxLayout *hlayout = new QHBoxLayout(); layout->addLayout(hlayout); - hlayout->addWidget(new CameraWidget("navd", VISION_STREAM_MAP, false)); hlayout->addWidget(new CameraWidget("camerad", VISION_STREAM_ROAD, false)); } diff --git a/system/athena/athenad.py b/system/athena/athenad.py index 9eec7a931b72c9..9769f065f6b468 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -328,19 +328,6 @@ def getVersion() -> dict[str, str]: } -@dispatcher.add_method -def setNavDestination(latitude: int = 0, longitude: int = 0, place_name: str = None, place_details: str = None) -> dict[str, int]: - destination = { - "latitude": latitude, - "longitude": longitude, - "place_name": place_name, - "place_details": place_details, - } - Params().put("NavDestination", json.dumps(destination)) - - return {"success": 1} - - def scan_dir(path: str, prefix: str) -> list[str]: files = [] # only walk directories that match the prefix diff --git a/system/manager/process_config.py b/system/manager/process_config.py index ced31077c9e14c..791d26a8f4a4fb 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -69,7 +69,6 @@ def only_offroad(started, params, CP: car.CarParams) -> bool: PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", driverview, enabled=(not PC or WEBCAM)), PythonProcess("qcomgpsd", "system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI), #PythonProcess("ugpsd", "system.ugpsd", only_onroad, enabled=TICI), - PythonProcess("navd", "selfdrive.navd.navd", only_onroad), PythonProcess("pandad", "selfdrive.pandad.pandad", always_run), PythonProcess("paramsd", "selfdrive.locationd.paramsd", only_onroad), NativeProcess("ubloxd", "system/ubloxd", ["./ubloxd"], ublox, enabled=TICI), diff --git a/third_party/maplibre-native-qt/.gitignore b/third_party/maplibre-native-qt/.gitignore deleted file mode 100644 index 9adc6681c02299..00000000000000 --- a/third_party/maplibre-native-qt/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/maplibre/ diff --git a/third_party/maplibre-native-qt/aarch64 b/third_party/maplibre-native-qt/aarch64 deleted file mode 120000 index 062c65e8d99c64..00000000000000 --- a/third_party/maplibre-native-qt/aarch64 +++ /dev/null @@ -1 +0,0 @@ -larch64/ \ No newline at end of file diff --git a/third_party/maplibre-native-qt/build.sh b/third_party/maplibre-native-qt/build.sh deleted file mode 100755 index a368026f0fe00e..00000000000000 --- a/third_party/maplibre-native-qt/build.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -set -e - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" - -ARCHNAME=$(uname -m) -MAPLIBRE_FLAGS="-DMLN_QT_WITH_LOCATION=OFF" -if [ -f /TICI ]; then - ARCHNAME="larch64" - #MAPLIBRE_FLAGS="$MAPLIBRE_FLAGS -DCMAKE_SYSTEM_NAME=Android -DANDROID_ABI=arm64-v8a" -fi - -cd $DIR -if [ ! -d maplibre ]; then - git clone --single-branch https://github.com/maplibre/maplibre-native-qt.git $DIR/maplibre -fi - -cd maplibre -git checkout 3726266e127c1f94ad64837c9dbe03d238255816 -git submodule update --depth=1 --recursive --init - -# build -mkdir -p build -cd build -cmake $MAPLIBRE_FLAGS $DIR/maplibre -make -j$(nproc) - -INSTALL_DIR="$DIR/$ARCHNAME" -rm -rf $INSTALL_DIR -mkdir -p $INSTALL_DIR - -rm -rf $DIR/include -mkdir -p $INSTALL_DIR/lib $INSTALL_DIR/include $DIR/include -cp -r $DIR/maplibre/build/src/core/*.so* $INSTALL_DIR/lib -cp -r $DIR/maplibre/build/src/core/include/* $INSTALL_DIR/include -cp -r $DIR/maplibre/src/**/*.hpp $DIR/include diff --git a/third_party/maplibre-native-qt/include/conversion_p.hpp b/third_party/maplibre-native-qt/include/conversion_p.hpp deleted file mode 100644 index 38b03d498e8939..00000000000000 --- a/third_party/maplibre-native-qt/include/conversion_p.hpp +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2018 Mapbox, Inc. - -// SPDX-License-Identifier: BSD-2-Clause - -#pragma once - -#include "geojson_p.hpp" -#include "types.hpp" - -#include -#include - -#include -#include - -#include - -namespace mbgl::style::conversion { - -std::string convertColor(const QColor &color); - -template <> -class ConversionTraits { -public: - static bool isUndefined(const QVariant &value) { return value.isNull() || !value.isValid(); } - - static bool isArray(const QVariant &value) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - return QMetaType::canConvert(value.metaType(), QMetaType(QMetaType::QVariantList)); -#else - return value.canConvert(QVariant::List); -#endif - } - - static std::size_t arrayLength(const QVariant &value) { return value.toList().size(); } - - static QVariant arrayMember(const QVariant &value, std::size_t i) { return value.toList()[static_cast(i)]; } - - static bool isObject(const QVariant &value) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - return QMetaType::canConvert(value.metaType(), QMetaType(QMetaType::QVariantMap)) || - value.typeId() == QMetaType::QByteArray -#else - return value.canConvert(QVariant::Map) || value.type() == QVariant::ByteArray -#endif - || QString(value.typeName()) == QStringLiteral("QMapLibre::Feature") || - value.userType() == qMetaTypeId>() || - value.userType() == qMetaTypeId>() || - value.userType() == qMetaTypeId>(); - } - - static std::optional objectMember(const QVariant &value, const char *key) { - auto map = value.toMap(); - auto iter = map.constFind(key); - - if (iter != map.constEnd()) { - return iter.value(); - } - - return {}; - } - - template - static std::optional eachMember(const QVariant &value, Fn &&fn) { - auto map = value.toMap(); - auto iter = map.constBegin(); - - while (iter != map.constEnd()) { - std::optional result = fn(iter.key().toStdString(), QVariant(iter.value())); - if (result) { - return result; - } - - ++iter; - } - - return {}; - } - - static std::optional toBool(const QVariant &value) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - if (value.typeId() == QMetaType::Bool) { -#else - if (value.type() == QVariant::Bool) { -#endif - return value.toBool(); - } - - return {}; - } - - static std::optional toNumber(const QVariant &value) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - if (value.typeId() == QMetaType::Int || value.typeId() == QMetaType::Double || - value.typeId() == QMetaType::Long || value.typeId() == QMetaType::LongLong || - value.typeId() == QMetaType::ULong || value.typeId() == QMetaType::ULongLong) { -#else - if (value.type() == QVariant::Int || value.type() == QVariant::Double || value.type() == QVariant::LongLong || - value.type() == QVariant::ULongLong) { -#endif - return value.toFloat(); - } - - return {}; - } - - static std::optional toDouble(const QVariant &value) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - if (value.typeId() == QMetaType::Int || value.typeId() == QMetaType::Double || - value.typeId() == QMetaType::Long || value.typeId() == QMetaType::LongLong || - value.typeId() == QMetaType::ULong || value.typeId() == QMetaType::ULongLong) { -#else - if (value.type() == QVariant::Int || value.type() == QVariant::Double || value.type() == QVariant::LongLong || - value.type() == QVariant::ULongLong) { -#endif - return value.toDouble(); - } - - return {}; - } - - static std::optional toString(const QVariant &value) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - if (value.typeId() == QMetaType::QString) { - return value.toString().toStdString(); - } - - if (value.typeId() == QMetaType::QColor) { - return convertColor(value.value()); - } -#else - if (value.type() == QVariant::String) { - return value.toString().toStdString(); - } - - if (value.type() == QVariant::Color) { - return convertColor(value.value()); - } -#endif - return {}; - } - - static std::optional toValue(const QVariant &value) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - if (value.typeId() == QMetaType::Bool) { - return {value.toBool()}; - } - - if (value.typeId() == QMetaType::QString) { - return {value.toString().toStdString()}; - } - - if (value.typeId() == QMetaType::QColor) { - return {convertColor(value.value())}; - } - - if (value.typeId() == QMetaType::Int) { - return {static_cast(value.toInt())}; - } - - if (QMetaType::canConvert(value.metaType(), QMetaType(QMetaType::Double))) { - return {value.toDouble()}; - } -#else - if (value.type() == QVariant::Bool) { - return {value.toBool()}; - } - - if (value.type() == QVariant::String) { - return {value.toString().toStdString()}; - } - - if (value.type() == QVariant::Color) { - return {convertColor(value.value())}; - } - - if (value.type() == QVariant::Int) { - return {static_cast(value.toInt())}; - } - - if (value.canConvert(QVariant::Double)) { - return {value.toDouble()}; - } -#endif - return {}; - } - - static std::optional toGeoJSON(const QVariant &value, Error &error) { - if (value.typeName() == QStringLiteral("QMapLibre::Feature")) { - return GeoJSON{QMapLibre::GeoJSON::asFeature(value.value())}; - } - - if (value.userType() == qMetaTypeId>()) { - return featureCollectionToGeoJSON(value.value>()); - } - - if (value.userType() == qMetaTypeId>()) { - return featureCollectionToGeoJSON(value.value>()); - } - - if (value.userType() == qMetaTypeId>()) { - return featureCollectionToGeoJSON(value.value>()); - } - -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - if (value.typeId() != QMetaType::QByteArray) { -#else - if (value.type() != QVariant::ByteArray) { -#endif - error = {"JSON data must be in QByteArray"}; - return {}; - } - - const QByteArray data = value.toByteArray(); - return parseGeoJSON(std::string(data.constData(), data.size()), error); - } - -private: - template - static GeoJSON featureCollectionToGeoJSON(const T &features) { - mapbox::feature::feature_collection collection; - collection.reserve(static_cast(features.size())); - for (const auto &feature : features) { - collection.push_back(QMapLibre::GeoJSON::asFeature(feature)); - } - return GeoJSON{std::move(collection)}; - } -}; - -template -std::optional convert(const QVariant &value, Error &error, Args &&...args) { - return convert(Convertible(value), error, std::forward(args)...); -} - -inline std::string convertColor(const QColor &color) { - return QString::asprintf("rgba(%d,%d,%d,%lf)", color.red(), color.green(), color.blue(), color.alphaF()) - .toStdString(); -} - -} // namespace mbgl::style::conversion diff --git a/third_party/maplibre-native-qt/include/export_core.hpp b/third_party/maplibre-native-qt/include/export_core.hpp deleted file mode 100644 index bd5ad495db6a85..00000000000000 --- a/third_party/maplibre-native-qt/include/export_core.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors - -// SPDX-License-Identifier: BSD-2-Clause - -#ifndef QMAPLIBRE_CORE_EXPORT_H -#define QMAPLIBRE_CORE_EXPORT_H - -#include - -#if !defined(QT_MAPLIBRE_STATIC) -#if defined(QT_BUILD_MAPLIBRE_CORE_LIB) -#define Q_MAPLIBRE_CORE_EXPORT Q_DECL_EXPORT -#else -#define Q_MAPLIBRE_CORE_EXPORT Q_DECL_IMPORT -#endif -#else -#define Q_MAPLIBRE_CORE_EXPORT -#endif - -#endif // QMAPLIBRE_CORE_EXPORT_H diff --git a/third_party/maplibre-native-qt/include/export_location.hpp b/third_party/maplibre-native-qt/include/export_location.hpp deleted file mode 100644 index a9863468841fa0..00000000000000 --- a/third_party/maplibre-native-qt/include/export_location.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors - -// SPDX-License-Identifier: BSD-2-Clause - -#ifndef QMAPLIBRE_LOCATION_EXPORT_H -#define QMAPLIBRE_LOCATION_EXPORT_H - -#include - -#if !defined(QT_MAPLIBRE_STATIC) -#if defined(QT_BUILD_MAPLIBRE_LOCATION_LIB) -#define Q_MAPLIBRE_LOCATION_EXPORT Q_DECL_EXPORT -#else -#define Q_MAPLIBRE_LOCATION_EXPORT Q_DECL_IMPORT -#endif -#else -#define Q_MAPLIBRE_LOCATION_EXPORT -#endif - -#endif // QMAPLIBRE_LOCATION_EXPORT_H diff --git a/third_party/maplibre-native-qt/include/export_widgets.hpp b/third_party/maplibre-native-qt/include/export_widgets.hpp deleted file mode 100644 index 11bc28819033d1..00000000000000 --- a/third_party/maplibre-native-qt/include/export_widgets.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors - -// SPDX-License-Identifier: BSD-2-Clause - -#ifndef QMAPLIBRE_WIDGETS_EXPORT_H -#define QMAPLIBRE_WIDGETS_EXPORT_H - -#include - -#if !defined(QT_MAPLIBRE_STATIC) -#if defined(QT_BUILD_MAPLIBRE_WIDGETS_LIB) -#define Q_MAPLIBRE_WIDGETS_EXPORT Q_DECL_EXPORT -#else -#define Q_MAPLIBRE_WIDGETS_EXPORT Q_DECL_IMPORT -#endif -#else -#define Q_MAPLIBRE_WIDGETS_EXPORT -#endif - -#endif // QMAPLIBRE_WIDGETS_EXPORT_H diff --git a/third_party/maplibre-native-qt/include/geojson_p.hpp b/third_party/maplibre-native-qt/include/geojson_p.hpp deleted file mode 100644 index 8387f70c4b193b..00000000000000 --- a/third_party/maplibre-native-qt/include/geojson_p.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2019 Mapbox, Inc. - -// SPDX-License-Identifier: BSD-2-Clause - -#pragma once - -#include "types.hpp" - -#include -#include -#include - -#include - -#include - -namespace QMapLibre::GeoJSON { - -mbgl::Point asPoint(const Coordinate &coordinate); -mbgl::MultiPoint asMultiPoint(const Coordinates &multiPoint); -mbgl::LineString asLineString(const Coordinates &lineString); -mbgl::MultiLineString asMultiLineString(const CoordinatesCollection &multiLineString); -mbgl::Polygon asPolygon(const CoordinatesCollection &polygon); -mbgl::MultiPolygon asMultiPolygon(const CoordinatesCollections &multiPolygon); -mbgl::Value asPropertyValue(const QVariant &value); -mbgl::FeatureIdentifier asFeatureIdentifier(const QVariant &id); -mbgl::GeoJSONFeature asFeature(const Feature &feature); - -} // namespace QMapLibre::GeoJSON diff --git a/third_party/maplibre-native-qt/include/gl_widget.hpp b/third_party/maplibre-native-qt/include/gl_widget.hpp deleted file mode 100644 index b2630daea75548..00000000000000 --- a/third_party/maplibre-native-qt/include/gl_widget.hpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors - -// SPDX-License-Identifier: BSD-2-Clause - -#ifndef QMAPLIBRE_GL_WIDGET_H -#define QMAPLIBRE_GL_WIDGET_H - -#include - -#include -#include - -#include - -#include - -QT_BEGIN_NAMESPACE - -class QKeyEvent; -class QMouseEvent; -class QWheelEvent; - -QT_END_NAMESPACE - -namespace QMapLibre { - -class GLWidgetPrivate; - -class Q_MAPLIBRE_WIDGETS_EXPORT GLWidget : public QOpenGLWidget { - Q_OBJECT - -public: - explicit GLWidget(const Settings &); - ~GLWidget() override; - - Map *map(); - -protected: - // QWidget implementation. - void mousePressEvent(QMouseEvent *event) override; - void mouseMoveEvent(QMouseEvent *event) override; - void wheelEvent(QWheelEvent *event) override; - - // Q{,Open}GLWidget implementation. - void initializeGL() override; - void paintGL() override; - -private: - Q_DISABLE_COPY(GLWidget) - - std::unique_ptr d_ptr; -}; - -} // namespace QMapLibre - -#endif // QMAPLIBRE_GL_WIDGET_H diff --git a/third_party/maplibre-native-qt/include/gl_widget_p.hpp b/third_party/maplibre-native-qt/include/gl_widget_p.hpp deleted file mode 100644 index c97781fd29d5cb..00000000000000 --- a/third_party/maplibre-native-qt/include/gl_widget_p.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors - -// SPDX-License-Identifier: BSD-2-Clause - -#pragma once - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -class QKeyEvent; -class QMouseEvent; -class QWheelEvent; - -QT_END_NAMESPACE - -namespace QMapLibre { - -class GLWidgetPrivate : public QObject { - Q_OBJECT - -public: - explicit GLWidgetPrivate(QObject *parent, Settings settings); - ~GLWidgetPrivate() override; - - void handleMousePressEvent(QMouseEvent *event); - void handleMouseMoveEvent(QMouseEvent *event); - void handleWheelEvent(QWheelEvent *event) const; - - std::unique_ptr m_map{}; - Settings m_settings; - -private: - Q_DISABLE_COPY(GLWidgetPrivate); - - QPointF m_lastPos; -}; - -} // namespace QMapLibre diff --git a/third_party/maplibre-native-qt/include/map.hpp b/third_party/maplibre-native-qt/include/map.hpp deleted file mode 100644 index cd56996185be72..00000000000000 --- a/third_party/maplibre-native-qt/include/map.hpp +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2019 Mapbox, Inc. - -// SPDX-License-Identifier: BSD-2-Clause - -#ifndef QMAPLIBRE_MAP_H -#define QMAPLIBRE_MAP_H - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace QMapLibre { - -class MapPrivate; - -class Q_MAPLIBRE_CORE_EXPORT Map : public QObject { - Q_OBJECT - Q_PROPERTY(double latitude READ latitude WRITE setLatitude) - Q_PROPERTY(double longitude READ longitude WRITE setLongitude) - Q_PROPERTY(double zoom READ zoom WRITE setZoom) - Q_PROPERTY(double bearing READ bearing WRITE setBearing) - Q_PROPERTY(double pitch READ pitch WRITE setPitch) - Q_PROPERTY(QString styleJson READ styleJson WRITE setStyleJson) - Q_PROPERTY(QString styleUrl READ styleUrl WRITE setStyleUrl) - Q_PROPERTY(double scale READ scale WRITE setScale) - Q_PROPERTY(QMapLibre::Coordinate coordinate READ coordinate WRITE setCoordinate) - Q_PROPERTY(QMargins margins READ margins WRITE setMargins) - -public: - enum MapChange { - MapChangeRegionWillChange = 0, - MapChangeRegionWillChangeAnimated, - MapChangeRegionIsChanging, - MapChangeRegionDidChange, - MapChangeRegionDidChangeAnimated, - MapChangeWillStartLoadingMap, - MapChangeDidFinishLoadingMap, - MapChangeDidFailLoadingMap, - MapChangeWillStartRenderingFrame, - MapChangeDidFinishRenderingFrame, - MapChangeDidFinishRenderingFrameFullyRendered, - MapChangeWillStartRenderingMap, - MapChangeDidFinishRenderingMap, - MapChangeDidFinishRenderingMapFullyRendered, - MapChangeDidFinishLoadingStyle, - MapChangeSourceDidChange - }; - - enum MapLoadingFailure { - StyleParseFailure, - StyleLoadFailure, - NotFoundFailure, - UnknownFailure - }; - - // Determines the orientation of the map. - enum NorthOrientation { - NorthUpwards, // Default - NorthRightwards, - NorthDownwards, - NorthLeftwards, - }; - - explicit Map(QObject *parent = nullptr, - const Settings &settings = Settings(), - const QSize &size = QSize(), - qreal pixelRatio = 1); - ~Map() override; - - [[nodiscard]] QString styleJson() const; - [[nodiscard]] QString styleUrl() const; - - void setStyleJson(const QString &); - void setStyleUrl(const QString &); - - [[nodiscard]] double latitude() const; - void setLatitude(double latitude); - - [[nodiscard]] double longitude() const; - void setLongitude(double longitude); - - [[nodiscard]] double scale() const; - void setScale(double scale, const QPointF ¢er = QPointF()); - - [[nodiscard]] double zoom() const; - void setZoom(double zoom); - - [[nodiscard]] double minimumZoom() const; - [[nodiscard]] double maximumZoom() const; - - [[nodiscard]] double bearing() const; - void setBearing(double degrees); - void setBearing(double degrees, const QPointF ¢er); - - [[nodiscard]] double pitch() const; - void setPitch(double pitch); - void pitchBy(double pitch); - - [[nodiscard]] NorthOrientation northOrientation() const; - void setNorthOrientation(NorthOrientation); - - [[nodiscard]] Coordinate coordinate() const; - void setCoordinate(const Coordinate &coordinate); - void setCoordinateZoom(const Coordinate &coordinate, double zoom); - - void jumpTo(const CameraOptions &); - - void setGestureInProgress(bool inProgress); - - void setTransitionOptions(qint64 duration, qint64 delay = 0); - - void addAnnotationIcon(const QString &name, const QImage &sprite); - - AnnotationID addAnnotation(const Annotation &annotation); - void updateAnnotation(AnnotationID id, const Annotation &annotation); - void removeAnnotation(AnnotationID id); - - bool setLayoutProperty(const QString &layerId, const QString &propertyName, const QVariant &value); - bool setPaintProperty(const QString &layerId, const QString &propertyName, const QVariant &value); - - [[nodiscard]] bool isFullyLoaded() const; - - void moveBy(const QPointF &offset); - void scaleBy(double scale, const QPointF ¢er = QPointF()); - void rotateBy(const QPointF &first, const QPointF &second); - - void resize(const QSize &size); - - [[nodiscard]] QPointF pixelForCoordinate(const Coordinate &coordinate) const; - [[nodiscard]] Coordinate coordinateForPixel(const QPointF &pixel) const; - - [[nodiscard]] CoordinateZoom coordinateZoomForBounds(const Coordinate &sw, const Coordinate &ne) const; - [[nodiscard]] CoordinateZoom coordinateZoomForBounds(const Coordinate &sw, - const Coordinate &ne, - double bearing, - double pitch); - - void setMargins(const QMargins &margins); - [[nodiscard]] QMargins margins() const; - - void addSource(const QString &id, const QVariantMap ¶ms); - bool sourceExists(const QString &id); - void updateSource(const QString &id, const QVariantMap ¶ms); - void removeSource(const QString &id); - - void addImage(const QString &id, const QImage &sprite); - void removeImage(const QString &id); - - void addCustomLayer(const QString &id, - std::unique_ptr host, - const QString &before = QString()); - void addLayer(const QString &id, const QVariantMap ¶ms, const QString &before = QString()); - bool layerExists(const QString &id); - void removeLayer(const QString &id); - - [[nodiscard]] QVector layerIds() const; - - void setFilter(const QString &layerId, const QVariant &filter); - [[nodiscard]] QVariant getFilter(const QString &layerId) const; - // When rendering on a different thread, - // should be called on the render thread. - void createRenderer(); - void destroyRenderer(); - void setFramebufferObject(quint32 fbo, const QSize &size); - -public slots: - void render(); - void setConnectionEstablished(); - - // Commit changes, load all the resources - // and renders the map when completed. - void startStaticRender(); - -signals: - void needsRendering(); - void mapChanged(Map::MapChange); - void mapLoadingFailed(Map::MapLoadingFailure, const QString &reason); - void copyrightsChanged(const QString ©rightsHtml); - - void staticRenderFinished(const QString &error); - -private: - Q_DISABLE_COPY(Map) - - std::unique_ptr d_ptr; -}; - -} // namespace QMapLibre - -Q_DECLARE_METATYPE(QMapLibre::Map::MapChange); -Q_DECLARE_METATYPE(QMapLibre::Map::MapLoadingFailure); - -#endif // QMAPLIBRE_MAP_H diff --git a/third_party/maplibre-native-qt/include/map_observer_p.hpp b/third_party/maplibre-native-qt/include/map_observer_p.hpp deleted file mode 100644 index e68c72b17b0571..00000000000000 --- a/third_party/maplibre-native-qt/include/map_observer_p.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2019 Mapbox, Inc. - -// SPDX-License-Identifier: BSD-2-Clause - -#pragma once - -#include "map.hpp" - -#include -#include - -#include - -#include -#include - -namespace QMapLibre { - -class MapPrivate; - -class MapObserver : public QObject, public mbgl::MapObserver { - Q_OBJECT - -public: - explicit MapObserver(MapPrivate *ptr); - ~MapObserver() override; - - // mbgl::MapObserver implementation. - void onCameraWillChange(mbgl::MapObserver::CameraChangeMode mode) final; - void onCameraIsChanging() final; - void onCameraDidChange(mbgl::MapObserver::CameraChangeMode mode) final; - void onWillStartLoadingMap() final; - void onDidFinishLoadingMap() final; - void onDidFailLoadingMap(mbgl::MapLoadError error, const std::string &what) final; - void onWillStartRenderingFrame() final; - void onDidFinishRenderingFrame(mbgl::MapObserver::RenderFrameStatus status) final; - void onWillStartRenderingMap() final; - void onDidFinishRenderingMap(mbgl::MapObserver::RenderMode mode) final; - void onDidFinishLoadingStyle() final; - void onSourceChanged(mbgl::style::Source &source) final; - -signals: - void mapChanged(Map::MapChange); - void mapLoadingFailed(Map::MapLoadingFailure, const QString &reason); - void copyrightsChanged(const QString ©rightsHtml); - -private: - Q_DISABLE_COPY(MapObserver) - - MapPrivate *d_ptrRef; -}; - -} // namespace QMapLibre diff --git a/third_party/maplibre-native-qt/include/map_p.hpp b/third_party/maplibre-native-qt/include/map_p.hpp deleted file mode 100644 index 9ca0c7e6f5a983..00000000000000 --- a/third_party/maplibre-native-qt/include/map_p.hpp +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2019 Mapbox, Inc. - -// SPDX-License-Identifier: BSD-2-Clause - -#pragma once - -#include "map.hpp" -#include "map_observer_p.hpp" -#include "map_renderer_p.hpp" - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -namespace QMapLibre { - -class MapPrivate : public QObject, public mbgl::RendererFrontend { - Q_OBJECT - -public: - explicit MapPrivate(Map *map, const Settings &settings, const QSize &size, qreal pixelRatio); - ~MapPrivate() override; - - // mbgl::RendererFrontend implementation. - void reset() final {} - void setObserver(mbgl::RendererObserver &observer) final; - void update(std::shared_ptr parameters) final; - - // These need to be called on the same thread. - void createRenderer(); - void destroyRenderer(); - void render(); - void setFramebufferObject(quint32 fbo, const QSize &size); - - using PropertySetter = std::optional (mbgl::style::Layer::*)( - const std::string &, const mbgl::style::conversion::Convertible &); - [[nodiscard]] bool setProperty(const PropertySetter &setter, - const QString &layerId, - const QString &name, - const QVariant &value) const; - - mbgl::EdgeInsets margins; - std::unique_ptr mapObj{}; - -public slots: - void requestRendering(); - -signals: - void needsRendering(); - -private: - Q_DISABLE_COPY(MapPrivate) - - std::recursive_mutex m_mapRendererMutex; - std::shared_ptr m_rendererObserver{}; - std::shared_ptr m_updateParameters{}; - - std::unique_ptr m_mapObserver{}; - std::unique_ptr m_mapRenderer{}; - std::unique_ptr> m_resourceTransform{}; - - Settings::GLContextMode m_mode; - qreal m_pixelRatio; - - QString m_localFontFamily; - - std::atomic_flag m_renderQueued = ATOMIC_FLAG_INIT; -}; - -} // namespace QMapLibre diff --git a/third_party/maplibre-native-qt/include/map_renderer_p.hpp b/third_party/maplibre-native-qt/include/map_renderer_p.hpp deleted file mode 100644 index b9a087c392ee80..00000000000000 --- a/third_party/maplibre-native-qt/include/map_renderer_p.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2019 Mapbox, Inc. - -// SPDX-License-Identifier: BSD-2-Clause - -#pragma once - -#include "settings.hpp" - -#include "utils/renderer_backend.hpp" - -#include -#include -#include - -#include - -#include - -#include -#include - -namespace mbgl { -class Renderer; -class UpdateParameters; -} // namespace mbgl - -namespace QMapLibre { - -class RendererBackend; - -class MapRenderer : public QObject { - Q_OBJECT - -public: - MapRenderer(qreal pixelRatio, Settings::GLContextMode, const QString &localFontFamily); - ~MapRenderer() override; - - void render(); - void updateFramebuffer(quint32 fbo, const mbgl::Size &size); - void setObserver(mbgl::RendererObserver *observer); - - // Thread-safe, called by the Frontend - void updateParameters(std::shared_ptr parameters); - -signals: - void needsRendering(); - -private: - MBGL_STORE_THREAD(tid) - - Q_DISABLE_COPY(MapRenderer) - - std::mutex m_updateMutex; - std::shared_ptr m_updateParameters; - - RendererBackend m_backend; - std::unique_ptr m_renderer{}; - - bool m_forceScheduler{}; -}; - -} // namespace QMapLibre diff --git a/third_party/maplibre-native-qt/include/qgeomap.hpp b/third_party/maplibre-native-qt/include/qgeomap.hpp deleted file mode 100644 index 5eb01805034bff..00000000000000 --- a/third_party/maplibre-native-qt/include/qgeomap.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2017 The Qt Company Ltd. -// Copyright (C) 2017 Mapbox, Inc. - -// SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -#pragma once - -#include "export_location.hpp" - -#include -#include - -#include - -namespace QMapLibre { - -class QGeoMapMapLibrePrivate; - -class Q_MAPLIBRE_LOCATION_EXPORT QGeoMapMapLibre : public QGeoMap { - Q_OBJECT - Q_DECLARE_PRIVATE(QGeoMapMapLibre) - -public: - explicit QGeoMapMapLibre(QGeoMappingManagerEngine *engine, QObject *parent = nullptr); - ~QGeoMapMapLibre() override; - - [[nodiscard]] Capabilities capabilities() const override; - - void setSettings(const Settings &settings); - void setMapItemsBefore(const QString &mapItemsBefore); - - void addStyleParameter(StyleParameter *parameter); - void removeStyleParameter(StyleParameter *parameter); - void clearStyleParameters(); - -private Q_SLOTS: - // QMapLibre - void onMapChanged(Map::MapChange); - - // QDeclarativeGeoMapItemBase - void onMapItemPropertyChanged(); - void onMapItemSubPropertyChanged(); - void onMapItemUnsupportedPropertyChanged(); - void onMapItemGeometryChanged(); - - // StyleParameter - void onStyleParameterUpdated(StyleParameter *parameter); - -private: - QSGNode *updateSceneGraph(QSGNode *oldNode, QQuickWindow *window) override; -}; - -} // namespace QMapLibre diff --git a/third_party/maplibre-native-qt/include/qgeomap_p.hpp b/third_party/maplibre-native-qt/include/qgeomap_p.hpp deleted file mode 100644 index ce415d9bcf0af7..00000000000000 --- a/third_party/maplibre-native-qt/include/qgeomap_p.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2017 The Qt Company Ltd. -// Copyright (C) 2017 Mapbox, Inc. - -// SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -#pragma once - -#include "qgeomap.hpp" - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -namespace QMapLibre { - -class Map; -class StyleChange; - -class QGeoMapMapLibrePrivate : public QGeoMapPrivate { - Q_DECLARE_PUBLIC(QGeoMapMapLibre) - -public: - explicit QGeoMapMapLibrePrivate(QGeoMappingManagerEngine *engine); - ~QGeoMapMapLibrePrivate() override; - - QSGNode *updateSceneGraph(QSGNode *oldNode, QQuickWindow *window); - - QGeoMap::ItemTypes supportedMapItemTypes() const override; - void addMapItem(QDeclarativeGeoMapItemBase *item) override; - void removeMapItem(QDeclarativeGeoMapItemBase *item) override; - - void addStyleParameter(StyleParameter *parameter); - void removeStyleParameter(StyleParameter *parameter); - void clearStyleParameters(); - - /* Data members */ - enum SyncState : int { - NoSync = 0, - ViewportSync = 1 << 0, - CameraDataSync = 1 << 1, - MapTypeSync = 1 << 2, - VisibleAreaSync = 1 << 3 - }; - Q_DECLARE_FLAGS(SyncStates, SyncState); - - Settings m_settings; - QString m_mapItemsBefore; - - QList m_mapParameters; - - QTimer m_refresh; - bool m_shouldRefresh = true; - bool m_warned = false; - bool m_threadedRendering = false; - bool m_styleLoaded = false; - - SyncStates m_syncState = NoSync; - - std::vector> m_styleChanges; - -protected: - void changeViewportSize(const QSize &size) override; - void changeCameraData(const QGeoCameraData &data) override; -#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) - void changeActiveMapType(const QGeoMapType &mapType) override; -#else - void changeActiveMapType(const QGeoMapType mapType) override; -#endif - - void setVisibleArea(const QRectF &visibleArea) override; - QRectF visibleArea() const override; - -private: - Q_DISABLE_COPY(QGeoMapMapLibrePrivate); - - void syncStyleChanges(Map *map); - void threadedRenderingHack(QQuickWindow *window, Map *map); - - QRectF m_visibleArea; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QGeoMapMapLibrePrivate::SyncStates) - -} // namespace QMapLibre diff --git a/third_party/maplibre-native-qt/include/qmaplibre.hpp b/third_party/maplibre-native-qt/include/qmaplibre.hpp deleted file mode 100644 index a8dc445e2b6c46..00000000000000 --- a/third_party/maplibre-native-qt/include/qmaplibre.hpp +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors - -// SPDX-License-Identifier: BSD-2-Clause - -#include "export_core.hpp" -#include "map.hpp" -#include "settings.hpp" -#include "types.hpp" -#include "utils.hpp" diff --git a/third_party/maplibre-native-qt/include/qmaplibrewidgets.hpp b/third_party/maplibre-native-qt/include/qmaplibrewidgets.hpp deleted file mode 100644 index ebe9a8eea4cd67..00000000000000 --- a/third_party/maplibre-native-qt/include/qmaplibrewidgets.hpp +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors - -// SPDX-License-Identifier: BSD-2-Clause - -#include "export_widgets.hpp" -#include "gl_widget.hpp" diff --git a/third_party/maplibre-native-qt/include/qt_mapping_engine.hpp b/third_party/maplibre-native-qt/include/qt_mapping_engine.hpp deleted file mode 100644 index 67cb4b56ced996..00000000000000 --- a/third_party/maplibre-native-qt/include/qt_mapping_engine.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2017 The Qt Company Ltd. -// Copyright (C) 2017 Mapbox, Inc. - -// SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -#pragma once - -#include "export_location.hpp" - -#include - -#include -#include - -namespace QMapLibre { - -class Q_MAPLIBRE_LOCATION_EXPORT QtMappingEngine : public QGeoMappingManagerEngine { - Q_OBJECT - -public: - QtMappingEngine(const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString); - - QGeoMap *createMap() override; - -private: - Settings m_settings; - QString m_mapItemsBefore; -}; - -} // namespace QMapLibre diff --git a/third_party/maplibre-native-qt/include/settings.hpp b/third_party/maplibre-native-qt/include/settings.hpp deleted file mode 100644 index d6f88b871b7a7d..00000000000000 --- a/third_party/maplibre-native-qt/include/settings.hpp +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2019 Mapbox, Inc. - -// SPDX-License-Identifier: BSD-2-Clause - -#ifndef QMAPLIBRE_SETTINGS_H -#define QMAPLIBRE_SETTINGS_H - -#include -#include - -#include -#include - -#include -#include - -// TODO: this will be wrapped at some point -namespace mbgl { -class TileServerOptions; -} // namespace mbgl - -namespace QMapLibre { - -class SettingsPrivate; - -class Q_MAPLIBRE_CORE_EXPORT Settings { -public: - enum GLContextMode : bool { - UniqueGLContext, - SharedGLContext - }; - - enum MapMode { - Continuous = 0, - Static - }; - - enum ConstrainMode { - NoConstrain = 0, - ConstrainHeightOnly, - ConstrainWidthAndHeight - }; - - enum ViewportMode { - DefaultViewport = 0, - FlippedYViewport - }; - - enum ProviderTemplate { - NoProvider = 0, - MapLibreProvider, - MapTilerProvider, - MapboxProvider - }; - - using ResourceTransformFunction = std::function; - - explicit Settings(ProviderTemplate provider = NoProvider); - ~Settings(); - Settings(const Settings &s); - Settings(Settings &&s) noexcept; - Settings &operator=(const Settings &s); - Settings &operator=(Settings &&s) noexcept; - - [[nodiscard]] GLContextMode contextMode() const; - void setContextMode(GLContextMode); - - [[nodiscard]] MapMode mapMode() const; - void setMapMode(MapMode); - - [[nodiscard]] ConstrainMode constrainMode() const; - void setConstrainMode(ConstrainMode); - - [[nodiscard]] ViewportMode viewportMode() const; - void setViewportMode(ViewportMode); - - [[nodiscard]] unsigned cacheDatabaseMaximumSize() const; - void setCacheDatabaseMaximumSize(unsigned); - - [[nodiscard]] QString cacheDatabasePath() const; - void setCacheDatabasePath(const QString &path); - - [[nodiscard]] QString assetPath() const; - void setAssetPath(const QString &path); - - [[nodiscard]] QString apiKey() const; - void setApiKey(const QString &key); - - [[nodiscard]] QString apiBaseUrl() const; - void setApiBaseUrl(const QString &url); - - [[nodiscard]] QString localFontFamily() const; - void setLocalFontFamily(const QString &family); - - [[nodiscard]] QString clientName() const; - void setClientName(const QString &name); - - [[nodiscard]] QString clientVersion() const; - void setClientVersion(const QString &version); - - [[nodiscard]] ResourceTransformFunction resourceTransform() const; - void setResourceTransform(const ResourceTransformFunction &transform); - - void setProviderTemplate(ProviderTemplate providerTemplate); - void setStyles(const Styles &styles); - - [[nodiscard]] const Styles &styles() const; - [[nodiscard]] Styles providerStyles() const; - - [[nodiscard]] Coordinate defaultCoordinate() const; - void setDefaultCoordinate(const Coordinate &coordinate); - [[nodiscard]] double defaultZoom() const; - void setDefaultZoom(double zoom); - - [[nodiscard]] bool customTileServerOptions() const; - [[nodiscard]] const mbgl::TileServerOptions &tileServerOptions() const; - -private: - std::unique_ptr d_ptr; -}; - -} // namespace QMapLibre - -#endif // QMAPLIBRE_SETTINGS_H diff --git a/third_party/maplibre-native-qt/include/settings_p.hpp b/third_party/maplibre-native-qt/include/settings_p.hpp deleted file mode 100644 index 257bdfd5a9afdb..00000000000000 --- a/third_party/maplibre-native-qt/include/settings_p.hpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2019 Mapbox, Inc. - -// SPDX-License-Identifier: BSD-2-Clause - -#pragma once - -#include "settings.hpp" -#include "types.hpp" - -#include - -#include -#include - -#include -#include - -namespace mbgl { -class TileServerOptions; -} // namespace mbgl - -namespace QMapLibre { - -class SettingsPrivate { -public: - SettingsPrivate(); - - void setProviderTemplate(Settings::ProviderTemplate providerTemplate); - void setProviderApiBaseUrl(const QString &url); - - Settings::GLContextMode m_contextMode{Settings::SharedGLContext}; - Settings::MapMode m_mapMode{Settings::Continuous}; - Settings::ConstrainMode m_constrainMode{Settings::ConstrainHeightOnly}; - Settings::ViewportMode m_viewportMode{Settings::DefaultViewport}; - Settings::ProviderTemplate m_providerTemplate{Settings::NoProvider}; - - unsigned m_cacheMaximumSize; - QString m_cacheDatabasePath; - QString m_assetPath; - QString m_apiKey; - QString m_localFontFamily; - QString m_clientName; - QString m_clientVersion; - - Coordinate m_defaultCoordinate{}; - double m_defaultZoom{}; - - Styles m_styles; - - std::function m_resourceTransform; - - bool m_customTileServerOptions{}; - mbgl::TileServerOptions m_tileServerOptions{}; -}; - -} // namespace QMapLibre diff --git a/third_party/maplibre-native-qt/include/style_change_utils_p.hpp b/third_party/maplibre-native-qt/include/style_change_utils_p.hpp deleted file mode 100644 index 991bb4077ea0d1..00000000000000 --- a/third_party/maplibre-native-qt/include/style_change_utils_p.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2017 Mapbox, Inc. - -// SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -#pragma once - -#include - -#include -#include -#include -#include -#include - -namespace QMapLibre::StyleChangeUtils { - -Feature featureFromMapRectangle(QDeclarativeRectangleMapItem *item); -Feature featureFromMapCircle(QDeclarativeCircleMapItem *item); -Feature featureFromMapPolygon(QDeclarativePolygonMapItem *item); -Feature featureFromMapPolyline(QDeclarativePolylineMapItem *item); -Feature featureFromMapItem(QDeclarativeGeoMapItemBase *item); - -QString featureId(QDeclarativeGeoMapItemBase *item); -std::vector featureLayoutPropertiesFromMapPolyline(QDeclarativePolylineMapItem *item); -std::vector featureLayoutPropertiesFromMapItem(QDeclarativeGeoMapItemBase *item); -std::vector featurePaintPropertiesFromMapRectangle(QDeclarativeRectangleMapItem *item); -std::vector featurePaingPropertiesFromMapCircle(QDeclarativeCircleMapItem *item); -std::vector featurePaintPropertiesFromMapPolygon(QDeclarativePolygonMapItem *item); -std::vector featurePaintPropertiesFromMapPolyline(QDeclarativePolylineMapItem *item); -std::vector featurePaintPropertiesFromMapItem(QDeclarativeGeoMapItemBase *item); -std::vector featurePropertiesFromMapItem(QDeclarativeGeoMapItemBase *item); - -} // namespace QMapLibre::StyleChangeUtils diff --git a/third_party/maplibre-native-qt/include/texture_node.hpp b/third_party/maplibre-native-qt/include/texture_node.hpp deleted file mode 100644 index 96f63b353492f5..00000000000000 --- a/third_party/maplibre-native-qt/include/texture_node.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2017 The Qt Company Ltd. -// Copyright (C) 2017 Mapbox, Inc. - -// SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -#pragma once - -#include -#include -#include -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) -#include -#else -#include -#endif - -#include - -namespace QMapLibre { - -class QGeoMapMapLibre; - -class TextureNode : public QSGSimpleTextureNode { -public: - TextureNode(const Settings &setting, const QSize &size, qreal pixelRatio, QGeoMapMapLibre *geoMap); - - [[nodiscard]] Map *map() const; - -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - void resize(const QSize &size, qreal pixelRatio, QQuickWindow *window); -#else - void resize(const QSize &size, qreal pixelRatio); -#endif - void render(QQuickWindow *); - -private: - std::unique_ptr m_map{}; - std::unique_ptr m_fbo{}; -}; - -} // namespace QMapLibre diff --git a/third_party/maplibre-native-qt/include/types.hpp b/third_party/maplibre-native-qt/include/types.hpp deleted file mode 100644 index 696fab1a88f229..00000000000000 --- a/third_party/maplibre-native-qt/include/types.hpp +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright (C) 2023 MapLibre contributors -// Copyright (C) 2019 Mapbox, Inc. - -// SPDX-License-Identifier: BSD-2-Clause - -#ifndef QMAPLIBRE_TYPES_H -#define QMAPLIBRE_TYPES_H - -#include - -#include -#include -#include -#include -#include -#include - -namespace QMapLibre { - -using Coordinate = QPair; -using CoordinateZoom = QPair; -using ProjectedMeters = QPair; - -using Coordinates = QVector; -using CoordinatesCollection = QVector; - -using CoordinatesCollections = QVector; - -struct Q_MAPLIBRE_CORE_EXPORT Style { - enum Type { // Taken from Qt to be in sync with QtLocation - NoMap = 0, - StreetMap, - SatelliteMapDay, - SatelliteMapNight, - TerrainMap, - HybridMap, - TransitMap, - GrayStreetMap, - PedestrianMap, - CarNavigationMap, - CycleMap, - CustomMap = 100 - }; - -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) - explicit Style(QString url_, QString name_ = QString()) - : url(std::move(url_)), - name(std::move(name_)) {} -#else - explicit Style(QString url_ = QString(), QString name_ = QString()) - : url(std::move(url_)), - name(std::move(name_)) {} -#endif - - QString url; - QString name; - QString description; - bool night{}; - Type type{CustomMap}; -}; - -using Styles = QVector
%1%2%4%5%6%7