Always on Lateral
Added toggle for Always On Lateral / No disengage lateral on gas and brake. Lots of credit goes to "pfeiferj"! Couldn't of done it without him! https: //github.com/pfeiferj/openpilot Co-Authored-By: Jacob Pfeifer <jacob@pfeifer.dev>
This commit is contained in:
@@ -151,7 +151,7 @@ class CarController:
|
||||
use_fca = self.CP.flags & HyundaiFlags.USE_FCA.value
|
||||
can_sends.extend(hyundaican.create_acc_commands(self.packer, CC.enabled, accel, jerk, int(self.frame / 2),
|
||||
hud_control.leadVisible, set_speed_in_units, stopping,
|
||||
CC.cruiseControl.override, use_fca))
|
||||
CC.cruiseControl.override, use_fca, CS.out.cruiseState.available))
|
||||
|
||||
# 20 Hz LFA MFA message
|
||||
if self.frame % 5 == 0 and self.CP.flags & HyundaiFlags.SEND_LFA.value:
|
||||
|
||||
@@ -102,7 +102,7 @@ class CarState(CarStateBase):
|
||||
# cruise state
|
||||
if self.CP.openpilotLongitudinalControl:
|
||||
# These are not used for engage/disengage since openpilot keeps track of state using the buttons
|
||||
ret.cruiseState.available = cp.vl["TCS13"]["ACCEnable"] == 0
|
||||
ret.cruiseState.available = self.main_enabled
|
||||
ret.cruiseState.enabled = cp.vl["TCS13"]["ACC_REQ"] == 1
|
||||
ret.cruiseState.standstill = False
|
||||
ret.cruiseState.nonAdaptive = False
|
||||
@@ -162,7 +162,10 @@ class CarState(CarStateBase):
|
||||
self.steer_state = cp.vl["MDPS12"]["CF_Mdps_ToiActive"] # 0 NOT ACTIVE, 1 ACTIVE
|
||||
self.prev_cruise_buttons = self.cruise_buttons[-1]
|
||||
self.cruise_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwState"])
|
||||
self.prev_main_buttons = self.main_buttons[-1]
|
||||
self.main_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwMain"])
|
||||
if self.prev_main_buttons == 0 and self.main_buttons[-1] != 0:
|
||||
self.main_enabled = not self.main_enabled
|
||||
|
||||
return ret
|
||||
|
||||
@@ -217,7 +220,7 @@ class CarState(CarStateBase):
|
||||
|
||||
# cruise state
|
||||
# CAN FD cars enable on main button press, set available if no TCS faults preventing engagement
|
||||
ret.cruiseState.available = cp.vl["TCS"]["ACCEnable"] == 0
|
||||
ret.cruiseState.available = self.main_enabled
|
||||
if self.CP.openpilotLongitudinalControl:
|
||||
# These are not used for engage/disengage since openpilot keeps track of state using the buttons
|
||||
ret.cruiseState.enabled = cp.vl["TCS"]["ACC_REQ"] == 1
|
||||
@@ -238,7 +241,10 @@ class CarState(CarStateBase):
|
||||
|
||||
self.prev_cruise_buttons = self.cruise_buttons[-1]
|
||||
self.cruise_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"])
|
||||
self.prev_main_buttons = self.main_buttons[-1]
|
||||
self.main_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["ADAPTIVE_CRUISE_MAIN_BTN"])
|
||||
if self.prev_main_buttons == 0 and self.main_buttons[-1] != 0:
|
||||
self.main_enabled = not self.main_enabled
|
||||
self.buttons_counter = cp.vl[self.cruise_btns_msg_canfd]["COUNTER"]
|
||||
ret.accFaulted = cp.vl["TCS"]["ACCEnable"] != 0 # 0 ACC CONTROL ENABLED, 1-3 ACC CONTROL DISABLED
|
||||
|
||||
|
||||
@@ -126,11 +126,11 @@ def create_lfahda_mfc(packer, enabled, hda_set_speed=0):
|
||||
}
|
||||
return packer.make_can_msg("LFAHDA_MFC", 0, values)
|
||||
|
||||
def create_acc_commands(packer, enabled, accel, upper_jerk, idx, lead_visible, set_speed, stopping, long_override, use_fca):
|
||||
def create_acc_commands(packer, enabled, accel, upper_jerk, idx, lead_visible, set_speed, stopping, long_override, use_fca, cruise_available):
|
||||
commands = []
|
||||
|
||||
scc11_values = {
|
||||
"MainMode_ACC": 1,
|
||||
"MainMode_ACC": 1 if cruise_available else 0,
|
||||
"TauGapSet": 4,
|
||||
"VSetDis": set_speed if enabled else 0,
|
||||
"AliveCounterACC": idx % 0x10,
|
||||
|
||||
@@ -360,6 +360,8 @@ class CarStateBase(ABC):
|
||||
self.param = Params()
|
||||
self.param_memory = Params("/dev/shm/params")
|
||||
|
||||
self.main_enabled = False
|
||||
|
||||
def update_speed_kf(self, v_ego_raw):
|
||||
if abs(v_ego_raw - self.v_ego_kf.x[0][0]) > 2.0: # Prevent large accelerations when car starts at non zero speed
|
||||
self.v_ego_kf.set_x([[v_ego_raw], [0.0]])
|
||||
|
||||
@@ -108,6 +108,16 @@ class Controls:
|
||||
if not self.disengage_on_accelerator:
|
||||
self.CP.alternativeExperience |= ALTERNATIVE_EXPERIENCE.DISABLE_DISENGAGE_ON_GAS
|
||||
|
||||
# Set "Always On Lateral" conditions
|
||||
self.always_on_lateral = self.params.get_bool("AlwaysOnLateral")
|
||||
self.always_on_lateral_main = self.params.get_bool("AlwaysOnLateralMain")
|
||||
self.lateral_allowed = False
|
||||
if self.always_on_lateral:
|
||||
self.CP.alternativeExperience |= ALTERNATIVE_EXPERIENCE.ALWAYS_ON_LATERAL
|
||||
if self.disengage_on_accelerator:
|
||||
self.disengage_on_accelerator = False
|
||||
self.params.put_bool("DisengageOnAccelerator", False)
|
||||
|
||||
self.CP.alternativeExperience |= ALTERNATIVE_EXPERIENCE.RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX
|
||||
|
||||
# read params
|
||||
@@ -596,9 +606,18 @@ class Controls:
|
||||
gear = car.CarState.GearShifter
|
||||
driving_gear = CS.gearShifter not in (gear.neutral, gear.park, gear.reverse, gear.unknown)
|
||||
|
||||
# Always on lateral
|
||||
if self.always_on_lateral:
|
||||
self.lateral_allowed &= CS.cruiseState.available
|
||||
self.lateral_allowed |= CS.cruiseState.enabled or (CS.cruiseState.available and self.always_on_lateral_main)
|
||||
|
||||
self.FPCC.alwaysOnLateral = self.lateral_allowed and driving_gear
|
||||
if self.FPCC.alwaysOnLateral:
|
||||
self.current_alert_types.append(ET.WARNING)
|
||||
|
||||
# Check which actuators can be enabled
|
||||
standstill = CS.vEgo <= max(self.CP.minSteerSpeed, MIN_LATERAL_CONTROL_SPEED) or CS.standstill
|
||||
CC.latActive = self.active and not CS.steerFaultTemporary and not CS.steerFaultPermanent and \
|
||||
CC.latActive = (self.active or self.FPCC.alwaysOnLateral) and not CS.steerFaultTemporary and not CS.steerFaultPermanent and \
|
||||
(not standstill or self.joystick_mode)
|
||||
CC.longActive = self.enabled and not self.events.contains(ET.OVERRIDE_LONGITUDINAL) and self.CP.openpilotLongitudinalControl
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.5 KiB |
@@ -3,6 +3,8 @@
|
||||
|
||||
FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPilotListWidget(parent) {
|
||||
const std::vector<std::tuple<QString, QString, QString, QString>> controlToggles {
|
||||
{"AlwaysOnLateral", "Always on Lateral", "Maintain openpilot lateral control when the brake or gas pedals are used.\n\nDeactivation occurs only through the 'Cruise Control' button.", "../frogpilot/assets/toggle_icons/icon_always_on_lateral.png"},
|
||||
|
||||
{"LateralTune", "Lateral Tuning", "Modify openpilot's steering behavior.", "../frogpilot/assets/toggle_icons/icon_lateral_tune.png"},
|
||||
|
||||
{"LongitudinalTune", "Longitudinal Tuning", "Modify openpilot's acceleration and braking behavior.", "../frogpilot/assets/toggle_icons/icon_longitudinal_tune.png"},
|
||||
@@ -13,7 +15,22 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
|
||||
for (const auto &[param, title, desc, icon] : controlToggles) {
|
||||
ParamControl *toggle;
|
||||
|
||||
if (param == "LateralTune") {
|
||||
if (param == "AlwaysOnLateral") {
|
||||
std::vector<QString> aolToggles{tr("AlwaysOnLateralMain")};
|
||||
std::vector<QString> aolToggleNames{tr("Enable On Cruise Main")};
|
||||
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, aolToggles, aolToggleNames);
|
||||
|
||||
QObject::connect(static_cast<FrogPilotParamToggleControl*>(toggle), &FrogPilotParamToggleControl::buttonClicked, [this](const bool checked) {
|
||||
if (checked) {
|
||||
FrogPilotConfirmationDialog::toggleAlert("WARNING: This is very experimental and isn't guaranteed to work. If you run into any issues, please report it in the FrogPilot Discord!",
|
||||
"I understand the risks.", this);
|
||||
}
|
||||
if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) {
|
||||
Hardware::reboot();
|
||||
}
|
||||
});
|
||||
|
||||
} else if (param == "LateralTune") {
|
||||
FrogPilotParamManageControl *lateralTuneToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
||||
QObject::connect(lateralTuneToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
||||
parentToggleClicked();
|
||||
@@ -68,7 +85,7 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
|
||||
});
|
||||
}
|
||||
|
||||
std::set<std::string> rebootKeys = {};
|
||||
std::set<std::string> rebootKeys = {"AlwaysOnLateral"};
|
||||
for (const std::string &key : rebootKeys) {
|
||||
QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this]() {
|
||||
if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) {
|
||||
|
||||
@@ -124,7 +124,7 @@ void MapWindow::updateState(const UIState &s) {
|
||||
if (sm.updated("modelV2")) {
|
||||
// set path color on change, and show map on rising edge of navigate on openpilot
|
||||
bool nav_enabled = sm["modelV2"].getModelV2().getNavEnabled() &&
|
||||
sm["controlsState"].getControlsState().getEnabled();
|
||||
(sm["controlsState"].getControlsState().getEnabled() || sm["frogpilotCarControl"].getFrogpilotCarControl().getAlwaysOnLateral());
|
||||
if (nav_enabled != uiState()->scene.navigate_on_openpilot) {
|
||||
if (loaded_once) {
|
||||
m_map->setPaintProperty("navLayer", "line-color", getNavPathColor(nav_enabled));
|
||||
|
||||
@@ -178,7 +178,7 @@ void OnroadAlerts::paintEvent(QPaintEvent *event) {
|
||||
|
||||
int margin = 40;
|
||||
int radius = 30;
|
||||
int offset = true ? 25 : 0;
|
||||
int offset = scene.always_on_lateral ? 25 : 0;
|
||||
if (alert.size == cereal::ControlsState::AlertSize::FULL) {
|
||||
margin = 0;
|
||||
radius = 0;
|
||||
@@ -258,7 +258,7 @@ void ExperimentalButton::updateState(const UIState &s) {
|
||||
void ExperimentalButton::paintEvent(QPaintEvent *event) {
|
||||
QPainter p(this);
|
||||
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);
|
||||
drawIcon(p, QPoint(btn_size / 2, btn_size / 2), img, QColor(0, 0, 0, 166), (isDown() || (!engageable && !scene.always_on_lateral_active)) ? 0.6 : 1.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -548,7 +548,7 @@ void AnnotatedCameraWidget::drawDriverState(QPainter &painter, const UIState *s)
|
||||
|
||||
// base icon
|
||||
int offset = UI_BORDER_SIZE + btn_size / 2;
|
||||
offset += true ? 25 : 0;
|
||||
offset += alwaysOnLateral ? 25 : 0;
|
||||
int x = rightHandDM ? width() - offset : offset;
|
||||
int y = height() - offset;
|
||||
float opacity = dmActive ? 0.65 : 0.2;
|
||||
@@ -739,9 +739,10 @@ void AnnotatedCameraWidget::initializeFrogPilotWidgets() {
|
||||
}
|
||||
|
||||
void AnnotatedCameraWidget::updateFrogPilotWidgets(QPainter &p) {
|
||||
alwaysOnLateral = scene.always_on_lateral_active;
|
||||
experimentalMode = scene.experimental_mode;
|
||||
|
||||
if (true) {
|
||||
if (alwaysOnLateral) {
|
||||
drawStatusBar(p);
|
||||
}
|
||||
|
||||
@@ -772,6 +773,10 @@ void AnnotatedCameraWidget::drawStatusBar(QPainter &p) {
|
||||
p.setOpacity(1.0);
|
||||
p.drawRoundedRect(statusBarRect, 30, 30);
|
||||
|
||||
if (alwaysOnLateral) {
|
||||
newStatus = QString("Always On Lateral active") + (". Press the \"Cruise Control\" button to disable");
|
||||
}
|
||||
|
||||
// Check if status has changed
|
||||
if (newStatus != lastShownStatus) {
|
||||
displayStatusText = true;
|
||||
|
||||
@@ -117,6 +117,7 @@ private:
|
||||
|
||||
QHBoxLayout *bottom_layout;
|
||||
|
||||
bool alwaysOnLateral;
|
||||
bool experimentalMode;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -213,6 +213,9 @@ static void update_state(UIState *s) {
|
||||
}
|
||||
if (sm.updated("frogpilotCarControl")) {
|
||||
auto frogpilotCarControl = sm["frogpilotCarControl"].getFrogpilotCarControl();
|
||||
if (scene.always_on_lateral) {
|
||||
scene.always_on_lateral_active = !scene.enabled && frogpilotCarControl.getAlwaysOnLateral();
|
||||
}
|
||||
}
|
||||
if (sm.updated("frogpilotLateralPlan")) {
|
||||
auto frogpilotLateralPlan = sm["frogpilotLateralPlan"].getFrogpilotLateralPlan();
|
||||
@@ -244,6 +247,8 @@ void ui_update_params(UIState *s) {
|
||||
|
||||
// FrogPilot variables
|
||||
UIScene &scene = s->scene;
|
||||
|
||||
scene.always_on_lateral = params.getBool("AlwaysOnLateral");
|
||||
}
|
||||
|
||||
void UIState::updateStatus() {
|
||||
@@ -252,6 +257,8 @@ void UIState::updateStatus() {
|
||||
auto state = controls_state.getState();
|
||||
if (state == cereal::ControlsState::OpenpilotState::PRE_ENABLED || state == cereal::ControlsState::OpenpilotState::OVERRIDING) {
|
||||
status = STATUS_OVERRIDE;
|
||||
} else if (scene.always_on_lateral_active) {
|
||||
status = STATUS_LATERAL_ACTIVE;
|
||||
} else {
|
||||
status = controls_state.getEnabled() ? STATUS_ENGAGED : STATUS_DISENGAGED;
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@ typedef enum UIStatus {
|
||||
STATUS_ENGAGED,
|
||||
|
||||
// FrogPilot statuses
|
||||
STATUS_LATERAL_ACTIVE,
|
||||
} UIStatus;
|
||||
|
||||
enum PrimeType {
|
||||
@@ -125,6 +126,7 @@ const QColor bg_colors [] = {
|
||||
[STATUS_ENGAGED] = QColor(0x17, 0x86, 0x44, 0xf1),
|
||||
|
||||
// FrogPilot colors
|
||||
[STATUS_LATERAL_ACTIVE] = QColor(0x0a, 0xba, 0xb5, 0xf1),
|
||||
};
|
||||
|
||||
static std::map<cereal::ControlsState::AlertStatus, QColor> alert_colors = {
|
||||
@@ -167,6 +169,8 @@ typedef struct UIScene {
|
||||
uint64_t started_frame;
|
||||
|
||||
// FrogPilot variables
|
||||
bool always_on_lateral;
|
||||
bool always_on_lateral_active;
|
||||
bool enabled;
|
||||
bool experimental_mode;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user