mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-11 18:53:47 +08:00
FrogPilot base
This commit is contained in:
@@ -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()
|
||||
@@ -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()
|
||||
Executable
BIN
Binary file not shown.
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
Reference in New Issue
Block a user