Switch personalities via steering wheel / onroad UI

Added toggle to switch between the personalities via the steering wheel for GM/Toyota/Volkswagen vehicles and an onroad button for other makes.

Co-Authored-By: henryccy <104284652+henryccy@users.noreply.github.com>
Co-Authored-By: Jason Jackrel <23621790+thinkpad4by3@users.noreply.github.com>
Co-Authored-By: Eric Brown <13560103+nworb-cire@users.noreply.github.com>
Co-Authored-By: Kevin Robert Keegan <3046315+krkeegan@users.noreply.github.com>
Co-Authored-By: Jacob Pfeifer <jacob@pfeifer.dev>
Co-Authored-By: mike8643 <98910897+mike8643@users.noreply.github.com>
This commit is contained in:
FrogAi
2024-01-12 22:39:30 -07:00
parent 22bfc8d9b7
commit c9298a885f
29 changed files with 300 additions and 21 deletions

View File

@@ -110,7 +110,7 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
toggles[param.toStdString()] = toggle;
// insert longitudinal personality after NDOG toggle
if (param == "DisengageOnAccelerator") {
if (param == "DisengageOnAccelerator" && !params.getInt("AdjustablePersonalities")) {
addItem(long_personality_setting);
}
}

View File

@@ -879,6 +879,7 @@ void AnnotatedCameraWidget::drawDriverState(QPainter &painter, const UIState *s)
int offset = UI_BORDER_SIZE + btn_size / 2;
offset += alwaysOnLateral || conditionalExperimental || roadNameUI ? 25 : 0;
int x = rightHandDM ? width() - offset : offset;
x += onroadAdjustableProfiles ? 250 : 0;
int y = height() - offset;
float opacity = dmActive ? 0.65 : 0.2;
drawIcon(painter, QPoint(x, y), dm_img, blackColor(70), opacity);
@@ -1110,6 +1111,9 @@ void AnnotatedCameraWidget::initializeFrogPilotWidgets() {
bottom_layout = new QHBoxLayout();
personality_btn = new PersonalityButton(this);
bottom_layout->addWidget(personality_btn);
QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
bottom_layout->addItem(spacer);
@@ -1185,6 +1189,7 @@ void AnnotatedCameraWidget::updateFrogPilotWidgets(QPainter &p) {
muteDM = scene.mute_dm;
obstacleDistance = scene.obstacle_distance;
obstacleDistanceStock = scene.obstacle_distance_stock;
onroadAdjustableProfiles = scene.personalities_via_screen;
roadNameUI = scene.road_name_ui;
showDriverCamera = scene.show_driver_camera;
slcOverridden = scene.speed_limit_overridden;
@@ -1225,6 +1230,15 @@ void AnnotatedCameraWidget::updateFrogPilotWidgets(QPainter &p) {
bottom_layout->setAlignment(compass_img, (rightHandDM ? Qt::AlignLeft : Qt::AlignRight));
}
const bool enablePersonalityButton = onroadAdjustableProfiles && !hideBottomIcons;
personality_btn->setVisible(enablePersonalityButton);
if (enablePersonalityButton) {
if (paramsMemory.getBool("PersonalityChangedViaWheel")) {
personality_btn->checkUpdate();
}
bottom_layout->setAlignment(personality_btn, (rightHandDM ? Qt::AlignRight : Qt::AlignLeft));
}
map_settings_btn_bottom->setEnabled(map_settings_btn->isEnabled());
if (map_settings_btn_bottom->isEnabled()) {
map_settings_btn_bottom->setVisible(!hideBottomIcons && !compass);
@@ -1470,6 +1484,79 @@ void AnnotatedCameraWidget::drawLeadInfo(QPainter &p) {
p.restore();
}
PersonalityButton::PersonalityButton(QWidget *parent) : QPushButton(parent), scene(uiState()->scene) {
setFixedSize(btn_size * 1.5, btn_size * 1.5);
// Configure the profile vector
profile_data = {
{QPixmap("../frogpilot/assets/other_images/aggressive.png"), "Aggressive"},
{QPixmap("../frogpilot/assets/other_images/standard.png"), "Standard"},
{QPixmap("../frogpilot/assets/other_images/relaxed.png"), "Relaxed"}
};
// Start the timer as soon as the button is created
transitionTimer.start();
// Initialize the click event
connect(this, &QPushButton::clicked, this, &PersonalityButton::handleClick);
personalityProfile = params.getInt("LongitudinalPersonality");
setVisible(scene.personalities_via_screen);
}
void PersonalityButton::checkUpdate() {
// Sync with the steering wheel button
personalityProfile = params.getInt("LongitudinalPersonality");
updateState();
paramsMemory.putBool("PersonalityChangedViaWheel", false);
}
void PersonalityButton::handleClick() {
int mapping[] = {2, 0, 1};
personalityProfile = mapping[personalityProfile];
params.putInt("LongitudinalPersonality", personalityProfile);
paramsMemory.putBool("PersonalityChangedViaUI", true);
updateState();
}
void PersonalityButton::updateState() {
// Start the transition
transitionTimer.restart();
}
void PersonalityButton::paintEvent(QPaintEvent *) {
// Declare the constants
constexpr qreal fadeDuration = 1000.0; // 1 second
constexpr qreal textDuration = 3000.0; // 3 seconds
QPainter p(this);
int elapsed = transitionTimer.elapsed();
qreal textOpacity = qBound(0.0, 1.0 - ((elapsed - textDuration) / fadeDuration), 1.0);
qreal imageOpacity = qBound(0.0, (elapsed - textDuration) / fadeDuration, 1.0);
// Enable Antialiasing
p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
// Configure the button
const auto &[profile_image, profile_text] = profile_data[personalityProfile];
QRect rect(0, 0, width(), height() + 95);
// Draw the profile text with the calculated opacity
if (textOpacity > 0.0) {
p.setOpacity(textOpacity);
p.setFont(InterFont(40, QFont::Bold));
p.setPen(Qt::white);
p.drawText(rect, Qt::AlignCenter, profile_text);
}
// Draw the profile image with the calculated opacity
if (imageOpacity > 0.0) {
drawIcon(p, QPoint((btn_size / 2) * 1.25, btn_size / 2 + 95), profile_image, Qt::transparent, imageOpacity);
}
}
void AnnotatedCameraWidget::drawStatusBar(QPainter &p) {
p.save();

View File

@@ -104,6 +104,30 @@ private:
QPixmap settings_img;
};
// FrogPilot buttons
class PersonalityButton : public QPushButton {
public:
explicit PersonalityButton(QWidget *parent = 0);
void checkUpdate();
void handleClick();
void updateState();
private:
void paintEvent(QPaintEvent *event) override;
Params params;
Params paramsMemory{"/dev/shm/params"};
UIScene &scene;
int personalityProfile = 0;
QElapsedTimer transitionTimer;
QVector<std::pair<QPixmap, QString>> profile_data;
};
// container window for the NVG UI
class AnnotatedCameraWidget : public CameraWidget {
Q_OBJECT
@@ -153,6 +177,7 @@ private:
UIScene &scene;
Compass *compass_img;
PersonalityButton *personality_btn;
ScreenRecorder *recorder_btn;
QHBoxLayout *bottom_layout;
@@ -168,6 +193,7 @@ private:
bool leadInfo;
bool mapOpen;
bool muteDM;
bool onroadAdjustableProfiles;
bool roadNameUI;
bool showDriverCamera;
bool slcOverridden;

View File

@@ -325,6 +325,7 @@ void ui_update_params(UIState *s) {
scene.driver_camera = params.getBool("DriverCamera");
scene.experimental_mode_via_press = params.getBool("ExperimentalModeViaPress");
scene.mute_dm = params.getBool("FireTheBabysitter") && params.getBool("MuteDM");
scene.personalities_via_screen = (params.getInt("AdjustablePersonalities") == 2 || params.getInt("AdjustablePersonalities") == 3);
scene.rotating_wheel = params.getBool("RotatingWheel");
scene.screen_brightness = params.getInt("ScreenBrightness");
scene.speed_limit_controller = params.getBool("SpeedLimitController");

View File

@@ -189,6 +189,7 @@ typedef struct UIScene {
bool map_open;
bool model_ui;
bool mute_dm;
bool personalities_via_screen;
bool road_name_ui;
bool rotating_wheel;
bool show_driver_camera;