-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample13.html
356 lines (306 loc) · 16.3 KB
/
example13.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
<title>Example with potentialmetter</title>
</head>
<body onload="load()">
<div>Server conected, board is ready.</div>
<div>
<canvas id="potValuesCanvas" width ="200" height = "100" style="border: 1px dashed #00c3c3;"></canvas>
<canvas id="errorCanvas" width = "200" height = "100" style="border: 1px dashed #00c3c3;"></canvas>
<canvas id="performanceCanvas" width = "200" height = "100" style="border: 1px dashed #00c3c3;"></canvas>
</div>
<br>
<div>
<canvas id="pwmCanvas" width = "200" height = "100" style="border: 1px dashed #00c3c3;"></canvas>
<canvas id="integralCanvas" width = "200" height = "100" style="border: 1px dashed #00c3c3;"></canvas>
<canvas id="absErrorCanvas" width = "200" height = "100" style="border: 1px dashed #00c3c3;"></canvas>
</div>
<br>
<div>
<canvas id="comparationCanvas" width = "200" height = "100" style="border: 1px dashed #00c3c3;"></canvas>
<canvas id="derivativeCanvas" width = "200" height = "100" style="border: 1px dashed #00c3c3;"></canvas>
<canvas id="testInputCanvas" width = "200" height = "100" style="border: 1px dashed #00c3c3;"></canvas>
</div>
<br>
<div>
Position: <input id="position" value=200 />
Set Algorithm: <input id="algorithmId" value=1 />
<button id="sendPosition" onClick="sendPosition()">Send position</button>
Pulse duration in s: <input id="pulseDuration" value="7" size="5" />
<button id="pulse" onClick="pulse()">Send pulse</button>
<button id="pulse" onClick="testInputTimed()" style="width:160;height:24; background-color:#ff4c4c">Send Test Input</button>
<button id="step" onClick="testInputTimedFeedback();" style="width:160;height:24; background-color:#4cff4c">Send Step</button>
<button id="pulsetimed" onClick="pulseTimed()">Send pulse Timed</button>
<button id="testFunction" onClick="startTestFunction()">Send test Func</button>
<button id="buttonStop" onClick="stop()">STOP</button>
<br>
</div>
pCoeff: <input id="pCoeff" value="0.1" size="5" />
<button id="buttonStartControlAlgorithm1" onClick="startControlAlgorithm(1)">Start Ctrl Alg1</button>
<br>
Kp: <input id="Kp1" value="0.15" size="5" />
Ki: <input id="Ki1" value="0.0055" size="5" />
Kd: <input id="Kd1" value="0.25" size="5" />
<button id="buttonStartControlAlgorithm2" onClick="startControlAlgorithm(2)">Start Ctrl Alg2</button>
<button id="buttonStopControlAlgorithm" onClick="stopControlAlgorithm()">Stop Ctrl Alg</button>
<br>
<div id="divForStaticPrint"> </div>
<br>
<div>desiredValue | actualValue | Difference | PWM</div>
<div id="print1"></div>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
"use strict";
class Graph {
constructor(canvasId, minGraphX, maxGraphX, minGraphY, maxGraphY, color, legend, axisDescription) {
this.canvas = document.getElementById(canvasId);
this.ctx = this.canvas.getContext("2d");
this.canvasWidth = this.canvas.width;
this.canvasHeight = this.canvas.height;
this.x = [];
this.y = [];
this.rangeX = maxGraphX - minGraphX;
this.rangeY = maxGraphY - minGraphY;
// create y array (size) according to the color vector (could have multiple rows i.e. 2d)
for( var i=0; i<color.length; i++ ) {
this.y.push([]); // example of three row array init. would be: this.y = [[],[],[]];
}
this.minGraphX = minGraphX;
this.maxGraphX = maxGraphX;
this.minGraphY = minGraphY;
this.maxGraphY = maxGraphY;
this.color = color; // color of the graph
this.legend = legend;
this.axisDescription = axisDescription;
// fill x vector; vector y is filled in real-time
for (var i=0; i<this.maxGraphX+1; i++) {
this.x[i] = i; // values for the x coordinate; 0, 1, 2, ...
}
}
addValueOrCutAndAdd(yValue) {
if (this.y[0].length == this.maxGraphX+1) { // if canvas size is 10x10 we have 11x11 points (starting with 0 and ending with 10)
for (var i = 0; i < yValue.length; i++) {
this.y[i].splice(0, 1);
this.y[i][this.maxGraphX] = yValue[i];
}
} else {
for (var i = 0; i < yValue.length; i++) {
this.y[i].push(yValue[i]);
}
}
}
plot(yValue) {
this.addValueOrCutAndAdd(yValue);
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
for (var i=0; i < yValue.length; i++) {
this.ctx.strokeStyle = this.color[i];
this.ctx.beginPath();
for (var j=0; j<this.y[0].length; j++) {
this.ctx.lineTo(this.x[j]/this.rangeX*this.canvasWidth, (this.canvasHeight - ((this.y[i][j]-this.minGraphY)/this.rangeY) * this.canvasHeight));
}
this.ctx.stroke();
}
// add legend
for( var i=0; i<this.legend.length; i++ ) { // legend and color should be of the same size
this.ctx.font = "11px Arial";
this.ctx.fillText(this.legend[i], 49+i*54, 10);
this.ctx.strokeStyle = this.color[i];
this.ctx.beginPath();
this.ctx.lineTo(37+i*54, 6);
this.ctx.lineTo(46+i*54, 6);
this.ctx.stroke();
}
// add axis descritions
this.ctx.fillText("<-" + this.axisDescription[0] + "|" + this.axisDescription[1] + "->", 150, 95)
this.ctx.fillText(this.axisDescription[2], 5, 95);
this.ctx.fillText(this.axisDescription[3], 5, 11);
}
}
var numberOfLinesBeforeScroll = 20;
var linesPrintCounter = 0;
var potValue1 = 0; // value of the first potentiometer
var potValue2 = 0; // value of the second potentiometer
var potValuesGraph;
var pwmGraph;
var errorGraph;
var integralGraph;
var comparationGraph;
var derivativeGraph;
var performanceGraph;
var absErrorGraph;
var testInputGraph;
var pwm;
var intervalPulseFunction;
var intervalTestFunction; // for setTimeout / setInterval
var timeCounter = 0;
var performanceMeasure = 0;
var divElement = document.getElementById("print1"); // variable for div object where the values will be printed (logged)
var socket = io.connect("192.168.1.134:8080");
function log(msg) {
var node=document.createElement("tr"); // we create the variable node as the a table row (tr)
var textnode=document.createTextNode(linesPrintCounter + " | " + msg); // we create element with the text adding the counter
node.appendChild(textnode); // adding text to "node", i.e. table row
divElement.insertBefore(node, divElement.childNodes[0]); // inserting into variable node
if (linesPrintCounter > numberOfLinesBeforeScroll-1) { // if the lines are more than limit -> start with scroll
divElement.removeChild(divElement.childNodes[numberOfLinesBeforeScroll]); // we remove the oldest printout
}
linesPrintCounter++; // increasing the number of printouts
}
function load() {
potValuesGraph = new Graph("potValuesCanvas", 0, 200, 0, 1023, ["red", "green"], ["desired", "actual"], ["0", "200", "0", "1023"]); // arguments: Arg1: canvasId, Arg2: maxX, Arg3: maxY, Arg4: [vector of colors]; this determines the size
pwmGraph = new Graph("pwmCanvas", 0, 200, -254, 254, ["orange"], ["PWM"], ["0", "200", "-254", "254"]);
comparationGraph = new Graph("comparationCanvas", 0, 200, -100, 100, ["red", "green", "blue"], ["KpE", "KiIedt", "KdDe_dt"], ["0", "200", "-100", "100"]);
errorGraph = new Graph("errorCanvas", 0, 200, -1023, 1023, ["red"], ["Error"], ["0", "200", "-1023", "1023"]);
integralGraph = new Graph("integralCanvas", 0, 200, -10000, 10000, ["red"], ["Integ(Err*dt)"], ["0", "200", "-10000", "10000"]);
derivativeGraph = new Graph("derivativeCanvas", 0, 200, -150, 150, ["red"], ["dError/dt"], ["0", "200", "-150", "150"]);
performanceGraph = new Graph("performanceCanvas", 0, 2000, 0, 500000, ["red"], ["Int(Abs(Error)dt)"], ["0", "2000", "0", "0.5M"]);
absErrorGraph = new Graph("absErrorCanvas", 0, 200, 0, 1000, ["red"], ["errAbs"], ["0", "200", "0", "1000"]);
testInputGraph = new Graph("testInputCanvas", 0, 200, 0, 1000, ["red"], ["errAbs"], ["0", "200", "0", "1000"]);
};
socket.on("messageToClient", function (msg){
log(msg); // add msg
});
socket.on('staticMsgToClient', function(msg) { // when we receive the message
document.getElementById("divForStaticPrint").innerHTML = "Status: " + msg; // we print it to div
});
socket.on("clientReadValues", function(value) {
potValue1 = value.desiredValue;
potValue2 = value.actualValue;
pwm = parseInt((value.pwm).toFixed(0), 10);
potValuesGraph.plot([potValue1, potValue2]); // desired Vs actual graph
pwmGraph.plot([pwm]); // plot pwm
// draw centerline in pwmGraph
pwmGraph.ctx.strokeStyle = "#add8e6";
pwmGraph.ctx.beginPath(); // draw centerline at 0
pwmGraph.ctx.lineTo(0, 50);
pwmGraph.ctx.lineTo(200, 50);
pwmGraph.ctx.stroke();
comparationGraph.plot([value.KpE, value.KiIedt, value.KdDe_dt]);
errorGraph.plot([value.err]); // graph for P part
integralGraph.plot([value.errSum]); // graph for I part
derivativeGraph.plot([value.dErr]); // graph for D part
performanceGraph.plot([value.errSumAbs]); // graph for performance measure
performanceGraph.ctx.fillText(parseInt(value.errSumAbs),70,27);
absErrorGraph.plot([value.errAbs]);
testInputGraph.plot([value.errAbs]);
log(potValue1 + "|" + potValue2 + "|" + (potValue1 - potValue2) + "|" + (value.pwm).toFixed(0) ); // log to div
});
socket.on("disconnect", function(){
log("Disconnected from the server"); // we print status of disconn. to div
});
function startControlAlgorithm (algorithmId, withFeedback) {
// first stop ctrlAlg, just in case
stopControlAlgorithm ();
var pCoeff = document.getElementById("pCoeff").value;
var Kp1 = document.getElementById("Kp1").value;
var Ki1 = document.getElementById("Ki1").value;
var Kd1 = document.getElementById("Kd1").value;
switch (algorithmId) {
case 1 :
socket.emit("startControlAlgorithm", {"ctrlAlgNo": 1, "pCoeff": pCoeff}); // send pCoeff value
break;
case 2:
socket.emit("startControlAlgorithm", {"ctrlAlgNo": 2, "Kp1": Kp1, "Ki1": Ki1, "Kd1": Kd1}); // send also parameters
break;
case 3:
socket.emit("startControlAlgorithm", {"ctrlAlgNo": 3}, withFeedback); // send value of coeff
break;
}
}
function sendPosition () {
var positionValue = document.getElementById("position").value;
startControlAlgorithm(Number(document.getElementById("algorithmId").value));
socket.emit("sendPosition", positionValue);
}
function pulse() {
var positionInterval = 300;
socket.emit("sendPosition", positionInterval); // at start we send position
intervalPulseFunction = setInterval(function() {
if (positionInterval == 300) {
positionInterval = 600;
} else {
positionInterval = 300;
}
socket.emit("sendPosition", positionInterval);
}, 2000);
}
function inputStep() {
var input = 200;
socket.emit("sendPosition", input);
setTimeout(function() {
input = 820;
socket.emit("sendPosition", input);
}, 6000);
}
function stop () {
document.getElementById("divForStaticPrint").innerHTML = document.getElementById("divForStaticPrint").innerHTML + " | C = " + performanceMeasure;
clearInterval(intervalPulseFunction);
clearInterval(intervalTestFunction);
stopControlAlgorithm();
}
function inputPulse() {
var input = 0;
socket.emit("sendPosition", input);
intervalPulseFunction = setInterval(function() {
if (input == 50) {
input = -50;
} else {
input = 50;
}
socket.emit("sendPosition", input);
}, 400);
}
var functionValue = 0;
function testFunction() {
var initialValue = 256;
switch (timeCounter >= 0) {
case (timeCounter <= 1000):
functionValue = initialValue + 0.5 * timeCounter;
break;
case (timeCounter > 1000 && timeCounter <= 1500):
functionValue = 256 + 500 + (-0.5 * (timeCounter - 1000)); // 500 = previous max value
break;
case (timeCounter > 1500 && timeCounter <= 2000):
functionValue = 506 + (0.5 * (timeCounter - 1500));
break;
case (timeCounter > 2000 && timeCounter <= 3000):
functionValue = 756 - 500 + 500 * Math.exp(-0.005 * (timeCounter - 2000)); // 756 - previous val; (756-220) - limit val
}
socket.emit("sendPosition", functionValue);
timeCounter++;
}
function startTestFunction () {
startControlAlgorithm(Number(document.getElementById("algorithmId").value));
timeCounter = 0;
intervalTestFunction = setInterval(function() {testFunction(), 10});
var pulseDuration = document.getElementById("pulseDuration").value;
setTimeout(function() {stop();}, pulseDuration * 1000);
}
function testInputTimed () {
document.getElementById("algorithmId").value = 3;
startControlAlgorithm(Number(document.getElementById("algorithmId").value), false);
inputPulse(); // starting pulse function for INPUT
var pulseDuration = document.getElementById("pulseDuration").value;
setTimeout(function() {stop();}, pulseDuration * 1000); // 30000
}
function testInputTimedFeedback () {
document.getElementById("algorithmId").value = 3;
startControlAlgorithm(Number(document.getElementById("algorithmId").value), true);
inputStep(); // starting pulse function for INPUT
//var pulseDuration = document.getElementById("pulseDuration").value;
//setTimeout(function() {stop();}, pulseDuration * 1000); // 30000
}
function stopControlAlgorithm () {
socket.emit("stopControlAlgorithm");
}
function pulseTimed () {
startControlAlgorithm(Number(document.getElementById("algorithmId").value));
pulse();
var pulseDuration = document.getElementById("pulseDuration").value;
setTimeout(function() {stop();}, pulseDuration * 1000); //pulseDuration in seconds
}
</script>
</body>
</html>