Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update calibration system #17

Merged
merged 6 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file modified index.html.gz
Binary file not shown.
293 changes: 53 additions & 240 deletions www/js/calculatesCalibrationStuff.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,13 @@
const initialWidth = 3048 + 12
const initialHeight = 2200 - 14

//These are the true corners of the machine that we want to solve for (only used for simulated measurments)
const trueTLX = -0.6948090610228441
const trueTLY = 2131.275233532367
const trueTRX = 3034.4072793128926
const trueTRY = 2127.1780972406527
const trueBLX = 0
const trueBLY = 0
const trueBRX = 3034.960970894897
const trueBRY = 0

//Establish initial guesses for the corners
var initialGuess = {
tl: { x: 0, y: initialHeight },
tr: { x: initialWidth, y: initialHeight },
bl: { x: 0, y: 0 },
br: { x: initialWidth, y: 0 },
fitness: 0,
fitness: 100000000,
}

const centerX = initialWidth / 2
Expand All @@ -37,25 +27,6 @@ let result
*------------------------------------------------------------------------------
*/

/**
* Simulates a measurement at a given location with random and constant errors.
* @param {number} x - The x-coordinate of the location to measure.
* @param {number} y - The y-coordinate of the location to measure.
* @param {number} randomError - The maximum amount of random error to add to the measurement.
* @param {number} constantError - The constant error to add to the measurement.
* @returns {Object} - An object containing the simulated measurements at the given location.
*/
function takeSimulatedMeasurement(x, y, randomError, constantError) {
const tl =
distanceBetweenPoints(trueTLX, trueTLY, x, y) + (Math.random() * randomError * 2 - randomError) + constantError
const tr =
distanceBetweenPoints(trueTRX, trueTRY, x, y) + (Math.random() * randomError * 2 - randomError) + constantError
const bl =
distanceBetweenPoints(trueBLX, trueBLY, x, y) + (Math.random() * randomError * 2 - randomError) + constantError
const br =
distanceBetweenPoints(trueBRX, trueBRY, x, y) + (Math.random() * randomError * 2 - randomError) + constantError
return { tl: tl, tr: tr, bl: bl, br: br }
}

/**
* Computes the distance between two points.
Expand Down Expand Up @@ -419,38 +390,7 @@ function calculateAverage(array) {
return total / count
}

/**
* Prints the difference between the real values and the computed values for the corners. Only useful when using simulated
* measurements.
* @param {Object} guess - An object containing the x and y coordinates of the top left, top right, bottom left, and bottom right corners of a trapazoid.
* @returns {void}
*/
function printResults(guess) {
// console.log("tlX error: " + (guess.tl.x - trueTLX) + "mm at: " + guess.tl.x);
// console.log("tlY error: " + (guess.tl.y - trueTLY) + "mm at: " + guess.tl.y);
// console.log("trX error: " + (guess.tr.x - trueTRX) + "mm at: " + guess.tr.x);
// console.log("trY error: " + (guess.tr.y - trueTRY) + "mm at: " + guess.tr.y);
// console.log("brX error: " + (guess.br.x - trueBRX) + "mm at: " + guess.br.x);
// console.log(
// '(' +
// guess.tl.x +
// ', ' +
// guess.tl.y +
// '), (' +
// guess.tr.x +
// ', ' +
// guess.tr.y +
// ')\n (' +
// guess.bl.x +
// ', ' +
// guess.bl.y +
// '), (' +
// guess.br.x +
// ', ' +
// guess.br.y +
// ')'
// )
}


