Controls - Driving Personalities - Onroad Distance Button

Simulate a distance button via the onroad UI to control personalities, 'Experimental Mode', and 'Traffic Mode'.
This commit is contained in:
FrogAi
2024-07-31 20:25:48 -07:00
parent dcb5f615ec
commit 02786d6fde
13 changed files with 120 additions and 2 deletions
+4 -2
View File
@@ -190,6 +190,7 @@ class Controls:
self.always_on_lateral_active = False
self.drive_added = False
self.onroad_distance_pressed = False
self.openpilot_crashed_triggered = False
self.update_toggles = False
@@ -671,12 +672,13 @@ class Controls:
# decrement personality on distance button press
if self.CP.openpilotLongitudinalControl:
if any(not be.pressed and be.type == ButtonType.gapAdjustCruise for be in CS.buttonEvents):
if any(not be.pressed and be.type == ButtonType.gapAdjustCruise for be in CS.buttonEvents) or self.onroad_distance_pressed:
menu_open = self.display_timer > 0 or not self.sm['frogpilotCarState'].hasMenu
if menu_open:
if not self.params_memory.get_bool("OnroadDistanceButtonPressed") and menu_open:
self.personality = (self.personality - 1) % 3
self.params.put_nonblocking('LongitudinalPersonality', str(self.personality))
self.display_timer = 350
self.onroad_distance_pressed = self.params_memory.get_bool("OnroadDistanceButtonPressed")
self.display_timer -= 1
Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

