option to disable bumpoff

This commit is contained in:
legop3
2026-03-25 21:43:28 -04:00
parent d74879caa9
commit 904f28eeef
5 changed files with 186 additions and 128 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -11,7 +11,7 @@
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
<title>Multi Roomba Rover</title>
<script type="module" crossorigin src="/assets/index-DNMLDCtc.js"></script>
<script type="module" crossorigin src="/assets/index-DWSaRjmF.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CwUXm7Ls.css">
</head>
<body>
+22
View File
@@ -33,10 +33,15 @@ export default function SettingsPanel() {
hudMapDesktop: false,
connectionTransport: 'websocket',
swapMobileControlColumns: false,
driveMacroBackoffEnabled: true,
});
const { value: audioSettings, save: saveAudioSettings } = useSettingsNamespace('audio', AUDIO_SETTINGS_DEFAULTS);
const connectionTransport = pageSettings?.connectionTransport || 'websocket';
const swapMobileControlColumns = Boolean(pageSettings?.swapMobileControlColumns);
const driveMacroBackoffEnabled =
typeof pageSettings?.driveMacroBackoffEnabled === 'boolean'
? pageSettings.driveMacroBackoffEnabled
: true;
const masterVolume = Number.isFinite(audioSettings?.masterVolume) ? audioSettings.masterVolume : AUDIO_SETTINGS_DEFAULTS.masterVolume;
const alertVolume = Number.isFinite(audioSettings?.alertVolume) ? audioSettings.alertVolume : AUDIO_SETTINGS_DEFAULTS.alertVolume;
const roverVolume = Number.isFinite(audioSettings?.roverVolume) ? audioSettings.roverVolume : AUDIO_SETTINGS_DEFAULTS.roverVolume;
@@ -87,6 +92,11 @@ export default function SettingsPanel() {
const checked = Boolean(event.target.checked);
savePageSettings((current) => ({ ...(current ?? {}), swapMobileControlColumns: checked }));
};
const handleDriveMacroBackoffEnabled = (event) => {
const checked = Boolean(event.target.checked);
savePageSettings((current) => ({ ...(current ?? {}), driveMacroBackoffEnabled: checked }));
};
return (
<Tabs defaultTab="keybindings">
<TabList>
@@ -133,6 +143,18 @@ export default function SettingsPanel() {
<span>Swap control columns (put joystick on the left)</span>
</label>
</section>
<section className="panel-section space-y-0.5 text-sm">
<p className="text-slate-400">Macros</p>
<label className="flex items-center gap-0.5 text-slate-200">
<input
type="checkbox"
className="accent-emerald-500"
checked={driveMacroBackoffEnabled}
onChange={handleDriveMacroBackoffEnabled}
/>
<span>Enable backward bump in drive macro</span>
</label>
</section>
<section className="panel-section space-y-0.5 text-sm">
<p className="text-slate-400">Audio</p>
<label className="grid gap-0.5 text-slate-200">
+38 -2
View File
@@ -36,6 +36,23 @@ function clampServoAngle(config, value) {
return clamp(value, min, max);
}
function removeDriveSequenceBackoff(steps = []) {
if (!Array.isArray(steps) || steps.length < 3) return steps;
const last3 = steps.slice(-3);
const [backoffStep, pauseStep, stopStep] = last3;
const isBackoffStep =
backoffStep?.type === 'drive' &&
Number(backoffStep?.speeds?.left) === -300 &&
Number(backoffStep?.speeds?.right) === -300;
const isPauseStep = pauseStep?.type === 'pause' && Number(pauseStep?.duration) === 600;
const isStopStep =
stopStep?.type === 'drive' &&
Number(stopStep?.speeds?.left) === 0 &&
Number(stopStep?.speeds?.right) === 0;
if (!isBackoffStep || !isPauseStep || !isStopStep) return steps;
return steps.slice(0, -3);
}
export function ControlSystemProvider({ children }) {
const [state, dispatch] = useReducer(controlReducer, initialControlState);
const prevModeRef = useRef(null);
@@ -48,7 +65,12 @@ export function ControlSystemProvider({ children }) {
value: controlSettings,
save: saveControlSettings,
} = useSettingsNamespace('controls', { keymap: DEFAULT_KEYMAP, macros: DEFAULT_MACROS });
const { value: pageSettings } = useSettingsNamespace('page', { driveMacroBackoffEnabled: true });
const { value: hornSettings } = useSettingsNamespace('horn', HORN_SETTINGS_DEFAULTS);
const driveMacroBackoffEnabled =
typeof pageSettings?.driveMacroBackoffEnabled === 'boolean'
? pageSettings.driveMacroBackoffEnabled
: true;
const { session, homeAssistantSetState } = useSession();
const roverId = session?.assignment?.roverId ?? null;
const overcurrentLimiter = useOvercurrentLimiter(roverId);
@@ -280,18 +302,32 @@ export function ControlSystemProvider({ children }) {
async (macroId) => {
const macro = state.macros.find((item) => item.id === macroId) || null;
if (!macro) return;
let macroToRun = macro;
if (macroId === 'drive-sequence') {
turnOnAllLights();
if (!session?.homeAssistant?.entities) {
pendingLightsRef.current = true;
}
recordControlIntent();
if (!driveMacroBackoffEnabled) {
macroToRun = {
...macro,
steps: removeDriveSequenceBackoff(macro.steps),
};
}
} else if (macroId === 'seek-dock') {
recordControlIntent();
}
await pipeline.runMacroSteps(macro);
await pipeline.runMacroSteps(macroToRun);
},
[pipeline, recordControlIntent, session?.homeAssistant?.entities, state.macros, turnOnAllLights],
[
driveMacroBackoffEnabled,
pipeline,
recordControlIntent,
session?.homeAssistant?.entities,
state.macros,
turnOnAllLights,
],
);
const stopAllMotion = useCallback(() => {