mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 09:31:20 -04:00
guhpad
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -5,7 +5,7 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>webui</title>
|
<title>webui</title>
|
||||||
<script type="module" crossorigin src="/assets/index-DFvdwweA.js"></script>
|
<script type="module" crossorigin src="/assets/index-CMp74UW-.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-DxO2_uri.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-DxO2_uri.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -25,17 +25,17 @@ function useGamepad() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ACTIONS = [
|
const ACTIONS = [
|
||||||
{ id: 'driveHorizontal', label: 'Drive horizontal', type: 'axis', section: 'Drive stick', path: ['drive', 'horizontal'] },
|
{ id: 'driveHorizontal', label: 'Drive horizontal', type: 'axis', section: 'Drive joystick', path: ['drive', 'horizontal'] },
|
||||||
{ id: 'driveVertical', label: 'Drive vertical', type: 'axis', section: 'Drive stick', path: ['drive', 'vertical'] },
|
{ id: 'driveVertical', label: 'Drive vertical', type: 'axis', section: 'Drive joystick', path: ['drive', 'vertical'] },
|
||||||
{ id: 'cameraVertical', label: 'Camera vertical', type: 'axis', section: 'Camera stick', path: ['camera', 'vertical'] },
|
{ id: 'cameraVertical', label: 'Camera vertical', type: 'axis', section: 'Camera joystick', path: ['camera', 'vertical'] },
|
||||||
{ id: 'mainTrigger', label: 'Main brush trigger', type: 'button', section: 'Brush triggers', path: ['triggers', 'main'] },
|
{ id: 'mainAxis', label: 'Main brush axis', type: 'axis', section: 'Brush analog', path: ['brushes', 'mainAxis'] },
|
||||||
{ id: 'mainReverse', label: 'Main reverse button', type: 'button', section: 'Brush triggers', path: ['buttons', 'mainReverse'] },
|
{ id: 'sideAxis', label: 'Side brush axis', type: 'axis', section: 'Brush analog', path: ['brushes', 'sideAxis'] },
|
||||||
{ id: 'sideTrigger', label: 'Side brush trigger', type: 'button', section: 'Brush triggers', path: ['triggers', 'side'] },
|
{ id: 'mainReverse', label: 'Toggle main reverse', type: 'button', section: 'Brush toggles', path: ['buttons', 'mainReverse'] },
|
||||||
{ id: 'sideReverse', label: 'Side reverse button', type: 'button', section: 'Brush triggers', path: ['buttons', 'sideReverse'] },
|
{ id: 'sideReverse', label: 'Toggle side reverse', type: 'button', section: 'Brush toggles', path: ['buttons', 'sideReverse'] },
|
||||||
{ id: 'vacuum', label: 'Vacuum button', type: 'button', section: 'Auxiliary buttons', path: ['buttons', 'vacuum'] },
|
{ id: 'vacuum', label: 'Vacuum button', type: 'button', section: 'Auxiliary buttons', path: ['buttons', 'vacuum'] },
|
||||||
{ id: 'allAux', label: 'All aux forward button', type: 'button', section: 'Auxiliary buttons', path: ['buttons', 'allAux'] },
|
{ id: 'allAux', label: 'All aux button', type: 'button', section: 'Auxiliary buttons', path: ['buttons', 'allAux'] },
|
||||||
{ id: 'driveMacro', label: 'Drive macro button', type: 'button', section: 'Mode buttons', path: ['buttons', 'driveMacro'] },
|
{ id: 'drive', label: 'Drive macro button', type: 'button', section: 'Mode buttons', path: ['buttons', 'drive'] },
|
||||||
{ id: 'dockMacro', label: 'Dock macro button', type: 'button', section: 'Mode buttons', path: ['buttons', 'dockMacro'] },
|
{ id: 'dock', label: 'Dock macro button', type: 'button', section: 'Mode buttons', path: ['buttons', 'dock'] },
|
||||||
];
|
];
|
||||||
|
|
||||||
function formatAxis(value) {
|
function formatAxis(value) {
|
||||||
@@ -71,8 +71,13 @@ export default function GamepadMappingSettings() {
|
|||||||
if (capture.type === 'axis') {
|
if (capture.type === 'axis') {
|
||||||
for (let i = 0; i < pad.axes.length; i += 1) {
|
for (let i = 0; i < pad.axes.length; i += 1) {
|
||||||
const value = pad.axes[i];
|
const value = pad.axes[i];
|
||||||
if (Math.abs(value) > 0.55) {
|
if (Math.abs(value) > 0.65) {
|
||||||
save((prev) => updatePath(prev, capture.path, () => ({ index: i, invert: value < 0 })));
|
save((prev) =>
|
||||||
|
updatePath(prev, capture.path, () => ({
|
||||||
|
index: i,
|
||||||
|
invert: value < 0,
|
||||||
|
})),
|
||||||
|
);
|
||||||
setCapture(null);
|
setCapture(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -120,7 +125,9 @@ export default function GamepadMappingSettings() {
|
|||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-semibold uppercase tracking-wide text-slate-400">Gamepad mapping</p>
|
<p className="text-xs font-semibold uppercase tracking-wide text-slate-400">Gamepad mapping</p>
|
||||||
<p className="text-[0.65rem] text-slate-500">
|
<p className="text-[0.65rem] text-slate-500">
|
||||||
{gamepadConnected ? 'Press buttons or move sticks when prompted.' : 'Connect a controller to configure.'}
|
{gamepadConnected
|
||||||
|
? 'Move sticks/axes with a big sweep or press buttons when capturing.'
|
||||||
|
: 'Connect a controller to configure.'}
|
||||||
</p>
|
</p>
|
||||||
{capture && (
|
{capture && (
|
||||||
<p className="mt-1 text-[0.7rem] text-emerald-400">Capturing {capture.label}…</p>
|
<p className="mt-1 text-[0.7rem] text-emerald-400">Capturing {capture.label}…</p>
|
||||||
|
|||||||
@@ -54,19 +54,20 @@ export default function GamepadInputManager() {
|
|||||||
Boolean(mapping?.drive?.horizontal) &&
|
Boolean(mapping?.drive?.horizontal) &&
|
||||||
Boolean(mapping?.drive?.vertical) &&
|
Boolean(mapping?.drive?.vertical) &&
|
||||||
Boolean(mapping?.camera?.vertical) &&
|
Boolean(mapping?.camera?.vertical) &&
|
||||||
Boolean(mapping?.triggers?.main) &&
|
Boolean(mapping?.brushes?.mainAxis) &&
|
||||||
Boolean(mapping?.triggers?.side) &&
|
Boolean(mapping?.brushes?.sideAxis) &&
|
||||||
Boolean(mapping?.buttons?.mainReverse) &&
|
Boolean(mapping?.buttons?.mainReverse) &&
|
||||||
Boolean(mapping?.buttons?.sideReverse) &&
|
Boolean(mapping?.buttons?.sideReverse) &&
|
||||||
Boolean(mapping?.buttons?.vacuum) &&
|
Boolean(mapping?.buttons?.vacuum) &&
|
||||||
Boolean(mapping?.buttons?.allAux) &&
|
Boolean(mapping?.buttons?.allAux) &&
|
||||||
Boolean(mapping?.buttons?.driveMacro) &&
|
Boolean(mapping?.buttons?.drive) &&
|
||||||
Boolean(mapping?.buttons?.dockMacro);
|
Boolean(mapping?.buttons?.dock);
|
||||||
const rafRef = useRef(null);
|
const rafRef = useRef(null);
|
||||||
const lastVectorRef = useRef({ x: 0, y: 0, boost: false });
|
const lastVectorRef = useRef({ x: 0, y: 0, boost: false });
|
||||||
const lastAuxRef = useRef({ main: 0, side: 0, vacuum: 0 });
|
const lastAuxRef = useRef({ main: 0, side: 0, vacuum: 0 });
|
||||||
const buttonStateRef = useRef(new Map());
|
const buttonStateRef = useRef(new Map());
|
||||||
const servoThrottleRef = useRef(0);
|
const servoThrottleRef = useRef(0);
|
||||||
|
const reverseStateRef = useRef({ main: false, side: false });
|
||||||
|
|
||||||
const handleButtonEdge = useCallback((key, pressed) => {
|
const handleButtonEdge = useCallback((key, pressed) => {
|
||||||
const prev = buttonStateRef.current.get(key) || false;
|
const prev = buttonStateRef.current.get(key) || false;
|
||||||
@@ -126,13 +127,15 @@ export default function GamepadInputManager() {
|
|||||||
setDriveVector(vector, { source: SOURCE });
|
setDriveVector(vector, { source: SOURCE });
|
||||||
}
|
}
|
||||||
|
|
||||||
const mainMagnitude = Math.round(getButtonValue(pad, mapping.triggers.main) * 127);
|
const mainRaw = getAxisValue(pad, mapping.brushes.mainAxis);
|
||||||
const mainReverse = isButtonPressed(pad, mapping.buttons.mainReverse);
|
const mainMagnitude = Math.round(Math.min(Math.abs(mainRaw), 1) * 127);
|
||||||
const main = mainReverse ? -mainMagnitude : mainMagnitude;
|
const main = reverseStateRef.current.main ? -mainMagnitude : mainMagnitude;
|
||||||
|
|
||||||
const sideMagnitude = Math.round(getButtonValue(pad, mapping.triggers.side) * 127);
|
const sideRaw = getAxisValue(pad, mapping.brushes.sideAxis);
|
||||||
const sideReverse = isButtonPressed(pad, mapping.buttons.sideReverse);
|
const sideMagnitude = Math.round(Math.min(Math.abs(sideRaw), 1) * 127);
|
||||||
const side = sideReverse ? -Math.round(sideMagnitude * auxReverseScale) : sideMagnitude;
|
const side = reverseStateRef.current.side
|
||||||
|
? -Math.round(sideMagnitude * auxReverseScale)
|
||||||
|
: Math.round(sideMagnitude * auxReverseScale);
|
||||||
|
|
||||||
const vacuum = isButtonPressed(pad, mapping.buttons.vacuum) ? 127 : 0;
|
const vacuum = isButtonPressed(pad, mapping.buttons.vacuum) ? 127 : 0;
|
||||||
let aux = { main, side, vacuum };
|
let aux = { main, side, vacuum };
|
||||||
@@ -151,28 +154,29 @@ export default function GamepadInputManager() {
|
|||||||
nudgeServo(cameraAxis > 0 ? servoStep : -servoStep);
|
nudgeServo(cameraAxis > 0 ? servoStep : -servoStep);
|
||||||
}
|
}
|
||||||
|
|
||||||
const driveMacroPressed = isButtonPressed(pad, mapping.buttons.driveMacro);
|
if (handleButtonEdge('toggle-main', isButtonPressed(pad, mapping.buttons.mainReverse))) {
|
||||||
if (handleButtonEdge(`macro-${mapping.buttons.driveMacro.index}`, driveMacroPressed)) {
|
reverseStateRef.current.main = !reverseStateRef.current.main;
|
||||||
|
}
|
||||||
|
if (handleButtonEdge('toggle-side', isButtonPressed(pad, mapping.buttons.sideReverse))) {
|
||||||
|
reverseStateRef.current.side = !reverseStateRef.current.side;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handleButtonEdge(`macro-${mapping.buttons.drive.index}`, isButtonPressed(pad, mapping.buttons.drive))) {
|
||||||
setMode('drive');
|
setMode('drive');
|
||||||
runMacro('drive-sequence');
|
runMacro('drive-sequence');
|
||||||
}
|
}
|
||||||
const dockMacroPressed = isButtonPressed(pad, mapping.buttons.dockMacro);
|
if (handleButtonEdge(`macro-${mapping.buttons.dock.index}`, isButtonPressed(pad, mapping.buttons.dock))) {
|
||||||
if (handleButtonEdge(`macro-${mapping.buttons.dockMacro.index}`, dockMacroPressed)) {
|
|
||||||
setMode('dock');
|
setMode('dock');
|
||||||
runMacro('seek-dock');
|
runMacro('seek-dock');
|
||||||
}
|
}
|
||||||
|
|
||||||
registerInputState(SOURCE, {
|
registerInputState(SOURCE, {
|
||||||
connected: true,
|
connected: true,
|
||||||
|
mappingReady: true,
|
||||||
id: pad.id,
|
id: pad.id,
|
||||||
index: pad.index,
|
index: pad.index,
|
||||||
axes: [axisLX, axisLY, cameraAxis],
|
axes: [axisLX, axisLY, cameraAxis],
|
||||||
buttons: {
|
reverse: { ...reverseStateRef.current },
|
||||||
a: pad.buttons?.[0]?.pressed || false,
|
|
||||||
b: pad.buttons?.[1]?.pressed || false,
|
|
||||||
lb: pad.buttons?.[4]?.pressed || false,
|
|
||||||
rb: pad.buttons?.[5]?.pressed || false,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}, [
|
}, [
|
||||||
auxReverseScale,
|
auxReverseScale,
|
||||||
@@ -183,16 +187,16 @@ export default function GamepadInputManager() {
|
|||||||
handleButtonEdge,
|
handleButtonEdge,
|
||||||
isButtonPressed,
|
isButtonPressed,
|
||||||
mapping.buttons?.allAux,
|
mapping.buttons?.allAux,
|
||||||
mapping.buttons?.dockMacro,
|
mapping.buttons?.dock,
|
||||||
mapping.buttons?.driveMacro,
|
mapping.buttons?.drive,
|
||||||
mapping.buttons?.mainReverse,
|
mapping.buttons?.mainReverse,
|
||||||
mapping.buttons?.sideReverse,
|
mapping.buttons?.sideReverse,
|
||||||
mapping.buttons?.vacuum,
|
mapping.buttons?.vacuum,
|
||||||
mapping.camera?.vertical,
|
mapping.camera?.vertical,
|
||||||
mapping.drive?.horizontal,
|
mapping.drive?.horizontal,
|
||||||
mapping.drive?.vertical,
|
mapping.drive?.vertical,
|
||||||
mapping.triggers?.main,
|
mapping.brushes?.mainAxis,
|
||||||
mapping.triggers?.side,
|
mapping.brushes?.sideAxis,
|
||||||
mappingReady,
|
mappingReady,
|
||||||
nudgeServo,
|
nudgeServo,
|
||||||
registerInputState,
|
registerInputState,
|
||||||
|
|||||||
@@ -19,16 +19,16 @@ export const GAMEPAD_MAPPING_DEFAULT = {
|
|||||||
camera: {
|
camera: {
|
||||||
vertical: null,
|
vertical: null,
|
||||||
},
|
},
|
||||||
triggers: {
|
brushes: {
|
||||||
main: null,
|
mainAxis: null,
|
||||||
side: null,
|
sideAxis: null,
|
||||||
},
|
},
|
||||||
buttons: {
|
buttons: {
|
||||||
|
allAux: null,
|
||||||
|
vacuum: null,
|
||||||
mainReverse: null,
|
mainReverse: null,
|
||||||
sideReverse: null,
|
sideReverse: null,
|
||||||
vacuum: null,
|
dock: null,
|
||||||
allAux: null,
|
drive: null,
|
||||||
driveMacro: null,
|
|
||||||
dockMacro: null,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user