unit Keys; {!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! К Л Ю Ч И !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!} interface uses WinTypes, WinProcs,gltype,glproc,MathObj,srcs,nolines, Classes, SysUtils, MVTU_TLB; function TKey0(at,adt:RealType;var time,dtime:RealType;var AU,AY:TPtrExt;var AX,ADX:array of RealType; var CU,CY : TIntArray;var Prop:TPtrArray;var Vars:Pointer;Action:Integer):Integer;export; function TKey1(at,adt:RealType;var time,dtime:RealType;var AU,AY:TPtrExt;var AX,ADX:array of RealType; var CU,CY : TIntArray;var Prop:TPtrArray;var Vars:Pointer;Action:Integer):Integer;export; function TKey2(at,adt:RealType;var time,dtime:RealType;var AU,AY:TPtrExt;var AX,ADX:array of RealType; var CU,CY : TIntArray;var Prop:TPtrArray;var Vars:Pointer;Action:Integer):Integer;export; function TKey3(at,adt:RealType;var time,dtime:RealType;var AU,AY:TPtrExt;var AX,ADX:array of RealType; var CU,CY : TIntArray;var Prop:TPtrArray;var Vars:Pointer;Action:Integer):Integer;export; function TKey4(at,adt:RealType;var time,dtime:RealType;var AU,AY:TPtrExt;var AX,ADX:array of RealType; var CU,CY : TIntArray;var Prop:TPtrArray;var Vars:Pointer;Action:Integer):Integer;export; function TKey5(at,adt:RealType;var time,dtime:RealType;var AU,AY:TPtrExt;var AX,ADX:array of RealType; var CU,CY : TIntArray;var Prop:TPtrArray;var Vars:Pointer;Action:Integer):Integer;export; function TKey6(at,adt:RealType;var time,dtime:RealType;var AU,AY:TPtrExt;var AX,ADX:array of RealType; var CU,CY : TIntArray;var Prop:TPtrArray;var Vars:Pointer;Action:Integer):Integer;export; function TKey7(at,adt:RealType;var time,dtime:RealType;var AU,AY:TPtrExt;var AX,ADX:array of RealType; var CU,CY : TIntArray;var Prop:TPtrArray;var Vars:Pointer;Action:Integer):Integer;export; function TKey8(at,adt:RealType;var time,dtime:RealType;var AU,AY:TPtrExt;var AX,ADX:array of RealType; var CU,CY : TIntArray;var Prop:TPtrArray;var Vars:Pointer;Action:Integer):Integer;export; {********************************************************************************************************} IMPLEMENTATION {********************************************************************************************************} type PKey2Rec = ^TKey2Rec; TKey2Rec = record K1 : TExtArray; K2 : TExtArray; Y01 : TExtArray; Y02 : TExtArray end; PKey3Rec = ^TKey3Rec; TKey3Rec = record K : TExtArray; fl : ^Integer; end; {--------------------------------------------------------------------------- Простой ключ - если u(t) >= K, то y(t)=u(t), иначе y(t)=Y0 K,Y0 - векторы, размерность которых равна размерности входного сигнала ---------------------------------------------------------------------------} function TKey0Convert(Action: integer; Vars: Pointer; Prop: TPtrArray; PropStr: TStringList; BlockId: integer; var MVTU: IMVTU_Server):integer; const RecName:PChar = 'Ключ-0 '; var Res: integer; begin case Action of //Возвращаем ссылку на имя записи в базе МВТУ-4 cnv_GetRecName: Result:=integer(RecName); //Конвертируем и устанавливаем параметры при помощи интерфейса МВТУ cnv_Convert: begin MVTU.SetBlockProp(BlockId,'k',PChar(ConvertVector(PropStr[0])),Res); MVTU.SetBlockProp(BlockId,'y0',PChar(ConvertVector(PropStr[1])),Res); end; end; end; function TKey0; var j : Integer; begin Result:=0; with PNoLine2Rec(Prop.arr)^ do case Action of f_GetConvertFuncAdr: Result:=integer(@TKey0Convert); f_EditErr : if (Y0.Count <> Parms.Count) then Result:=er_Count; f_GetDeriCount : Result:=0; f_GetStateCount : Result:=0; f_GetInit : Result:=0; f_GetCount : begin CY.arr^[0]:=Y0.Count; CU.arr^[0]:=Y0.Count end; f_UpdateOuts, f_RestoreOuts, f_UpdateJacoby, f_GoodStep, f_InitState : for j:=0 to Y0.Count-1 do if AU.Ptr(0).arr^[j] >= Parms.arr^[j] then AY.Ptr(0).arr^[j]:=AU.Ptr(0).arr^[j] else AY.Ptr(0).arr^[j]:=Y0.arr^[j]; end{END CASE} end;{END TKey0} {--------------------------------------------------------------------------- Ключ - если u(t) >= K, то y1(t)=u(t);y2(t)=Y0, иначе y1(t)=Y0;y2(t)=u(t) K,Y0 - векторы, размерность которых равна размерности входного сигнала ---------------------------------------------------------------------------} function TKey1Convert(Action: integer; Vars: Pointer; Prop: TPtrArray; PropStr: TStringList; BlockId: integer; var MVTU: IMVTU_Server):integer; const RecName:PChar = 'Ключ-1 '; var Res: integer; begin case Action of //Возвращаем ссылку на имя записи в базе МВТУ-4 cnv_GetRecName: Result:=integer(RecName); //Конвертируем и устанавливаем параметры при помощи интерфейса МВТУ cnv_Convert: begin MVTU.SetBlockProp(BlockId,'k',PChar(ConvertVector(PropStr[0])),Res); MVTU.SetBlockProp(BlockId,'y0',PChar(ConvertVector(PropStr[1])),Res); end; end; end; function TKey1; var j : Integer; begin Result:=0; with PNoLine2Rec(Prop.arr)^ do case Action of f_GetConvertFuncAdr: Result:=integer(@TKey1Convert); f_EditErr : if (Y0.Count <> Parms.Count) then Result:=er_Count; f_GetDeriCount, f_GetStateCount : Result:=0; f_GetInit : Result:=0; f_GetCount : begin CY.arr^[0]:=Y0.Count; CU.arr^[0]:=Y0.Count; CY.arr^[1]:=Y0.Count end; f_UpdateOuts, f_RestoreOuts, f_UpdateJacoby, f_GoodStep, f_InitState : for j:=0 to Y0.Count-1 do if AU.Ptr(0).arr^[j] >= Parms.arr^[j] then begin AY.Ptr(0).arr^[j]:=AU.Ptr(0).arr^[j]; AY.Ptr(1).arr^[j]:=Y0.arr^[j] end else begin AY.Ptr(1).arr^[j]:=AU.Ptr(0).arr^[j]; AY.Ptr(0).arr^[j]:=Y0.arr^[j] end; end{END CASE} end;{END TKey1} {--------------------------------------------------------------------------- Ключ - если u(t) < K1, то y1(t)=u(t);y2(t)=Y2(0), если u(t) > K2, то y2(t)=u(t);y1(t)=Y1(0), иначе y1(t)=Y1(0);y2(t)=Y2(0) K1,K2,Y1(0),Y2(0) - вектора, размерность которых равна размерности входа ---------------------------------------------------------------------------} function TKey2Convert(Action: integer; Vars: Pointer; Prop: TPtrArray; PropStr: TStringList; BlockId: integer; var MVTU: IMVTU_Server):integer; const RecName:PChar = 'Ключ-2 '; var Res: integer; begin case Action of //Возвращаем ссылку на имя записи в базе МВТУ-4 cnv_GetRecName: Result:=integer(RecName); //Конвертируем и устанавливаем параметры при помощи интерфейса МВТУ cnv_Convert: begin MVTU.SetBlockProp(BlockId,'k1',PChar(ConvertVector(PropStr[0])),Res); MVTU.SetBlockProp(BlockId,'k2',PChar(ConvertVector(PropStr[1])),Res); MVTU.SetBlockProp(BlockId,'y01',PChar(ConvertVector(PropStr[2])),Res); MVTU.SetBlockProp(BlockId,'y02',PChar(ConvertVector(PropStr[3])),Res); end; end; end; function TKey2; var j : Integer; begin Result:=0; with PKey2Rec(Prop.arr)^ do case Action of f_GetConvertFuncAdr: Result:=integer(@TKey2Convert); f_EditErr : begin j:=Y01.Count; if (j <> Y02.Count)or(j <> K1.Count)or(j <> K2.Count) then Result:=er_Count end; f_GetDeriCount, f_GetStateCount, f_GetInit : Result:=0; f_GetCount : begin CY.arr^[0]:=Y01.Count; CU.arr^[0]:=Y01.Count; CY.arr^[1]:=Y01.Count end; f_UpdateOuts, f_RestoreOuts, f_UpdateJacoby, f_GoodStep, f_InitState : for j:=0 to Y01.Count-1 do if AU.Ptr(0).arr^[j] < K1.arr^[j] then begin AY.Ptr(0).arr^[j]:=AU.Ptr(0).arr^[j]; AY.Ptr(1).arr^[j]:=Y02.arr^[j] end else if AU.Ptr(0).arr^[j] > K2.arr^[j] then begin AY.Ptr(1).arr^[j]:=AU.Ptr(0).arr^[j]; AY.Ptr(0).arr^[j]:=Y01.arr^[j] end else begin AY.Ptr(1).arr^[j]:=Y02.arr^[j]; AY.Ptr(0).arr^[j]:=Y01.arr^[j] end; end{END CASE} end;{END TKey2} {--------------------------------------------------------------------------- Ключ - если u2(t) < K, то y(t)=u1(t) иначе y(t)=u3(t) ---------------------------------------------------------------------------} function TKey3Convert(Action: integer; Vars: Pointer; Prop: TPtrArray; PropStr: TStringList; BlockId: integer; var MVTU: IMVTU_Server):integer; const RecName:PChar = 'Ключ-3 '; var Res: integer; begin case Action of //Возвращаем ссылку на имя записи в базе МВТУ-4 cnv_GetRecName: Result:=integer(RecName); //Конвертируем и устанавливаем параметры при помощи интерфейса МВТУ cnv_Convert: with PKey3Rec(Prop.arr)^ do begin MVTU.SetBlockProp(BlockId,'k',PChar(ConvertVector(PropStr[0])),Res); MVTU.SetBlockProp(BlockId,'fl',PChar(IntToStr(fl^)),Res); end; end; end; function TKey3; var i : Integer; begin Result:=0; with PKey3Rec(Prop.arr)^ do case Action of f_GetConvertFuncAdr: Result:=integer(@TKey3Convert); f_GetDeriCount, f_GetStateCount, f_GetInit : Result:=0; f_GetCount : if fl^ = 1 then begin CY.arr^[0]:=k.Count; CU.arr^[0]:=k.Count; CU.arr^[1]:=k.Count; CU.arr^[2]:=k.Count end else begin CY.arr^[0]:=CU.arr^[0]; CU.arr^[1]:=1; CU.arr^[2]:=CU.arr^[0] end; f_UpdateOuts, f_RestoreOuts, f_UpdateJacoby, f_GoodStep, f_InitState : for i:=0 to AU.Ptr(0).Count-1 do if fl^ = 1 then begin if AU.Ptr(1).arr^[i] < k.arr^[i] then AY.Ptr(0).arr^[i]:=AU.Ptr(0).arr^[i] else AY.Ptr(0).arr^[i]:=AU.Ptr(2).arr^[i] end else begin if AU.Ptr(1).arr^[0] < k.arr^[0] then AY.Ptr(0).arr^[i]:=AU.Ptr(0).arr^[i] else AY.Ptr(0).arr^[i]:=AU.Ptr(2).arr^[i] end end{END CASE} end;{END TKey3} {--------------------------------------------------------------------------- Ключ временной - если t < T0, то y(t)=Y0 иначе y(t)=u(t) T0,Y0 - вектора, размерность которых равна размерности входа ---------------------------------------------------------------------------} function TKey4Convert(Action: integer; Vars: Pointer; Prop: TPtrArray; PropStr: TStringList; BlockId: integer; var MVTU: IMVTU_Server):integer; const RecName:PChar = 'Ключ-4(t)'; var Res: integer; begin case Action of //Возвращаем ссылку на имя записи в базе МВТУ-4 cnv_GetRecName: Result:=integer(RecName); //Конвертируем и устанавливаем параметры при помощи интерфейса МВТУ cnv_Convert: begin MVTU.SetBlockProp(BlockId,'k',PChar(ConvertVector(PropStr[0])),Res); MVTU.SetBlockProp(BlockId,'y0',PChar(ConvertVector(PropStr[1])),Res); end; end; end; function TKey4; var j : Integer; begin Result:=0; with PNoLine2Rec(Prop.arr)^ do case Action of f_GetConvertFuncAdr: Result:=integer(@TKey4Convert); f_EditErr : if (Parms.Count <> Y0.Count) then Result:=er_Count; f_GetDeriCount : Result:=0; f_GetStateCount : Result:=0; f_GetInit : Result:=0; f_GetCount : begin CY.arr^[0]:=Y0.Count; CU.arr^[0]:=Y0.Count end; f_UpdateOuts, f_RestoreOuts, f_UpdateJacoby, f_GoodStep, f_InitState : for j:=0 to Y0.Count-1 do if at <= Parms.arr^[j] then AY.Ptr(0).arr^[j]:=Y0.arr^[j] else AY.Ptr(0).arr^[j]:=AU.Ptr(0).arr^[j]; end{END CASE} end;{END TKey4} {--------------------------------------------------------------------------- Ключ временной - если t < u(t), то y1(t)=u(t);y2(t)=Y0 иначе y1(t)=Y0;y2(t)=u(t) Y0 - вектор, размерность которых равна размерности входа ---------------------------------------------------------------------------} function TKey5Convert(Action: integer; Vars: Pointer; Prop: TPtrArray; PropStr: TStringList; BlockId: integer; var MVTU: IMVTU_Server):integer; const RecName:PChar = 'Ключ-5(t)'; var Res: integer; begin case Action of //Возвращаем ссылку на имя записи в базе МВТУ-4 cnv_GetRecName: Result:=integer(RecName); //Конвертируем и устанавливаем параметры при помощи интерфейса МВТУ cnv_Convert: begin MVTU.SetBlockProp(BlockId,'y0',PChar(ConvertVector(PropStr[0])),Res); end; end; end; function TKey5; var j : Integer; begin Result:=0; with TSourceRec(Prop.arr^[0]).Parms do case Action of f_GetConvertFuncAdr: Result:=integer(@TKey5Convert); f_GetDeriCount, f_GetStateCount : Result:=0; f_GetInit : Result:=0; f_GetCount : begin CY.arr^[0]:=Count; CY.arr^[1]:=Count; CU.arr^[0]:=Count end; f_UpdateOuts, f_RestoreOuts, f_UpdateJacoby, f_GoodStep, f_InitState : for j:=0 to Count-1 do if at < AU.Ptr(0).arr^[j] then begin AY.Ptr(0).arr^[j]:=AU.Ptr(0).arr^[j]; AY.Ptr(1).arr^[j]:=arr^[j] end else begin AY.Ptr(1).arr^[j]:=AU.Ptr(0).arr^[j]; AY.Ptr(0).arr^[j]:=arr^[j] end; end{END CASE} end;{END TKey5} {--------------------------------------------------------------------------- Ключ временной - если t < K1, то y1(t)=u(t);y2(t)=Y2(0), если t > K2, то y2(t)=u(t);y1(t)=Y1(0), иначе y1(t)=Y1(0);y2(t)=Y2(0) K1,K2,Y1(0),Y2(0) - вектора, размерность которых равна размерности входа ---------------------------------------------------------------------------} function TKey6Convert(Action: integer; Vars: Pointer; Prop: TPtrArray; PropStr: TStringList; BlockId: integer; var MVTU: IMVTU_Server):integer; const RecName:PChar = 'Ключ-6(t)'; var Res: integer; begin case Action of //Возвращаем ссылку на имя записи в базе МВТУ-4 cnv_GetRecName: Result:=integer(RecName); //Конвертируем и устанавливаем параметры при помощи интерфейса МВТУ cnv_Convert: begin MVTU.SetBlockProp(BlockId,'k1',PChar(ConvertVector(PropStr[0])),Res); MVTU.SetBlockProp(BlockId,'k2',PChar(ConvertVector(PropStr[1])),Res); MVTU.SetBlockProp(BlockId,'y01',PChar(ConvertVector(PropStr[2])),Res); MVTU.SetBlockProp(BlockId,'y02',PChar(ConvertVector(PropStr[3])),Res); end; end; end; function TKey6; var j : Integer; begin Result:=0; with PKey2Rec(Prop.arr)^ do case Action of f_GetConvertFuncAdr: Result:=integer(@TKey6Convert); f_EditErr : begin j:=Y01.Count; if (j <> Y02.Count)or(j <> K1.Count)or(j <> K2.Count) then Result:=er_Count end; f_GetDeriCount, f_GetStateCount : Result:=0; f_GetInit : Result:=0; f_GetCount : begin CY.arr^[0]:=Y01.Count; CU.arr^[0]:=Y01.Count; CY.arr^[1]:=Y01.Count end; f_UpdateOuts, f_RestoreOuts, f_UpdateJacoby, f_GoodStep, f_InitState : for j:=0 to Y01.Count-1 do if at < K1.arr^[j] then begin AY.Ptr(0).arr^[j]:=AU.Ptr(0).arr^[j]; AY.Ptr(1).arr^[j]:=Y02.arr^[j] end else if at > K2.arr^[j] then begin AY.Ptr(1).arr^[j]:=AU.Ptr(0).arr^[j]; AY.Ptr(0).arr^[j]:=Y01.arr^[j] end else begin AY.Ptr(1).arr^[j]:=Y02.arr^[j]; AY.Ptr(0).arr^[j]:=Y01.arr^[j] end; end{END CASE} end;{END TKey6} {--------------------------------------------------------------------------- Ключ временной - если t < K, то y(j,t)=u1(j,t) иначе y(j,t)=u2(j,t) ---------------------------------------------------------------------------} function TKey7Convert(Action: integer; Vars: Pointer; Prop: TPtrArray; PropStr: TStringList; BlockId: integer; var MVTU: IMVTU_Server):integer; const RecName:PChar = 'Ключ-7(t)'; var Res: integer; begin case Action of //Возвращаем ссылку на имя записи в базе МВТУ-4 cnv_GetRecName: Result:=integer(RecName); //Конвертируем и устанавливаем параметры при помощи интерфейса МВТУ cnv_Convert: begin MVTU.SetBlockProp(BlockId,'y0',PChar(ConvertVector(PropStr[0])),Res); end; end; end; function TKey7; var j : Integer; begin Result:=0; with TSourceRec(Prop.arr^[0]).Parms do case Action of f_GetConvertFuncAdr: Result:=integer(@TKey7Convert); f_GetDeriCount, f_GetStateCount : Result:=0; f_GetInit : Result:=0; f_GetCount : begin CY.arr^[0]:=Count; CU.arr^[0]:=Count; CU.arr^[1]:=Count end; f_UpdateOuts, f_RestoreOuts, f_UpdateJacoby, f_GoodStep, f_InitState : for j:=0 to Count-1 do if at < arr^[j] then AY.Ptr(0).arr^[j]:=AU.Ptr(0).arr^[j] else AY.Ptr(0).arr^[j]:=AU.Ptr(1).arr^[j]; end{END CASE} end;{END TKey7} {--------------------------------------------------------------------------- Ключ интегратора Блок реализует функцию управляемого ключа для интегрирующего привода (типа интегратора или инерционно-интегрирующего звена) по следующему алгоритму: y(t) = x1(t), если a1 < x2(t) < a2; y(t) = 0, если x2(t) <=a1 и x1(t) <= 0, или x2(t) >= a2 и x1(t) >= 0; y(t) = x1(t), если x2(t) <=a1 и x1(t) > 0, или x2(t) >= a2 и x1(t) < 0, гле x1(t) - сигнал на 1-ый вход на Ключ; x2(t) - управляющий сигнал на 2-ой вход Ключа с выхода интегратора; y(t) - сигнал на выходе Ключа (на входе в интегратор); коэффициент усиления интегратора К > 0. Для работы блока необходимо задать параметры a1 и a2. ---------------------------------------------------------------------------} function TKey8Convert(Action: integer; Vars: Pointer; Prop: TPtrArray; PropStr: TStringList; BlockId: integer; var MVTU: IMVTU_Server):integer; const RecName:PChar = 'Ключ интегратора'; var SL: TStringList; Res: integer; begin case Action of //Возвращаем ссылку на имя записи в базе МВТУ-4 cnv_GetRecName: Result:=integer(RecName); //Конвертируем и устанавливаем параметры при помощи интерфейса МВТУ cnv_Convert: try SL:=TStringList.Create; //Парсим свойство заданное в одной строчке ExtractStrings([' ',';'],[' '],PChar(PropStr[0]),SL); //Присваиваем параметры для блока MVTU.SetBlockProp(BlockId,'ymin',PChar(SL[0]),Res); MVTU.SetBlockProp(BlockId,'ymax',PChar(SL[1]),Res); finally SL.Free; end; end; end; function TKey8; begin Result:=0; with TSourceRec(Prop.arr^[0]).Parms do case Action of f_GetConvertFuncAdr: Result:=integer(@TKey8Convert); f_GetDeriCount, f_GetStateCount : Result:=0; f_GetInit : Result:=0; f_GetCount : begin CY.arr^[0]:=1; CU.arr^[0]:=1; CU.arr^[1]:=1 end; f_UpdateOuts, f_RestoreOuts, f_UpdateJacoby, f_GoodStep, f_InitState : if ((AU.Ptr(1).arr^[0] <= arr^[0]) and (AU.Ptr(0).arr^[0] <= 0)) or ((AU.Ptr(1).arr^[0] >= arr^[1]) and (AU.Ptr(0).arr^[0] >= 0)) then AY.Ptr(0).arr^[0]:=0 else AY.Ptr(0).arr^[0]:=AU.Ptr(0).arr^[0]; end{END CASE} end;{END TKey8} end.