<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Robot Control</title>
<style>
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
}
#joysticks {
display: flex;
gap: 20px;
}
.joystick {
width: 150px;
height: 150px;
position: relative;
}
.nipple {
width: 100%;
height: 100%;
}
</style>
<script src="static/nipplejs.min.js"></script>
</head>
<body>
<h1>Robot Control</h1>
<div id="joysticks">
<div id="leftJoystick" class="joystick"></div>
<div id="rightJoystick" class="joystick"></div>
</div>
<script>
const leftJoystick = document.getElementById('leftJoystick');
const rightJoystick = document.getElementById('rightJoystick');
const socketProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
const socket = new WebSocket(`${socketProtocol}//${location.host}/ws`);
socket.onopen = () => {
console.log('WebSocket connection established');
};
socket.onerror = (error) => {
console.error('WebSocket error:', error);
};
function sendDriveCommand(left, right) {
if (socket.readyState !== WebSocket.OPEN) {
return;
}
const message = JSON.stringify({ left, right });
socket.send(message);
}
const leftNipple = nipplejs.create({
zone: leftJoystick,
mode: 'static',
position: { left: '50%', top: '50%' },
color: 'blue'
});
const rightNipple = nipplejs.create({
zone: rightJoystick,
mode: 'static',
position: { left: '50%', top: '50%' },
color: 'red'
});
leftNipple.on('move', (evt, data) => {
const value = Math.max(-1, Math.min(1, data.vector.y));
sendDriveCommand(value, rightJoystick.value || 0);
leftJoystick.value = value;
});
rightNipple.on('move', (evt, data) => {
const value = Math.max(-1, Math.min(1, data.vector.y));
sendDriveCommand(leftJoystick.value || 0, value);
rightJoystick.value = value;
});
leftNipple.on('end', () => {
leftJoystick.value = 0;
sendDriveCommand(0, rightJoystick.value || 0);
});
rightNipple.on('end', () => {
rightJoystick.value = 0;
sendDriveCommand(leftJoystick.value || 0, 0);
});
</script>
</body>
</html>