用matlab求解单循环的微分方程

时间:2015-02-06 16:58:04

标签: matlab controls ode differential-equations

我的机械系统有以下等式:

xdot = Ax+ Bu

我想在一个循环中解决这个等式,因为在每个步骤中我都需要更新你,但求解器如ode45lsim求解时间间隔的微分方程。

 for i = 1:10001
    if  x(i,:)>= Sin1 &  x(i,:)<=Sout2
        U(i,:) = Ueq - (K*(S/Alpha))
    else
        U(i,:) = Ueq - (K*S)
    end
   % [y(i,:),t,x(i+1,:)]=lsim(sys,U(i,:),(time=i/1000),x(i,:));
   or %[t,x] = ode45(@(t,x)furuta(t,x,A,B,U),(time=i/1000),x)
end

我是否有另一种方法可以在一个循环中解决这个等式一次(非单一时间步)。

1 个答案:

答案 0 :(得分:1)

有许多方法可以跨函数调用更新和存储数据。 对于ODE套件,我开始喜欢所谓的“闭包”。 闭包基本上是一个嵌套函数,从其父函数访问或修改变量。

下面的代码通过将传递给ode45的右侧函数和'OutputFcn'包含在名为odeClosure()的父函数中来使用此功能。

您会注意到我使用的是逻辑索引而不是if语句。 if中的向量 - 语句只有在所有元素都为真时才为真,反之亦然。 因此,我创建了一个逻辑数组,并根据1 / Alpha每行的信号值使用它来分母xU

'OutputFcn' storeU()成功完成ode45步骤后调用U U。 该函数增加x存储阵列并适当更新它。 数组bsxfun将具有与tspan请求的解决方案点数相同的列数(在此示例中为12)。 如果成功的完整步骤超过任何请求的点,则调用该函数,其中包含所有请求的中间时间及其关联的解决方案值(因此storeU可以是矩形而不仅仅是向量);这就是为什么我在rhs而不是function [sol,U] = odeClosure() % Initilize % N = 10 ; A = [ 0,0,1.0000,0; 0,0,0,1.0000;0,1.3975,-3.7330,-0.0010;0,21.0605,-6.4748,-0.0149]; B = [0;0;0.6199;1.0752 ] ; x0 = [11;11;0;0]; K = 100; S = [-0.2930;4.5262;-0.5085;1.2232]; Alpha = 0.2 ; Ueq = [0;-25.0509;6.3149;-4.5085]; U = Ueq; Sin1 = [-0.0172;-4.0974;-0.0517;-0.2993]; Sout2 = [0.0172 ; 4.0974; 0.0517; 0.2993]; % Solve options = odeset('OutputFcn', @(t,x,flag) storeU(t,x,flag)); sol = ode45(@(t,x) rhs(t,x),[0,0.01:0.01:0.10,5],x0,options); function xdot = rhs(~,x) between = (x >= Sin1) & (x <= Sout2); uwork = Ueq - K*S./(1 + (Alpha-1).*between); xdot = A*x + B.*uwork; end function status = storeU(t,x,flag) if isempty(flag) % grow array nAdd = length(t) ; iCol = size(U,2) + (1:nAdd); U(:,iCol) = 0 ; % update U between = bsxfun(@ge,x,Sin1) & bsxfun(@le,x,Sout2); U(:,iCol) = Ueq(:,ones(1,nAdd)) - K*S./(1 + (Alpha-1).*between); end status = 0; end end 中使用{{1}}。

示例功能:

{{1}}
相关问题