horn cooldown adjustments

This commit is contained in:
legop3
2026-01-31 16:16:26 -05:00
parent c24ae71e63
commit 00d1edd11b
5 changed files with 136 additions and 125 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-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" /> <meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
<title>Multi Roomba Rover</title> <title>Multi Roomba Rover</title>
<script type="module" crossorigin src="/assets/index-CoJQOHy3.js"></script> <script type="module" crossorigin src="/assets/index-B4BVCZld.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CQCz6Dh4.css"> <link rel="stylesheet" crossorigin href="/assets/index-CQCz6Dh4.css">
</head> </head>
<body> <body>
+15 -4
View File
@@ -2,7 +2,7 @@ import { createContext, useCallback, useContext, useEffect, useMemo, useReducer,
import { controlReducer, initialControlState } from './controlReducer.js'; import { controlReducer, initialControlState } from './controlReducer.js';
import { computeDifferentialSpeeds, clamp } from './controlMath.js'; import { computeDifferentialSpeeds, clamp } from './controlMath.js';
import { useCommandPipeline } from './commandPipeline.js'; import { useCommandPipeline } from './commandPipeline.js';
import { DEFAULT_KEYMAP, DEFAULT_MACROS, HORN_COOLDOWN_MS, HORN_MAX_MS, SONG_DEFAULT_NOTE } from './constants.js'; import { DEFAULT_KEYMAP, DEFAULT_MACROS, HORN_COOLDOWN_RATIO, HORN_MAX_MS, SONG_DEFAULT_NOTE } from './constants.js';
import { canonicalizeKeyInput } from './keymapUtils.js'; import { canonicalizeKeyInput } from './keymapUtils.js';
import { useSettingsNamespace } from '../settings/index.js'; import { useSettingsNamespace } from '../settings/index.js';
import { useSession } from '../context/SessionContext.jsx'; import { useSession } from '../context/SessionContext.jsx';
@@ -35,6 +35,7 @@ export function ControlSystemProvider({ children }) {
const servoAngleRef = useRef(initialControlState.camera.angle); const servoAngleRef = useRef(initialControlState.camera.angle);
const hornAutoStopRef = useRef(null); const hornAutoStopRef = useRef(null);
const hornCooldownRef = useRef(null); const hornCooldownRef = useRef(null);
const hornStartAtRef = useRef(0);
const { const {
value: controlSettings, value: controlSettings,
save: saveControlSettings, save: saveControlSettings,
@@ -372,6 +373,7 @@ export function ControlSystemProvider({ children }) {
if (state.horn?.active) return false; if (state.horn?.active) return false;
pipeline.sendHorn({ action: 'start', ...normalizedHornSettings }); pipeline.sendHorn({ action: 'start', ...normalizedHornSettings });
dispatch({ type: 'control/set-horn-active', payload: true }); dispatch({ type: 'control/set-horn-active', payload: true });
hornStartAtRef.current = now;
if (hornAutoStopRef.current) { if (hornAutoStopRef.current) {
clearTimeout(hornAutoStopRef.current); clearTimeout(hornAutoStopRef.current);
hornAutoStopRef.current = null; hornAutoStopRef.current = null;
@@ -391,15 +393,24 @@ export function ControlSystemProvider({ children }) {
clearTimeout(hornAutoStopRef.current); clearTimeout(hornAutoStopRef.current);
hornAutoStopRef.current = null; hornAutoStopRef.current = null;
} }
const cooldownUntil = Date.now() + HORN_COOLDOWN_MS; const now = Date.now();
const holdMs = Math.max(0, now - (hornStartAtRef.current || now));
hornStartAtRef.current = 0;
const cooldownMs = Math.max(0, Math.round(holdMs * HORN_COOLDOWN_RATIO));
const cooldownUntil = cooldownMs > 0 ? now + cooldownMs : 0;
dispatch({ type: 'control/set-horn-cooldown', payload: cooldownUntil }); dispatch({ type: 'control/set-horn-cooldown', payload: cooldownUntil });
if (hornCooldownRef.current) { if (hornCooldownRef.current) {
clearTimeout(hornCooldownRef.current); clearTimeout(hornCooldownRef.current);
} }
hornCooldownRef.current = setTimeout(() => { if (cooldownMs > 0) {
hornCooldownRef.current = setTimeout(() => {
dispatch({ type: 'control/set-horn-cooldown', payload: 0 });
hornCooldownRef.current = null;
}, cooldownMs);
} else {
dispatch({ type: 'control/set-horn-cooldown', payload: 0 }); dispatch({ type: 'control/set-horn-cooldown', payload: 0 });
hornCooldownRef.current = null; hornCooldownRef.current = null;
}, HORN_COOLDOWN_MS); }
}, [dispatch, pipeline]); }, [dispatch, pipeline]);
const registerInputState = useCallback((source, data) => { const registerInputState = useCallback((source, data) => {
+1 -1
View File
@@ -18,7 +18,7 @@ export const SONG_DEFAULT_DURATION = 8;
export const SONG_REPEAT_MS = 250; export const SONG_REPEAT_MS = 250;
export const HORN_MAX_MS = 1200; export const HORN_MAX_MS = 1200;
export const HORN_COOLDOWN_MS = 2500; export const HORN_COOLDOWN_RATIO = 0.9;
export const OI_COMMANDS = { export const OI_COMMANDS = {
start: [128], start: [128],