در این مثال، قصد داریم یک سیستم غیرخطی ساده را کنترل کنیم و با استفاده از روش کنترل پس‌خورد (Feedback Linearization) کنترل‌کننده‌ای برای آن طراحی کنیم. برای این منظور، از یک سیستم غیرخطی مرتبه دوم به شکل زیر استفاده می‌کنیم:

                                                                                                 x˙1=x2 

                                                                                            x˙2=−x13+u

در اینجا:

  • x1 و x2 متغیرهای حالت هستند.
  • u ورودی کنترل است.

هدف ما این است که با طراحی کنترل‌کننده‌ای، متغیر حالت x1 را به نقطه تعادل صفر هدایت کنیم. برای این منظور، ابتدا سیستم را با استفاده از روش خطی‌سازی فیدبک خطی می‌کنیم. 

کد متلب برای حل مسئله کنترل غیرخطی

% تعریف پارامترها و شرایط اولیه
x0 = [1; 0]; % شرایط اولیه [x1(0); x2(0)]
tspan = [0 10]; % بازه زمانی شبیه‌سازی

% شبیه‌سازی سیستم با استفاده از ode45
[t, x] = ode45(@(t, x) nonlinear_system(t, x), tspan, x0);

% ترسیم نتایج
figure;
plot(t, x(:,1), 'r', 'LineWidth', 2); hold on;
plot(t, x(:,2), 'b', 'LineWidth', 2);
xlabel('Time (s)');
ylabel('States');
legend('x_1', 'x_2');
title('Response of Nonlinear Controlled System');

% تعریف تابع دینامیک سیستم غیرخطی با کنترل پس‌خورد
function dxdt = nonlinear_system(t, x)
x1 = x(1);
x2 = x(2);

% قانون کنترل (خطی‌سازی پس‌خورد)
u = x1^3 - 2*x2 - 2*x1; % کنترل پس‌خورد

% معادلات حالت سیستم
dx1 = x2;
dx2 = -x1^3 + u;

dxdt = [dx1; dx2];
end

توضیحات خط به خط کد

1- تعریف شرایط اولیه:

x0 = [1; 0];

در اینجا شرایط اولیه متغیرهای حالت   x1(0)=1  و x2(0)=0 تنظیم می‌شود.

2- تعیین بازه زمانی شبیه‌سازی:

tspan = [0 10];

بازه زمانی شبیه‌سازی بین 0 تا 10 ثانیه انتخاب می‌شود.

 3- شبیه‌سازی سیستم با استفاده از تابع ode45:

[t, x] = ode45(@(t, x) nonlinear_system(t, x), tspan, x0);

از ode45 برای حل عددی سیستم دیفرانسیلی غیرخطی استفاده می‌کنیم. تابع nonlinear_system دینامیک سیستم غیرخطی را به همراه کنترل ارائه می‌دهد. 

4- ترسیم نمودار نتایج شبیه‌سازی:

figure;
plot(t, x(:,1), 'r', 'LineWidth', 2); hold on;
plot(t, x(:,2), 'b', 'LineWidth', 2);
xlabel('Time (s)');
ylabel('States');
legend('x_1', 'x_2');
title('Response of Nonlinear Controlled System');

نمودار متغیرهای حالت x1 و x2 در طول زمان رسم می‌شود.

5- تابع تعریف دینامیک سیستم غیرخطی:

function dxdt = nonlinear_system(t, x)
x1 = x(1);
x2 = x(2);

% قانون کنترل (خطی‌سازی پس‌خورد)
u = x1^3 - 2*x2 - 2*x1; % کنترل پس‌خورد

% معادلات حالت سیستم
dx1 = x2;
dx2 = -x1^3 + u;

dxdt = [dx1; dx2];
end

در اینجا، تابع nonlinear_system دینامیک سیستم غیرخطی و قانون کنترل پس‌خورد را شامل می‌شود. کنترل uuu به گونه‌ای طراحی شده که رفتار سیستم خطی شود و پایدار گردد.

تحلیل نتایج

این کنترل‌کننده طراحی شده باعث می‌شود که x1 و x2 به تدریج به صفر نزدیک شوند و سیستم به حالت تعادل پایدار برسد.

بررسی خطاها

Unrecognized function or variable 'nonlinear_system'. Error in @(t,x)nonlinear_system(t,x) Error in odearguments (line 92) f0 = ode(t0,y0,args{:});   % ODE15I sets args{1} to yp0. Error in ode45 (line 104)     odearguments(odeIsFuncHandle,odeTreatAsMFile, solver_name, ode, tspan, y0, options, varargin);

این خطا به دلیل آن است که متلب نمی‌تواند تابع nonlinear_system را پیدا کند. این مشکل معمولاً وقتی رخ می‌دهد که تابعی که برای شبیه‌سازی به ode45 ارسال می‌شود به درستی تعریف نشده باشد یا به درستی در دسترس نباشد. برای رفع این مشکل، می‌توانید از دو روش زیر استفاده کنید: 

روش اول: تعریف تابع به صورت توکار (Embedded Function)

اگر کل کد در یک فایل اسکریپت (مانند script.m) قرار دارد، مطمئن شوید که تابع nonlinear_system به صورت توکار در انتهای فایل تعریف شده باشد و در همان فایل اسکریپت نوشته شده باشد. مثل نمونه زیر: 

% اسکریپت اصلی
x0 = [1; 0]; % شرایط اولیه [x1(0); x2(0)]
tspan = [0 10]; % بازه زمانی شبیه‌سازی

% شبیه‌سازی سیستم با استفاده از ode45
[t, x] = ode45(@(t, x) nonlinear_system(t, x), tspan, x0);

% ترسیم نتایج
figure;
plot(t, x(:,1), 'r', 'LineWidth', 2); hold on;
plot(t, x(:,2), 'b', 'LineWidth', 2);
xlabel('Time (s)');
ylabel('States');
legend('x_1', 'x_2');
title('Response of Nonlinear Controlled System');

% تابع غیرخطی با کنترل پس‌خورد
function dxdt = nonlinear_system(t, x)
x1 = x(1);
x2 = x(2);

% قانون کنترل (خطی‌سازی پس‌خورد)
u = x1^3 - 2*x2 - 2*x1; % کنترل پس‌خورد

% معادلات حالت سیستم
dx1 = x2;
dx2 = -x1^3 + u;

dxdt = [dx1; dx2];
end
 

روش دوم: ایجاد تابع مجزا

می‌توانید تابع nonlinear_system را در یک فایل جداگانه با نام nonlinear_system.m ذخیره کنید. فایل جدیدی با همین نام ایجاد کنید و کدهای زیر را در آن قرار دهید:  

function dxdt = nonlinear_system(t, x)
x1 = x(1);
x2 = x(2);

% قانون کنترل (خطی‌سازی پس‌خورد)
u = x1^3 - 2*x2 - 2*x1; % کنترل پس‌خورد

% معادلات حالت سیستم
dx1 = x2;
dx2 = -x1^3 + u;

dxdt = [dx1; dx2];
end
  

سپس کد اصلی را در یک اسکریپت مجزا اجرا کنید.