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