/**
* Projects the measurements to the plane of the machine. This is needed
Expand Down Expand Up @@ -549,67 +489,62 @@ function scaleMeasurementsBasedOnTension(measurements, guess) {
return newMeasurements
}


function findMaxFitness(measurements) {
let currentGuess = JSON.parse(JSON.stringify(initialGuess));
let stagnantCounter = 0;
let totalCounter = 0;
var bestGuess = JSON.parse(JSON.stringify(initialGuess));

var messagesBox = document.querySelector('#messages');

function loop() {
//Clear the canvass
clearCanvas();

currentGuess = computeLinesFitness(measurements, currentGuess);

if (1/currentGuess.fitness > 1/bestGuess.fitness) {
bestGuess = JSON.parse(JSON.stringify(currentGuess));
stagnantCounter = 0;
} else {
stagnantCounter++;
}
totalCounter++;

var maxFitness = -1;
var newFitness = 0;
var stagnantCounter = 0;
const maxCycles = 300000;
var currentCycles = 0;

function runCycle() {
if (stagnantCounter < 14 && currentCycles < maxCycles) {
maxFitness = newFitness;

var maxFitnessThisRun = 0;
//Run 100 steps
for (let i = 0; i < 100; i++) {
initialGuess = computeLinesFitness(measurements, initialGuess);
maxFitnessThisRun = Math.max(1 / initialGuess.fitness, maxFitnessThisRun);
}

currentCycles += 100;

newFitness = maxFitnessThisRun;
var messagesBox = document.querySelector('#messages');
messagesBox.value += '\nFitness: ' + newFitness + ' in ' + currentCycles + ' cycles';
messagesBox.scrollTop = messagesBox.scrollHeight;

if (stagnantCounter > 1) {
console.log("Stagnant Counter: " + stagnantCounter);
}

if (newFitness <= maxFitness) {
stagnantCounter++;
} else {
stagnantCounter = 0;
}

setTimeout(runCycle, 0); // schedule the next cycle
} else {
var messagesBox = document.querySelector('#messages');
if(maxFitness < 0.5){
messagesBox.value += '\nWARNING FITNESS TOO LOW. DO NOT USE THESE CALIBRATION VALUES!';
}
messagesBox.value += '\nCalibration complete \nCalibration values:';
messagesBox.value += '\nMaslow_tlX: ' + initialGuess.tl.x.toFixed(1);
messagesBox.value += '\nMaslow_tlY: ' + initialGuess.tl.y.toFixed(1);
messagesBox.value += '\nMaslow_trX: ' + initialGuess.tr.x.toFixed(1);
messagesBox.value += '\nMaslow_trY: ' + initialGuess.tr.y.toFixed(1);
messagesBox.value += '\nMaslow_blX: ' + initialGuess.bl.x.toFixed(1);
messagesBox.value += '\nMaslow_blY: ' + initialGuess.bl.y.toFixed(1);
messagesBox.value += '\nMaslow_brX: ' + initialGuess.br.x.toFixed(1);
messagesBox.value += '\nMaslow_brY: ' + initialGuess.br.y.toFixed(1);
messagesBox.scrollTop
messagesBox.scrollTop = messagesBox.scrollHeight;
if(totalCounter % 100 == 0) {
messagesBox.value += '\nFitness: ' + 1/bestGuess.fitness.toFixed(7) + ' in ' + totalCounter;
messagesBox.scrollTop
messagesBox.scrollTop = messagesBox.scrollHeight;
}

if (stagnantCounter < 100 && totalCounter < 200000) {
requestAnimationFrame(loop);
} else {

if(1/bestGuess.fitness < 0.5){
messagesBox.value += '\nWARNING FITNESS TOO LOW. DO NOT USE THESE CALIBRATION VALUES!';
}
messagesBox.value += '\nCalibration complete \nCalibration values:';
messagesBox.value += '\nMaslow_tlX: ' + bestGuess.tl.x.toFixed(1);
messagesBox.value += '\nMaslow_tlY: ' + bestGuess.tl.y.toFixed(1);
messagesBox.value += '\nMaslow_trX: ' + bestGuess.tr.x.toFixed(1);
messagesBox.value += '\nMaslow_trY: ' + bestGuess.tr.y.toFixed(1);
messagesBox.value += '\nMaslow_blX: ' + bestGuess.bl.x.toFixed(1);
messagesBox.value += '\nMaslow_blY: ' + bestGuess.bl.y.toFixed(1);
messagesBox.value += '\nMaslow_brX: ' + bestGuess.br.x.toFixed(1);
messagesBox.value += '\nMaslow_brY: ' + bestGuess.br.y.toFixed(1);
messagesBox.scrollTop
messagesBox.scrollTop = messagesBox.scrollHeight;
}
}

runCycle(); // start the first cycle

return initialGuess;
loop();
return bestGuess;
}



//This is where the program really begins. The above is all function definitions
//The way that the progam works is that we basically guess where the four corners are and then
//check to see how good that guess was. To see how good a guess was we "draw" circles from the four corner points
Expand All @@ -619,127 +554,5 @@ function findMaxFitness(measurements) {
//Once we've figured out how good our guess was we try a different guess. We keep the good guesses and throw away the bad guesses
//using a genetic algorithm

calculateTensions(centerX, centerY, initialGuess)

//Un-comment this code to use the simulated measurements

// const randomMeasurementError = 6;
// const constantMeasurementError = 3;
// var measurements = [];
// measurements.push(takeSimulatedMeasurement(centerX,centerY,randomMeasurementError, constantMeasurementError));
// measurements.push(takeSimulatedMeasurement(centerX-800,centerY + 400,randomMeasurementError, constantMeasurementError));
// measurements.push(takeSimulatedMeasurement(centerX-800,centerY,randomMeasurementError, constantMeasurementError));
// measurements.push(takeSimulatedMeasurement(centerX-800,centerY - 400,randomMeasurementError, constantMeasurementError));
// measurements.push(takeSimulatedMeasurement(centerX,centerY + 400,randomMeasurementError, constantMeasurementError));
// measurements.push(takeSimulatedMeasurement(centerX,centerY - 400,randomMeasurementError, constantMeasurementError));
// measurements.push(takeSimulatedMeasurement(centerX + 800,centerY + 400,randomMeasurementError, constantMeasurementError));
// measurements.push(takeSimulatedMeasurement(centerX + 800,centerY,randomMeasurementError, constantMeasurementError));
// measurements.push(takeSimulatedMeasurement(centerX + 800,centerY - 400,randomMeasurementError, constantMeasurementError));

var measurements = [
{ bl: 1560.141, br: 2734.873, tr: 2433.119, tl: 883.419 },
{ bl: 1471.909, br: 2683.675, tr: 2461.234, tl: 956.507 },
{ bl: 1383.243, br: 2635.983, tr: 2492.822, tl: 1034.411 },
{ bl: 1295.276, br: 2590.421, tr: 2528.066, tl: 1116.038 },
// {bl:1210.792, br:2548.830, tr:2566.603, tl:1200.482},
// {bl:1126.427, br:2510.942, tr:2608.576, tl:1287.002},
// {bl:1046.081, br:2476.385, tr:2653.523, tl:1375.421},
// {bl:968.967, br:2447.814, tr:2701.411, tl:1465.449},
// {bl:895.371, br:2415.316, tr:2752.257, tl:1556.480},
// {bl:1025.801, br:2249.586, tr:2605.334, tl:1632.330},
// {bl:1089.195, br:2279.324, tr:2551.535, tl:1546.243},
// {bl:1157.331, br:2312.907, tr:2500.786, tl:1461.313},
// {bl:1230.047, br:2350.481, tr:2452.903, tl:1378.344},
// {bl:1306.512, br:2391.785, tr:2408.270, tl:1297.697},
// {bl:1386.383, br:2435.540, tr:2367.108, tl:1220.022},
// {bl:1468.597, br:2482.805, tr:2329.333, tl:1145.787},
// {bl:1551.947, br:2533.735, tr:2295.611, tl:1075.769},
// {bl:1634.958, br:2587.313, tr:2265.767, tl:1010.598},
// {bl:1728.145, br:2442.730, tr:2098.714, tl:1149.872},
// {bl:1648.569, br:2386.661, tr:2130.453, tl:1207.549},
// {bl:1570.891, br:2333.461, tr:2166.883, tl:1270.178},
// {bl:1495.139, br:2283.130, tr:2207.264, tl:1337.410},
// {bl:1422.099, br:2235.959, tr:2251.335, tl:1408.609},
// {bl:1353.098, br:2193.873, tr:2298.926, tl:1483.094},
// {bl:1286.170, br:2156.136, tr:2349.820, tl:1560.493},
// {bl:1223.028, br:2122.924, tr:2403.933, tl:1640.200},
// {bl:1166.862, br:2083.917, tr:2460.788, tl:1722.146},
// {bl:1315.195, br:1919.338, tr:2321.692, tl:1824.686},
// {bl:1366.049, br:1953.146, tr:2261.355, tl:1748.288},
// {bl:1421.447, br:1992.961, tr:2203.810, tl:1673.544},
// {bl:1482.321, br:2035.583, tr:2149.463, tl:1601.580},
// {bl:1546.732, br:2082.350, tr:2098.183, tl:1532.925},
// {bl:1613.913, br:2133.137, tr:2050.946, tl:1467.754},
// {bl:1684.494, br:2185.872, tr:2007.277, tl:1406.677},
// {bl:1757.250, br:2242.180, tr:1967.898, tl:1350.162},
// {bl:1832.770, br:2301.704, tr:1932.702, tl:1298.897},
// {bl:1946.723, br:2166.676, tr:1769.127, tl:1452.641},
// {bl:1878.595, br:2104.039, tr:1806.392, tl:1498.943},
// {bl:1810.246, br:2043.960, tr:1849.317, tl:1549.660},
// {bl:1743.664, br:1986.833, tr:1896.564, tl:1605.308},
// {bl:1681.212, br:1932.377, tr:1947.762, tl:1665.084},
// {bl:1622.794, br:1883.023, tr:2002.583, tl:1728.571},
// {bl:1567.820, br:1837.771, tr:2060.805, tl:1795.234},
// {bl:1517.503, br:1796.507, tr:2122.194, tl:1865.132},
// {bl:1471.375, br:1761.139, tr:2186.377, tl:1937.447},
// {bl:1634.411, br:1592.062, tr:2058.424, tl:2059.036},
// {bl:1674.032, br:1633.565, tr:1990.108, tl:1991.675},
// {bl:1719.851, br:1680.015, tr:1924.478, tl:1926.607},
// {bl:1769.114, br:1731.473, tr:1862.048, tl:1864.367},
// {bl:1823.390, br:1786.009, tr:1802.766, tl:1805.707},
// {bl:1880.629, br:1845.171, tr:1747.402, tl:1750.693},
// {bl:1940.614, br:1906.219, tr:1695.987, tl:1699.785},
// {bl:2003.563, br:1970.506, tr:1649.189, tl:1653.349},
// {bl:2068.878, br:2037.140, tr:1607.122, tl:1611.822},
// {bl:2200.589, br:1916.372, tr:1448.891, tl:1772.941},
// {bl:2139.036, br:1845.195, tr:1494.522, tl:1811.030},
// {bl:2079.239, br:1776.763, tr:1546.010, tl:1853.384},
// {bl:2023.803, br:1709.998, tr:1602.073, tl:1900.086},
// {bl:1970.343, br:1646.824, tr:1662.247, tl:1950.736},
// {bl:1920.302, br:1586.890, tr:1726.220, tl:2005.197},
// {bl:1875.213, br:1530.346, tr:1793.396, tl:2063.086},
// {bl:1833.670, br:1478.300, tr:1863.655, tl:2124.159},
// {bl:1796.638, br:1432.025, tr:1936.468, tl:2187.990},
// {bl:1960.304, br:1278.271, tr:1824.665, tl:2322.787},
// {bl:1992.856, br:1330.110, tr:1747.282, tl:2263.325},
// {bl:2031.970, br:1386.286, tr:1672.226, tl:2206.252},
// {bl:2074.118, br:1448.005, tr:1599.910, tl:2152.207},
// {bl:2120.323, br:1514.140, tr:1530.566, tl:2101.452},
// {bl:2169.395, br:1582.346, tr:1464.955, tl:2054.350},
// {bl:2222.525, br:1654.466, tr:1403.102, tl:2011.226},
// {bl:2278.323, br:1727.369, tr:1346.141, tl:1972.133},
// {bl:2336.156, br:1802.336, tr:1294.329, tl:1937.490},
// {bl:2476.785, br:1701.694, tr:1146.413, tl:2102.654},
// {bl:2423.263, br:1622.515, tr:1203.448, tl:2134.798},
// {bl:2370.519, br:1543.248, tr:1266.882, tl:2170.895},
// {bl:2321.040, br:1465.953, tr:1334.756, tl:2210.970},
// {bl:2274.754, br:1391.316, tr:1406.551, tl:2254.666},
// {bl:2231.957, br:1320.479, tr:1481.419, tl:2301.889},
// {bl:2192.091, br:1251.742, tr:1559.309, tl:2352.587},
// {bl:2155.932, br:1188.804, tr:1639.628, tl:2406.153},
// {bl:2124.218, br:1131.202, tr:1721.845, tl:2462.710},
// {bl:2289.548, br:992.052, tr:1633.098, tl:2606.764},
// {bl:2318.090, br:1058.084, tr:1546.224, tl:2554.037},
// {bl:2352.018, br:1127.769, tr:1460.926, tl:2503.489},
// {bl:2389.037, br:1201.926, tr:1377.300, tl:2455.968},
// {bl:2428.650, br:1281.083, tr:1296.253, tl:2411.657},
// {bl:2473.283, br:1361.113, tr:1218.022, tl:2370.777},
// {bl:2520.680, br:1443.875, tr:1142.934, tl:2333.437},
// {bl:2570.439, br:1528.110, tr:1072.146, tl:2299.951},
// {bl:2621.682, br:1613.040, tr:1006.344, tl:2270.363},
// {bl:2770.967, br:1541.329, tr:878.953, tl:2437.888},
// {bl:2720.736, br:1451.503, tr:952.865, tl:2465.791},
// {bl:2673.296, br:1361.403, tr:1031.907, tl:2497.052},
// {bl:2629.197, br:1273.123, tr:1114.285, tl:2531.945},
// {bl:2587.745, br:1187.167, tr:1199.266, tl:2570.259},
// {bl:2549.635, br:1102.365, tr:1286.454, tl:2611.834},
// {bl:2514.450, br:1019.056, tr:1375.496, tl:2656.550},
// {bl:2484.029, br:940.403, tr:1465.790, tl:2704.186},
// {bl:2458.091, br:866.263, tr:1557.264, tl:2754.657},
]

//Do projection and scaling
// measurements = scaleMeasurements(measurements, 0.9945);
measurements = projectMeasurements(measurements)

computeLinesFitness(measurements, initialGuess)