mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 17:40:46 -04:00
manual docking mode real life testing
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
HORN_HEAT_RESUME_THRESHOLD,
|
||||
HORN_HEAT_UP_PER_SEC,
|
||||
HORN_MAX_MS,
|
||||
MANUAL_DOCK_ASSIST_MAX_SPEED,
|
||||
SONG_DEFAULT_NOTE,
|
||||
} from './constants.js';
|
||||
import { canonicalizeKeyInput } from './keymapUtils.js';
|
||||
@@ -212,7 +213,23 @@ export function ControlSystemProvider({ children }) {
|
||||
|
||||
const setDriveVector = useCallback(
|
||||
(vector, meta = {}) => {
|
||||
const computed = computeDifferentialSpeeds(vector, meta.speedOptions);
|
||||
const speedOptions = { ...(meta.speedOptions || {}) };
|
||||
if (state.manualDockAssist?.active) {
|
||||
const capped = Math.max(1, Math.min(MANUAL_DOCK_ASSIST_MAX_SPEED, 500));
|
||||
speedOptions.maxSpeed = Math.min(
|
||||
typeof speedOptions.maxSpeed === 'number' ? speedOptions.maxSpeed : capped,
|
||||
capped,
|
||||
);
|
||||
speedOptions.baseSpeed = Math.min(
|
||||
typeof speedOptions.baseSpeed === 'number' ? speedOptions.baseSpeed : capped,
|
||||
capped,
|
||||
);
|
||||
speedOptions.boostSpeed = Math.min(
|
||||
typeof speedOptions.boostSpeed === 'number' ? speedOptions.boostSpeed : capped,
|
||||
capped,
|
||||
);
|
||||
}
|
||||
const computed = computeDifferentialSpeeds(vector, speedOptions);
|
||||
dispatch({
|
||||
type: 'control/update-drive',
|
||||
payload: { ...computed, source: meta.source ?? null },
|
||||
@@ -220,7 +237,7 @@ export function ControlSystemProvider({ children }) {
|
||||
recordControlIntent();
|
||||
pipeline.sendDriveDirect(computed.speeds);
|
||||
},
|
||||
[pipeline, recordControlIntent],
|
||||
[pipeline, recordControlIntent, state.manualDockAssist?.active],
|
||||
);
|
||||
|
||||
const setAuxMotors = useCallback(
|
||||
@@ -318,8 +335,6 @@ export function ControlSystemProvider({ children }) {
|
||||
steps: removeDriveSequenceBackoff(macro.steps),
|
||||
};
|
||||
}
|
||||
} else if (macroId === 'seek-dock') {
|
||||
recordControlIntent();
|
||||
}
|
||||
await pipeline.runMacroSteps(macroToRun);
|
||||
},
|
||||
@@ -509,6 +524,28 @@ export function ControlSystemProvider({ children }) {
|
||||
return () => clearInterval(interval);
|
||||
}, [dispatch, hornNeedsTick, HORN_HEAT_COOL_PER_SEC, HORN_HEAT_RESUME_THRESHOLD, HORN_HEAT_UP_PER_SEC]);
|
||||
|
||||
const setManualDockAssistActive = useCallback(
|
||||
(active) => {
|
||||
const nextActive = Boolean(active);
|
||||
const prevActive = Boolean(state.manualDockAssist?.active);
|
||||
if (prevActive === nextActive) return;
|
||||
dispatch({ type: 'control/set-manual-dock-assist', payload: nextActive });
|
||||
if (!nextActive) return;
|
||||
const minAngle =
|
||||
typeof pipeline.servoConfig?.minAngle === 'number'
|
||||
? pipeline.servoConfig.minAngle
|
||||
: -45;
|
||||
setServoAngle(minAngle);
|
||||
pipeline.sendSong([{ note: 76, duration: 10 }, { note: 83, duration: 10 }], { slot: 0 });
|
||||
recordControlIntent();
|
||||
},
|
||||
[pipeline, recordControlIntent, setServoAngle, state.manualDockAssist?.active],
|
||||
);
|
||||
|
||||
const toggleManualDockAssist = useCallback(() => {
|
||||
setManualDockAssistActive(!state.manualDockAssist?.active);
|
||||
}, [setManualDockAssistActive, state.manualDockAssist?.active]);
|
||||
|
||||
const registerInputState = useCallback((source, data) => {
|
||||
dispatch({ type: 'control/register-input-state', payload: { source, state: data } });
|
||||
}, []);
|
||||
@@ -539,6 +576,8 @@ export function ControlSystemProvider({ children }) {
|
||||
updateKeyBinding,
|
||||
resetKeyBindings,
|
||||
registerInputState,
|
||||
setManualDockAssistActive,
|
||||
toggleManualDockAssist,
|
||||
setSongNote,
|
||||
sendSong,
|
||||
startHorn,
|
||||
@@ -565,6 +604,8 @@ export function ControlSystemProvider({ children }) {
|
||||
updateKeyBinding,
|
||||
resetKeyBindings,
|
||||
registerInputState,
|
||||
setManualDockAssistActive,
|
||||
toggleManualDockAssist,
|
||||
setSongNote,
|
||||
sendSong,
|
||||
startHorn,
|
||||
|
||||
@@ -12,6 +12,8 @@ export const DRIVE_LIMITS = {
|
||||
boostSpeed: 400,
|
||||
};
|
||||
|
||||
export const MANUAL_DOCK_ASSIST_MAX_SPEED = 110;
|
||||
|
||||
export const COMMAND_DELAY_MS = 100;
|
||||
|
||||
export const SONG_NOTE_RANGE = [31, 127];
|
||||
@@ -78,12 +80,4 @@ export const DEFAULT_MACROS = [
|
||||
{ type: 'drive', speeds: { left: 0, right: 0 } },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'seek-dock',
|
||||
label: 'Dock',
|
||||
description: 'Send the seek dock command.',
|
||||
steps: [
|
||||
{ type: 'oi', command: 'dock' }
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -43,6 +43,12 @@ function createMicState() {
|
||||
};
|
||||
}
|
||||
|
||||
function createManualDockAssistState() {
|
||||
return {
|
||||
active: false,
|
||||
};
|
||||
}
|
||||
|
||||
export const initialControlState = {
|
||||
roverId: null,
|
||||
mode: 'drive',
|
||||
@@ -52,6 +58,7 @@ export const initialControlState = {
|
||||
song: createSongState(),
|
||||
horn: createHornState(),
|
||||
mic: createMicState(),
|
||||
manualDockAssist: createManualDockAssistState(),
|
||||
lastControlIntentAt: 0,
|
||||
macros: DEFAULT_MACROS,
|
||||
keymap: DEFAULT_KEYMAP,
|
||||
@@ -69,6 +76,7 @@ export function controlReducer(state, action) {
|
||||
song: action.payload ? state.song : createSongState(),
|
||||
horn: action.payload ? state.horn : createHornState(),
|
||||
mic: action.payload ? state.mic : createMicState(),
|
||||
manualDockAssist: action.payload ? state.manualDockAssist : createManualDockAssistState(),
|
||||
lastControlIntentAt: action.payload ? state.lastControlIntentAt : 0,
|
||||
};
|
||||
case 'control/set-mode':
|
||||
@@ -187,6 +195,14 @@ export function controlReducer(state, action) {
|
||||
pttActive: Boolean(action.payload),
|
||||
},
|
||||
};
|
||||
case 'control/set-manual-dock-assist':
|
||||
return {
|
||||
...state,
|
||||
manualDockAssist: {
|
||||
...(state.manualDockAssist || createManualDockAssistState()),
|
||||
active: Boolean(action.payload),
|
||||
},
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,8 @@ export default function GamepadInputManager() {
|
||||
state,
|
||||
actions: {
|
||||
setMode,
|
||||
setManualDockAssistActive,
|
||||
toggleManualDockAssist,
|
||||
setDriveVector,
|
||||
setAuxMotors,
|
||||
setServoAngle,
|
||||
@@ -243,6 +245,7 @@ export default function GamepadInputManager() {
|
||||
}
|
||||
|
||||
if (outputs.buttons.driveMacro && handleButtonEdge('driveMacro', true)) {
|
||||
setManualDockAssistActive(false);
|
||||
setMode('drive');
|
||||
runMacro('drive-sequence');
|
||||
} else if (!outputs.buttons.driveMacro) {
|
||||
@@ -250,8 +253,7 @@ export default function GamepadInputManager() {
|
||||
}
|
||||
|
||||
if (outputs.buttons.dockMacro && handleButtonEdge('dockMacro', true)) {
|
||||
setMode('dock');
|
||||
runMacro('seek-dock');
|
||||
toggleManualDockAssist();
|
||||
} else if (!outputs.buttons.dockMacro) {
|
||||
handleButtonEdge('dockMacro', false);
|
||||
}
|
||||
@@ -288,9 +290,11 @@ export default function GamepadInputManager() {
|
||||
handleCameraAxis,
|
||||
registerInputState,
|
||||
runMacro,
|
||||
setManualDockAssistActive,
|
||||
setAuxMotors,
|
||||
setDriveVector,
|
||||
setMode,
|
||||
toggleManualDockAssist,
|
||||
toggleNightVision,
|
||||
]);
|
||||
|
||||
|
||||
@@ -122,6 +122,8 @@ export default function KeyboardInputManager() {
|
||||
state,
|
||||
actions: {
|
||||
setMode,
|
||||
setManualDockAssistActive,
|
||||
toggleManualDockAssist,
|
||||
setDriveVector,
|
||||
setAuxMotors,
|
||||
nudgeServo,
|
||||
@@ -372,11 +374,11 @@ export default function KeyboardInputManager() {
|
||||
|
||||
if (newlyPressed.length > 0) {
|
||||
if (newlyPressed.some((token) => keymap.driveMacro?.has(token))) {
|
||||
setManualDockAssistActive(false);
|
||||
setMode('drive');
|
||||
runMacro('drive-sequence');
|
||||
} else if (newlyPressed.some((token) => keymap.dockMacro?.has(token))) {
|
||||
setMode('dock');
|
||||
runMacro('seek-dock');
|
||||
toggleManualDockAssist();
|
||||
} else if (newlyPressed.some((token) => keymap.nightVisionToggle?.has(token))) {
|
||||
toggleNightVision();
|
||||
} else if (newlyPressed.some((token) => keymap.hornHonk?.has(token))) {
|
||||
@@ -441,12 +443,14 @@ export default function KeyboardInputManager() {
|
||||
keymap.micPtt,
|
||||
resetAll,
|
||||
runMacro,
|
||||
setManualDockAssistActive,
|
||||
setMicPttActive,
|
||||
setMode,
|
||||
stopAllMotion,
|
||||
stopSongLoop,
|
||||
startHorn,
|
||||
stopHorn,
|
||||
toggleManualDockAssist,
|
||||
triggerHomeAssistantCycle,
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user