jonny_jr9 b03baa4687 Change folder structure (multiple boards)
- add second pcb board_control, currently copy of previous board
- not enough pins -> board_control handle ui send motorcommands via uart
  board_motorctl handle motors
2023-08-28 11:15:06 +02:00

246 lines
8.2 KiB
JavaScript

import { Joystick } from 'react-joystick-component';
import React, { useState} from 'react';
//import { w3cwebsocket as W3CWebSocket } from "websocket";
function App() {
//declare variables that can be used and updated in html
const [x_html, setX_html] = useState(0);
const [y_html, setY_html] = useState(0);
const [ip, setIp] = useState("10.0.0.66");
//===============================
//=========== config ============
//===============================
const decimalPlaces = 3;
const joystickSize = 250; //affects scaling of coordinates and size of joystick on website
const throttle = 300; //throtthe interval the joystick sends data while moving (ms)
const toleranceSnapToZeroPer = 20;//percentage of moveable range the joystick can be moved from the axix and value stays at 0
//-------------------------------------------------
//------- Scale coordinate, apply tolerance -------
//-------------------------------------------------
//function that:
// - scales the coodinate to a range of -1 to 1
// - snaps 0 zero for a given tolerance in percent
// - rounds value do given decimal places
// - TODO: add threshold it snaps to 1 / -1 (100%) toleranceEnd
const ScaleCoordinateTolerance = (input) => {
//calc tolerance threshold and available range
const tolerance = joystickSize/2 * toleranceSnapToZeroPer/100;
const range = joystickSize/2 - tolerance;
let result = 0;
//console.log("value:",input,"tolerance:",tolerance," range:",range);
//input positive and above 'snap to zero' threshold
if ( input > 0 && input > tolerance ){
result = ((input-tolerance)/range).toFixed(decimalPlaces);
}
//input negative and blow 'snap to zero' threshold
else if ( input < 0 && input < -tolerance ){
result = ((input+tolerance)/range).toFixed(decimalPlaces);
}
//inside threshold around zero
else {
result = 0;
}
//return result
//console.log("result:", result, "\n");
return result;
}
//----------------------------------------
//----------- Scale coordinate -----------
//----------------------------------------
//simply scale coordinate from joystick to a value of -1 to 1 without applying any tolerances
const ScaleCoordinate = (input) => {
return ( input / (joystickSize/2) ).toFixed(decimalPlaces);
}
//-------------------------------------------
//------- Senda data via POST request -------
//-------------------------------------------
//function that sends an object as json to the esp32 with a http post request
const httpSendObject = async (object_data) => {
//debug log
console.log("Sending:", object_data);
let json = JSON.stringify(object_data);
//console.log("json string:", json);
//remove quotes around numbers:
//so cJSON parses the values as actua[l numbers than strings
const regex2 = /"(-?[0-9]+\.{0,1}[0-9]*)"/g
json = json.replace(regex2, '$1')
//console.log("json removed quotes:", json);
//--- API url / ip ---
//await fetch("http://10.0.1.69/api/joystick", {
//await fetch("http://10.0.1.72/api/joystick", {
await fetch("api/joystick", {
method: "POST",
//apparently browser sends OPTIONS request before actual POST request, this OPTIONS request was not handled by esp32
//also the custom set Access-Control-Allow-Origin header in esp32 url header was not read because of that
//changed content type to text/plain to workaround this
//https://stackoverflow.com/questions/1256593/why-am-i-getting-an-options-request-instead-of-a-get-request
headers: {
//"Content-Type": "application/json",
"Content-Type": "text/plain",
},
body: json,
})
//.then((response) => console.log(response));
};
//---------------------------------------
//--- function when joystick is moved ---
//---------------------------------------
//function that is run for each move event
//evaluate coordinates and send to esp32
const handleMove = (e) => {
//console.log("data from joystick-element X:" + e.x + " Y:" + e.y + " distance:" + e.distance);
//--- convert coordinates ---
//Note: tolerance (snap to zero) now handled by controller -> send raw coordinates
//const x = ScaleCoordinateTolerance(e.x);
//const y = ScaleCoordinateTolerance(e.y);
const x = ScaleCoordinate(e.x);
const y = ScaleCoordinate(e.y);
//create object with necessary data
const joystick_data={
x: x,
y: y
}
//send object with joystick data as json to controller
httpSendObject(joystick_data);
//update variables for html
setX_html(joystick_data.x);
setY_html(joystick_data.y);
};
//------------------------------------------
//--- function when joystick is released ---
//------------------------------------------
const handleStop = (e) => {
//create object with all values 0
const joystick_data={
x: 0,
y: 0,
}
//update variables for html
setX_html(0);
setY_html(0);
//send object with joystick data as json to controller
httpSendObject(joystick_data);
};
//=============================
//======== return html ========
//=============================
return (
<>
<div style={{display:'flex', justifyContent:'center', alignItems:'center', height:'100vh'}}>
<div>
<div style={{position: 'absolute', top: '0', left: '0', width: '100%'}}>
<h1 style={{width:'100%', textAlign:'center'}}>Armchair ctl</h1>
</div>
<Joystick
size={joystickSize}
sticky={false}
baseColor="#8d0801"
stickColor="#708d81"
throttle={throttle}
move={handleMove}
stop={handleStop}
>
</Joystick>
<ul>
<li> x={x_html} </li>
<li> y={y_html} </li>
</ul>
</div>
</div>
{/*
buttons for changing the api IP
<div>
<a>current ip used: {ip}</a>
<button onClick={() => {setIp("10.0.0.66")}} >10.0.0.66 (BKA-network)</button>
</div>
*/}
</>
);
}
export default App;
//del, testing, unused code
//---------------------------------------------
//--------- Send data via websocket -----------
//---------------------------------------------
//moved to normal POST request since websocket connection was unreliable on esp32
// //create websocket
// const websocket = useRef(null);
// //const socketUrl = "ws://" + window.location.host + "/ws-api/servo";
// const socketUrl = "ws://10.0.1.69/ws-api/joystick";
// useEffect(() => {
// websocket.current = new W3CWebSocket(socketUrl);
// websocket.current.onmessage = (message) => {
// console.log('got reply! ', message);
// };
// websocket.current.onopen = (event) => {
// console.log('OPENED WEBSOCKET', event);
// //sendJoystickData(0, 0, 0, 0);
// websocket.current.send("");
// };
// websocket.current.onclose = (event) => {
// console.log('CLOSED WEBSOCKET', event);
// };
// return () => websocket.current.close();
// }, [])
//
//
//
// //function for sending joystick data (provided as parameters) to controller via websocket
// const sendJoystickDataWebsocket = (x, y, radius, angle) => {
// //debug log
// console.log("Sending:\n X:" + x + "\n Y:" + y + "\n radius:" + radius + "\n angle: " + angle);
//
// websocket.current.send(
// JSON.stringify({
// x: x,
// y: y,
// radius: radius,
// angle: angle
// })
// );
// }