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 relay::relay(MODULE *mod) : link(mod)
00052 {
00053
00054 if (oclass==NULL)
00055 {
00056
00057 relay_class = oclass = gl_register_class(mod,"relay",sizeof(relay),PC_BOTTOMUP);
00058 if (oclass==NULL)
00059 GL_THROW("unable to register object class implemented by %s",__FILE__);
00060
00061
00062 if (gl_publish_variable(oclass,
00063 PT_enumeration,"Curve",PADDR(Curve),
00064 PT_KEYWORD,"FC_U1",FC_U1,
00065 PT_KEYWORD,"FC_U2",FC_U2,
00066 PT_KEYWORD,"FC_U3",FC_U3,
00067 PT_KEYWORD,"FC_U4",FC_U4,
00068 PT_KEYWORD,"FC_U5",FC_U5,
00069 PT_double, "TimeDial", PADDR(TimeDial),
00070 PT_double, "SetCurrent", PADDR(SetCurrent),
00071 PT_enumeration,"State",PADDR(State),
00072 PT_KEYWORD,"FS_CLOSED",FS_CLOSED,
00073 PT_KEYWORD,"FS_TRIPPED",FS_TRIPPED,
00074 PT_KEYWORD,"FS_RECLOSED",FS_RECLOSED,
00075 PT_KEYWORD,"FS_LOCKOUT",FS_LOCKOUT,
00076 PT_KEYWORD,"FS_FAULT",FS_FAULT,
00077 NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00078
00079
00080 defaults = this;
00081 }
00082 }
00083
00084 int relay::create()
00085 {
00086 int result = link::create();
00087 memcpy(this,defaults,sizeof(*this));
00088 return result;
00089 }
00090
00091 TIMESTAMP relay::sync(TIMESTAMP t0)
00092 {
00093 link::sync(t0);
00094
00095 double M = I.Mag()/SetCurrent;
00096 switch (State) {
00097 case FS_CLOSED:
00098 if (M>1)
00099 {
00100 Tp = TimeDial * (Ap[Curve]+Bp[Curve]/(pow(M,Cp[Curve])-1));
00101 TIMESTAMP t1 = Tstate + (TIMESTAMP)(Tp*TS_SECOND);
00102 if (t1<=t0)
00103 {
00104 State=FS_TRIPPED;
00105 Tstate = t0;
00106 t1 = TS_NEVER;
00107 }
00108 return t1;
00109 }
00110 else if (M<=1)
00111 {
00112 Tstate = 0;
00113 return TS_NEVER;
00114 }
00115 break;
00116 case FS_TRIPPED:
00117 if (M<1)
00118 {
00119
00120 Tr = TimeDial *(Br[Curve]/(1-pow(M,Cr[Curve])));
00121 TIMESTAMP t1 = Tstate +(TIMESTAMP)(Tr*TS_SECOND);
00122 if (t1<=t0)
00123 {
00124 State = FS_RECLOSED;
00125 Tstate = t0;
00126 return TS_NEVER;
00127 }
00128 else
00129 return t1;
00130 }
00131 break;
00132 case FS_RECLOSED:
00133
00134 break;
00135 case FS_LOCKOUT:
00136
00137 break;
00138 case FS_FAULT:
00139
00140 break;
00141 default:
00142 break;
00143 }
00144
00145 return TS_NEVER;
00146 }
00148
00150
00151 EXPORT int create_relay(OBJECT **obj, OBJECT *parent)
00152 {
00153 *obj = gl_create_object(relay_class);
00154 if (*obj!=NULL)
00155 {
00156 relay *my = OBJECTDATA(*obj,relay);
00157 gl_set_parent(*obj,parent);
00158 my->create();
00159 return 1;
00160 }
00161 return 0;
00162 }
00163
00164 EXPORT TIMESTAMP sync_relay(OBJECT *obj, TIMESTAMP t0)
00165 {
00166 TIMESTAMP t1 = OBJECTDATA(obj,relay)->sync(t0);
00167 obj->clock = t0;
00168 return t1;
00169 }
00170