如何编写simulink library.

由于simulink中没有非线性系统的状态空间模块,即形如
x'=f(x)+g(x)u
y=h(x)
的模块,因此对于非线性系统,使用simulink建模比较困难。
但是现在这不是问题了,因为我们有了一个第三方的simulink library:NelinSys
下载下来之后,顺便分析了这个库的实现方法,发现真的是very easy!下面介绍一下如何编写simulink library:
1.打开simulink,选择File->new->library,这样就能在里面随便添加文本,等。。东西。然后保存为.mdl文件。
2.然后就得添加一个模块,这里我没找到如何用可视化的方法进行设计,但是我发现可以直接修改.mdl文件实现。比如有一个library中的一个模块叫做Nonlinear MIMO system,它对应的代码如下:

Block  {
      BlockType          SubSystem
      Name              
"Nonlinear MIMO system\n(State-Space model)"
      Ports              [
12000]
      Position          [
2552038595]
      ShowPortLabels      off
      MaskType          
"Nonlinear MIMO system - state-space model"
      MaskDescription      
"Nonlinear MIMO system is described by follo"
"wing nonlinear differential equations:\n                       dx/dt = f(x) +"
" g(x) u\n                        y = h(x)\n\n             states vector:  x ="
" [x1; x2; ; xN]\n             system input: u (vector)\n             syste"
"m output: y (vector)\n\nParameters f(x), g(x), h(x) can be specified either a"
"s a symbolic expression or as an identifier of a symbolic variable.\n\nFor a "
"detailed description of parameters, click \"Help\" button."
      MaskHelp          
"web(fullfile(cd,'help','stavp_mimo.html'));"
      MaskPromptString      
"System order (number of states, N)|f(x) - s"
"ymbolic expression:|f(x) - variable identifier:|g(x) - symbolic expression:|g"
"(x) - variable identifier:|h(x) - symbolic expression:|h(x) - variable identi"
"fier:|Initial conditions (initial states):"
      MaskStyleString      
"edit,edit,edit,edit,edit,edit,edit,edit"
      MaskTunableValueString  
"on,on,on,on,on,on,on,on"
      MaskVariables          
"n=@1;F=&2;Fp=@3;G=&4;Gp=@5;H=&6;Hp=@7;pp=@8"
";"
      MaskInitialization      
"% Overenie spravnosti zadania parametrov bl"
"oku %\nif ~isempty(F) & (Fp == 0)\n   F = sym(F);\nelseif isempty(F) & (any(F"
"p ~= 0))\n   F = sym(Fp);\nelse\n   error(['Matrix f(x) unspecified or specif"
"ied more than once - cannot continue!']);\nend\n\nif ~isempty(G) & (Gp == 0)"
"\n   G = sym(G);\nelseif isempty(G) & (any(Gp ~= 0))\n   G = sym(Gp);\nelse\n"
"   error(['Matrix g(x) unspecified or specified more than once - cannot conti"
"nue!']);\nend\n\nif ~isempty(H) & (Hp == 0)\n   H = sym(H);\nelseif isempty(H"
") & (any(Hp ~= 0))\n   H = sym(Hp);\nelse\n   error(['Matrix h(x) unspecified"
" or specified more than once - cannot continue!']);\nend\n\n% Zisti si symbol"
"icke premenne, ktore vystupuju vo vyrazoch %\npremF = strrep(strrep(findsym(s"
"ym(F)),', ',''),',',' ');\npremG = strrep(strrep(findsym(sym(G)),', ',''),','"
",' ');\npremH = strrep(strrep(findsym(sym(H)),', ',''),',',' ');\n\n% Premenn"
"e x1, x2, , xN su korektne, preskoc ich %\nfor k = 1 : n\n   premF = strre"
"p(premF, sprintf('x%d',k), '');\n   premG = strrep(premG, sprintf('x%d',k), '"
"');\n   premH = strrep(premH, sprintf('x%d',k), '');\nend\n\n% Ak niektory re"
"tazec nezostal prazdny, vyhlas chybu %\nif ~isempty(premF)\n   error(['Unknow"
"n symbol in f(x) expression - cannot continue!']);\nend\nif ~isempty(premG)\n"
"   error(['Unknown symbol in g(x) expression - cannot continue!']);\nend\nif "
"~isempty(premH)\n   error(['Unknown symbol in h(x) expression - cannot contin"
"ue!']);\nend\n\n% Otestovanie spravnosti rozmerov matic F,G,H (podla \"n\") %"
"\nif ~all(size(F) == [n,1])\n   error(['Invalid matrix dimensions: f(x) - can"
"not continue!']);\n   return;\nend\n\nnin = size(G);\nif (nin(1,1) ~= n)\n   "
"error(['Invalid matrix dimensions: g(x) - cannot continue!']);\n   return;\ne"
"nd\nnin = nin(1,2);\n\nnout = size(H);\nif (nout(1,2) ~= 1)\n   error(['Inval"
"id matrix dimensions: h(x) - cannot continue!']);\n   return;\nend\nnout = no"
"ut(1,1);\n\n% Kontrola vektora pociatocnych podmienok (pociatocnych stavov) %"
"\nif ~all(size(pp) == [n,1])\n   error(['Initial conditions vector: invalid d"
"imensions - cannot continue!']);\n   return;\nend\n\n% Nahradenie identifikat"
"orov \"xI\" identifikatormi \"x(I)\" %\nco_str = '{''x1'; cim_str = '{''x(1)'"
";\n\nfor k = 2 : n\n    co_str = sprintf('%s'',''x%d', co_str, k);\n    cim_s"
"tr = sprintf('%s'',''x(%d)', cim_str, k);\nend\n\nco_str = strcat(co_str, '''"
"}'); cim_str = strcat(cim_str, '''}');\n\nF = eval(sprintf('subs(F,%s,%s)', c"
"o_str, cim_str));\nG = eval(sprintf('subs(G,%s,%s)', co_str, cim_str));\nH = "
"eval(sprintf('subs(H,%s,%s)', co_str, cim_str));\n"
      MaskDisplay          
"disp('Nonlinear MIMO system\\n\\nx'' = f(x)"
" + g(x) u\\ny = h(x)');"
      MaskIconFrame          on
      MaskIconOpaque      on
      MaskIconRotate      none
      MaskIconUnits          autoscale
      MaskValueString      
"3|[84.249*x2*x3; -165.8654*x1*x3-62.5*x2; -"
"15.3846*x3]|0|[0 0; 2500 0; 0 0.9799]|0|[x1; x3]|0|[0; 0; 1e-9]"
      System 
{
        Name            
"Nonlinear MIMO system\n(State-Space model"
")"
        Location            [
124225456399]
        Open            off
        ToolBar            off
        StatusBar            off
        ScreenColor            white
        PaperOrientation        landscape
        PaperPositionMode        auto
        PaperType            usletter
        PaperUnits            inches
        Block 
{
          BlockType              Inport
          Name              
"Vstup"
          Position              [
15784592]
          Port              
"1"
          PortWidth              
"-1"
          SampleTime          
"-1"
        }

        Block 
{
          BlockType              Demux
          Name              
"Demux"
          Ports              [
12000]
          Position              [
2356240159]
          BackgroundColor          black
          ShowName              off
          Outputs              
"[nout n]"
        }

        Block 
{
          BlockType              "S-Function"
          Name              "S-funkcia realizujuca\nnelinearny syste"
"m"
          Ports              [1, 1, 0, 0, 0]
          Position              [85, 60, 195, 110]
          FunctionName          "stavp_mimo"
          Parameters          "n,nin,nout,F,G,H,pp"
          PortCounts          "[]"
          SFunctionModules          "''"
        }
        Block 
{
          BlockType              Outport
          Name              
"Vystup"
          Position              [
2803831052]
          Port              
"1"
          OutputWhenDisabled      held
          InitialOutput          
"0"
        }

        Block 
{
          BlockType              Outport
          Name              
"Stavovy\nvektor"
          Position              [
280113310127]
          Port              
"2"
          OutputWhenDisabled      held
          InitialOutput          
"[]"
        }

        Line 
{
          SrcBlock              
"Demux"
          SrcPort              
2
          DstBlock              
"Stavovy\nvektor"
          DstPort              
1
        }

        Line 
{
          SrcBlock              
"Demux"
          SrcPort              
1
          DstBlock              
"Vystup"
          DstPort              
1
        }

        Line 
{
          SrcBlock              
"S-funkcia realizujuca\nnelinearny syste"
"m"
          SrcPort              
1
          DstBlock              
"Demux"
          DstPort              
1
        }

        Line 
{
          SrcBlock              
"Vstup"
          SrcPort              
1
          DstBlock              
"S-funkcia realizujuca\nnelinearny syste"
"m"
          DstPort              
1
        }

      }

    }

