mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-20 08:42:11 +08:00
IsRHD
This commit is contained in:
@@ -68,7 +68,9 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"IsMetric", {PERSISTENT, BOOL}},
|
||||
{"IsOffroad", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||
{"IsOnroad", {PERSISTENT, BOOL}},
|
||||
{"IsRHD", {PERSISTENT, BOOL}},
|
||||
{"IsRhdDetected", {PERSISTENT, BOOL}},
|
||||
{"IsRHDOverride", {PERSISTENT, BOOL}},
|
||||
{"IsReleaseBranch", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||
{"IsTakingSnapshot", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||
{"IsTestedBranch", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||
|
||||
@@ -8,6 +8,10 @@ from openpilot.selfdrive.monitoring.helpers import DriverMonitoring
|
||||
GearShifter = structs.CarState.GearShifter
|
||||
|
||||
|
||||
def get_rhd_override(params):
|
||||
return params.get_bool("IsRHD") if params.get_bool("IsRHDOverride") else None
|
||||
|
||||
|
||||
def dmonitoringd_thread():
|
||||
config_realtime_process([0, 1, 2, 3], 5)
|
||||
|
||||
@@ -15,7 +19,11 @@ def dmonitoringd_thread():
|
||||
pm = messaging.PubMaster(['driverMonitoringState'])
|
||||
sm = messaging.SubMaster(['driverStateV2', 'liveCalibration', 'carState', 'selfdriveState', 'modelV2'], poll='driverStateV2')
|
||||
|
||||
DM = DriverMonitoring(rhd_saved=params.get_bool("IsRhdDetected"), always_on=params.get_bool("AlwaysOnDM"))
|
||||
DM = DriverMonitoring(
|
||||
rhd_saved=params.get_bool("IsRhdDetected"),
|
||||
always_on=params.get_bool("AlwaysOnDM"),
|
||||
rhd_override=get_rhd_override(params),
|
||||
)
|
||||
demo_mode=False
|
||||
|
||||
sm = sm.extend(['starpilotCarState'])
|
||||
@@ -44,13 +52,16 @@ def dmonitoringd_thread():
|
||||
# load live always-on toggle
|
||||
if sm['driverStateV2'].frameId % 40 == 1:
|
||||
DM.always_on = params.get_bool("AlwaysOnDM")
|
||||
DM.wheel_on_right_default = params.get_bool("IsRhdDetected")
|
||||
DM.wheel_on_right_override = get_rhd_override(params)
|
||||
demo_mode = params.get_bool("IsDriverViewEnabled") and sm["carState"].gearShifter != GearShifter.reverse
|
||||
|
||||
# save rhd virtual toggle every 5 mins
|
||||
if (sm['driverStateV2'].frameId % 6000 == 0 and not demo_mode and
|
||||
if (DM.wheel_on_right_override is None and sm['driverStateV2'].frameId % 6000 == 0 and not demo_mode and
|
||||
DM.wheelpos.prob_offseter.filtered_stat.n > DM.settings._WHEELPOS_FILTER_MIN_COUNT and
|
||||
DM.wheel_on_right == (DM.wheelpos.prob_offseter.filtered_stat.M > DM.settings._WHEELPOS_THRESHOLD)):
|
||||
params.put_bool_nonblocking("IsRhdDetected", DM.wheel_on_right)
|
||||
params.put_bool_nonblocking("IsRHD", DM.wheel_on_right)
|
||||
|
||||
def main():
|
||||
dmonitoringd_thread()
|
||||
|
||||
@@ -141,7 +141,7 @@ def face_orientation_from_net(angles_desc, pos_desc, rpy_calib):
|
||||
|
||||
|
||||
class DriverMonitoring:
|
||||
def __init__(self, rhd_saved=False, settings=None, always_on=False):
|
||||
def __init__(self, rhd_saved=False, settings=None, always_on=False, rhd_override=None):
|
||||
# init policy settings
|
||||
self.settings = settings if settings is not None else DRIVER_MONITOR_SETTINGS(device_type=HARDWARE.get_device_type())
|
||||
|
||||
@@ -159,6 +159,7 @@ class DriverMonitoring:
|
||||
self.wheel_on_right = False
|
||||
self.wheel_on_right_last = None
|
||||
self.wheel_on_right_default = rhd_saved
|
||||
self.wheel_on_right_override = rhd_override
|
||||
self.face_detected = False
|
||||
self.terminal_alert_cnt = 0
|
||||
self.terminal_time = 0
|
||||
@@ -268,12 +269,15 @@ class DriverMonitoring:
|
||||
self.wheelpos.prob_offseter.push_and_update(rhd_pred)
|
||||
|
||||
self.wheelpos.prob_calibrated = self.wheelpos.prob_offseter.filtered_stat.n > self.settings._WHEELPOS_FILTER_MIN_COUNT
|
||||
if self.wheelpos.prob_calibrated or demo_mode:
|
||||
if self.wheel_on_right_override is not None and not demo_mode:
|
||||
self.wheel_on_right = self.wheel_on_right_override
|
||||
elif self.wheelpos.prob_calibrated or demo_mode:
|
||||
self.wheel_on_right = self.wheelpos.prob_offseter.filtered_stat.M > self.settings._WHEELPOS_THRESHOLD
|
||||
else:
|
||||
self.wheel_on_right = self.wheel_on_right_default # use default/saved if calibration is unfinished
|
||||
# make sure no switching when engaged
|
||||
if op_engaged and self.wheel_on_right_last is not None and self.wheel_on_right_last != self.wheel_on_right and not demo_mode:
|
||||
if (self.wheel_on_right_override is None and op_engaged and self.wheel_on_right_last is not None and
|
||||
self.wheel_on_right_last != self.wheel_on_right and not demo_mode):
|
||||
self.wheel_on_right = self.wheel_on_right_last
|
||||
driver_data = driver_state.rightDriverData if self.wheel_on_right else driver_state.leftDriverData
|
||||
if not all(len(x) > 0 for x in (driver_data.faceOrientation, driver_data.facePosition,
|
||||
|
||||
@@ -66,6 +66,15 @@ class TestMonitoring:
|
||||
def _assert_no_events(self, events):
|
||||
assert all(not len(e) for e in events)
|
||||
|
||||
def test_rhd_manual_override_beats_saved_default(self):
|
||||
DM = DriverMonitoring(rhd_saved=False, rhd_override=True)
|
||||
DM._update_states(msg_ATTENTIVE, [0, 0, 0], 0, False, False)
|
||||
assert DM.wheel_on_right
|
||||
|
||||
DM = DriverMonitoring(rhd_saved=True, rhd_override=False)
|
||||
DM._update_states(msg_ATTENTIVE, [0, 0, 0], 0, False, False)
|
||||
assert not DM.wheel_on_right
|
||||
|
||||
# engaged, driver is attentive all the time
|
||||
def test_fully_aware_driver(self):
|
||||
events, _ = self._run_seq(always_attentive, always_false, always_true, always_false)
|
||||
|
||||
@@ -23,6 +23,7 @@ from openpilot.system.ui.widgets.scroller_tici import Scroller
|
||||
DESCRIPTIONS = {
|
||||
'pair_device': tr_noop("Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer."),
|
||||
'driver_camera': tr_noop("Preview the driver facing camera to ensure that driver monitoring has good visibility. (vehicle must be off)"),
|
||||
'reset_driver_monitoring': tr_noop("Clears the saved driver monitoring wheel-side calibration and any manual right-hand-driving override."),
|
||||
'reset_calibration': tr_noop("openpilot requires the device to be mounted within 4° left or right and within 5° up or 9° down."),
|
||||
'review_guide': tr_noop("Review the rules, features, and limitations of openpilot"),
|
||||
}
|
||||
@@ -61,6 +62,8 @@ class DeviceLayout(Widget):
|
||||
self._pair_device_btn,
|
||||
button_item(lambda: tr("Driver Camera"), lambda: tr("PREVIEW"), lambda: tr(DESCRIPTIONS['driver_camera']),
|
||||
callback=self._show_driver_camera, enabled=ui_state.is_offroad),
|
||||
button_item(lambda: tr("Reset Driver Monitoring"), lambda: tr("RESET"), lambda: tr(DESCRIPTIONS['reset_driver_monitoring']),
|
||||
callback=self._reset_driver_monitoring_prompt, enabled=ui_state.is_offroad),
|
||||
self._reset_calib_btn,
|
||||
button_item(lambda: tr("Review Training Guide"), lambda: tr("REVIEW"), lambda: tr(DESCRIPTIONS['review_guide']),
|
||||
self._on_review_training_guide, enabled=ui_state.is_offroad),
|
||||
@@ -119,6 +122,23 @@ class DeviceLayout(Widget):
|
||||
dialog = ConfirmDialog(tr("Are you sure you want to reset calibration?"), tr("Reset"))
|
||||
gui_app.set_modal_overlay(dialog, callback=reset_calibration)
|
||||
|
||||
def _reset_driver_monitoring_prompt(self):
|
||||
if ui_state.engaged:
|
||||
gui_app.set_modal_overlay(alert_dialog(tr("Disengage to Reset Driver Monitoring")))
|
||||
return
|
||||
|
||||
def reset_driver_monitoring(result: int):
|
||||
if ui_state.engaged or result != DialogResult.CONFIRM:
|
||||
return
|
||||
|
||||
self._params.remove("IsRhdDetected")
|
||||
self._params.remove("IsRHD")
|
||||
self._params.remove("IsRHDOverride")
|
||||
self._params.put_bool("OnroadCycleRequested", True)
|
||||
|
||||
dialog = ConfirmDialog(tr("Are you sure you want to reset driver monitoring calibration?"), tr("Reset"))
|
||||
gui_app.set_modal_overlay(dialog, callback=reset_driver_monitoring)
|
||||
|
||||
def _update_calib_description(self):
|
||||
desc = tr(DESCRIPTIONS['reset_calibration'])
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ DESCRIPTIONS = {
|
||||
),
|
||||
"AlwaysOnDM": tr_noop("Enable driver monitoring even when openpilot is not engaged."),
|
||||
'RecordFront': tr_noop("Upload data from the driver facing camera and help improve the driver monitoring algorithm."),
|
||||
"IsRHD": tr_noop("Use right-hand-drive driver monitoring. This follows the auto-detected side until changed manually."),
|
||||
"IsMetric": tr_noop("Display speed in km/h instead of mph."),
|
||||
"RecordAudio": tr_noop("Record and store microphone audio while driving. The audio will be included in the dashcam video in comma connect."),
|
||||
}
|
||||
@@ -38,6 +39,7 @@ class TogglesLayout(Widget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._params = Params()
|
||||
self._sync_rhd_toggle()
|
||||
|
||||
# param, title, desc, icon, needs_restart
|
||||
self._toggle_defs = {
|
||||
@@ -77,6 +79,12 @@ class TogglesLayout(Widget):
|
||||
"monitoring.png",
|
||||
False,
|
||||
),
|
||||
"IsRHD": (
|
||||
lambda: tr("Right Hand Driving"),
|
||||
DESCRIPTIONS["IsRHD"],
|
||||
"monitoring.png",
|
||||
False,
|
||||
),
|
||||
"RecordFront": (
|
||||
lambda: tr("Record and Upload Driver Camera"),
|
||||
DESCRIPTIONS["RecordFront"],
|
||||
@@ -158,6 +166,7 @@ class TogglesLayout(Widget):
|
||||
|
||||
def _update_toggles(self):
|
||||
ui_state.update_params()
|
||||
self._sync_rhd_toggle()
|
||||
safe_mode = self._params.get_bool("SafeMode")
|
||||
if safe_mode:
|
||||
if self._params.get_bool("ExperimentalMode"):
|
||||
@@ -246,8 +255,14 @@ class TogglesLayout(Widget):
|
||||
return
|
||||
|
||||
self._params.put_bool(param, state)
|
||||
if param == "IsRHD":
|
||||
self._params.put_bool("IsRHDOverride", True)
|
||||
if self._toggle_defs[param][3]:
|
||||
self._params.put_bool("OnroadCycleRequested", True)
|
||||
|
||||
def _set_longitudinal_personality(self, button_index: int):
|
||||
self._params.put("LongitudinalPersonality", button_index)
|
||||
|
||||
def _sync_rhd_toggle(self):
|
||||
if not self._params.get_bool("IsRHDOverride"):
|
||||
self._params.put_bool("IsRHD", self._params.get_bool("IsRhdDetected"))
|
||||
|
||||
@@ -370,6 +370,8 @@ class DeviceLayoutMici(NavScroller):
|
||||
def reset_driver_monitoring_callback():
|
||||
params = ui_state.params
|
||||
params.remove("IsRhdDetected")
|
||||
params.remove("IsRHD")
|
||||
params.remove("IsRHDOverride")
|
||||
params.put_bool("OnroadCycleRequested", True)
|
||||
|
||||
def uninstall_openpilot_callback():
|
||||
|
||||
@@ -12,6 +12,11 @@ PERSONALITY_TO_INT = log.LongitudinalPersonality.schema.enumerants
|
||||
class TogglesLayoutMici(NavScroller):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._sync_rhd_toggle()
|
||||
|
||||
def rhd_toggle_callback(checked: bool):
|
||||
ui_state.params.put_bool("IsRHD", checked)
|
||||
ui_state.params.put_bool("IsRHDOverride", True)
|
||||
|
||||
self._personality_toggle = BigMultiParamToggle("driving personality", "LongitudinalPersonality", ["aggressive", "standard", "relaxed"])
|
||||
self._safe_mode_btn = BigParamControl("safe mode", "SafeMode", toggle_callback=restart_needed_callback)
|
||||
@@ -19,6 +24,7 @@ class TogglesLayoutMici(NavScroller):
|
||||
is_metric_toggle = BigParamControl("use metric units", "IsMetric")
|
||||
ldw_toggle = BigParamControl("lane departure warnings", "IsLdwEnabled")
|
||||
always_on_dm_toggle = BigParamControl("always-on driver monitor", "AlwaysOnDM")
|
||||
rhd_toggle = BigParamControl("right hand driving", "IsRHD", toggle_callback=rhd_toggle_callback)
|
||||
record_front = BigParamControl("record & upload driver camera", "RecordFront", toggle_callback=restart_needed_callback)
|
||||
record_mic = BigParamControl("record & upload mic audio", "RecordAudio", toggle_callback=restart_needed_callback)
|
||||
enable_openpilot = BigParamControl("enable openpilot", "OpenpilotEnabledToggle", toggle_callback=restart_needed_callback)
|
||||
@@ -30,6 +36,7 @@ class TogglesLayoutMici(NavScroller):
|
||||
is_metric_toggle,
|
||||
ldw_toggle,
|
||||
always_on_dm_toggle,
|
||||
rhd_toggle,
|
||||
record_front,
|
||||
record_mic,
|
||||
enable_openpilot,
|
||||
@@ -42,6 +49,7 @@ class TogglesLayoutMici(NavScroller):
|
||||
("IsMetric", is_metric_toggle),
|
||||
("IsLdwEnabled", ldw_toggle),
|
||||
("AlwaysOnDM", always_on_dm_toggle),
|
||||
("IsRHD", rhd_toggle),
|
||||
("RecordFront", record_front),
|
||||
("RecordAudio", record_mic),
|
||||
("OpenpilotEnabledToggle", enable_openpilot),
|
||||
@@ -72,6 +80,7 @@ class TogglesLayoutMici(NavScroller):
|
||||
|
||||
def _update_toggles(self):
|
||||
ui_state.update_params()
|
||||
self._sync_rhd_toggle()
|
||||
safe_mode = ui_state.params.get_bool("SafeMode")
|
||||
self._experimental_btn.set_enabled(not safe_mode)
|
||||
self._personality_toggle.set_enabled(not safe_mode)
|
||||
@@ -100,3 +109,7 @@ class TogglesLayoutMici(NavScroller):
|
||||
# Refresh toggles from params to mirror external changes
|
||||
for key, item in self._refresh_toggles:
|
||||
item.set_checked(ui_state.params.get_bool(key))
|
||||
|
||||
def _sync_rhd_toggle(self):
|
||||
if not ui_state.params.get_bool("IsRHDOverride"):
|
||||
ui_state.params.put_bool("IsRHD", ui_state.params.get_bool("IsRhdDetected"))
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "starpilot/ui/qt/offroad/starpilot_settings.h"
|
||||
|
||||
TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
syncRhdToggle();
|
||||
|
||||
// param, title, desc, icon, restart needed
|
||||
std::vector<std::tuple<QString, QString, QString, QString, bool>> toggle_defs{
|
||||
{
|
||||
@@ -76,6 +78,13 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
"../assets/icons/monitoring.png",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"IsRHD",
|
||||
tr("Right Hand Driving"),
|
||||
tr("Use right-hand-drive driver monitoring. This follows the auto-detected side until changed manually."),
|
||||
"../assets/icons/monitoring.png",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"RecordFront",
|
||||
tr("Record and Upload Driver Camera"),
|
||||
@@ -136,6 +145,13 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
});
|
||||
}
|
||||
|
||||
if (param == "IsRHD") {
|
||||
QObject::connect(toggle, &ParamControl::toggleFlipped, this, [this](bool state) {
|
||||
params.putBool("IsRHD", state);
|
||||
params.putBool("IsRHDOverride", true);
|
||||
});
|
||||
}
|
||||
|
||||
addItem(toggle);
|
||||
toggles[param.toStdString()] = toggle;
|
||||
|
||||
@@ -154,6 +170,12 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
});
|
||||
}
|
||||
|
||||
void TogglesPanel::syncRhdToggle() {
|
||||
if (!params.getBool("IsRHDOverride")) {
|
||||
params.putBool("IsRHD", params.getBool("IsRhdDetected"));
|
||||
}
|
||||
}
|
||||
|
||||
void TogglesPanel::updateState(const UIState &s) {
|
||||
const SubMaster &sm = *(s.sm);
|
||||
|
||||
@@ -184,6 +206,8 @@ void TogglesPanel::showEvent(QShowEvent *event) {
|
||||
}
|
||||
|
||||
void TogglesPanel::updateToggles() {
|
||||
syncRhdToggle();
|
||||
|
||||
const bool showAllToggles = params.getBool("ShowAllToggles");
|
||||
const bool safe_mode = params.getBool("SafeMode");
|
||||
const bool simple_mode = params.getBool("SimpleMode");
|
||||
@@ -266,6 +290,7 @@ void TogglesPanel::updateToggles() {
|
||||
experimental_mode_toggle->setVisible(showAllToggles || !starpilot_toggles.value("conditional_experimental_mode").toBool());
|
||||
auto record_audio_toggle = toggles["RecordAudio"];
|
||||
record_audio_toggle->setVisible(showAllToggles || !starpilot_toggles.value("no_logging").toBool());
|
||||
toggles["IsRHD"]->refresh();
|
||||
|
||||
auto safe_mode_toggle = toggles["SafeMode"];
|
||||
if (safe_mode_toggle != nullptr) {
|
||||
@@ -410,7 +435,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
resetDmCalibBtn = new ButtonControl(
|
||||
tr("Reset Driver Monitoring"),
|
||||
tr("RESET"),
|
||||
tr("Clears the saved driver monitoring wheel-side calibration if the device thinks you're seated on the wrong side. "
|
||||
tr("Clears the saved driver monitoring wheel-side calibration and any manual right-hand-driving override if the device thinks you're seated on the wrong side. "
|
||||
"Resetting will restart openpilot if the car is powered on.")
|
||||
);
|
||||
connect(resetDmCalibBtn, &ButtonControl::clicked, [&]() {
|
||||
@@ -418,6 +443,8 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
if (ConfirmationDialog::confirm(tr("Are you sure you want to reset driver monitoring calibration?"), tr("Reset"), this)) {
|
||||
if (!uiState()->engaged()) {
|
||||
params.remove("IsRhdDetected");
|
||||
params.remove("IsRHD");
|
||||
params.remove("IsRHDOverride");
|
||||
params.putBool("OnroadCycleRequested", true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +116,7 @@ private:
|
||||
std::map<std::string, ParamControl*> toggles;
|
||||
ButtonParamControl *long_personality_setting;
|
||||
|
||||
void syncRhdToggle();
|
||||
void updateToggles();
|
||||
};
|
||||
|
||||
|
||||
@@ -644,6 +644,31 @@ async function updateParam(key, elType) {
|
||||
}
|
||||
}
|
||||
|
||||
async function restoreRhdAutoDetection() {
|
||||
const currentValues = { ...state.values }
|
||||
try {
|
||||
const res = await fetch("/api/params", {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ key: "IsRHDOverride", value: false }),
|
||||
})
|
||||
const data = await res.json()
|
||||
|
||||
if (res.ok) {
|
||||
const updated = (data.updated && typeof data.updated === "object") ? data.updated : {}
|
||||
state.values = { ...state.values, IsRHDOverride: false, ...updated }
|
||||
showParamSnackbar(data.message || "Right Hand Driving auto detection restored.")
|
||||
scheduleSyncInputs()
|
||||
} else {
|
||||
state.values = currentValues
|
||||
showParamSnackbar(data.error || "Failed to restore auto detection", "error")
|
||||
}
|
||||
} catch (e) {
|
||||
state.values = currentValues
|
||||
showParamSnackbar("Network error — is the device reachable?", "error")
|
||||
}
|
||||
}
|
||||
|
||||
function revertInput(key, current, elType) {
|
||||
const el = document.getElementById(`ds-${key}`)
|
||||
if (!el) return
|
||||
@@ -847,13 +872,30 @@ function renderSettingRow(p) {
|
||||
</div>
|
||||
`
|
||||
} else if (!isGroup) {
|
||||
rowControl = html`
|
||||
<input
|
||||
type="checkbox"
|
||||
class="ds-toggle"
|
||||
id="ds-${p.key}"
|
||||
@change="${() => updateParam(p.key, "checkbox")}" />
|
||||
`
|
||||
if (p.key === "IsRHD") {
|
||||
rowControl = html`
|
||||
<div style="display:flex; align-items:center; gap:0.75rem;">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="ds-toggle"
|
||||
id="ds-${p.key}"
|
||||
@change="${() => updateParam(p.key, "checkbox")}" />
|
||||
${() => state.values.IsRHDOverride ? html`
|
||||
<button
|
||||
class="ds-reset-btn"
|
||||
@click="${restoreRhdAutoDetection}">Auto</button>
|
||||
` : ""}
|
||||
</div>
|
||||
`
|
||||
} else {
|
||||
rowControl = html`
|
||||
<input
|
||||
type="checkbox"
|
||||
class="ds-toggle"
|
||||
id="ds-${p.key}"
|
||||
@change="${() => updateParam(p.key, "checkbox")}" />
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
return html`
|
||||
|
||||
@@ -2187,6 +2187,13 @@
|
||||
"data_type": "bool",
|
||||
"ui_type": "toggle"
|
||||
},
|
||||
{
|
||||
"key": "IsRHD",
|
||||
"label": "Right Hand Driving",
|
||||
"description": "Use right-hand-drive driver monitoring. This follows the auto-detected side until changed manually.",
|
||||
"data_type": "bool",
|
||||
"ui_type": "toggle"
|
||||
},
|
||||
{
|
||||
"key": "DisableOpenpilotLongitudinal",
|
||||
"label": "Disable openpilot Longitudinal",
|
||||
|
||||
@@ -2029,6 +2029,8 @@ _cached_param_types = None
|
||||
_cached_default_values = None
|
||||
_cached_static_default_values = None
|
||||
|
||||
POND_MANUAL_BOOL_PARAM_KEYS = {"IsRHD", "IsRHDOverride"}
|
||||
|
||||
def _get_param_type_info():
|
||||
global _cached_allowed_keys, _cached_param_types
|
||||
if _cached_allowed_keys is None:
|
||||
@@ -2049,6 +2051,12 @@ def _get_param_type_info():
|
||||
for k, dt in _get_layout_type_overrides().items():
|
||||
if k in types and dt in ("int", "float") and types[k] == bool:
|
||||
types[k] = float if dt == "float" else int
|
||||
elif k in types and dt == "bool":
|
||||
types[k] = bool
|
||||
|
||||
for k in POND_MANUAL_BOOL_PARAM_KEYS:
|
||||
if k in _cached_allowed_keys:
|
||||
types[k] = bool
|
||||
|
||||
# Keep legacy aliases editable for older payloads/UI clients.
|
||||
alias_to_key = {
|
||||
@@ -2223,6 +2231,9 @@ def _get_current_param_value(key, value_type, defaults_lookup=None):
|
||||
if key == CUSTOM_ACCEL_PROFILE_INITIALIZED_KEY:
|
||||
return _get_custom_accel_profile_initialized()
|
||||
|
||||
if key == "IsRHD" and not _safe_params_get_bool("IsRHDOverride"):
|
||||
return _safe_params_get_bool("IsRhdDetected")
|
||||
|
||||
if key in CUSTOM_ACCEL_PROFILE_PARAM_KEYS and not _get_custom_accel_profile_initialized():
|
||||
if defaults_lookup is None:
|
||||
defaults_lookup = _get_default_param_values()
|
||||
@@ -3790,6 +3801,32 @@ def setup(app):
|
||||
},
|
||||
}), 200
|
||||
|
||||
if key == "IsRHD":
|
||||
enabled = str_val.strip() in ("1", "true", "True")
|
||||
params.put_bool("IsRHD", enabled)
|
||||
params.put_bool("IsRHDOverride", True)
|
||||
return jsonify({
|
||||
"message": "Right Hand Driving override updated successfully.",
|
||||
"updated": {
|
||||
"IsRHD": enabled,
|
||||
"IsRHDOverride": True,
|
||||
},
|
||||
}), 200
|
||||
|
||||
if key == "IsRHDOverride":
|
||||
enabled = str_val.strip() in ("1", "true", "True")
|
||||
params.put_bool("IsRHDOverride", enabled)
|
||||
updated = {"IsRHDOverride": enabled}
|
||||
if not enabled:
|
||||
auto_rhd = params.get_bool("IsRhdDetected")
|
||||
params.put_bool("IsRHD", auto_rhd)
|
||||
updated["IsRHD"] = auto_rhd
|
||||
|
||||
return jsonify({
|
||||
"message": "Right Hand Driving auto detection restored." if not enabled else "Right Hand Driving override enabled.",
|
||||
"updated": updated,
|
||||
}), 200
|
||||
|
||||
if key == "CarMake":
|
||||
catalog = _get_fingerprint_catalog()
|
||||
normalized_make = _normalize_fingerprint_make_key(str_val)
|
||||
@@ -3933,6 +3970,8 @@ def setup(app):
|
||||
return _serialize_param_write_value(defaults_lookup.get(request_key)), 200
|
||||
if request_key == CUSTOM_ACCEL_PROFILE_INITIALIZED_KEY:
|
||||
return _serialize_param_write_value(_get_custom_accel_profile_initialized()), 200
|
||||
if request_key == "IsRHD" and not params.get_bool("IsRHDOverride"):
|
||||
return ("1" if params.get_bool("IsRhdDetected") else "0"), 200
|
||||
value = params.get(request_key) or ""
|
||||
if request_key in ("Model", "DrivingModel"):
|
||||
if isinstance(value, bytes):
|
||||
|
||||
@@ -50,6 +50,13 @@ INJECTED_SECTION_PARAMS = {
|
||||
"data_type": "bool",
|
||||
"ui_type": "toggle",
|
||||
},
|
||||
{
|
||||
"key": "IsRHD",
|
||||
"label": "Right Hand Driving",
|
||||
"description": "Use right-hand-drive driver monitoring. This follows the auto-detected side until changed manually.",
|
||||
"data_type": "bool",
|
||||
"ui_type": "toggle",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user