I would like to drive a transfer function block with a pulse signal in Simulink. This can for example be done with a Pulse Generator block. The only thing I am missing is an external input where I can specify the pulse width or duty cycle of the signal. Signal parameters can only be entered through the Pulse Generator's Block parameters. Is there a way to go around this?
Simulink model 1
Pulse generator block parameters
Alternatively, I tried to use a Matlab function block inside Simulink with the Matlab function "square", which takes a few constants as well as the current simulation time as inputs. I used the following function:
% Output data value for specific time instant
function DataValue = pulsegen(PulseWidth,Frequency,TimeInput)
PulseDutyCycle = PulseWidth*Frequency*100;
% Generate signal
t = 0:0.0001:60;
y = square(2*pi*Frequency*t,PulseDutyCycle);
y = max(y,0); % Set nonzero elements to zero
DataValue = y(find(t==TimeInput)); % find data value at specific time instance
end
And the following model:
Simulink model 2
But with no luck either. I get the following error message:
Simulink error messages
Which does not makes sense to me. When I test this function stand-alone in Matlab, the function output is just a 1x1 constant value, not an array. Does anyone know a solution to this?
Related
i'm new in Simulink and I'm using interpreted MATLAB function block to create a gaussian pulse generator.
This is the function:
function y=mono_gauss(t)
fs=20E9; %sample rate-10 times the highest frequency
ts=1/fs; %sample period
t1=.5E-9; %pulse width(0.5 nanoseconds)
x=(t/t1).*(t/t1); %x=(t^2/t1^2)(square of (t/t1);
A=1;
y=(A*(t/t1)-ts).*exp(-x); %first derivative of Gaussian pulsefunction
end
The problem is that the output of the block generate only one pulse and my objective is to generate a train of pulses just like a pulse generator block.
Any solutions ?
You're most likely better off designing your pulse in MATLAB, then using the Repeating Sequence to use it in Simulink.
For instance, in MATLAB
t = 0:0.01:1;
y = normpdf(t,0.5,0.05);
plot(t,y)
Then within Simulink,
I have also changed the step size of the model Solver to be 0.01.
You'll need to play around with various of these parameters to get the exact curve you desire.
I have a continuous S-Function that solves the derivatives for various state properties within a ICE cylinder. As such, the output of the function is set to output the integral of those derivatives for each time step which is a 7 element vector (1 for each of the properties being calculated)
block.OutputPort(1).Data = block.ContStates.Data;
At some point in the cycle I would like to change the value of this output to an explicit value (i.e. not the integral of the derivative) such as below (in this case the explicit value being x):
block.OutputPort(1).Data = block.ContStates.Data;
block.OutputPort(1).Data(3) = x;
I'm using a if statement to switch into this alternative output. Through debugging, I think I've verified that Simulink is entering this block of code at the right point - however the output of the S-Function remains as the integral of the derivatives which gives me a non-finite error.
Any help or suggestions that would allow me to explicitly set the output of a continuous S-Function would be much appreciated.
How do I convert a continuous PID (in s form) to discrete form (in z form)? Let's say I have the tuned gain of the PID (in s form) :
Kp=2266.76751174231;
Ki=3461.10112077832;
Kd=360.96017761997;
Now, I would like to apply the same gain to the PID in z form. However I couldn't get the same responses in discrete compared to continuous. Below is the z block diagram:
And this is the responses in z form:
Block diagram in s form:
this is the responses in continuous form:
Any suggestion what's my mistake?
thanks!
I tried running the model in continuous time with the PID parameters that you specified and the default N=100 for the derivative gain filter coefficient. I used ode45 solver with default parameters, but I limited the maximum time step to 0.01. Unfortunately, I found the system to be unstable.
I tuned the gains using a heuristic manual approach (I believe that the values of the gains are not relevant from the perspective of answering your question). I settled on the following set of gains:
Kp = 6
Ki = 12
Kd = 1
The models that I used are shown below. As you can see from the Simulink diagram, I constructed two models. They are (almost) equivalent. However, the first model (the topmost model) uses the standard Simulink PID(s) block and the second one (the lowermost model) uses a custom transfer function block instead of the Simulink PID(s) block. The custom transfer function should produce the output that is equivalent to the Simulink PID(s) block, as they only differ in their implementation. The second model was created to assist in the explanation of the method that I used for the conversion of the models from z-domain to s-domain. I also used it as a "sanity check" to ensure that the implementation of the Simulink PID is not different from the way I thought it was implemented.
The PID parameters for the continuous time simulation.
The parameters of the transfer function block associated with the plant.
The result of the continuous time simulation.
In order to convert the plant model from s-domain to z-domain I used the Tustin transformation. I used the symbolic toolbox in MATLAB to perform the conversion. This is my preferred approach, as it enables for a more general solution in comparison with the in-built toolboxes for control systems. I also constructed the PID function in s-domain and converted it to z-domain using the same approach. The script that does the conversion is shown below. Please note that I used 0.1 as the simulation time step for the discrete time simulation. This value should also be set in the solver configuration in Simulink.
The following variables are important from the perspective of the construction of the Simulink model in z-domain:
NPlantCoeffs - contains the coefficients of the numerator of the transfer function associated with the plant in z-domain. For a reference, the following value was obtained: [45 135 135 45].
DPlantCoeffs- contains the coefficients of the denominator of the transfer function associated with the plant in z-domain. For a reference, the following value was obtained: [406502 -1104494 1035506 -333498].
NPIDFiltCoeffs - contains the coefficients of the numerator of the transfer function associated with the PID in z-domain. For a reference, the following value was obtained: [-349 515 -196].
DPIDFiltCoeffs - contains the coefficients of the denominator of the transfer function associated with the PID in z-domain. For a reference, the following value was obtained: [-15 5 10].
Tval - the value of the time step. For a reference, the following value was used: 0.1.
The script for the definition of the parameters for the discrete-time simulation.
% Initialisation.
clear;
clc;
% Define the symbolic variables of interest.
% T is the time step for discrete simulation.
syms s z T;
% Define the controller parameters.
% The parameters should correspond to the parameters obtained from tuning
% the continuous system.
Kp = 6;
Ki = 12;
Kd = 1;
N = 100;
% Define the plant and the controller in the s-domain.
TFPlant = 0.09/(0.09*s^3 + 0.18*s^2 + s + 1.004);
TFPIDFilt = Kp + Ki/s + Kd*N/(1 + N/s);
% Obtain the numerator and the denominator of the transfer functions in the
% s-domain.
[NPIDCont, DPIDCont] = numden(collect(TFPIDFilt));
NPIDCont = sym2poly(NPIDCont);
DPIDCont = sym2poly(DPIDCont);
% Convert to z-domain using Tustin substitution (referred to as Trapezoidal
% method in Simulink block PID(s)).
TFPlant = collect(subs(TFPlant, s, (2/T)*(z - 1)/(z + 1)));
TFPIDFilt = collect(subs(TFPIDFilt, s, (2/T)*(z - 1)/(z + 1)));
% Define time step for discrete simulation.
Tval = 0.1;
% Perform substitution for the time step T.
TFPlant = subs(TFPlant, T, Tval);
TFPIDFilt = subs(TFPIDFilt, T, Tval);
% Decompose into the numerator and denominator.
[NPlant, DPlant] = numden(TFPlant);
[NPIDFilt, DPIDFilt] = numden(TFPIDFilt);
% Obtain the polynomial coefficients associated with the numerator and
% denominator.
NPlantCoeffs = sym2poly(NPlant);
DPlantCoeffs = sym2poly(DPlant);
NPIDFiltCoeffs = sym2poly(NPIDFilt);
DPIDFiltCoeffs = sym2poly(DPIDFilt);
For the discrete time simulation, it is important to select the fixed time step solver and set the time step to the value that is equivalent to the value that was used for the conversion of the plant model from s-domain to z-domain. As you can see below, I used the z-domain version of the continuous time PID controller block for the discrete time simulation. Given the calculated plant parameters for the discrete-time simulation, the result of the simulation is very close to the result of the simulation of the continuous time system.
Solver configuration for the discrete time simulation.
Models for the discrete time simulation.
Discrete time plant model parameters.
Parametrisation of the Simulink PID(s) block for discrete time simulation.
The result of the discrete time simulation.
To answer your original question, I am not sure where your mistake is exactly. However, I provide several assumptions below:
There is something strange with the PID gains that you obtained for continuous time simulation. The system that was specified in your screenshot is unstable when these gains are used, unless I misread the plant parameters in the screenshot.
I am not sure what process you followed for the conversion of the plant model from s-domain to z-domain. The conversion process that I presented in the answer should provide a valid methodology for the conversion. It is also important to use a fixed time step solver for the discrete time domain simulation. Moreover, it is important to use the time step that is equivalent to the time step used for the conversion of your plant model from s-domain to z-domain.
How can I introduce a continuos signal to a MATLAB Function block so I can get a continuos output.
My MATLAB Function block will be this:
function y = fcn(u)
y = 2*exp(-u);
So I can get a negative exponential, this because I need a control voltage source with a negative exponential signal. I need to introduce a controlled voltage source a exponential signal, is there other way?
Thanks
First of all, you don't need a MATLAB function to do that: take your input signal, multiply it by -1 with a Gain block, then use a Math Function block set to exp, and finally another Gain block to multiply it by 2.
Second, your input signal can be whatever you want. For example, you can use a Sine Wave block, or choose whatever block you want from the Sources library. If you leave the Sample Time parameter to 0, you will have a "continuous" signal (in the Simulink sense of the word), see Specify Sample Time in the documentation for more details. You can also use your own data from the MATLAB workspace using a From Workspace block.
I am trying to acquire the frequency information about a displacement signal(e.g., Vx) while the simulation is running.
My idea was to make use of the fft command supported by Embedded Matlab Function block.
The first thing which i performed was to store the values of displacement signal 'Vx' in a buffer of length 'L'.
The second thing is to compute the fft of those values stored in the buffer and calculate the index value corresponding to the maximum amplitude.
The third thing is to acquire the frequency from index value, sampling frequency and length of the buffer.
Embedded Matlab code is the following:-
Function[freq_Vx,buffero_Vx] = fcn(Vx,bufferi_Vx)
% This block supports the Embedded MATLAB subset.
% See the help menu for details.
buffo_Vx = [Vx;buffi_Vx(1:end-1)]; % buffer which stores the values of signal 'Vx'
Fs = 2000;
nfft = 2^nextpow2(length(buffo_Vx));
[max_Vx,index_Vx] = max(abs(fft(buffo_Vx,nfft)));
freq_Vx = index_Vx*Fs/length(buffo_Vx);
end
Is this the right way of acquiring the frequency content of a signal while the simulation is running?
I believe your approach to processing the data "real time" in the model is reasonable, however I believe the index_Vx*Fs/length(buffo_Vx) is not going to give the desired results and buffo_Vx = [Vx;buffi_Vx(1:end-1)]; will likely need to be buffo_Vx = [Vx;bufferi_Vx(1:end-1)];` Checkout this link for your frequency conversion.
For diagnostic purposes, check out the Simulink Extras -> Additional Sinks blocks on the Simulink library browser.
The Spectral densities should be helpful.