Pond Updates

This commit is contained in:
firestar5683
2026-03-08 17:32:27 -05:00
parent 283e9b1d78
commit 5ca3f503ee
5 changed files with 150 additions and 22 deletions
@@ -43,6 +43,13 @@
}
/* ――― Search / Filter ――― */
.ds-search-row {
align-items: center;
display: flex;
gap: 0.5rem;
margin-bottom: var(--margin-lg);
}
.ds-search {
background-color: var(--input-bg);
border: var(--border-style-input);
@@ -51,17 +58,37 @@
color: var(--text-color);
font-family: var(--font-body);
font-size: var(--font-size-base);
margin-bottom: var(--margin-lg);
margin-bottom: 0;
outline: none;
padding: var(--padding-sm) var(--padding-base);
transition: box-shadow var(--transition-fast);
width: 100%;
flex: 1;
}
.ds-search:focus {
box-shadow: 0 0 0 2px var(--main-fg);
}
.ds-search-clear {
background: var(--input-bg);
border: var(--border-style-main);
border-radius: var(--border-radius-base);
color: var(--text-color);
cursor: pointer;
font-family: var(--font-body);
font-size: var(--font-size-sm);
min-width: 4.75rem;
padding: 0.6rem 0.8rem;
transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.ds-search-clear:hover {
background: var(--main-fg);
border-color: var(--main-fg);
color: var(--color-black);
}
/* ――― Section Cards ――― */
.ds-section {
background-color: var(--secondary-bg);
@@ -397,6 +424,15 @@
padding: var(--padding-sm) var(--padding-base) var(--padding-xl);
}
.ds-search-row {
align-items: stretch;
flex-direction: column;
}
.ds-search-clear {
width: 100%;
}
.ds-tabs {
flex-wrap: nowrap;
overflow-x: auto;
@@ -1,5 +1,4 @@
import { html, reactive } from "https://esm.sh/@arrow-js/core"
import { Navigate } from "/assets/components/router.js"
const endpointOptionsCache = {}
const endpointOptionsInflight = {}
@@ -501,6 +500,29 @@ function matchesFilter(p) {
return p.label.toLowerCase().includes(q) || p.key.toLowerCase().includes(q)
}
function clearSearchFilter() {
if (!state.filter) return
state.filter = ""
scheduleSyncInputs()
}
function handleSectionTabClick(sectionSlug, event) {
if (!sectionSlug || sectionSlug === state.activeSectionSlug) return
// Preserve horizontal tab strip position on mobile when switching sections.
const tabsEl = event?.currentTarget?.closest(".ds-tabs")
const preservedScrollLeft = tabsEl ? tabsEl.scrollLeft : null
state.activeSectionSlug = sectionSlug
if (preservedScrollLeft !== null) {
requestAnimationFrame(() => {
const nextTabsEl = document.getElementById("ds-tabs")
if (nextTabsEl) nextTabsEl.scrollLeft = preservedScrollLeft
})
}
}
function renderSettingRow(p) {
if (p.parent_key && !state.filter) {
if (!state.values[p.parent_key]) return ""
@@ -619,14 +641,27 @@ export function DeviceSettings({ params }) {
<div class="ds-wrapper">
<h2>Toggles</h2>
<input
class="ds-search"
type="text"
placeholder="Search settings..."
@input="${(e) => {
state.filter = e.target.value
scheduleSyncInputs()
}}" />
<div class="ds-search-row">
<input
class="ds-search"
type="text"
placeholder="Search settings..."
value="${() => state.filter}"
@keydown="${(e) => {
if (e.key === "Escape") clearSearchFilter()
}}"
@input="${(e) => {
state.filter = e.target.value
scheduleSyncInputs()
}}" />
${() => state.filter ? html`
<button
class="ds-search-clear"
@click="${() => clearSearchFilter()}">
Clear
</button>
` : ""}
</div>
${() => {
if (state.loadingLayout || state.loadingValues) {
@@ -678,14 +713,12 @@ export function DeviceSettings({ params }) {
const visibleParams = activeSection.params.filter(p => matchesFilter(p))
return html`
<div class="ds-tabs">
<div class="ds-tabs" id="ds-tabs">
${sections.map(section => html`
<button
class="ds-tab ${section.slug === state.activeSectionSlug ? "active" : ""}"
@click="${() => {
if (section.slug !== state.activeSectionSlug) {
Navigate("/device_settings/" + section.slug)
}
@click="${(e) => {
handleSectionTabClick(section.slug, e)
}}">
<i class="bi ${section.icon}"></i>
<span>${section.name}</span>
@@ -811,12 +811,52 @@
"ui_type": "toggle",
"is_parent_toggle": true
},
{
"key": "AccelerationProfile",
"label": "Acceleration Profile",
"description": "How quickly openpilot speeds up: Eco, Normal, Sport, or Sport+.",
"data_type": "int",
"ui_type": "dropdown",
"options": [
{
"value": 0,
"label": "Normal"
},
{
"value": 1,
"label": "Eco"
},
{
"value": 2,
"label": "Sport"
},
{
"value": 3,
"label": "Sport+"
}
],
"parent_key": "LongitudinalTune"
},
{
"key": "DecelerationProfile",
"label": "Deceleration Profile",
"description": "How firmly openpilot slows down. \"Eco\" favors",
"data_type": "bool",
"ui_type": "toggle",
"description": "How firmly openpilot slows down: Eco, Normal, or Sport.",
"data_type": "int",
"ui_type": "dropdown",
"options": [
{
"value": 0,
"label": "Normal"
},
{
"value": 1,
"label": "Eco"
},
{
"value": 2,
"label": "Sport"
}
],
"parent_key": "LongitudinalTune"
},
{
+19 -1
View File
@@ -183,6 +183,8 @@ _fast_update_state = {
}
_PLOTS_POLL_INTERVAL_S = 0.5
_PLOTS_BOOT_STABILIZATION_WINDOW_S = 45.0
_PLOTS_BOOT_POLL_INTERVAL_S = 1.0
_PLOTS_CLIENT_IDLE_TIMEOUT_S = 15.0
_PLOTS_SAMPLE_STALE_AFTER_S = 1.5
@@ -220,6 +222,18 @@ def _safe_float(value, default=0.0):
except Exception:
return float(default)
def _get_system_uptime_seconds():
try:
with open("/proc/uptime", "r", encoding="utf-8") as uptime_file:
return _safe_float((uptime_file.read().split() or ["0"])[0], 0.0)
except Exception:
return 0.0
def _is_plots_boot_stabilizing():
if not params.get_bool("IsOnroad"):
return False
return _get_system_uptime_seconds() < _PLOTS_BOOT_STABILIZATION_WINDOW_S
def _extract_lateral_accel_values(controls_state, speed_mps):
v_ego = max(0.0, _safe_float(speed_mps))
speed_sq = v_ego * v_ego
@@ -353,7 +367,10 @@ def _plots_worker():
with _plots_lock:
_plots_state["lastError"] = str(exception)
time.sleep(_PLOTS_POLL_INTERVAL_S)
sleep_interval = _PLOTS_POLL_INTERVAL_S
if _is_plots_boot_stabilizing():
sleep_interval = max(_PLOTS_POLL_INTERVAL_S, _PLOTS_BOOT_POLL_INTERVAL_S)
time.sleep(sleep_interval)
with _plots_lock:
_plots_worker_thread = None
@@ -2547,6 +2564,7 @@ def setup(app):
return jsonify({
**payload,
"isOnroad": params.get_bool("IsOnroad"),
"bootStabilizing": _is_plots_boot_stabilizing(),
"sampleAgeSeconds": round(age_seconds, 3),
"stale": age_seconds > _PLOTS_SAMPLE_STALE_AFTER_S,
}), 200
+4 -3
View File
@@ -121,9 +121,10 @@ procs = [
PythonProcess("frogpilot_process", "frogpilot.frogpilot_process", always_run),
PythonProcess("mapd", "frogpilot.navigation.mapd", always_run),
PythonProcess("speed_limit_filler", "frogpilot.system.speed_limit_filler", run_speed_limit_filler),
# Lower priority so onroad processes win CPU time if The Pond is busy.
PythonProcess("the_pond", "frogpilot.system.the_pond.the_pond", always_run, nice=15),
PythonProcess("galaxy", "frogpilot.system.galaxy.galaxy", always_run),
# Keep remote UI/tunnel services at the lowest scheduling priority so
# driving-critical processes always win CPU under startup or onroad load.
PythonProcess("the_pond", "frogpilot.system.the_pond.the_pond", always_run, nice=19),
PythonProcess("galaxy", "frogpilot.system.galaxy.galaxy", always_run, nice=19),
PythonProcess("tinygrad_modeld", "frogpilot.tinygrad_modeld.tinygrad_modeld", run_tinygrad_modeld),
]