PROGRAM CONRED47;
{$F+}
{******************************************************************
								"   CIRCUITO  HVDC  "
Autores: JRomero - Arodri
Fecha: 16-02-98

		 La simulaci¢n corresponde a un CONVERTIDOR RECTIFICADOR DE
		 6 PULSOS junto con un CONVERTIDOR TRABAJANDO COMO INVERSOR
		 DE 6 PULSOS transmitiendo energia entre dos redes de distinta
		 frecuencia.

		 El convertidor B en principio actua como inversor y podemos
		 elegir el parametro ''gama'' para su funcionamiento, regulan-
		 dose el disparo para que nunca suceda una falla de conmutacion.

		 El convertidor A en principio actua como rectificador, en el
		 cual se regula el disparo de manera que mantenga la corriente
		 de salida constante.

**********************************************************}

USES
wincrt,xmatdefs, wingraph,Dibus,FilUSR, UCntrl, Simul4, traxp, variable,
PlotMems, Memorias,lib_basi, libep02, libep, libdig01;

CONST w=PI*100;           {frecuencia de red =50  Hz}
		periodo=20e-3;      {periodo=2*PI/w}
		Npuntos=1024;       {n£mero de puntos de muestreo}
		sexrad=PI/180;      {constante de conversi¢n de sexagesimal a rad}

VAR
	{ variables definidas para muestrear intensidad cada 60 grados}
		inten_med,
		tMuestra,
		NMuestra:Nreal;
		mem4:Tmemoria;

	Fr_inversor, t2, w2,L_conmu,tension,      {.Para controlar variables.}
	AlphaA, AlphaB:NReal;
	Intensidad, grados:NReal;  {variables para visualizar en pantalla}
	 gama_viejo, error_viejo, error, valor_medio_Ud, valor_medio_inv,
	 valor_medio_bobina, ir, Ud:NReal;
	  bandera_t2, otro_periodo, primera_vez:Boolean;
	  EnYa, EnYb, puntos_calculados:Integer;
	mem1, mem2, mem3:TMemoria;  {para calcular valores medios}
	suma,delta, guardo_t, desfase, periodo2, beta, u, R_serie, GAMA, DeltaA, Id:NReal;
{----------------------------------------------------------------------}

FUNCTION disparoA(k:integer): boolean;
var  vref:NREAL;
BEGIN
		vref:=-cos(alphaA*sexrad);
		disparoA:=(vref<=sin(w*t-2*PI/3-(k-1)*PI/3)) and
		(cos(w*t-2*PI/3-(k-1)*PI/3)>=0);
END;

{--------------------------------------------------------------------}

FUNCTION disparoB(k:integer): boolean;
var  vref:NREAL;
BEGIN
		vref:=-cos(alphaB*sexrad);
		disparoB:=(vref<=sin(w2*t2-2*PI/3-(k-1)*PI/3)) and
		(cos(w2*t2-2*PI/3-(k-1)*PI/3)>=0);


IF	 (t<0.001) and (primera_vez) then  {Condiciones iniciales}
	 begin
	 if (K=3) or (K=4) then disparoB:=TRUE;
	 if (K=1) or (K=2) or (K=5) or (K=6) then disparoB:=False;
	 end
	 else primera_vez:=false;
END;

{----------------------------------------------------------------------}
{*********************************************************
A continuaci¢n los procedimientos Cirt1, Cirt2 y Funcsr de
definici¢n del circuito.
*********************************************************}


