Compare commits

..

15 commits

Author SHA1 Message Date
92b065b950
Remove old graph js file 2024-04-26 11:24:45 -04:00
db17308b7e Add Coeff of restitution 2024-04-26 11:22:53 -04:00
626e922b4f Graph including coeff-restitution plot. Discussed calculation with Kaputa, use average velocity Eqs.
Needs work to add equation, inbounds/outbounds calculation on tracking graph
2024-04-26 09:44:28 -04:00
f0aaa5cffc
Merge branch 'stable' into devel 2024-04-18 16:13:49 -04:00
df51969535
Reorganise script for slightly faster loading 2024-04-18 16:06:11 -04:00
05f6cca022
User define input CSV file to call 2024-04-18 15:53:49 -04:00
e7db450787
Trim down required code, label values better 2024-04-18 14:44:16 -04:00
785943eeb3
Basic REST request send/recieve
As of now, this requires working comms-layer on the same device, running
at localhost:8000 to properly run. This will be changed in future
2024-04-17 17:11:33 -04:00
4e1847ec1e
Add CSV parsing 2024-04-16 16:26:55 -04:00
dabd967bd4
Add base docker file 2024-03-28 16:57:59 -04:00
39f46a4337
Local download of js library; reformat page
Page is now ready for demonstration purposes
Plotly is downloaded to allow the final project to be run without need
to access a CDN, and so the library can be directly built into the
container
2024-03-28 16:00:52 -04:00
71ea3a10e0
Update readme to include basic information 2024-03-28 14:28:00 -04:00
2f1df89d62
Finish proof of concept test page 2024-03-28 14:23:20 -04:00
9504cb7108
Successfully run Plotly HelloWorld 2024-03-28 13:57:16 -04:00
8306850bfe
Start development of view
Currently have the base hello world, with a div for the graph to
eventually go in.
Plan to use Plotly libraries for 3D graphing
2024-03-28 13:25:05 -04:00
2 changed files with 289 additions and 3 deletions

197
graph.js Normal file
View file

