Keyboard input added

This commit is contained in:
2025-11-03 10:51:46 -05:00
parent 83049815db
commit 5662142274
2 changed files with 185 additions and 21 deletions

147
script.js
View File

@ -288,6 +288,15 @@ const generateInputsBtn = document.getElementById('generate-inputs-btn');
const clearInputsBtn = document.getElementById('delete-inputs-btn');
const applyCustomBtn = document.getElementById('apply-custom-btn');
// Get control mode elements
const controlModeToggle = document.getElementById('control-mode-toggle');
const sliderControls = document.getElementById('slider-controls');
const keyboardControls = document.getElementById('keyboard-controls');
const keyboardMaxSpeed = document.getElementById('keyboard-max-speed');
const keyboardMaxSpeedOutput = document.getElementById('keyboard-max-speed-value');
const keyboardMaxRotation = document.getElementById('keyboard-max-rotation');
const keyboardMaxRotationOutput = document.getElementById('keyboard-max-rotation-value');
// Preset buttons
const preset2WheelBtn = document.getElementById('preset-2wheel');
const preset3WheelBtn = document.getElementById('preset-3wheel');
@ -301,6 +310,29 @@ const preset16OctBtn = document.getElementById('preset-16oct');
/*
* END DOM VARIABLES
* BEGIN CONTROL MODE AND INPUT DEVICE VARIABLES
*/
// Control mode state
let isManualInputMode = false; // true = keyboard/gamepad mode, false = slider mode
// Keyboard state tracking
const keyState = {
w: false, // Forward
a: false, // Left
s: false, // Backward
d: false, // Right
q: false, // Counter-clockwise
e: false // Clockwise
};
// Current manual input velocities (from keyboard or gamepad)
let manualInputVelX = 0;
let manualInputVelY = 0;
let manualInputOmega = 0;
/*
* END CONTROL MODE AND INPUT DEVICE VARIABLES
* BEGIN LISTENER CODE
*/
@ -319,6 +351,93 @@ resetBtn.addEventListener('click', (e) => {
omegaOutput.textContent = parseFloat(omegaSlider.value);
});
// Keyboard control sliders
keyboardMaxSpeed.addEventListener('input', (e) => {
keyboardMaxSpeedOutput.textContent = parseFloat(e.target.value);
});
keyboardMaxSpeedOutput.textContent = parseFloat(keyboardMaxSpeed.value);
keyboardMaxRotation.addEventListener('input', (e) => {
keyboardMaxRotationOutput.textContent = parseFloat(e.target.value);
});
keyboardMaxRotationOutput.textContent = parseFloat(keyboardMaxRotation.value);
// Control mode toggle
controlModeToggle.addEventListener('click', () => {
isManualInputMode = !isManualInputMode;
if (isManualInputMode) {
// Switch to manual input mode (keyboard/gamepad)
sliderControls.style.display = 'none';
keyboardControls.style.display = 'block';
controlModeToggle.textContent = 'Switch to Slider Controls';
// Reset slider values when switching to manual input
vxSlider.value = 0;
vySlider.value = 0;
omegaSlider.value = 0;
vxOutput.textContent = '0';
vyOutput.textContent = '0';
omegaOutput.textContent = '0';
} else {
// Switch to slider mode
sliderControls.style.display = 'block';
keyboardControls.style.display = 'none';
controlModeToggle.textContent = 'Switch to Keyboard Controls (WASD + QE)';
// Reset manual input state
Object.keys(keyState).forEach(key => keyState[key] = false);
manualInputVelX = 0;
manualInputVelY = 0;
manualInputOmega = 0;
}
});
// Keyboard event listeners
document.addEventListener('keydown', (e) => {
if (!isManualInputMode) return;
const key = e.key.toLowerCase();
if (key in keyState) {
keyState[key] = true;
e.preventDefault();
updateManualInputVelocities();
}
});
document.addEventListener('keyup', (e) => {
if (!isManualInputMode) return;
const key = e.key.toLowerCase();
if (key in keyState) {
keyState[key] = false;
e.preventDefault();
updateManualInputVelocities();
}
});
// Function to update velocities based on manual input devices (keyboard/gamepad)
function updateManualInputVelocities() {
const maxSpeed = parseFloat(keyboardMaxSpeed.value);
const maxRotation = parseFloat(keyboardMaxRotation.value);
// Calculate translation velocities from keyboard input
manualInputVelX = 0;
manualInputVelY = 0;
if (keyState.d) manualInputVelX += maxSpeed; // Right
if (keyState.a) manualInputVelX -= maxSpeed; // Left
if (keyState.w) manualInputVelY += maxSpeed; // Forward
if (keyState.s) manualInputVelY -= maxSpeed; // Backward
// Calculate rotation velocity from keyboard input
manualInputOmega = 0;
if (keyState.e) manualInputOmega += maxRotation; // Clockwise
if (keyState.q) manualInputOmega -= maxRotation; // Counter-clockwise
// TODO: Add gamepad input processing here
}
// Preset button event listeners
preset2WheelBtn.addEventListener('click', () => {
const positions = PresetConfigs.twoWheel(robotSize);
@ -652,10 +771,16 @@ function animate() {
ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
// Update speeds based on sliders
xSpeed = parseFloat(vxSlider.value);
ySpeed = -parseFloat(vySlider.value);
turnSpeed = parseFloat(omegaSlider.value);
// Update speeds based on control mode
if (isManualInputMode) {
xSpeed = manualInputVelX;
ySpeed = -manualInputVelY; // Negative because canvas Y axis is inverted
turnSpeed = manualInputOmega;
} else {
xSpeed = parseFloat(vxSlider.value);
ySpeed = -parseFloat(vySlider.value);
turnSpeed = parseFloat(omegaSlider.value);
}
// Update module states before drawing the robot
// The drive() method will update the gyroHeading internally
@ -665,11 +790,17 @@ function animate() {
// Get the actual robot velocity (after scaling to max module speed) for grid animation
const actualVelocity = robot.getActualVelocity();
// Update control outputs with actual speeds
vxOutput.textContent = `Requested: ${vxSlider.value} | Actual: ${actualVelocity.x.toFixed(2)}`;
vyOutput.textContent = `Requested: ${vySlider.value} | Actual: ${-actualVelocity.y.toFixed(2)}`;
omegaOutput.textContent = `Requested: ${omegaSlider.value} | Actual: ${robot.actualTurnSpeed.toFixed(2)}`;
if (isManualInputMode) {
// In manual input mode (keyboard/gamepad), show the current values
keyboardMaxSpeedOutput.textContent = `Max: ${keyboardMaxSpeed.value} | Current: ${Math.max(Math.abs(actualVelocity.x), Math.abs(actualVelocity.y)).toFixed(1)}`;
keyboardMaxRotationOutput.textContent = `Max: ${keyboardMaxRotation.value} | Current: ${Math.abs(robot.actualTurnSpeed || 0).toFixed(2)}`;
} else {
// In slider mode, show requested vs actual
vxOutput.textContent = `Requested: ${vxSlider.value} | Actual: ${actualVelocity.x.toFixed(2)}`;
vyOutput.textContent = `Requested: ${vySlider.value} | Actual: ${-actualVelocity.y.toFixed(2)}`;
omegaOutput.textContent = `Requested: ${omegaSlider.value} | Actual: ${(robot.actualTurnSpeed || 0).toFixed(2)}`;
}
// Animate the grid
let offsetSpeedDivisor = (100 - gridSquareSize <= 0 ? 1 : 100 - gridSquareSize);