值得注意的是其中一个s-function子模块:stavp_mimo,其实这个子模块才是最核心的地方,打开这个文件发现果然是一个标准的s-function模块:
function [sys,x0,str,ts] = stavp_mimo(t,x,u,flag,n,nin,nout,F,G,H,pp)

% NelinSys - a program tool for analysis and synthesis of nonlinear control systems
%            based on MATLAB/Simulink 5.2
%
% (C) 2002-2005, Martin Ondera (eskimo@pobox.sk) (Martin.Ondera@stuba.sk)

% This program is free software; you can redistribute it and/or
% modify it under the terms of the GNU General Public License
% as published by the Free Software Foundation; either version 2
% of the License, or (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
%
% Please, see the LICENSE.TXT file to read the full license.

switch flag,

% =========================== Inicializacna cast s-funkcie  ============================== %
case 0

   
% Definicia stavov, vstupov a vystupov nelinearneho systemu %
   sizes 
= simsizes;
   sizes.NumContStates 
= n;
   sizes.NumDiscStates 
= 0;
   sizes.NumOutputs 
= nout+n;
   sizes.NumInputs 
= nin;
   sizes.DirFeedthrough 
= 0;
   sizes.NumSampleTimes 
= 1;
   sys 
= simsizes(sizes);

   
% Inicializacia pociatocnych podmienok %
   x0 
= pp;

   
% Inicializacia "str" ako prazdna matica %
   str 
= [];
   
   
% Sample times in TS %
   ts 
= [0 0];

% ========================== Vypocet podla 1. stavovej rovnice ========================== %
case 1
   sys 
= eval(sym(F)) + eval(sym(G)) * u;

% ========================== Vypocet podla 2. stavovej rovnice ========================== %
case 3
   sys(
1:nout,:) = eval(sym(H));    % Ako vystup bloku sa berie nielen vystup systemu  %
   sys(nout
+1:nout+n,:) = x;        %  ale aj cely stavovy vektor nelinearneho systemu %

% ================================= Nepouzite priznaky ================================== %
case {249}
   sys 
= [];
   
% ================================= Spracovanie chyby =================================== %
otherwise
   error([
'Unknown flag = ',num2str(flag)]);
end
ok,现在分析结束。以后有了新的进展,我会随时汇报。

Powered by Jekyll and Theme by solid

本站总访问量