Commit 4cb362e2 authored by Wouter Klop's avatar Wouter Klop

First system ID working. R parameter added to web interface (controls amount...

First system ID working. R parameter added to web interface (controls amount of setpoint used for error signal of PID controller)
parent 985906a0
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -7,64 +7,71 @@ dataPath = 'data/';
fieldNames = {'accAngle','filterAngle',...
'setpoint1','input1','output1',...
'setpoint2','input2','output2',...
'setpoint3','input3','output3'};
'setpoint3','input3','output3','dist'};
%% Find all .csv files
files = dir([dataPath, '*.csv']);
fileNames = {files.name}.';
%% Read .csv file
file = fileNames{1};
file = fileNames{7};
dRaw = csvread([dataPath, file], 1, 0);
t = dRaw(:,1) - dRaw(1,1);
d = cell2struct(num2cell(dRaw(:,2:end),1), fieldNames,2);
dT = mean(diff(t));
Fs = 1/dT;
%% Plot some time domain data
y = d.filterAngle;
u = d.output1;
e = d.setpoint1-d.input1;
ds = d.dist;
%% Plot some data
figure(1)
clf
subplot(221)
plot(t, d.accAngle)
hold on
plot(t, d.filterAngle)
plot(t, d.setpoint1, 'g--')
hold off
plot(t, u)
subplot(222)
plot(t, d.output1)
plot(t,ds)
%% Calculate some FFTs
X = fft(d.filterAngle);
Y = fft(d.output1);
%% Try to do system ID
[S, f2] = tfestimate(ds, u, [],[],[],Fs);
PS = tfestimate(ds, y);
H = PS./S;
C = ((1./S)-1)./H;
l = floor(length(X)/2)*2;
X = X(1:l/2+1);
Y = Y(1:l/2+1);
f = (1/dT)*(1:l/2+1)/l;
Cs = mscohere(ds, u);
Cps = mscohere(ds, y);
figure(2)
figure(5)
clf
subplot(311)
loglog(f2, abs([S PS]))
legend('S', 'PS')
ylabel('Magnitude')
subplot(312)
semilogx(f2, angle([S PS])*180/pi)
ylabel('Phase [deg]')
subplot(313)
semilogx(f2, [Cs Cps])
ylabel('Coherence [-]')
xlabel('Frequency [Hz]')
figure(6)
subplot(211)
loglog(f, abs(X))
hold on
loglog(f, abs(Y))
hold off
loglog(f2, abs([H C H.*C]))
legend('H_1', 'C_1', 'C_1H_1')
ylabel('Magnitude')
subplot(212)
semilogx(f, angle(X)*180/pi)
hold on
semilogx(f, angle(Y)*180/pi)
hold off
semilogx(f2, angle([H C])*180/pi)
ylabel('Phase [deg]')
xlabel('Frequency [Hz]')
%% Run FRF
[txy, f] = tfestimate(d.output1,d.filterAngle);
figure(2)
clf
subplot(211)
loglog(abs(txy))
\ No newline at end of file
......@@ -42,13 +42,13 @@
document.getElementById(e.id+'_value').value=e.value; // update slider-value in textfield
}
function sendData(e) {
updateSliderText(e);
// var id = event.target.id;
// var val = parseFloat(document.getElementById(id).value).toString(10);
var val = e.value;
var val2 = e.id + val + 'x';
console.log(val2);
connection.send(val2);
updateSliderText(e);
}
function sendCommand(cmd, val) {
var text = cmd + val + 'x';
......@@ -115,6 +115,7 @@
I: <input id="c1i" type="range" min="0" max="1" step="0.01" oninput=sendData(this);><input type="text" id="c1i_value" readonly value="" style="width:40px"><br />
D: <input id="c1d" type="range" min="0" max="0.3" step="0.001" oninput=sendData(this);><input type="text" id="c1d_value" readonly value="" style="width:40px"><br />
N: <input id="c1n" type="range" min="0" max="50" step="0.1" oninput=sendData(this);><input type="text" id="c1n_value" readonly value="" style="width:40px"><br />
R: <input id="c1r" type="range" min="0" max="1" step="0.01" oninput=sendData(this);><input type="text" id="c1r_value" readonly value="" style="width:40px"><br />
Max: <input id="c1m" type="range" min="0" max="50" step="0.1" oninput=sendData(this);><input type="text" id="c1m_value" readonly value="" style="width:40px"><br />
Min: <input id="c1o" type="range" min="0" max="50" step="0.1" oninput=sendData(this);><input type="text" id="c1o_value" readonly value="" style="width:40px"><br />
<input id="c1t" type="radio" name="cType" value="0" onchange=sendData(this);>P
......@@ -123,10 +124,11 @@
<input id="c1t" type="radio" name="cType" value="3" onchange=sendData(this);>PID<br />
</td><td>
Pos:<br />
P: <input id="c2p" type="range" min="0.1" max="10" step="0.1" oninput=sendData(this);><input type="text" id="c2p_value" readonly value="" style="width:40px"><br />
P: <input id="c2p" type="range" min="0" max="10" step="0.1" oninput=sendData(this);><input type="text" id="c2p_value" readonly value="" style="width:40px"><br />
I: <input id="c2i" type="range" min="0" max="5" step="0.01" oninput=sendData(this);><input type="text" id="c2i_value" readonly value="" style="width:40px"><br />
D: <input id="c2d" type="range" min="0" max="3" step="0.01" oninput=sendData(this);><input type="text" id="c2d_value" readonly value="" style="width:40px"><br />
N: <input id="c2n" type="range" min="0" max="50" step="0.1" oninput=sendData(this);><input type="text" id="c2n_value" readonly value="" style="width:40px"><br />
R: <input id="c2r" type="range" min="0" max="1" step="0.01" oninput=sendData(this);><input type="text" id="c2r_value" readonly value="" style="width:40px"><br />
Max: <input id="c2m" type="range" min="0" max="50" step="0.1" oninput=sendData(this);><input type="text" id="c2m_value" readonly value="" style="width:40px"><br />
Min: <input id="c2o" type="range" min="0" max="50" step="0.1" oninput=sendData(this);><input type="text" id="c2o_value" readonly value="" style="width:40px"><br />
<input id="c2t" type="radio" name="cType" value="0" onchange=sendData(this);>P
......@@ -139,6 +141,7 @@
I: <input id="c3i" type="range" min="0" max="5" step="0.01" oninput=sendData(this);><input type="text" id="c3i_value" readonly value="" style="width:40px"><br />
D: <input id="c3d" type="range" min="0" max="0.3" step="0.001" oninput=sendData(this);><input type="text" id="c3d_value" readonly value="" style="width:40px"><br />
N: <input id="c3n" type="range" min="0" max="50" step="0.1" oninput=sendData(this);><input type="text" id="c3n_value" readonly value="" style="width:40px"><br />
R: <input id="c3r" type="range" min="0" max="1" step="0.01" oninput=sendData(this);><input type="text" id="c3r_value" readonly value="" style="width:40px"><br />
Max: <input id="c3m" type="range" min="0" max="50" step="0.1" oninput=sendData(this);><input type="text" id="c3m_value" readonly value="" style="width:40px"><br />
Min: <input id="c3o" type="range" min="0" max="50" step="0.1" oninput=sendData(this);><input type="text" id="c3o_value" readonly value="" style="width:40px"><br />
<input id="c3t" type="radio" name="cType" value="0" onchange=sendData(this);>P
......
......@@ -47,7 +47,7 @@ Signals to plot<br />
<legend>Signal generation</legend>
<button id="noiseOn" onclick="sendCommand('pn',1)">Start</button>
<button id="noiseOff" onclick="sendCommand('pn',0)">Stop</button><br />
<input id="noiseAmplitude" type="range" min="0.1" max="10" step="0.1" oninput="sendCommand('pa',this.value);document.getElementById('noiseAmplitude_value').value = this.value;">
<input id="noiseAmplitude" type="range" min="0.1" max="20" step="0.1" oninput="sendCommand('pa',this.value);document.getElementById('noiseAmplitude_value').value = this.value;">
<input type="text" id="noiseAmplitude_value" readonly value="" style="width:40px"><br />
</fieldset>
......@@ -76,6 +76,7 @@ for (var i=0; i<nSignal; i++) data[i].fill(0,0,nSample);
var logData = new Array(nSignal);
for (var i=0; i<nSignal; i++) logData[i] = new Array;
var settingList = [];
var updateChart = function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
......@@ -108,6 +109,7 @@ connection.onerror = function (error) {
connection.onmessage = function (e) {
if (typeof(e.data)=='string') { // Text frame
settingList.push(e.data);
} else { // Binary
var d = e.data;
var dv = new DataView(d);
......@@ -135,6 +137,12 @@ var exportLogData = function() {
if (l>0) {
var csvFile = '';
// Add header with all settings
for (var i=0; i<settingList.length; i++) {
csvFile += settingList[i];
if (i<settingList.length) csvFile += ',';
}
for (var i=0; i<l; i++) {
for (var j=0; j<nSignal; j++) {
// logData.forEach(function(x) {
......
......@@ -380,6 +380,7 @@ void loop() {
static uint32_t lastInputTime = 0;
uint32_t tNowMs;
float absSpeed = 0;
float noiseValue = 0;
unsigned long tNow = micros();
tNowMs = millis();
......@@ -442,14 +443,19 @@ void loop() {
// Optionally, add some noise to angle for system identification purposes
if (noiseSourceEnable) {
pidAngle.input = filterAngle + noiseSourceAmplitude*((random(1000)/1000.0)-0.5);
} else {
// if (noiseSourceEnable) {
// pidAngle.input = filterAngle + noiseSourceAmplitude*((random(1000)/1000.0)-0.5);
// } else {
pidAngle.input = filterAngle;
}
// }
pidAngleOutput = pidAngle.calculate();
if (noiseSourceEnable) {
noiseValue = noiseSourceAmplitude*((random(1000)/1000.0)-0.5);
pidAngleOutput += noiseValue;
}
avgMotSpeedSum += pidAngleOutput/2;
if (avgMotSpeedSum>maxStepSpeed) {
avgMotSpeedSum = maxStepSpeed;
......@@ -512,9 +518,9 @@ void loop() {
uint8_t fill1;
uint8_t fill2;
uint8_t fill3;
float f[12];
float f[13];
};
uint8_t b[52];
uint8_t b[56];
} plotData;
plotData.f[0] = micros()/1000000.0;
......@@ -529,6 +535,7 @@ void loop() {
plotData.f[9] = pidSpeed.setpoint;
plotData.f[10] = pidSpeed.input;
plotData.f[11] = pidSpeedOutput;
plotData.f[12] = noiseValue;
wsServer.sendBIN(0, plotData.b, sizeof(plotData.b));
}
}
......@@ -875,6 +882,8 @@ void sendConfigurationData(uint8_t num) {
wsServer.sendTXT(num, wBuf);
sprintf(wBuf, "c%dn%.4f", 1, pidAngle.N);
wsServer.sendTXT(num, wBuf);
sprintf(wBuf, "c%dr%.4f", 1, pidAngle.R);
wsServer.sendTXT(num, wBuf);
sprintf(wBuf, "c%dm%.4f", 1, pidAngle.maxOutput);
wsServer.sendTXT(num, wBuf);
sprintf(wBuf, "c%do%.4f", 1, -pidAngle.minOutput);
......@@ -887,6 +896,8 @@ void sendConfigurationData(uint8_t num) {
wsServer.sendTXT(num, wBuf);
sprintf(wBuf, "c%dn%.4f", 2, pidPos.N);
wsServer.sendTXT(num, wBuf);
sprintf(wBuf, "c%dr%.4f", 2, pidPos.R);
wsServer.sendTXT(num, wBuf);
sprintf(wBuf, "c%dm%.4f", 2, pidPos.maxOutput);
wsServer.sendTXT(num, wBuf);
sprintf(wBuf, "c%do%.4f", 2, -pidPos.minOutput);
......@@ -899,6 +910,8 @@ void sendConfigurationData(uint8_t num) {
wsServer.sendTXT(num, wBuf);
sprintf(wBuf, "c%dn%.4f", 3, pidSpeed.N);
wsServer.sendTXT(num, wBuf);
sprintf(wBuf, "c%dr%.4f", 3, pidSpeed.R);
wsServer.sendTXT(num, wBuf);
sprintf(wBuf, "c%dm%.4f", 3, pidSpeed.maxOutput);
wsServer.sendTXT(num, wBuf);
sprintf(wBuf, "c%do%.4f", 3, -pidSpeed.minOutput);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment