unit DSS; interface uses gltype, glproc, mathobj, Classes,SysUtils, MVTU_TLB; function TElectro_DSS(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 PElectro_DSSRec = ^TElectro_DSSRec; TElectro_DSSRec = record Rds,Rqs: ^realtype; Lds,Lqs: ^realtype; l,J : ^realtype; Rdr,Rqr: ^realtype; Ldr,Lqr: ^realtype; Ldm,Lqm: ^realtype; p,phi : ^integer; q0 : ^realtype; pq0 : ^realtype; P10 : ^realtype; P20 : ^realtype; P30 : ^realtype; P40 : ^realtype; AddOuts: TMultiSelect; end; PElectro_DSSVars = ^TElectro_DSSVars; TElectro_DSSVars = record Dd,Dq, K11,K12,K13, K21,K22,K23, K31,K32, K41,K42, C11,C12,C13, C21,C22, K10, K, id, iq : realtype; end; function TElectro_DSSConvert(Action: integer; Vars: Pointer; Prop: TPtrArray; PropStr: TStringList; BlockId: integer; var MVTU: IMVTU_Server):integer; const RecName:PChar = 'Двигатель синхронный с успокаювающими обмотками'; var Res: integer; begin case Action of //Возвращаем ссылку на имя записи в базе МВТУ-4 cnv_GetRecName: Result:=integer(RecName); cnv_Convert: with PElectro_DSSRec(Prop.arr)^ do try //Присваиваем параметры для блока MVTU.SetBlockProp(BlockId,'Rds',PChar(PropStr[0]),Res); MVTU.SetBlockProp(BlockId,'Rqs',PChar(PropStr[1]),Res); MVTU.SetBlockProp(BlockId,'Lds',PChar(PropStr[2]),Res); MVTU.SetBlockProp(BlockId,'Lqs',PChar(PropStr[3]),Res); MVTU.SetBlockProp(BlockId,'l',PChar(PropStr[4]),Res); MVTU.SetBlockProp(BlockId,'J',PChar(PropStr[5]),Res); MVTU.SetBlockProp(BlockId,'Rdr',PChar(PropStr[6]),Res); MVTU.SetBlockProp(BlockId,'Rqr',PChar(PropStr[7]),Res); MVTU.SetBlockProp(BlockId,'Ldr',PChar(PropStr[8]),Res); MVTU.SetBlockProp(BlockId,'Lqr',PChar(PropStr[9]),Res); MVTU.SetBlockProp(BlockId,'Ldm',PChar(PropStr[10]),Res); MVTU.SetBlockProp(BlockId,'Lqm',PChar(PropStr[11]),Res); MVTU.SetBlockProp(BlockId,'p',PChar(PropStr[12]),Res); MVTU.SetBlockProp(BlockId,'phi',PChar(PropStr[13]),Res); MVTU.SetBlockProp(BlockId,'q0',PChar(PropStr[14]),Res); MVTU.SetBlockProp(BlockId,'pq0',PChar(PropStr[15]),Res); MVTU.SetBlockProp(BlockId,'p10',PChar(PropStr[16]),Res); MVTU.SetBlockProp(BlockId,'p20',PChar(PropStr[17]),Res); MVTU.SetBlockProp(BlockId,'p30',PChar(PropStr[18]),Res); MVTU.SetBlockProp(BlockId,'p40',PChar(PropStr[19]),Res); MVTU.SetBlockProp(BlockId,'AddOuts',PChar(ConvertMultiSelect(AddOuts)),Res); finally end; end; end; function TElectro_DSS;export; var kk : Integer; qm,Vd,Vq : realtype; // угол поворота магнитного поля и напряжения во вращающейся СК begin Result := 0; case Action of f_GetConvertFuncAdr: Result:=integer(@TElectro_DSSConvert); // Выделяем память под переменные блока f_Create : Vars := New(PElectro_DSSVars); // Освобождаем память переменных блока f_Free : Dispose(Vars); // Указываем количесво переменных состояния f_GetDeriCount : Result := 6; f_GetInit : Result := 1; f_GetCount : begin for kk:=0 to (CU.Count-1) do CU.arr^[kk]:=1; CY.arr^[0]:=1;// размер выхода строго определён CY.arr^[1]:=1;// размер выхода строго определён CY.arr^[2]:= PElectro_DSSRec(Prop.arr)^.AddOuts.Selected.Count;//размер выхода меняется в зависимости от выбранных параметров end; f_UpdateJacoby, f_InitState, f_UpdateOuts, f_RestoreOuts, f_GoodStep : with PElectro_DSSRec(Prop.arr)^ do begin if Action = f_initState then begin // Подсчёт констант (через вновь введённые свойства блока): PElectro_DSSVars(Vars)^.Dd := Lds^*Ldr^-Ldm^*Ldm^; PElectro_DSSVars(Vars)^.Dq := Lqs^*Lqr^-Lqm^*Lqm^; PElectro_DSSVars(Vars)^.K11:= Rds^*Ldr^/PElectro_DSSVars(Vars)^.Dd; PElectro_DSSVars(Vars)^.K12:= Rds^*Ldm^/PElectro_DSSVars(Vars)^.Dd; PElectro_DSSVars(Vars)^.K13:= Rds^*Ldr^*l^/PElectro_DSSVars(Vars)^.Dd; PElectro_DSSVars(Vars)^.K21:= Rdr^*Lds^/PElectro_DSSVars(Vars)^.Dd; PElectro_DSSVars(Vars)^.K22:= Rdr^*Ldm^/PElectro_DSSVars(Vars)^.Dd; PElectro_DSSVars(Vars)^.K23:= Rdr^*Ldm^*l^/PElectro_DSSVars(Vars)^.Dd; PElectro_DSSVars(Vars)^.K31:= Rqs^*Lqr^/PElectro_DSSVars(Vars)^.Dq; PElectro_DSSVars(Vars)^.K32:= Rqs^*Lqm^/PElectro_DSSVars(Vars)^.Dq; PElectro_DSSVars(Vars)^.K41:= Rqr^*Lqs^/PElectro_DSSVars(Vars)^.Dq; PElectro_DSSVars(Vars)^.K42:= Rqr^*Lqm^/PElectro_DSSVars(Vars)^.Dq; PElectro_DSSVars(Vars)^.C11:= Ldr^/PElectro_DSSVars(Vars)^.Dd; PElectro_DSSVars(Vars)^.C12:= Ldm^/PElectro_DSSVars(Vars)^.Dd; PElectro_DSSVars(Vars)^.C13:= Ldr^*l^/PElectro_DSSVars(Vars)^.Dd; PElectro_DSSVars(Vars)^.C21:= Lqr^/PElectro_DSSVars(Vars)^.Dq; PElectro_DSSVars(Vars)^.C22:= Lqm^/PElectro_DSSVars(Vars)^.Dq; PElectro_DSSVars(Vars)^.K10:= 1/J^; PElectro_DSSVars(Vars)^.K := 0.5*phi^*p^; //инициальзация переменных состояния из вновь введённых начальных условий: AX[0]:=q0^; AX[1]:=pq0^; AX[2]:=P10^; AX[3]:=P20^; AX[4]:=P30^; AX[5]:=P40^; end; //Расчёт выходов (на каждом шаге): AY.Ptr(0).arr^[0] := AX[0]; //q AY.Ptr(1).arr^[0] := AX[1]; //pq PElectro_DSSVars(Vars)^.id := PElectro_DSSVars(Vars)^.C11*AX[2] - PElectro_DSSVars(Vars)^.C12*AX[4] - PElectro_DSSVars(Vars)^.C13; PElectro_DSSVars(Vars)^.iq := PElectro_DSSVars(Vars)^.C21*AX[3] - PElectro_DSSVars(Vars)^.C22*AX[5]; for kk:=0 to AddOuts.Selected.Count-1 do case AddOuts.selected.arr^[kk] of 0 : AY.Ptr(2).arr^[kk] := PElectro_DSSVars(Vars)^.K* (AX[2]*PElectro_DSSVars(Vars)^.iq - AX[3]*PElectro_DSSVars(Vars)^.id);//Te = ... 1 : AY.Ptr(2).arr^[kk] := PElectro_DSSVars(Vars)^.id; 2 : AY.Ptr(2).arr^[kk] := PElectro_DSSVars(Vars)^.iq; else AY.Ptr(2).arr^[kk] := 0; end; end; //расчёт приращений: f_GetDeri : with PElectro_DSSRec(Prop.arr)^ do begin //пересчитываем напряжения во вращающихся обмотках: qm := p^*AX[0]; //угол поворота магнитного поля Vd := AU.Ptr(0).arr^[0]*sin(qm)-AU.Ptr(1).arr^[0]*cos(qm); Vq := AU.Ptr(0).arr^[0]*cos(qm)+AU.Ptr(1).arr^[0]*sin(qm); ADX[0] := AX[1]; ADX[1] := PElectro_DSSVars(Vars)^.K10*((PElectro_DSSVars(Vars)^.K*(AX[2]*(PElectro_DSSVars(Vars)^.C21*AX[3]-PElectro_DSSVars(Vars)^.C22*AX[5])-AX[3]*(PElectro_DSSVars(Vars)^.C11*AX[2]-PElectro_DSSVars(Vars)^.C12*AX[4]-PElectro_DSSVars(Vars)^.C13)))-AU.Ptr(2).arr^[0]); ADX[2] := +Vd -PElectro_DSSVars(Vars)^.K11*AX[2] +PElectro_DSSVars(Vars)^.K12*AX[4] +PElectro_DSSVars(Vars)^.K13 +p^*AX[3]*AX[1]; ADX[3] := +Vq -PElectro_DSSVars(Vars)^.K31*AX[3] +PElectro_DSSVars(Vars)^.K32*AX[5] -p^*AX[2]*AX[1]; ADX[4] := -PElectro_DSSVars(Vars)^.K21*AX[4] +PElectro_DSSVars(Vars)^.K22*AX[2] +PElectro_DSSVars(Vars)^.K23; ADX[5] := -PElectro_DSSVars(Vars)^.K41*AX[5] +PElectro_DSSVars(Vars)^.K42*AX[3]; end; f_EditErr : if ( (PElectro_DSSRec(Prop.arr)^.Rds^ < 0) OR (PElectro_DSSRec(Prop.arr)^.Rqs^ < 0) OR (PElectro_DSSRec(Prop.arr)^.Lds^ < 0) OR (PElectro_DSSRec(Prop.arr)^.Lqs^ < 0) OR (PElectro_DSSRec(Prop.arr)^.L^ < 0) OR (PElectro_DSSRec(Prop.arr)^.J^ < 0) OR (PElectro_DSSRec(Prop.arr)^.Rdr^ < 0) OR (PElectro_DSSRec(Prop.arr)^.Rqr^ < 0) OR (PElectro_DSSRec(Prop.arr)^.Ldr^ < 0) OR (PElectro_DSSRec(Prop.arr)^.Lqr^ < 0) OR (PElectro_DSSRec(Prop.arr)^.Ldm^ < 0) OR (PElectro_DSSRec(Prop.arr)^.Lqm^ < 0) OR (PElectro_DSSRec(Prop.arr)^.p^ < 0) OR (PElectro_DSSRec(Prop.arr)^.phi^ < 0) ) then Result:=er_RangeMin; end; // case end; //TElectro_DSS end.