I got a TF of my plant G(s) = s + 10/3s^3 + 8s^2 + 30s + 25 and I would like to implement a PID controller so that the system closely follows the varying input signal, I used r(t) = 0.5sin(t) + 0.5. How can I calculate the correct setting for Kp, Ki and Kd to do this without guessing random values?
I made this feedbackloop in simulink
And I want an output signal that follows the input signal, so the yellow and blue line should lie on eachother.
Related
Take a look at the following simple system
where Kp=7130 and Kd=59.3880. These values are designed so that the system should exhibit an overshoot of 20% and steady-state error less than 0.01. The Simulink model yields correct results whereas tf() doesn't. This is the model
and its result is
Now implementing same system with tf as follows:
clear all
clc
kp=7130;
kd=59.3880;
num=[kd kp];
den=[1 18+kd 72+kp];
F=tf(num,den);
step(F)
stepinfo(F)
yields different overshoot.
Any suggestions why there is an inconsistent response? Do I have to put the system in specific form in order to use tf()?
The error is considering correct the response of the Simulink implementation. step is giving you the correct response.
A pure derivative does not exists in Simulink, and if out try a transfer function block with [kd, kp] as numerator and [1] as denominator you will get an error.
The derivative is a filter with a pole when you use the fixed step integrator, the behavior with variable step is quite uncertain, and should be avoided. The closed loop system you get with your controller has relative degree one (1 zeros, 2 poles).
If you look at the response, the Simulink implementation starts with dy/dt = 0 for t = 0, and this is not possible with this kind of closed loop system. The correct response is the one of tf (dy/dt > 0 for t = 0).
Your closed loop transfer function is correct, and you should consider its response as correct. Try to simulate the transfer function in the image with Simulink. You will see the same response of the step command.
Let's test this with some code:
In the image we have three test:
the analytic transfer function
an approximation of the derivative
the simulation with your derivative block
Try to implement it and test the value of 0.001 in the tf s / (0.001 s + 1), you will see that if you decrease the coefficient towards 0, the response of Transfer Fnc2 will approximate the one of the analytic closed loop tf (up to a point Simulink will not evaluate the derivative and will stop the simulation).
And finally, the analytic transfer function in Simulink gives the same response of the step command.
In the comment you said you evaluated the inverse laplace, so let us check also the inverse laplace. The symbolic toolbox will do that for us:
syms s kp kd t
Plant = 1/(s^2 + 18 * s + 72)
Reg = kp + kd * s
L = Plant * Reg
ClosedLoop = simplify(L / (1 + L))
Step = 1/s
ResponseStep = simplify(ilaplace(ClosedLoop * Step))
ResponseStep_f = matlabFunction(simplify( ...
subs( ...
subs(ResponseStep, kp, 7130), kd, 59.3880)));
t_ = linspace(0, 0.15, 200);
y_ = arrayfun(t_closedLoop_d, t_);
plot(t_, y_);
as you can see the inverse Laplace shows an overshoot of more than 25%.
EDIT: Evaluating the inverse Laplace that you evaluated at this link
Again the overshoot is at 25.9%
I am processing a real audio data which consists of three different signals of the same frequency. Those three signals are consisted of 7 beeps and are different in length and energy level. (For every signal, the delay between each beep is different)
Signal 1:
Signal 2:
Signal 3
My goal is to filter out every of these signal using the respective matched filter. But the problem is the strength of the signal 1 is too high and I can not apply the other signals matched filter for the data (because the signal 1 will mask the filtering results of other matched filter).
I try to put the process in a loop. After each loop, the filtered signal will be subtracted from the data. But in many cases, the beeps from one signal will be aligned with the beeps of other ones (as in the second picture: the final beep of signal 2 is masked by the stronger beep of another signal).
My questions are:
How can I correctly subtract the stronger signals without affecting the weaker ones?
After matched filtering, I only got the energy of the signal and matching position. Is there any way to determine the peaks of the beeps from this energy?
Edit:
This is my code to extract the strongest signal:
t_matched = 165428; %matching position
ct3133 = signal_generator(ones(250,1), fs/25, 380, 640, 460, 640, 400, 640); %generate the "signal 1"
n = length(ct3133);
signal_size = length(A222203_30s_d);
t_begin = t_matched - 3.16*fs/25 -125-5; %position where the signal 1 begin to transmitted
% 3.16(s) = (380 + 640 + 460 + 640 + 400 + 640)(ms)
% 25: decimation factor
% 125: the length of 1 beep (10ms)
% 5: correction coeffecient due to the dealy between each beep is not ideal.
%Extracting the signal 1
signal = cat(1, zeros(t_begin, 1), abs(ct3133), zeros(signal_size - t_begin - n, 1));
ct3133_sup = abs(ones(length(signal),1)-signal);
ct3133_extracted = A222203_30s_d.*ct3133_sup;
With this method, I was able to remove the Signal 1 from the input data. However, this also removed the last beep of the signal 2 which is masked by the fifth beep of the signal 1.
With the last beep of the signal 2 gone, the signal 2 can be detected by a corresponded matched filter but the matching position is not correct. Therefore, the future operation of removing the signal 2 can not be performed.
Edit 2:
Here is some graph and data after the extracting of signal 1 operation.
Signal 1 peak and location values:
0.0413 & 125804
0.0411 & 130555
0.0410 & 138555
0.0415 & 144305
0.0417 & 152305
0.0413 & 157306
0.0415 & 165306
Matched filtering result of signal 1 (X: matched position, Y: Signal 1 Energy):
X = 165427, Y = 21.32.
Input data after signal 1 is removed:
Clearly, the signal 2 only contains 6 beeps where it supposes to be 7.
Signal 2 peaks values and locations, respectively:
Peak 1: 0.00102 & 110460
Peak 2: 0.001114 & 115211
Peak 3: 0.001097 & 123211
Peak 4: 0.001141 & 128961
Peak 5: 0.001139 & 136711
Peak 6: 0.001119 & 145462
Result after filtering the above data with the matched filter of signal 2:
The peak value and location are : 0.3615 & 152383
*The location is the samples, data sampling rate : 12500Hz
I have a datasheet (around 100 samples) where for a real SISO system (DC motor), I know the input and output. With tfest command, I can form first order to nth order transfer function using the same data (loaded with iddata function) for the system.
But in real life the system can be either 1st order or nth order.
Like in MATLAB, using same iddat (contains the sample values), I can generate following transfer functions:
sys1 = tfest(iddat, 1, 1, 0.5); %number of zero=1, pole=1, 1st order system
sys1 =
From input "u1" to output "y1":
exp(-0.5*s) * (2.932 s - 0.1862) / (s + 1.082)
sys = tfest(iddat, 3, 2, 0.5);%number of zero=3, pole=2, 2nd order system
sys =
From input "u1" to output "y1":
exp(-0.5*s) * (0.1936 s^2 - 0.02193 s + 0.0006905) / ( s^3 + 0.07175 s^2 + 0.05526 s + 1.772e-13)
Can someone explain the scenario?
Fitting a model to an experimental data requires a minimum amount of knowledge about the underlying physical system.
Here you have a DC motor which probably does not have any zeros and no DC gain but you are forcing matlab to fit a proper 3rd order transfer function and it is giving you the closest one (not necessarily the correct one).
Instead remove the half a second delay and let the function find the time constant for you. So
tfest(iddat,1);
would be sufficient (or try with 3 if you are suspicious about the motor drive).
As far as I know the IFFT of spectrum which amplitude part is even symmetric and phase part is odd symmetric should be real.
Let's consider this example:
signal_spectrum = [1 2+i 3+2*i 4+8*i 5 4-8*i 3-2*i 2-i 1];
It's clear that this spectrum meets two conditions that I listed above. When I perform IFFT using Matlab I obtain:
signal= ifft(signal_spectrum) =
2.7778
0.8003 - 0.2913i
-1.2861 + 1.0792i
0.5218 - 0.9038i
-0.0812 + 0.4604i
0.0976 + 0.5536i
-0.6329 - 1.0962i
1.3343 + 1.1196i
-2.5316 - 0.9214i
Obtained signal is complex-valued. Why? What's the problem?
Just remove the last 1 from the vector :)
The symmetry should be relative to the first element.
You can think of it like circular buffer or one period of a periodical signal.
My objective is to classify non-speech signal for which I am using mfcc and dtw in java. However I am stuck in middle. I would appreciate any help.
I have evaluated 13 mfcc values for each frame however some values are negative, I am confused whether the process I am following is right or wrong. Currently I am using the code provided by JAudio. I have also tried other code, they give me negative values as well.
Secondly, I get 13 coefficients for each frame, considering 157 frames for a certain length of sample, I get 157 sets of 13 mfccs. I am having hard time how to use all the coefficients in DTW because dtw only gives closest distance between two time signals. I do have code of DTW to compare two time signals. I am not sure how to use all the mfccs values of the signal as features.
Is there some crucial step of classification I am missing? Please help me.
The use of DTW suppose to verify 2 audio sequences in your case. Thus, for the sequence to be verify you will have a matrix M1xN and for the query M2xN. This implies that your cost matrix will have M1xM2.
To construct the cost matrix you have to apply a distance/cost measure between the sequences, as cost(i,j) = your_chosen_multidimension_metric(M1[i,:],M2[j,:])
The resulted cost matrix will be 2D, and you could apply easily DTW.
I made a similar code for DTW based on MFCC. Below is the Python implementation which returs DTW score; x and y are the MFCC matrix of voice sequences, with M1xN and M2xN dimensions:
def my_dtw (x, y):
cost_matrix = cdist(x, y,metric='seuclidean')
m,n = np.shape(cost_matrix)
for i in range(m):
for j in range(n):
if ((i==0) & (j==0)):
cost_matrix[i,j] = cost_matrix[i,j]
elif (i==0):
cost_matrix[i,j] = cost_matrix[i,j] + cost_matrix[i,j-1]
elif (j==0):
cost_matrix[i,j] = cost_matrix[i,j] + cost_matrix[i-1,j]
else:
min_local_dist = cost_matrix[i-1,j]
if min_local_dist > cost_matrix[i,j-1]:
min_local_dist = cost_matrix[i,j-1]
if min_local_dist > cost_matrix[i-1,j-1]:
min_local_dist = cost_matrix[i-1,j-1]
cost_matrix[i,j] = cost_matrix[i,j] + min_local_dist
return cost_matrix[m-1,n-1]
Say you have N1 sets of 13 MFCCs each for the first signal and N2 sets of MFCCs for the second.
You should compute the distance between each set in from the first signal and each set from the second (you can use the Euclidian Distance for the distance between two 13-sized arrays)
This would leave you with an N1xN2 bidimensional array on which you should now apply the DTW.
Check out: http://code.google.com/p/aquila/
Specifically: http://code.google.com/p/aquila/source/browse/trunk/examples/dtw_distance/main.cpp which has an example codeof dtw distace calculation.