163 lines
5.8 KiB
C++
163 lines
5.8 KiB
C++
|
|
const char index_html[] PROGMEM = R"rawliteral(
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>PID Controller</title>
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
background-color: black;
|
|
color: greenyellow;
|
|
font-family: monospace;
|
|
display: flex;
|
|
height: 100vh;
|
|
overflow: hidden;
|
|
}
|
|
#jsonOutput {
|
|
flex: 1;
|
|
padding: 20px;
|
|
white-space: pre-wrap;
|
|
word-wrap: break-word;
|
|
overflow: auto;
|
|
}
|
|
#controls {
|
|
width: 50vw;
|
|
padding: 20px;
|
|
background: #222;
|
|
color: white;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
label, button {
|
|
font-size: 16px;
|
|
}
|
|
input {
|
|
width: 100%;
|
|
}
|
|
.slider-value {
|
|
display: inline-block;
|
|
width: 40px;
|
|
text-align: right;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<pre id="jsonOutput">Loading...</pre>
|
|
<div id="controls">
|
|
<button onclick="setHome()">Set Home</button>
|
|
|
|
<h3>PID</h3>
|
|
<label for="pidIndex">Index:</label>
|
|
<select id="pidIndex">
|
|
<option value="0">angle</option>
|
|
<option value="1">pos</option>
|
|
<option value="2">turn</option>
|
|
</select>
|
|
<button onclick="fetchPID()">Get PID</button>
|
|
<label>Kp: <input type="range" id="kp" min="0" max="20" step="0.0001" oninput="updateValue('kp_value', this.value)"><span id="kp_value" class="slider-value">0</span></label>
|
|
<label>Ki: <input type="range" id="ki" min="0" max="120" step="0.0001" oninput="updateValue('ki_value', this.value)"><span id="ki_value" class="slider-value">0</span></label>
|
|
<label>Kd: <input type="range" id="kd" min="0" max="0.3" step="0.0001" oninput="updateValue('kd_value', this.value)"><span id="kd_value" class="slider-value">0</span></label>
|
|
<div>
|
|
<label>Direction:</label>
|
|
<label><input type="radio" name="direction" value="0" checked> Direct</label>
|
|
<label><input type="radio" name="direction" value="1"> Reverse</label>
|
|
</div>
|
|
<button onclick="setPID()">Set PID</button>
|
|
|
|
<label>Desired Yaw: <input type="range" id="gyro_kp" min="-180" max="180" step="5" oninput="updateValue('desired_yaw', this.value);setDesiredYaw(this.value)"><span id="desired_yaw" class="slider-value">0</span></label>
|
|
</div>
|
|
<script>
|
|
async function fetchData(){
|
|
try{
|
|
const res = await fetch("get_stuff");
|
|
document.getElementById("jsonOutput").textContent = JSON.stringify(await res.json(), null, 2);
|
|
}catch(error){
|
|
document.getElementById("jsonOutput").textContent = "Error: " + error.message;
|
|
}
|
|
}
|
|
|
|
async function loopFetch(){
|
|
while(true){
|
|
await fetchData();
|
|
}
|
|
}
|
|
loopFetch();
|
|
|
|
document.getElementById("pidIndex").addEventListener("change", (event) => {
|
|
fetchPID();
|
|
});
|
|
|
|
async function fetchPID() {
|
|
const index = parseInt(document.getElementById("pidIndex").value);
|
|
|
|
const res = await fetch("/get_pid", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({index})
|
|
});
|
|
const data = await res.json();
|
|
document.getElementById("kp").value = data.kp;
|
|
document.getElementById("ki").value = data.ki;
|
|
document.getElementById("kd").value = data.kd;
|
|
updateValue('kp_value', data.kp);
|
|
updateValue('ki_value', data.ki);
|
|
updateValue('kd_value', data.kd);
|
|
document.querySelector(`input[name="direction"][value="${data.direction}"]`).checked = true;
|
|
}
|
|
window.onload = () => {
|
|
fetchPID();
|
|
}
|
|
|
|
async function setPID() {
|
|
const index = parseInt(document.getElementById("pidIndex").value);
|
|
|
|
const direction = document.querySelector('input[name="direction"]:checked').value;
|
|
const data = {
|
|
index,
|
|
kp: parseFloat(document.getElementById("kp").value),
|
|
ki: parseFloat(document.getElementById("ki").value),
|
|
kd: parseFloat(document.getElementById("kd").value),
|
|
direction: parseInt(direction)
|
|
};
|
|
await fetch("/set_pid", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify(data)
|
|
});
|
|
}
|
|
|
|
function setDesiredYaw(yaw){
|
|
fetch("/set_desired_yaw", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({yaw})
|
|
});
|
|
}
|
|
|
|
function setGyroPID() {
|
|
const direction = document.querySelector('input[name="gyro_direction"]:checked').value;
|
|
const data = {
|
|
kp: parseFloat(document.getElementById("gyro_kp").value),
|
|
ki: parseFloat(document.getElementById("gyro_ki").value),
|
|
kd: parseFloat(document.getElementById("gyro_kd").value),
|
|
direction: parseInt(direction)
|
|
};
|
|
fetch("/set_gyro_pid", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify(data)
|
|
});
|
|
}
|
|
|
|
function updateValue(id, value) {
|
|
document.getElementById(id).textContent = value;
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|
|
)rawliteral";
|