PROCEDURE CIRT1;
BEGIN
	  VG(4,6,7,100);         {UR2 }
	  VG(5,6,8,100);         {US2 }
	  VG(6,6,9,100);     	 {UT2 }

	  L(7,16,L_CONMU);
	  r(7,16,1000);   	{R LINEA}
		L(8,2,L_CONMU);
		r(8,2, 1000);		{R LINEA}
	  L(9,3,L_CONMU);
	  r(9,3, 1000);		{R LINEA}

	  R(16,1,0.01);         {r para medir la i de la fase R DE B}

	 { R(4,10, 0.01);			{r para medir i de tiristores}
	 { R(4,11, 0.01);			{r para medir i de tiristores}
	 { R(4,12, 0.01);			{r para medir i de tiristores}

	 { R(0,13, 0.01);			{r para medir i de tiristores}
	 { R(0,14, 0.01);			{r para medir i de tiristores}
	 { R(0,25, 0.01);			{r para medir i de tiristores}


	  {RECTIFICADOR}

	  VG(1,17,5,100);     { tension de linea del rectificador fase R}
	  VG(2,17,14,100);     { tension de linea del rectificador fase S}
	  VG(3,17,15,100);     { tension de linea del rectificador fase T}

	  L(5,12,L_CONMU);
	  r(5,12,1000);
		L(14,19,L_CONMU);
		r(14,19,1000);
	  L(15,10,L_CONMU);
	  r(15,10,1000);



	  L(13,0, 0.02);         { L de interconexion y su R en paralelo}
	  R(13,0,1000000);

	  r(11,13, R_serie);       {R para medir la corriente por el inductor}
	  r(12,18,0.01);       {R para medir la corriente de fase R de A}



END;

{---------------------------------------------------------------------}

PROCEDURE CIRT2;
BEGIN
			{rectificador}
	  TH(18,11, disparoA(1));     {T1} {del rectificador}
	  TH(4,10,  disparoA(2));     {T2}
	  TH(19,11, disparoA(3));     {T3}
	  TH(4,18,  disparoA(4));     {T4}
	  TH(10,11, disparoA(5));     {T5}
	  TH(4,19,  disparoA(6));     {T6}
			{inversor}
	  th(1,4, disparoB(1));     {T1}
	  th(0,3, disparoB(2));     {T2}
	  th(2,4, disparoB(3));     {T3}
	  th(0,1, disparoB(4));     {T4}
	  th(3,4, disparoB(5));     {T5}
	  th(0,2, disparoB(6));     {T6}
END;

{---------------------------------------------------------------------}

PROCEDURE FUNCSR(t:NReal);
BEGIN
rf[1]:=sin(w*t);        	{Ra}
rf[2]:=sin(w*t -2*PI/3);	{Sa}
rf[3]:=sin(w*t -4*PI/3);	{Ta}

rf[4]:=sin(w2*t2);        	{Rb}
rf[5]:=sin(w2*t2 -2*PI/3);	{Sb}
rf[6]:=sin(w2*t2 -4*PI/3);	{Tb}
END;


{---------------------------------------------------------------------}

{********************************************************
A continuaci¢n los procedimientos de inicio, fin  y Pesca
necesarios para Simeep
*********************************************************}

PROCEDURE INICIO;
BEGIN
nn:=19;			{n£mero de nodos del circuito sin incluir 0 (Tierra)}
nindep:=6;		{n£mero de fuentes independientes}
tinicial:=0e-3;   {tiempo incial de cada simulaci¢n}
tfinal:=20e-3; {tiempo final de cada simulaci¢n}

{Valores iniciales de variables de estado.
 Estas se definen en el orden en que aparecen las inductancias
 y Capacitancias en Cirt1}
x0[1]:= -10;
x0[2]:=  9.71;
x0[3]:=  0.025;

x0[4]:= -9.76;
x0[5]:=  0.025;
x0[6]:=  9.78;

x0[7]:= 10;		{corresponde a  L de union entre convertidores}

{valores de precisi¢n de Simeep}
dtmax0:=10e-6;
dtmin:=dtmax0/100;
PasoDivisor:=6;
TmaxTmin:=1e3;

{indicamos a TRAXP los tiempos que debe graficar}
traxp.tinicial:=tinicial;
traxp.tfinal:=tfinal;

{En esta secci¢n, definimos el n£mero de pantallas, y los colores,
 en n£mero de grillas inciales, y si tenemos alguna superpocici¢n
 de se¤ales en una misma ventana}
gridx:=12;	{las divisiones en X son 12}
gridy:=8;	{las diviciones en Y son 8}
subplot(1,3); {matriz de pantallas de 1 por 1}


{definiciones de visualizaci¢n para la pantalla 0, que
 est  asociada al canal 0}
definaY(0,-200, 50);
titulo('  (Azul): U_salida A. Frecuencia fija de 50 Hz.         (Rojo): U_salida B.');
xlabel('30§/Div.');
ylabel('50 V/Div. ');
linea0;
grid;
superponga(3,0);
superponga(4, 0);
superponga(5,0);
  definacolor(0,azul);
  definacolor(3,rojo);
  definacolor(4,rojo);
  definacolor(5,rojo);


{definiciones de visualizaci¢n para la pantalla 1, que
 est  asociada al canal 1}
definaY(1,-200, 50);
titulo('(Amarillo): Tension sobre la bobina de conexion.  (Rojo): Intensidad de salida');
xlabel('30§/Div.');
ylabel('50 V/Div.  5 A/Div.');
linea0;
grid;
superponga(6, 1);
  definacolor(1,  ROJO);
  definacolor(6,  14);


{definiciones de visualizaci¢n para la pantalla 2, que
 est  asociada al canal 2}
definaY(2,-180, 20);
titulo('(Azul claro) UR de A. (Azul): iR de A  (Rojo claro) UR de B. (Rojo): iR de B');
xlabel('30§/Div.');
ylabel(' Conv.B    Conv.A');
linea0;
grid;
superponga(7, 2);
superponga(8, 2);
superponga(9, 2);
superponga(10, 2);
superponga(11, 2);
  definacolor(2,  1);
  definacolor(7,  11);
  definacolor(8, rojo);
  definacolor(9, 12);
END;

{---------------------------------------------------------------------}

PROCEDURE PESCA;
var   k1,k2,k3, vector_U, coseno, coseno_absoluto:NReal;
		k,enX:integer;
BEGIN
INC(puntos_calculados);

grados:=18000*t; {....Para ver en el display el tiempo y los grados.}
if grados>=360 then grados:=grados-360*Int(t/0.02);

ir:=v[16]-v[1];  {calculo de la intensidad de fase R de B}
Intensidad:=(v[11]-v[13])/R_serie;  {calculo de la intensidad de salida de A}


{...................calculo para el cambio de frecuencia en B.........}
W2:=2*PI*Fr_inversor;     {calculo de w2 para convertidorB}
periodo2:=1/Fr_inversor;  {calculo del periodo para B}
t2:=t+desfase;            {calculo del avance del tiempo para B}


if (t2>periodo2) and (NOT bandera_t2) then {mientra pasa T2 entra aqui}
											 begin
											 t2:=t-guardo_t; {reajuste del tiempo para B}

											 if t2>periodo2 then otro_periodo:=true;
											 {esto es porque los 60 Hz pueden entran dentro de los 50Hz}
											 {y entonces levanto una bandera para que vuelva a entrar}
											 {en final del periodo T2}
											 end;

		  {entra primero aqui al llegar a su T2}
if ((t2>periodo2) and (bandera_t2)) or (otro_periodo)
											 then
											 begin

											 t2:=0;   {reajuste del tiempo para B}
											 guardo_t:=t;
											 bandera_t2:=false;
											 otro_periodo:=false;
											 end;
{......................................................................}

Ud:=v[11]-v[4];
mem1.tic(t,Ud);
mem2.tic(t,v[13]-v[0]);
mem3.tic(t,v[4]-v[0]);


			  {Calculo el tiempo de conmutacion Uk}
coseno:=cos(alphaB*PI/180)-w*L_conmu*2*intensidad/ (SQRT(3)*tension);
if (coseno>-0.000001) AND (coseno<0.000001) then coseno:=0.000001;
coseno_absoluto:=ABS(coseno);
vector_U:=ArcTan(SQRT(ABS(1-SQR(coseno_absoluto)))/coseno_absoluto);
  if coseno<0 then	vector_U:=PI-vector_U; {aqui tengo u }
vector_u:=vector_u*180/pi;
U:=vector_U-alphaB;
Beta:=gama+u;
						{...................................}

{pesca de intensidad para muestreo, para halla el valor medio cada 60 grados}
	if tMuestra>=periodo/6 then
	begin                       {Aqui solo entra una vez cada 60 grados}
		tMuestra:=0;
		NMuestra:=NMuestra+1;

		mem4.fft;
		inten_med:=mem4.ValorMedio;
		mem4.retrocesobarrido(periodo/6);

		  {  Realimentacion, control P-I-D }
		  error:=inten_med-Id;

		  K1:=0.05;      {constante de P}
		  k2:=0.02;      {constante de D}
		  k3:=0.0009;    {constante de I}

		  if alphaA<>0 then
		  suma:=suma+error;

		  delta:=K1*error+ K2*suma+ K3* (error_viejo-error)/50;
		  alphaA:=alphaA+delta;
		  if alphaA>180 then
							delay(100);

		  if alphaA<0 then alphaA:=0; {limito el valor minimo}
		  error_viejo:=error; {restauro el valor viejo por el actual}
		  {  Fin de realimentacion, control P-I-D }
		end
	else
	tMuestra:=t-NMuestra*periodo/6;
	mem4.tic(tMuestra,intensidad);


					 {.......otro ajuste sobre el control.......}

alphaB:=180-Gama-u; {controlo el valor de alphaB para que no haya falla}

if TRUNC(gama_viejo)<>TRUNC(gama) then  {vigilo si modifico gama}
		alphaA:=alphaA+gama-gama_viejo;   {y retoco alphaA}

gama_viejo:=gama;  {restaura el valor viejo por el actual}






{indicar el tiempo de simulaci¢n a el graficador}
traxp.t:=t;
{relaci¢n de se¤ales a graficar con los canales deseados}


{...Pinto anotaciones sobre las graficas...}
enX:=PUNTOX+25; {paso la ordenada x que pinta la onda a la variable enX por medio de la funcion puntox}
{ANOTAR_EVENTO(GRAD1,GRAD2,GRAD, ENX,       y,y1a,y1b,y2a,y2b,etiqueta)}
{Alpha1}ANOTAR_EVENTO(1,30, 30+alphaA, grados,enx, enYa-10,enYa-13,enYa-7,enYa-13,EnYa-7,CHR(224));



{grafica 0}
SetLineStyle(0,0,3);
trazo(0, (v[13]-v[4]) );              { TENSION EN LA CARGA R-L }
enYa:=PUNTOY+22; {paso la ordenada y que pinta la onda a la variable enY por medio de la funcion puntox}
trazo(3,v[4]);  {TENSION DE ENTRADA AL INVERSOR}
enYb:=PUNTOY+22; {paso la ordenada y que pinta la onda a la variable enY por medio de la funcion puntox}


trazo(4,v[4]);  {TENSION DE ENTRADA AL INVERSOR}
trazo(5,v[4]);  {TENSION DE ENTRADA AL INVERSOR}
SetLineStyle(0,0,0);

{GRAFIA 1}
SetLineStyle(0,0,0);
TRAZO(6,(V[13]-V[0]));         {TENSION DE BOBINA}
TRAZO(6,0);

SetLineStyle(0,0,3);
TRAZO(1,intensidad*10);   {INTENSIDAD DE BOBINA}
SetLineStyle(0,0,0);


{GRAFICA 2}

if fr_inversor<=100 then
begin
trazo(2, (v[12]-v[18])*170 - 80);              { i fase R }
trazo(2,-80);
trazo(7, (v[5]-v[17])*0.3  -80  );            { v fase R }

trazo(8, (v[1]-v[16])*170 -140);                { i fase R }
trazo(8,-140);
trazo(9, (v[7]-v[6]) *0.3  -140 );              { v fase R }
end
else
begin
  trazo(2, (v[10]-v[4]) *100  -80 );              { v fase R }
  {trazo(7, (v[0]-v[15]) *100  -100 );              { v fase R }
	trazo(8, (v[11]-v[4]) *100  -120 );              { v fase R }
	trazo(9, (v[0]-v[13]) *100  -140 );              { v fase R }
  trazo(10, (v[12]-v[4]) *100  -160 );              { v fase R }
  trazo(11, (v[0]-v[14]) *100  -180 );              { v fase R }
end;

	{borrado de la pantalla despu‚s de cada simulaci¢n}
	if t >= tfinal then
	begin
	bandera_t2:=true;
	desfase:=t2;

			{resetear variables de muestreo de intensidad}
			tMuestra:=0;
			NMuestra:=0;

		for k:= 0 to 11 do
				begin
		borrecanal(k,0);
		desligue(k);


		borde;
		grid;
		linea0;
		end;

		mem1.fft;                           {valor medio de Ud }
		valor_medio_Ud:=mem1.valormedio;
		mem1.retrocesobarrido(tfinal-tinicial);

		mem2.fft;
		valor_medio_Bobina:=mem2.valormedio;    {valor medio en bobina}
		mem2.retrocesobarrido(tfinal-tinicial);

		mem3.fft;
		valor_medio_Inv:=mem3.valormedio;    {valor medio en inv}
		mem3.retrocesobarrido(tfinal-tinicial);


		t:=t-tfinal+tinicial;
	end;
END;


{---------------------------------------------------------------------}

PROCEDURE FIN;
BEGIN
	halt;
END;


{---------------------------------------------------------------------}

PROCEDURE INICIALIZACION_PARAMETROS;
BEGIN
tension:=100;
primera_vez:=true;
bandera_t2:=true;
R_serie:=1;
t2:=0;
guardo_t:=0;
desfase:=0;
otro_periodo:=false;
valor_medio_inv:=-124.6;
valor_medio_Ud:=135.7;
valor_medio_bobina:=1.4;
error:=0;           {para el control P-I-D}
delta:=0;           {para el control P-I-D}
alphaA:=28;
L_conmu:=0.002;
gama_viejo:=40;   {para saber cuando cambio gama}
suma:=0;

inten_med:=10;	{valor "inicial", antes de hacer el primer calculo}
	NMuestra:=0;   {para calcular la I salida media cada 60 grados}
	tMuestra:=0;
	mem4:= TMemoria.Create_init(periodo/6/npuntos,npuntos,0,0);

END;


{----------------------------------------------------------------------}
{******************************PRINCIPAL*******************************}
{----------------------------------------------------------------------}
BEGIN
INICIALIZACION_PARAMETROS;

{Indicamos a Simeep donde est n las funciones que preparamos}
FilUSR.Cirt1:=Cirt1;
FilUSR.Cirt2:=Cirt2;
FilUSR.FuncsR:=FuncsR;
FilUSR.Inicio:=Inicio;
FilUSR.Pesca:=Pesca;
FilUSR.Fin:=Fin;

{Pantalla de controles}
UCntrl.init;
mem1:= TMemoria.Create_init(20e-3/1024,1024,0,0);
mem2:= TMemoria.Create_init(20e-3/1024,1024,0,0);
mem3:= TMemoria.Create_init(20e-3/1024,1024,0,0);

{------------------PARA VISUALIZAR TEXTO EN LA SIMULACION--------------}

UCntrl.insertdisplay(new(PCtrlVerTexto,init
(    0,   '        HVDC ',
			 '    RECTIFICADOR',
			 '      INVERSOR   ')));


{---------------PARA CONTROLAR VARIABLES EN LA SIMULACION--------------}

UCntrl.insert(new(PCtrlBotonVar,Init
{renglon, nombre,  unidad, decimales, min, max,   def, inc,    var}
(    6, ' Fr. de B',  'Hz'    ,0,          50,  60,    50,   1, Fr_inversor)));


UCntrl.insert(new(PCtrlBotonVar,Init
{renglon, nombre,  unidad, decimales, min, max,   def, inc,    var}
(    7, ' L_CONMU',  'mH'    ,0,       1,  5,     2, 1, L_CONMU)));


UCntrl.insert(new(PCtrlBotonVar,Init
{renglon, nombre,  unidad, decimales, min, max,   def, inc,    var}
(    8, '   Id',       'A'      ,1,      2,  15,    10,   0.5, Id)));


UCntrl.insert(new(PCtrlBotonVar,Init
{renglon, nombre,  unidad, decimales, min, max,   def, inc,    var}
(    9, '  Gama',  '§'       ,0,       20, 160,    40, 2,  Gama)));



{-----------------PARA VER VARIABLES EN LA SIMULACION------------------}

UCntrl.insertdisplay(new(PCtrlVer2Var,init
 {renglon,  nombre1,  uni1, deci1,  var1 , nombre2,  uni2, deci2, var2}
(    1,    'Tiempo_A',   'Sg',   3  ,  t ,  'Grados_A',  '§',   0 ,grados)));

UCntrl.insertdisplay(new(PCtrlVer2Var,init
{ renglon, nombre1, uni1, deci1,  var1 , nombre2, uni2, deci2, var2}
(    2, 'u', '§',1, u , 'Beta',  '§', 1  , Beta )));

UCntrl.insertdisplay(new(PCtrlVer2Var,init
{ renglon, nombre1, uni1, deci1,  var1 , nombre2, uni2, deci2, var2}
(    3, 'Ud_A_M', 'V',1, valor_medio_Ud , 'Ud_B_M',  'V', 1  , valor_medio_inv )));

UCntrl.insertdisplay(new(PCtrlVer2Var,init
{ renglon, nombre1, uni1, deci1,  var1 , nombre2, uni2, deci2, var2}
(    4, 'Ud_Bob_M',  'V',1 ,valor_medio_bobina, 'id_med', 'A',3 ,Inten_med)));

UCntrl.insertdisplay(new(PCtrlVer2Var,init
{ renglon, nombre1, uni1, deci1,  var1 , nombre2, uni2, deci2, var2}
(    5, 'Alpha_A',  '§',1 ,AlphaA, 'Alpha_B', '§',1 ,alphaB)));


{----------------------------------------------------------------------}

{Inicio de Simulaciones}
PASEO;
END.