@ -0,0 +1,197 @@
//Create delay function
const delay = ms => new Promise(res => setTimeout(res, ms));
//Tennis court coordinates
//Y: [-5.02m, 5.02m] X: [-11.88m, 11.88m] no Z height
var x = [-11.88, 11.88, 11.88, -11.88]
var y = [-5.02, -5.02, 5.02, 5.02]
//Shift the court slightly up so its not interfering with the grid
var z = [0.01, 0.01, 0.01, 0.01]
//Face is made up of 2 triangles, both need to be set to the same colour
var facecolor = [ 'rgb(30, 175, 0)', 'rgb(30, 175, 0)', ]
var court = { name:"Court", x, y, z, facecolor, type: 'mesh3d', }
var x_val =new Array();
var y_val =new Array();
var z_val =new Array();
var trajectory = {
name: "Trajectory",
type: 'scatter3d',
mode: 'lines+markers',
x: x_val,
y: y_val,
z: z_val,
line: {
width: 4,
color: '#ff0000',
},
marker: {
color: '#0000ff',
size: 2,
symbol: 'circle',
},
};
var layout = {
title: 'Tennis Ball Trajectory Plot',
autosize: true,
margin: { autoexpand: true, },
scene:{
xaxis:{ range:[-18,18], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", },
yaxis:{ range:[-10,10], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", },
zaxis:{ range:[ 0, 2], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", },
}
};
//COEFF = document.getElementById("cor_plot");
var pointCount = 1600;
var coeff_restitution = 0;
var velocity_vector_pre = 1;
var velocity_vector_post = 1;
var bounce_sample = new Array();
var center_bounce = 0;
var sample = new Array();
// variables for failed PolynomialRegression attempt
//const vector_length = 1; // Determines how many points back to use to calculate average z-velocity
//const degree = 3;
//var sample_division = new Array();
// Failed implementation for PolynomialRegression library
// Implementation using regression to create a function that models all points of bounce
// Third order polynomial has 3 zeros and is the minimum number necessary
//const regression = new PolynomialRegression(sample, z_val, degree)
// for(let point = 0; point < pointCount * 10; point++)
// {
// //sample_division[point] = regression.predict(point / 10)
// if(sample_division[point] > 0.005 && sample_division[point] < 0.015)
// // gathers all sub-points within the regression that fall at a "bounce height"
// // but this could result in more than one point being recorded. needs to have one centered
// // point. gather into array and then take the middle value?
// {
// bounce_sample.push(point);
// }
// }
// center_bounce = Math.floor((bounce_sample.length - 1) / 2); // find center of sample
//make sure that this can be indexed within the regression. Is this 10x the actual array size?
// velocity_vector_pre = regression.predict(bounce_sample[center_bounce - 1]);
// velocity_vector_post = regression.predict(bounce_sample[center_bounce + 1]);
// coeff_restitution = Math.abs(velocity_vector_post) / Math.abs(velocity_vector_pre);
var cor_trace1 = {
name: "2D Tennis Ball Bounce",
type: 'scatter',
mode: 'lines+markers',
x:sample,
y:z_val,
};
var data = [cor_trace1,];
var cor_layout = {
title: '2D Tennis Ball Bounce Graph',
autosize: true,
margin: { autoexpand: true, },
scene:{
xaxis:{ range:[0,1800], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", },
yaxis:{ range:[-10,10], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", },
}
};
//Init plot
Plotly.newPlot("secondplot", [trajectory,court] , layout, {responsive: true} );
Plotly.newPlot('cor_plot', data, cor_layout, {responsive: true} );
//Update plot with info from GET call
function poll(filename) {
var jqueryRequest = $.get("http://129.21.94.11:8000/serve/" + filename)
.done(function(data) {
Papa.parse(data, {
dynamicTyping: true,
delimiter: " ",
//Only include if the input contains a header row; i.e. the first row is labels.
//header: true,
worker: true,
complete: function(results){
results.data.forEach((element) => {
x_val.push(element[2]);
y_val.push(element[0]);
//Compensate for court offset
z_val.push(element[1]+0.01);
});
console.log(x_val.length)
pointCount = x_val.length;
for (let point = 0; point < pointCount; point++)
{
sample.push(point); // Create a series for just sample count
}
console.log(sample)
Plotly.update("secondplot", [trajectory,court], layout, {responsive: true});
Plotly.update('cor_plot', data, cor_layout, {responsive: true});
console.log(pointCount)
},
});
}).fail(function(errorData){
console.error("Backend Request failed! Is the backend running?");
});
}
//Get the button from the HTML file
var button = document.getElementById("sendPost");
//Get the input field from the HTML file
var input_field = document.getElementById("csvSelector");
//If the user presses "enter" on the input field, call to press the button, as this is expected behaviour
input_field.addEventListener("keypress",function(event){
if (event.key === "Enter"){
event.preventDefault();
button.click();
}
});
//On button click...
button.addEventListener("click",function(e){
//Get the file name from the text input
var file_name = input_field.value;
//Send the text input to the web server
$.post("http://129.21.94.11:8000/serve", { file_name })
//Once the POST response comes back
.done(function(){
//Wait 2s for image processing to run
delay(2000);
//Clear current values to graph the new file
x_val.length = 0;
y_val.length = 0;
z_val.length = 0;
sample.length = 0;
//Run a GET call, with the given file name
poll(file_name);
//FitCurve(sample, z_val);
});
},false);
//Failed test implementation for polyfit library
//function FitCurve(x, y)
//{
// var poly = Polyfit(x, y);
// solver = poly.getPolynomial(degree);
// console.log(solver(1.17));
//}

View file

@ -1,3 +1,5 @@
//Create delay function
const delay = ms => new Promise(res => setTimeout(res, ms));
@ -13,7 +15,7 @@ var facecolor = [ 'rgb(30, 175, 0)', 'rgb(30, 175, 0)', ]
var court = { name:"Court", x, y, z, facecolor, type: 'mesh3d', }
var x_val =new Array();
var x_val =new Array();
var y_val =new Array();
var z_val =new Array();
@ -46,12 +48,76 @@ var layout = {
}
};
//COEFF = document.getElementById("cor_plot");
var pointCount = 1600;
var coeff_restitution = 0;
var velocity_vector_pre = 1;
var velocity_vector_post = 1;
var bounce_sample = new Array();
var center_bounce = 0;
var sample = new Array();
// variables for failed PolynomialRegression attempt
//const vector_length = 1; // Determines how many points back to use to calculate average z-velocity
//const degree = 3;
//var sample_division = new Array();
// Failed implementation for PolynomialRegression library
// Implementation using regression to create a function that models all points of bounce
// Third order polynomial has 3 zeros and is the minimum number necessary
//const regression = new PolynomialRegression(sample, z_val, degree)
// for(let point = 0; point < pointCount * 10; point++)
// {
// //sample_division[point] = regression.predict(point / 10)
// if(sample_division[point] > 0.005 && sample_division[point] < 0.015)
// // gathers all sub-points within the regression that fall at a "bounce height"
// // but this could result in more than one point being recorded. needs to have one centered
// // point. gather into array and then take the middle value?
// {
// bounce_sample.push(point);
// }
// }
// center_bounce = Math.floor((bounce_sample.length - 1) / 2); // find center of sample
//make sure that this can be indexed within the regression. Is this 10x the actual array size?
// velocity_vector_pre = regression.predict(bounce_sample[center_bounce - 1]);
// velocity_vector_post = regression.predict(bounce_sample[center_bounce + 1]);
// coeff_restitution = Math.abs(velocity_vector_post) / Math.abs(velocity_vector_pre);
var cor_trace1 = {
name: "2D Tennis Ball Bounce",
type: 'scatter',
mode: 'lines+markers',
x:sample,
y:z_val,
};
var data = [cor_trace1,];
var cor_layout = {
title: '2D Tennis Ball Bounce Graph',
autosize: true,
margin: { autoexpand: true, },
scene:{
xaxis:{ range:[0,1800], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", },
yaxis:{ range:[-10,10], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", },
}
};
//Init plot
Plotly.newPlot("secondplot", [trajectory,court] , layout, {responsive: true} );
Plotly.newPlot('cor_plot', data, cor_layout, {responsive: true} );
//Update plot with info from GET call
function poll(filename) {
var jqueryRequest = $.get("http://192.168.0.90:8000/serve/" + filename)
var jqueryRequest = $.get("http://129.21.94.11:8000/serve/" + filename)
.done(function(data) {
Papa.parse(data, {
dynamicTyping: true,
@ -66,7 +132,18 @@ function poll(filename) {
//Compensate for court offset
z_val.push(element[1]+0.01);
});
console.log(x_val.length)
pointCount = x_val.length;
for (let point = 0; point < pointCount; point++)
{
sample.push(point); // Create a series for just sample count
}
console.log(sample)
Plotly.update("secondplot", [trajectory,court], layout, {responsive: true});
Plotly.update('cor_plot', data, cor_layout, {responsive: true});
console.log(pointCount)
},
});
}).fail(function(errorData){
@ -93,7 +170,7 @@ button.addEventListener("click",function(e){
//Get the file name from the text input
var file_name = input_field.value;
//Send the text input to the web server
$.post("http://192.168.0.90:8000/serve", { file_name })
$.post("http://129.21.94.11:8000/serve", { file_name })
//Once the POST response comes back
.done(function(){
//Wait 2s for image processing to run
@ -102,7 +179,19 @@ button.addEventListener("click",function(e){
x_val.length = 0;
y_val.length = 0;
z_val.length = 0;
sample.length = 0;
//Run a GET call, with the given file name
poll(file_name);
//FitCurve(sample, z_val);
});
},false);
//Failed test implementation for polyfit library
//function FitCurve(x, y)
//{
// var poly = Polyfit(x, y);
// solver = poly.getPolynomial(degree);
// console.log(solver(1.17));
//}