00001
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <errno.h>
00032 #include <math.h>
00033 #include "network.h"
00034
00035
00036 static const double Ap[] = {0.0226, 0.1800, 0.0963, 0.0352, 0.00262 };
00037 static const double Bp[] = {0.0104, 5.9500, 3.8800, 5.6700, 0.00342 };
00038 static const double Cp[] = {0.0200, 2.0000, 2.0000, 2.0000, 0.02000 };
00039 static const double Br[] = {1.0800, 5.9500, 3.8800, 5.6700, 0.32300 };
00040 static const double Cr[] = {2.0000, 2.0000, 2.0000, 2.0000, 2.00000 };
00041
00042
00044
00046 CLASS* relay::oclass = NULL;
00047 CLASS* relay::pclass = NULL;
00048 relay *relay::defaults = NULL;
00049
00050 relay::relay(MODULE *mod) : link(mod)
00051 {
00052
00053 if (oclass==NULL)
00054 {
00055
00056 relay_class = oclass = gl_register_class(mod,"relay",PC_BOTTOMUP);
00057 if (oclass==NULL)
00058 GL_THROW("unable to register object class implemented by %s",__FILE__);
00059
00060
00061 if (gl_publish_variable(oclass,
00062 PT_enumeration,"Curve",PADDR(Curve),
00063 PT_KEYWORD,"FC_U1",FC_U1,
00064 PT_KEYWORD,"FC_U2",FC_U2,
00065 PT_KEYWORD,"FC_U3",FC_U3,
00066 PT_KEYWORD,"FC_U4",FC_U4,
00067 PT_KEYWORD,"FC_U5",FC_U5,
00068 PT_double, "TimeDial", PADDR(TimeDial),
00069 PT_double, "SetCurrent", PADDR(SetCurrent),
00070 PT_enumeration,"State",PADDR(State),
00071 PT_KEYWORD,"FS_CLOSED",FS_CLOSED,
00072 PT_KEYWORD,"FS_TRIPPED",FS_TRIPPED,
00073 PT_KEYWORD,"FS_RECLOSED",FS_RECLOSED,
00074 PT_KEYWORD,"FS_LOCKOUT",FS_LOCKOUT,
00075 PT_KEYWORD,"FS_FAULT",FS_FAULT,
00076 NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00077
00078
00079 defaults = this;
00080 }
00081 }
00082
00083 int relay::create()
00084 {
00085 int result = link::create();
00086 memcpy(this,defaults,sizeof(*this));
00087 return result;
00088 }
00089
00090 TIMESTAMP relay::sync(TIMESTAMP t0)
00091 {
00092 link::sync(t0);
00093
00094 double M = I.Mag()/SetCurrent;
00095 switch (State) {
00096 case FS_CLOSED:
00097 if (M>1)
00098 {
00099 Tp = TimeDial * (Ap[Curve]+Bp[Curve]/(pow(M,Cp[Curve])-1));
00100 TIMESTAMP t1 = Tstate + (TIMESTAMP)(Tp*TS_SECOND);
00101 if (t1<=t0)
00102 {
00103 State=FS_TRIPPED;
00104 Tstate = t0;
00105 t1 = TS_NEVER;
00106 }
00107 return t1;
00108 }
00109 else if (M<=1)
00110 {
00111 Tstate = 0;
00112 return TS_NEVER;
00113 }
00114 break;
00115 case FS_TRIPPED:
00116 if (M<1)
00117 {
00118
00119 Tr = TimeDial *(Br[Curve]/(1-pow(M,Cr[Curve])));
00120 TIMESTAMP t1 = Tstate +(TIMESTAMP)(Tr*TS_SECOND);
00121 if (t1<=t0)
00122 {
00123 State = FS_RECLOSED;
00124 Tstate = t0;
00125 return TS_NEVER;
00126 }
00127 else
00128 return t1;
00129 }
00130 break;
00131 case FS_RECLOSED:
00132
00133 break;
00134 case FS_LOCKOUT:
00135
00136 break;
00137 case FS_FAULT:
00138
00139 break;
00140 default:
00141 break;
00142 }
00143
00144 return TS_NEVER;
00145 }
00147
00149
00150 EXPORT int create_relay(OBJECT **obj, OBJECT *parent)
00151 {
00152 *obj = gl_create_object(relay_class,sizeof(relay));
00153 if (*obj!=NULL)
00154 {
00155 relay *my = OBJECTDATA(*obj,relay);
00156 gl_set_parent(*obj,parent);
00157 my->create();
00158 return 1;
00159 }
00160 return 0;
00161 }
00162
00163 EXPORT TIMESTAMP sync_relay(OBJECT *obj, TIMESTAMP t0)
00164 {
00165 TIMESTAMP t1 = OBJECTDATA(obj,relay)->sync(t0);
00166 obj->clock = t0;
00167 return t1;
00168 }
00169