@@ -286,6 +286,8 @@ void AnnotatedCameraWidget::drawDriverState(QPainter &painter, const UIState *s)
int x = rightHandDM ? width() - offset : offset;
if (rightHandDM && map_settings_btn->isEnabled()) {
x -= 250;
} else if (onroadDistanceButton) {
x += 250;
}
offset += showAlwaysOnLateralStatusBar || showConditionalExperimentalStatusBar ? 25 : 0;
int y = height() - offset;
@@ -465,6 +467,9 @@ void AnnotatedCameraWidget::showEvent(QShowEvent *event) {
void AnnotatedCameraWidget::initializeFrogPilotWidgets() {
bottom_layout = new QHBoxLayout();
distance_btn = new DistanceButton(this);
bottom_layout->addWidget(distance_btn, 0, Qt::AlignBottom | Qt::AlignLeft);
QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
bottom_layout->addItem(spacer);
@@ -514,6 +519,14 @@ void AnnotatedCameraWidget::paintFrogPilotWidgets(QPainter &painter, const UISce
map_settings_btn_bottom->setVisible(!hideBottomIcons);
bottom_layout->setAlignment(map_settings_btn_bottom, (rightHandDM ? Qt::AlignLeft : Qt::AlignRight) | Qt::AlignBottom);
}
onroadDistanceButton = scene.onroad_distance_button;
bool enableDistanceButton = onroadDistanceButton && !hideBottomIcons;
distance_btn->setVisible(enableDistanceButton);
if (enableDistanceButton) {
distance_btn->updateState(scene);
bottom_layout->setAlignment(distance_btn, (rightHandDM ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignBottom);
}
}
void AnnotatedCameraWidget::drawStatusBar(QPainter &p) {
@@ -50,11 +50,14 @@ private:
// FrogPilot variables
Params paramsMemory{"/dev/shm/params"};
DistanceButton *distance_btn;
QHBoxLayout *bottom_layout;
bool alwaysOnLateralActive;
bool experimentalMode;
bool mapOpen;
bool onroadDistanceButton;
bool showAlwaysOnLateralStatusBar;
bool showConditionalExperimentalStatusBar;
+55
View File
@@ -65,3 +65,58 @@ 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);
}
// FrogPilot buttons
// DistanceButton
DistanceButton::DistanceButton(QWidget *parent) : QPushButton(parent) {
setFixedSize(btn_size * 1.5, btn_size * 1.5);
connect(this, &QPushButton::pressed, this, &DistanceButton::buttonPressed);
connect(this, &QPushButton::released, this, &DistanceButton::buttonReleased);
}
void DistanceButton::buttonPressed() {
paramsMemory.putBool("OnroadDistanceButtonPressed", true);
}
void DistanceButton::buttonReleased() {
paramsMemory.putBool("OnroadDistanceButtonPressed", false);
}
void DistanceButton::updateState(const UIScene &scene) {
bool stateChanged = (trafficModeActive != scene.traffic_mode_active) ||
(personality != static_cast<int>(scene.personality) + 1 && !trafficModeActive);
if (stateChanged) {
personality = static_cast<int>(scene.personality) + 1;
trafficModeActive = scene.traffic_mode_active;
int profile = trafficModeActive ? 0 : personality;
std::tie(profileImage, profileText) = (scene.use_kaofui_icons ? profileDataKaofui : profileData)[profile];
transitionTimer.restart();
update();
} else if (transitionTimer.isValid()) {
update();
} else {
return;
}
}
void DistanceButton::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
int elapsed = transitionTimer.elapsed();
qreal textOpacity = qBound(0.0, 1.0 - ((elapsed - 3000.0) / 1000.0), 1.0);
qreal imageOpacity = 1.0 - textOpacity;
p.setOpacity(textOpacity);
p.setFont(InterFont(40, QFont::Bold));
p.setPen(Qt::white);
QRect textRect(-25, 0, width(), height() + btn_size / 2);
p.drawText(textRect, Qt::AlignCenter, profileText);
drawIcon(p, QPoint((btn_size / 2) * 1.25, btn_size), profileImage, Qt::transparent, imageOpacity);
}
+39
View File
@@ -42,3 +42,42 @@ private:
};
void drawIcon(QPainter &p, const QPoint &center, const QPixmap &img, const QBrush &bg, float opacity);
// FrogPilot buttons
class DistanceButton : public QPushButton {
Q_OBJECT
public:
explicit DistanceButton(QWidget *parent = 0);
void updateState(const UIScene &scene);
private:
void buttonPressed();
void buttonReleased();
void paintEvent(QPaintEvent *event) override;
bool trafficModeActive;
int personality;
QElapsedTimer transitionTimer;
QPixmap profileImage;
QString profileText;
Params paramsMemory{"/dev/shm/params"};
const QVector<std::pair<QPixmap, QString>> profileData = {
{QPixmap("../frogpilot/assets/other_images/traffic.png"), "Traffic"},
{QPixmap("../frogpilot/assets/other_images/aggressive.png"), "Aggressive"},
{QPixmap("../frogpilot/assets/other_images/standard.png"), "Standard"},
{QPixmap("../frogpilot/assets/other_images/relaxed.png"), "Relaxed"}
};
const QVector<std::pair<QPixmap, QString>> profileDataKaofui = {
{QPixmap("../frogpilot/assets/other_images/traffic_kaofui.png"), "Traffic"},
{QPixmap("../frogpilot/assets/other_images/aggressive_kaofui.png"), "Aggressive"},
{QPixmap("../frogpilot/assets/other_images/standard_kaofui.png"), "Standard"},
{QPixmap("../frogpilot/assets/other_images/relaxed_kaofui.png"), "Relaxed"}
};
};
+4
View File
@@ -278,6 +278,10 @@ void ui_update_frogpilot_params(UIState *s, Params &params) {
scene.conditional_speed_lead = scene.conditional_experimental ? params.getInt("CESpeedLead") : 0;
scene.show_cem_status_bar = scene.conditional_experimental && !params.getBool("HideCEMStatusBar");
bool driving_personalities = scene.longitudinal_control && params.getBool("DrivingPersonalities");
scene.onroad_distance_button = driving_personalities && params.getBool("OnroadDistanceButton");
scene.use_kaofui_icons = scene.onroad_distance_button && params.getBool("KaofuiIcons");
scene.tethering_config = params.getInt("TetheringEnabled");
if (scene.tethering_config == 2) {
WifiManager(s).setTetheringEnabled(true);
+2
View File
@@ -124,11 +124,13 @@ typedef struct UIScene {
bool experimental_mode;
bool map_open;
bool online;
bool onroad_distance_button;
bool parked;
bool right_hand_drive;
bool show_aol_status_bar;
bool show_cem_status_bar;
bool tethering_enabled;
bool use_kaofui_icons;
int alert_size;
int conditional_speed;