5 views (last 30 days)

Show older comments

I am simulating a system controlled by a PID controller. The system is very simple:

I*x_ddot + d*x_dot + m*g*L*x = u.

I suppose the step response should be the same as the code using Matlab build-in functions, if the user uses the ode45 running the system combined with the PID controller by setting reference to 1. But they generate different results!

The user's code is:

function test2

clear all

clc

close all

global error ref

error = 0;

ref = 1;

t = [0,5];

x0 = [0; 0];

dtspan = t;

[t, x] = ode45(@ODESolver, dtspan, x0);

plot(t, x(:,1), 'r', 'LineWidth', 2);

title('Regulation Problem','Interpreter','LaTex');

xlabel('time (sec)');

ylabel('$\theta(t)$', 'Interpreter','LaTex');

grid on

function dx = ODESolver(t, x)

global error ref; % for PID controller

persistent t_prv

if isempty(t_prv)

t_prv = 0;

end

dx = zeros(2,1);

%Parameters:

m = 0.5; % mass (Kg)

d = 0.0023e-6; % viscous friction coefficient

L = 1; % arm length (m)

I = 1/3*m*L^2; % inertia seen at the rotation axis. (Kg.m^2)

g = 9.81; % acceleration due to gravity m/s^2

% PID tuning

Kp = 5;

Kd = 1.9;

Ki =0.20;

% u: joint torque

u = Kp*(ref - x(1)) + Kd*(-x(2)) + Ki*error;

error = error + (ref - x(1))*(t-t_prv);

dx(1) = x(2);

dx(2) = 1/I*(u - d*x(2) - m*g*L*(x(1)));

t_prv = t;

The outcome is as the following image:

The code using Matlab build-in functions for step response is as the following:

clear all

clc

close all

% Model Parameters

m = 0.5; % mass (Kg)

d = 0.0023e-6; % viscous friction coefficient

L = 1; % arm length (m)

I = 1/3*m*L^2; % inertia seen at the rotation axis. (Kg.m^2)

g = 9.81; % acceleration due to gravity m/s^2

s = tf('s');

P_pend = 1/(I*s^2 + d*s + m*g*L);

% PID tuning

Kp = 5;

Kd = 1.9;

Ki = 0.2;

C = pid(Kp,Ki,Kd)

T = feedback(P_pend*C,1)

t=0:0.1:5;

step(T,t)

%axis([0, 2.5, -0.2, 0.2]);

title('Response under PID Control: Kp = 5, Ki = 1.9, Kd = 0.2');

For this code its outcome is as the following image:

Any suggestion about the difference?

Arkadiy Turevskiy
on 26 Jan 2016

The difference is due to how the derivative term is handled in the simulation. When you use ode45 (the first approach in the question) you compute the pure derivative of the signal. In general, this is not a recommended thing to do: in real life signals are noisy, and taking a derivative of a noisy signal amplifies the noise at high frequencies. That's why it is recommended instead of calculating a pure derivative using a derivative with a lowpass filter. Derivative with a low pass filter can be calculated without taking a derivative of a signal.

The second approach with pid and feedback does not result in taking a pure derivative of a signal during simulation - you first compute closed-loop transfer function using "feedback" and when you do that, the resulting close-loop transfer function does not have a pure derivative term anymore. So when you simulate it with 'step' command, you get a different response than your first method.

I guess your next question would be - which of the 2 answers is right. I would argue it is the second one, because in real life you would not want to implement a PID with pure derivative.

Hope this helps.

Arkadiy

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!