FrogPilot base

This commit is contained in:
James
2025-12-01 12:00:00 -07:00
parent 4726bdce29
commit 41bf1bd2cb
144 changed files with 1254 additions and 39 deletions
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/env python3
import threading
import time
from openpilot.common.time_helpers import system_time_valid
from openpilot.system.hardware import HARDWARE
def frogpilot_boot_functions():
def boot_thread():
while not system_time_valid():
print("Waiting for system time to become valid...")
time.sleep(1)
threading.Thread(target=boot_thread, daemon=True).start()
def install_frogpilot():
paths = [
]
for path in paths:
path.mkdir(parents=True, exist_ok=True)
def uninstall_frogpilot():
HARDWARE.uninstall()
+82
View File
@@ -0,0 +1,82 @@
#!/usr/bin/env python3
import datetime
import time
from cereal import messaging
from openpilot.common.params import Params
from openpilot.common.realtime import DT_MDL, Priority, Ratekeeper, config_realtime_process
from openpilot.common.time_helpers import system_time_valid
ASSET_CHECK_RATE = (1 / DT_MDL)
def check_assets():
def transition_offroad(time_validated, sm, params):
def transition_onroad():
def update_checks(now, params, boot_run=False):
while not (is_url_pingable("https://github.com") or is_url_pingable("https://gitlab.com")):
time.sleep(60)
time.sleep(1)
def frogpilot_thread():
rate_keeper = Ratekeeper(1 / DT_MDL, None)
config_realtime_process(5, Priority.CTRL_LOW)
sm = messaging.SubMaster(["carControl", "carState", "controlsState", "deviceState", "driverMonitoringState",
"gpsLocation", "gpsLocationExternal", "liveParameters", "managerState", "modelV2",
"onroadEvents", "pandaStates", "radarState", "selfdriveState"],
poll="modelV2")
params = Params()
run_update_checks = False
started_previously = False
time_validated = False
while True:
sm.update()
now = datetime.datetime.now(datetime.timezone.utc)
started = sm["deviceState"].started
if not started and started_previously:
transition_offroad(time_validated, sm, params)
run_update_checks = True
elif started and not started_previously:
transition_onroad()
if started and sm.updated["modelV2"]:
elif not started:
started_previously = started
if rate_keeper.frame % ASSET_CHECK_RATE == 0:
check_assets()
run_update_checks |= now.second == 0 and (now.minute % 60 == 0)
run_update_checks &= time_validated
if run_update_checks:
thread_manager.run_with_lock(update_checks, (now, params))
run_update_checks = False
elif not time_validated:
time_validated = system_time_valid()
if not time_validated:
continue
thread_manager.run_with_lock(update_checks, (now, params, True))
rate_keeper.keep_time()
def main():
frogpilot_thread()
if __name__ == "__main__":
main()
Binary file not shown.
+35
View File
@@ -0,0 +1,35 @@
#include "frogpilot/ui/frogpilot_ui.h"
static void update_state(FrogPilotUIState *fs) {
FrogPilotUIScene &frogpilot_scene = fs->frogpilot_scene;
SubMaster &fpsm = *(fs->sm);
fpsm.update(0);
if (fpsm.updated("deviceState")) {
const cereal::DeviceState::Reader &deviceState = fpsm["deviceState"].getDeviceState();
}
if (fpsm.updated("selfdriveState")) {
const cereal::SelfdriveState::Reader &selfdriveState = fpsm["selfdriveState"].getSelfdriveState();
frogpilot_scene.enabled = selfdriveState.getEnabled();
}
}
FrogPilotUIState::FrogPilotUIState(QObject *parent) : QObject(parent) {
sm = std::make_unique<SubMaster, const std::initializer_list<const char *>>({
"carControl", "deviceState",
"liveDelay",
"liveParameters", "liveTorqueParameters", "liveTracks", "selfdriveState"
});
wifi = new WifiManager(this);
}
FrogPilotUIState *frogpilotUIState() {
static FrogPilotUIState frogpilot_ui_state;
return &frogpilot_ui_state;
}
void FrogPilotUIState::update() {
update_state(this);
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include "cereal/messaging/messaging.h"
#include "selfdrive/ui/qt/network/wifi_manager.h"
#include "frogpilot/ui/qt/widgets/frogpilot_controls.h"
struct FrogPilotUIScene {
bool enabled;
bool parked;
bool reverse;
bool standstill;
int started_timer;
};
class FrogPilotUIState : public QObject {
Q_OBJECT
public:
explicit FrogPilotUIState(QObject *parent = nullptr);
void update();
std::unique_ptr<SubMaster> sm;
FrogPilotUIScene frogpilot_scene;
Params params;
WifiManager *wifi;
signals:
};
FrogPilotUIState *frogpilotUIState();
@@ -0,0 +1,46 @@
#include "frogpilot/ui/qt/onroad/frogpilot_annotated_camera.h"
FrogPilotAnnotatedCameraWidget::FrogPilotAnnotatedCameraWidget(QWidget *parent) : QWidget(parent) {
QSize iconSize(img_size / 4, img_size / 4);
}
void FrogPilotAnnotatedCameraWidget::showEvent(QShowEvent *event) {
}
void FrogPilotAnnotatedCameraWidget::updateState(const UIState &s, const FrogPilotUIState &fs) {
const UIScene &scene = s.scene;
const SubMaster &sm = *(s.sm);
const SubMaster &fpsm = *(fs.sm);
const cereal::CarState::Reader &carState = sm["carState"].getCarState();
const cereal::ModelDataV2::Reader &modelV2 = sm["modelV2"].getModelV2();
const cereal::SelfdriveState::Reader &selfdriveState = sm["selfdriveState"].getSelfdriveState();
if (scene.is_metric || frogpilot_toggles.value("use_si_metrics").toBool()) {
leadDistanceUnit = tr(" meters");
leadSpeedUnit = frogpilot_toggles.value("use_si_metrics").toBool() ? tr(" m/s") : tr(" km/h");
speedUnit = scene.is_metric ? tr("km/h") : tr("mph");
distanceConversion = 1.0f;
speedConversion = scene.is_metric ? MS_TO_KPH : MS_TO_MPH;
speedConversionMetrics = frogpilot_toggles.value("use_si_metrics").toBool() ? 1.0f : MS_TO_KPH;
} else {
leadDistanceUnit = tr(" feet");
leadSpeedUnit = tr(" mph");
speedUnit = tr("mph");
distanceConversion = METER_TO_FOOT;
speedConversion = MS_TO_MPH;
speedConversionMetrics = MS_TO_MPH;
}
hideBottomIcons = selfdriveState.getAlertSize() != cereal::SelfdriveState::AlertSize::NONE;
}
void FrogPilotAnnotatedCameraWidget::mousePressEvent(QMouseEvent *mouseEvent) {
mouseEvent->ignore();
}
void FrogPilotAnnotatedCameraWidget::paintFrogPilotWidgets(QPainter &p, UIState &s) {
}
@@ -0,0 +1,52 @@
#pragma once
#include "selfdrive/ui/qt/onroad/buttons.h"
#include "selfdrive/ui/qt/widgets/cameraview.h"
const int widget_size = img_size + (UI_BORDER_SIZE / 2);
class FrogPilotAnnotatedCameraWidget : public QWidget {
Q_OBJECT
public:
explicit FrogPilotAnnotatedCameraWidget(QWidget *parent = 0);
void mousePressEvent(QMouseEvent *mouseEvent) override;
void paintFrogPilotWidgets(QPainter &p, UIState &s);
void updateState(const UIState &s, const FrogPilotUIState &fs);
bool hideBottomIcons;
bool isCruiseSet;
bool rightHandDM;
float speed;
FrogPilotUIScene frogpilot_scene;
QColor blueColor(int alpha = 255) { return QColor(0, 0, 255, alpha); }
QColor purpleColor(int alpha = 255) { return QColor(128, 0, 128, alpha); }
QColor whiteColor(int alpha = 255) { return QColor(255, 255, 255, alpha); }
QPoint dmIconPosition;
QPoint experimentalButtonPosition;
QRect setSpeedRect;
QSize defaultSize;
protected:
void showEvent(QShowEvent *event) override;
private:
float distanceConversion;
float setSpeed;
float speedConversion;
float speedConversionMetrics;
QColor blackColor(int alpha = 255) { return QColor(0, 0, 0, alpha); }
QColor redColor(int alpha = 255) { return QColor(201, 34, 49, alpha); }
QString leadDistanceUnit;
QString leadSpeedUnit;
QString speedUnit;
};
@@ -0,0 +1 @@
#include "frogpilot/ui/qt/onroad/frogpilot_buttons.h"
@@ -0,0 +1,3 @@
#pragma once
#include "selfdrive/ui/qt/onroad/buttons.h"
@@ -0,0 +1,26 @@
#include "frogpilot/ui/qt/onroad/frogpilot_onroad.h"
FrogPilotOnroadWindow::FrogPilotOnroadWindow(QWidget *parent) : QWidget(parent) {
}
void FrogPilotOnroadWindow::resizeEvent(QResizeEvent *event) {
rect = QWidget::rect();
marginRegion = QRegion(rect) - QRegion(rect.marginsRemoved(QMargins(UI_BORDER_SIZE, UI_BORDER_SIZE, UI_BORDER_SIZE, UI_BORDER_SIZE)));
}
void FrogPilotOnroadWindow::updateState(const UIState &s, const FrogPilotUIState &fs) {
const SubMaster &sm = *(s.sm);
const SubMaster &fpsm = *(fs.sm);
const cereal::CarState::Reader &carState = sm["carState"].getCarState();
const cereal::CarControl::Reader &carControl = fpsm["carControl"].getCarControl();
update();
}
void FrogPilotOnroadWindow::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.setClipRegion(marginRegion);
p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
}
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include "selfdrive/ui/qt/onroad/annotated_camera.h"
class FrogPilotOnroadWindow : public QWidget {
Q_OBJECT
public:
FrogPilotOnroadWindow(QWidget* parent = 0);
void updateState(const UIState &s, const FrogPilotUIState &fs);
FrogPilotUIScene frogpilot_scene;
QColor bg;
private:
void paintEvent(QPaintEvent *event);
void resizeEvent(QResizeEvent *event);
QRect rect;
QRegion marginRegion;
};
@@ -0,0 +1,59 @@
#include "selfdrive/ui/ui.h"
#include "frogpilot/ui/frogpilot_ui.h"
void clearMovie(QSharedPointer<QMovie> &movie, QWidget *parent) {
if (!movie) {
return;
}
QObject::disconnect(movie.data(), nullptr, parent, nullptr);
movie->stop();
movie.reset();
}
void loadGif(const QString &gifPath, QSharedPointer<QMovie> &movie, const QSize &size, QWidget *parent) {
clearMovie(movie, parent);
movie = QSharedPointer<QMovie>::create(gifPath);
movie->setCacheMode(QMovie::CacheAll);
movie->setScaledSize(size);
QPointer<QWidget> safeParent(parent);
QObject::connect(movie.data(), &QMovie::frameChanged, parent, [safeParent]() {
if (safeParent && safeParent->isVisible()) {
safeParent->update();
}
}, Qt::UniqueConnection);
movie->start();
}
void loadImage(const QString &basePath, QPixmap &pixmap, QSharedPointer<QMovie> &movie, const QSize &size, QWidget *parent) {
if (!parent) {
return;
}
QString gifPath = basePath + ".gif";
if (QFileInfo::exists(gifPath)) {
loadGif(gifPath, movie, size, parent);
if (!pixmap.isNull()) {
pixmap = QPixmap();
parent->update();
}
return;
}
QString pngPath = basePath + ".png";
clearMovie(movie, parent);
QPixmap loadedPixmap(pngPath);
if (!loadedPixmap.isNull()) {
pixmap = loadedPixmap.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
} else {
pixmap = QPixmap();
}
parent->update();
}
@@ -0,0 +1,19 @@
#pragma once
#include <cmath>
#include <iostream>
#include <set>
#include <QElapsedTimer>
#include <QJsonObject>
#include <QMovie>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QStyle>
#include "selfdrive/ui/qt/util.h"
#include "selfdrive/ui/qt/widgets/controls.h"
void loadGif(const QString &gifPath, QSharedPointer<QMovie> &movie, const QSize &size, QWidget *parent);
void loadImage(const QString &basePath, QPixmap &pixmap, QSharedPointer<QMovie> &movie, const QSize &size, QWidget *parent);