<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Contrôle du robot</title> </head> <body> <h1>Contrôle du robot sans fils</h1> <p> Cette page permet de contrôler le robot depuis un PC portable connecté au WiFi du robot. Elle est destinée aux personnes n'ayant pas de smartphone. </p> <h2>Paramètres de contrôle</h2> <p> Ici vous pourrez paramétrer les contrôles du robot, rentrer son adresse IP ainsi que lui indiquer la distance à parcourir ou l'angle de rotation désiré. </p> <form class="settings" id="settings"> <label> <span>Adresse IP du robot</span> <input type="text" name="ip-address" title="Adresse IP du robot (ex: 192.168.0.1)" pattern="\d+\.\d+\.\d+\.\d+" placeholder="192.168.0.0" required /> </label> <button>Se connecter</button> </form> <div class="controls"> <label> <span>Rotation en degrés</span> <input id="rotate-input" type="number" title="Rotation en degrés (-360° à 360°)" min="-360" max="360" step="1" placeholder="90" /> </label> <label> <span>Distance en cm</span> <input id="move-input" type="number" title="Distance en cm (-2^31 à 2^31)" min="-2147483647" step="1" max="2147483647" placeholder="10" /> </label> </div> <h2>Contrôle</h2> <p> Amusez vous ! Pour contrôler le robot, utilisez les flèches directionnelles pour le diriger et la barre espace pour le stopper. </p> </body> <script type="module"> // Input handlers document .querySelector('move-input') .addEventListener('change', (event) => assignCommands('backward', 'forward', event) ) document .querySelector('rotate-input') .addEventListener('change', (event) => assignCommands('left', 'right', event) ) // Keyboard handler document.addEventListener('keydown', (event) => { const key = event.keyCode const { command, value } = keyMap[key] const endpoint = getEndpoint() sendCommand(endpoint, command, value) }) // Settings handler document .querySelector('#settings') .addEventListener('submit', async (event) => { // Don't interrupt event if not form submitting if (!(event instanceof SubmitEvent)) return true if (event.target === null) return true // Disable form sending event.preventDefault() const form = new FormData(event.target) const ipAddress = form.get('ip-address') if (ipAddress === null) return const endpoint = `http://${ipAddress}` await testEndpoint(endpoint) setEndpoint(endpoint) }) /** * A command string. * @typedef {('forward' | 'backward' | 'left' | 'right' | 'stop')} Command */ /** * Send command to the robot. * * @param {string} endpoint Address IP of the robot. * @param {Command} command Command to send. * @param {number} value Value of the command if needed. * * @returns {Promise<void>} */ async function sendCommand(endpoint, command, value) { const url = new URL( `/get?command=${command}&value=${value}`, endpoint ) const response = await fetch(url) const text = await response.text() console.log(text) } /** * Get robot endpoint address. * * @returns {string} */ function getEndpoint() { const endpoint = sessionStorage.getItem('robot-endpoint') if (endpoint === null) { alert("Aucune adresse IP n'a été renseignée !") throw new Error('no given ip address') } return endpoint } /** * Set robot endpoint address. * * @param {string} ip Robot ip. * * @returns void */ function setEndpoint(ip) { sessionStorage.setItem('robot-endpoint') } /** * Test connection to endpoint. * * @param {string} endpoint Endpoint to test for. * * @returns {void} * @throws {Error} Endpoint unreachable. */ async function testEndpoint(endpoint) { try { const response = await fetch(endpoint) if (response.ok) return } catch (cause) { alert(`Impossible de joindre l'adresse "${endpoint}"`) throw new Error(`unable to connect to robot at ${endpoint}`, { cause, }) } } /** * Assign a command to an input. * Do negative command if value < 0 else do positive command. * * @param {Command} negativeCommand Command if value < 0. * @param {Command} positiveCommand Command if value >= 0. * @param {event} event Event of the input. * * @returns {Promise<void>} */ function assignCommands(negativeCommand, positiveCommand, event) { if (event.target === null) return /** @type {HTMLInputElement} */ const target = event.target const value = target.valueAsNumber const endpoint = getEndpoint() if (value < 0) { return sendCommand(endpoint, negativeCommand, Math.abs(value)) } return sendCommand(endpoint, positiveCommand, value) } function storeInput() { ipInput = document.getElementById('ip').value valueRot = document.getElementById('valueRot').value valueLength = document.getElementById('valueLength').value keyMap = { 38: { command: 'forward', value: valueLength }, 40: { command: 'backward', value: valueLength }, 37: { command: 'left', value: valueRot }, 39: { command: 'right', value: valueRot }, 32: { command: 'stop', value: 0 }, } } </script> </html>