00001
00002
00003
00004
00005
00006
00007
00008 #include <stdlib.h>
00009 #include <stdio.h>
00010 #include <errno.h>
00011 #include <math.h>
00012 #include <complex.h>
00013
00014 #include "controller_dg.h"
00015
00016 CLASS* controller_dg::oclass = NULL;
00017 controller_dg *controller_dg::defaults = NULL;
00018
00019 static PASSCONFIG passconfig = PC_BOTTOMUP|PC_POSTTOPDOWN;
00020 static PASSCONFIG clockpass = PC_BOTTOMUP;
00021
00022 controller_dg::controller_dg(MODULE *mod)
00023 {
00024 if(oclass == NULL)
00025 {
00026 oclass = gl_register_class(mod,"controller_dg",sizeof(controller_dg),passconfig|PC_AUTOLOCK);
00027 if (oclass==NULL)
00028 throw "unable to register class controller_dg";
00029 else
00030 oclass->trl = TRL_PROOF;
00031
00032 if(gl_publish_variable(oclass,
00033
00034 PT_char32,"groupid_dg", PADDR(controlled_dgs), PT_DESCRIPTION, "the group ID of the dg objects the controller controls.",
00035 PT_double,"ki", PADDR(ki), PT_DESCRIPTION, "parameter of the propotional control",
00036 PT_double,"kp", PADDR(kp), PT_DESCRIPTION, "parameter of the integral control",
00037 PT_double,"gain", PADDR(gain), PT_DESCRIPTION, "Gain of the controller",
00038 PT_double,"ki_QV", PADDR(ki_QV), PT_DESCRIPTION, "parameter of the propotional control for secondary voltage control",
00039 PT_double,"kp_QV", PADDR(kp_QV), PT_DESCRIPTION, "parameter of the integral control for secondary voltage control",
00040 PT_double,"gain_QV", PADDR(gain_QV), PT_DESCRIPTION, "Gain of the controller for secondary voltage control",
00041 NULL) < 1) GL_THROW("unable to publish properties in %s",__FILE__);
00042
00043 defaults = this;
00044
00045 memset(this,0,sizeof(controller_dg));
00046
00047 if (gl_publish_function(oclass, "interupdate_controller_object", (FUNCTIONADDR)interupdate_controller_dg)==NULL)
00048 GL_THROW("Unable to publish controller_dg deltamode function");
00049 if (gl_publish_function(oclass, "postupdate_controller_object", (FUNCTIONADDR)postupdate_controller_dg)==NULL)
00050 GL_THROW("Unable to publish controller_dg deltamode function");
00051
00052 }
00053 }
00054
00055 int controller_dg::create(void)
00056 {
00057
00058 omega_ref=2*PI*60;
00059
00060 deltamode_inclusive = false;
00061 mapped_freq_variable = NULL;
00062
00063 dgswitchFound = 0;
00064
00065
00066 controller_Pref_convergence_criterion = 0.0001;
00067
00068
00069 gain = 150;
00070 kp = 0.005;
00071 ki = 0.2;
00072
00073 first_run = true;
00074 flag_switchOn = false;
00075
00076 controlTime = 0;
00077
00078 return 1;
00079 }
00080
00081
00082 int controller_dg::init(OBJECT *parent)
00083 {
00084 OBJECT *obj = OBJECTHDR(this);
00085
00086
00087 if ((obj->flags & OF_DELTAMODE) == OF_DELTAMODE)
00088 {
00089 deltamode_inclusive = true;
00090 }
00091
00092
00093 if(controlled_dgs[0] == '\0'){
00094 dgs = gl_find_objects(FL_NEW,FT_CLASS,SAME,"diesel_dg",FT_END);
00095 if(dgs == NULL){
00096 gl_error("No diesel_dg objects were found.");
00097 return 0;
00098
00099
00100
00101 }
00102 }
00103 else {
00104
00105 dgs = gl_find_objects(FL_NEW,FT_CLASS,SAME,"diesel_dg",AND,FT_GROUPID,SAME,controlled_dgs.get_string(),FT_END);
00106 if(dgs == NULL){
00107 gl_error("Although controller given group id, no dgs with given group id found.");
00108
00109
00110
00111
00112 return 0;
00113 }
00114 }
00115
00116
00117 obj = NULL;
00118 int index = 0;
00119 if(dgs != NULL){
00120 pDG = (diesel_dg **)gl_malloc(dgs->hit_count*sizeof(diesel_dg*));
00121 DGpNdName = (char **)gl_malloc(dgs->hit_count*sizeof(char*));
00122 if(pDG == NULL){
00123 gl_error("Failed to allocate diesel_dg array.");
00124 return TS_NEVER;
00125 }
00126
00127 GenPobj = (node **)gl_malloc(dgs->hit_count*sizeof(node*));
00128
00129 while(obj = gl_find_next(dgs,obj)){
00130
00131
00132
00133 OBJECT *dgParent = obj->parent;
00134 if(dgParent == NULL){
00135 gl_error("Failed to find diesel_dg parent node object.");
00136 return 0;
00137 }
00138 DGpNdName[index] = dgParent->name;
00139
00140
00141 if(index >= dgs->hit_count){
00142 break;
00143 }
00144 pDG[index] = OBJECTDATA(obj,diesel_dg);
00145 if(pDG[index] == NULL){
00146 gl_error("Unable to map object as diesel_dg object.");
00147 return 0;
00148 }
00149
00150
00151
00152
00153 node *tempNode = OBJECTDATA(dgParent,node);
00154 if(tempNode == NULL){
00155 gl_error("Unable to map object as diesel_dg object.");
00156 }
00157 GenPobj[index] = tempNode;
00158
00159 ++index;
00160 }
00161
00162
00163 ctrlGen = (CTRL_Gen **)gl_malloc(dgs->hit_count*sizeof(CTRL_Gen*));
00164 prev_Pref_val = (double*)gl_malloc(dgs->hit_count*sizeof(double));
00165 prev_Vset_val = (double*)gl_malloc(dgs->hit_count*sizeof(double));
00166
00167
00168 if (ctrlGen == NULL || prev_Pref_val == NULL)
00169 {
00170 GL_THROW("Restoration:Failed to allocate new chain");
00171
00172 }
00173
00174
00175 for (int i = 0; i < dgs->hit_count; i++) {
00176 ctrlGen[i] = (CTRL_Gen *)gl_malloc(sizeof(CTRL_Gen));
00177
00178 if (ctrlGen[i] == NULL)
00179 {
00180 GL_THROW("Restoration:Failed to allocate new chain");
00181
00182 }
00183 ctrlGen[i]->curr_state = (CTRL_VARS*)gl_malloc(sizeof(CTRL_VARS));
00184 ctrlGen[i]->next_state = (CTRL_VARS*)gl_malloc(sizeof(CTRL_VARS));
00185
00186 prev_Pref_val[i] = 0;
00187 prev_Vset_val[i] = 0;
00188 ctrlGen[i]->curr_state->Vset_ref = -1;
00189 }
00190
00191
00192 }
00193
00194
00195 obj = NULL;
00196 switches = gl_find_objects(FL_NEW,FT_CLASS,SAME,"switch",FT_END);
00197 if(switches == NULL){
00198 gl_error("No switch objects were found.");
00199 return 0;
00200
00201
00202
00203 }
00204 index = 0;
00205 if(switches != NULL){
00206
00207 dgSwitchObj = (OBJECT**)gl_malloc(dgs->hit_count*sizeof(OBJECT*));
00208 pSwitch = (switch_object **)gl_malloc(dgs->hit_count*sizeof(switch_object*));
00209 if(pSwitch == NULL){
00210 gl_error("Failed to allocate switch array.");
00211 return TS_NEVER;
00212 }
00213
00214 while(obj = gl_find_next(switches,obj)){
00215 if(index >= switches->hit_count){
00216 break;
00217 }
00218
00219
00220 switch_object *temp_switch = OBJECTDATA(obj,switch_object);
00221
00222
00223
00224 char *temp_from_name = temp_switch->from->name;
00225 char *temp_to_name = temp_switch->to->name;
00226
00227 bool found = false;
00228 for (int i = 0; i < dgs->hit_count; i++) {
00229 if (strcmp(temp_from_name, DGpNdName[i]) == 0 || strcmp(temp_to_name, DGpNdName[i]) == 0) {
00230 found = true;
00231 break;
00232 }
00233 }
00234 if (found == true) {
00235
00236 pSwitch[dgswitchFound] = OBJECTDATA(obj,switch_object);
00237 dgSwitchObj[dgswitchFound] = obj;
00238 if(pSwitch[dgswitchFound] == NULL){
00239 gl_error("Unable to map object as switch object.");
00240 return 0;
00241 }
00242 dgswitchFound++;
00243 }
00244
00245 ++index;
00246 }
00247 }
00248
00249
00250 if (deltamode_inclusive)
00251 {
00252
00253 if (enable_subsecond_models!=true)
00254 {
00255 gl_warning("diesel_dg:%s indicates it wants to run deltamode, but the module-level flag is not set!",obj->name?obj->name:"unnamed");
00256
00257
00258
00259
00260 }
00261 else
00262 {
00263
00264 mapped_freq_variable = (double *)gl_get_module_var(gl_find_module("powerflow"),"current_frequency");
00265
00266
00267 if (mapped_freq_variable == NULL)
00268 {
00269 GL_THROW("controller_dg:%s - Failed to map frequency checking variable from powerflow for deltamode",obj->name?obj->name:"unnamed");
00270
00271 }
00272
00273 gen_object_count++;
00274 }
00275 }
00276 else
00277 {
00278 if (enable_subsecond_models == true)
00279 {
00280 gl_warning("diesel_dg:%d %s - Deltamode is enabled for the module, but not this generator!",obj->id,(obj->name ? obj->name : "Unnamed"));
00281
00282
00283
00284
00285
00286 }
00287 }
00288
00289
00290 obj = OBJECTHDR(this);
00291 gl_set_rank(obj,1);
00292
00293 return 1;
00294 }
00295
00296
00297 TIMESTAMP controller_dg::presync(TIMESTAMP t0, TIMESTAMP t1)
00298 {
00299
00300 return TS_NEVER;
00301 }
00302
00303
00304 TIMESTAMP controller_dg::sync(TIMESTAMP t0, TIMESTAMP t1)
00305 {
00306 OBJECT *obj = OBJECTHDR(this);
00307 TIMESTAMP tret_value;
00308
00309
00310 tret_value = TS_NEVER;
00311
00312
00313 if (first_run == true)
00314 {
00315
00316 if (deltamode_inclusive && enable_subsecond_models )
00317 {
00318 if (((gen_object_current == -1) || (delta_objects==NULL)) && (enable_subsecond_models == true))
00319 {
00320
00321 allocate_deltamode_arrays();
00322 }
00323
00324
00325 if (gen_object_current>=gen_object_count)
00326 {
00327 GL_THROW("Too many objects tried to populate deltamode objects array in the generators module!");
00328
00329
00330
00331
00332
00333 }
00334
00335
00336 delta_objects[gen_object_current] = obj;
00337
00338
00339 delta_functions[gen_object_current] = (FUNCTIONADDR)(gl_get_function(obj,"interupdate_controller_object"));
00340
00341
00342 if (delta_functions[gen_object_current] == NULL)
00343 {
00344 GL_THROW("Failure to map deltamode function for device:%s",obj->name);
00345
00346
00347
00348
00349
00350 }
00351
00352
00353 post_delta_functions[gen_object_current] = (FUNCTIONADDR)(gl_get_function(obj,"postupdate_controller_object"));
00354
00355
00356 if (post_delta_functions[gen_object_current] == NULL)
00357 {
00358 GL_THROW("Failure to map post-deltamode function for device:%s",obj->name);
00359
00360
00361
00362
00363
00364 }
00365
00366
00367 gen_object_current++;
00368
00369
00370 tret_value = t1;
00371
00372 }
00373
00374 }
00375
00376 return TS_NEVER;
00377 }
00378
00379
00380 TIMESTAMP controller_dg::postsync(TIMESTAMP t0, TIMESTAMP t1)
00381 {
00382 int ret_state;
00383 OBJECT *obj = OBJECTHDR(this);
00384
00385
00386 if (deltamode_endtime != TS_NEVER)
00387 {
00388 deltamode_endtime = TS_NEVER;
00389 deltamode_endtime_dbl = TSNVRDBL;
00390 }
00391
00392
00393 if (first_run == true)
00394 {
00395 if (deltamode_inclusive && enable_subsecond_models)
00396 {
00397
00398 for (int index = 0; index < dgs->hit_count; index++) {
00399
00400 ret_state = init_dynamics(ctrlGen[index]->curr_state, index);
00401
00402 if (ret_state == FAILED)
00403 {
00404 GL_THROW("diesel_dg:%s - unsuccessful call to dynamics initialization",(obj->name?obj->name:"unnamed"));
00405
00406
00407
00408
00409 }
00410 }
00411
00412 }
00413
00414 }
00415
00416 first_run = false;
00417
00418 return TS_NEVER;
00419 }
00420
00422
00424
00425
00426 SIMULATIONMODE controller_dg::inter_deltaupdate(unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val)
00427 {
00428 unsigned char pass_mod;
00429 double deltat, deltath;
00430 double temp_double = 0;
00431
00432 OBJECT *switchFromNdObj = NULL;
00433 node *switchFromNd = NULL;
00434 complex vtemp[3];
00435 double nominal_voltage;
00436 FUNCTIONADDR funadd = NULL;
00437 int return_val;
00438 unsigned char openPhases[] = {0x04, 0x02, 0x01};
00439
00440
00441
00442
00443 OBJECT *obj = NULL;
00444 for (int index = 0; index < dgswitchFound; index++) {
00445
00446
00447 obj = dgSwitchObj[index];
00448
00449
00450
00451 switchFromNdObj = gl_get_object(pSwitch[index]->from->name);
00452 if (switchFromNdObj==NULL) {
00453 throw "Switch from node is not specified";
00454
00455
00456
00457 }
00458
00459
00460 switchFromNd = OBJECTDATA(switchFromNdObj,node);
00461
00462
00463 vtemp[0] = switchFromNd->voltage[0];
00464 vtemp[1] = switchFromNd->voltage[1];
00465 vtemp[2] = switchFromNd->voltage[2];
00466 nominal_voltage = switchFromNd->nominal_voltage;
00467
00468
00469 enumeration phase_A_state_check = pSwitch[index]->phase_A_state;
00470 enumeration phase_B_state_check = pSwitch[index]->phase_B_state;
00471 enumeration phase_C_state_check = pSwitch[index]->phase_C_state;
00472
00473
00474 int total_phase_P = pSwitch[index]->power_in.Re();
00475 int phase_A_P = pSwitch[index]->indiv_power_out[0].Re();
00476 int phase_B_P = pSwitch[index]->indiv_power_out[1].Re();
00477 int phase_C_P = pSwitch[index]->indiv_power_out[2].Re();
00478
00479
00480 if (phase_A_P > 0 || phase_B_P > 0 || phase_C_P > 0) {
00481 gl_warning("Reverse real power flow detected at generator switch %s, generator is absorbing real power now!", obj->name);
00482
00483
00484
00485
00486
00487
00488 }
00489
00490
00491
00492 if ((phase_A_state_check == 1 || phase_B_state_check == 1 || phase_C_state_check == 1) &&
00493 (((*mapped_freq_variable > omega_ref/(2.0*PI)*1.01) || vtemp[0].Mag() > 1.2*nominal_voltage || vtemp[1].Mag() > 1.2*nominal_voltage || vtemp[2].Mag() > 1.2*nominal_voltage)) ||
00494 (phase_A_P > 0 || phase_B_P > 0 || phase_C_P > 0))
00495 {
00496
00497 if ((flag_switchOn == false) || (controlTime == delta_time)) {
00498
00499
00500 funadd = (FUNCTIONADDR)(gl_get_function(obj,"change_switch_state"));
00501
00502
00503 if (funadd==NULL)
00504 {
00505 GL_THROW("Failed to find reliability manipulation method on object %s",obj->name);
00506
00507
00508
00509
00510
00511 }
00512
00513
00514 for (int i = 0; i < 3; i++) {
00515 return_val = ((int (*)(OBJECT *, unsigned char, bool))(*funadd))(obj,openPhases[i],false);
00516 if (return_val == 0)
00517 {
00518 GL_THROW("Failed to handle reliability manipulation on %s",obj->name);
00519
00520
00521
00522
00523 }
00524 }
00525
00526
00527 phase_A_state_check = pSwitch[index]->phase_A_state;
00528 phase_B_state_check = pSwitch[index]->phase_B_state;
00529 phase_C_state_check = pSwitch[index]->phase_C_state;
00530
00531
00532 if (flag_switchOn == false) {
00533 flag_switchOn = true;
00534 }
00535
00536
00537 controlTime == delta_time + 100*dt;
00538
00539 }
00540 }
00541 }
00542
00543
00544 deltat = (double)dt/(double)DT_SECOND;
00545 deltath = deltat/2.0;
00546
00547
00548
00549 if ((delta_time==0) && (iteration_count_val==0))
00550 {
00551
00552 for (int index = 0; index < dgs->hit_count; index++) {
00553
00554 init_dynamics(ctrlGen[index]->curr_state, index);
00555
00556
00557 prev_Pref_val[index] = ctrlGen[index]->curr_state->Pref_ctrl;
00558 prev_Vset_val[index] = ctrlGen[index]->curr_state->Vset_ref;
00559
00560
00561 memcpy(ctrlGen[index]->next_state,ctrlGen[index]->curr_state,sizeof(CTRL_VARS));
00562 }
00563
00564 }
00565
00566
00567 pass_mod = iteration_count_val - ((iteration_count_val >> 1) << 1);
00568
00569
00570 if (pass_mod==0)
00571 {
00572
00573 for (int index = 0; index < dgs->hit_count; index++) {
00574
00575
00576 apply_dynamics(ctrlGen[index]->curr_state,&predictor_vals,deltat, index);
00577
00578
00579 ctrlGen[index]->next_state->x = ctrlGen[index]->curr_state->x + predictor_vals.x*deltat;
00580 ctrlGen[index]->next_state->Pref_ctrl = ctrlGen[index]->next_state->x + predictor_vals.x*(kp/ki);
00581
00582 pDG[index]->gen_base_set_vals.Pref = ctrlGen[index]->next_state->Pref_ctrl;
00583
00584
00585 ctrlGen[index]->next_state->x_QV = ctrlGen[index]->curr_state->x_QV + predictor_vals.x_QV*deltat;
00586 ctrlGen[index]->next_state->Vset_ctrl = ctrlGen[index]->next_state->x_QV + predictor_vals.x_QV*(kp_QV/ki_QV);
00587
00588 pDG[index]->gen_base_set_vals.vset = ctrlGen[index]->next_state->Vset_ctrl;
00589 }
00590
00591 return SM_DELTA_ITER;
00592
00593 }
00594 else
00595 {
00596
00597 for (int index = 0; index < dgs->hit_count; index++) {
00598
00599
00600 apply_dynamics(ctrlGen[index]->next_state,&corrector_vals,deltat, index);
00601
00602
00603 ctrlGen[index]->next_state->x = ctrlGen[index]->curr_state->x + (predictor_vals.x + corrector_vals.x)*deltath;
00604 ctrlGen[index]->next_state->Pref_ctrl = ctrlGen[index]->next_state->x + (predictor_vals.x + corrector_vals.x)*0.5*(kp/ki);
00605
00606 pDG[index]->gen_base_set_vals.Pref = ctrlGen[index]->next_state->Pref_ctrl;
00607
00608
00609 ctrlGen[index]->next_state->x_QV = ctrlGen[index]->curr_state->x_QV + (predictor_vals.x_QV + corrector_vals.x_QV)*deltat;
00610 ctrlGen[index]->next_state->Vset_ctrl = ctrlGen[index]->next_state->x_QV + (predictor_vals.x_QV + corrector_vals.x_QV)*0.5*(kp_QV/ki_QV);
00611
00612 pDG[index]->gen_base_set_vals.vset = ctrlGen[index]->next_state->Vset_ctrl;
00613
00614
00615 memcpy(ctrlGen[index]->curr_state,ctrlGen[index]->next_state,sizeof(CTRL_VARS));
00616
00617
00618 temp_double = fmax(temp_double, fabs(ctrlGen[index]->curr_state->Pref_ctrl - prev_Pref_val[index]));
00619 temp_double = fmax(temp_double, fabs(ctrlGen[index]->curr_state->Vset_ctrl - prev_Vset_val[index]));
00620
00621
00622 prev_Pref_val[index] = ctrlGen[index]->curr_state->Pref_ctrl;
00623 prev_Vset_val[index] = ctrlGen[index]->curr_state->Vset_ref;
00624
00625 }
00626
00627
00628 if (temp_double<=controller_Pref_convergence_criterion)
00629 {
00630
00631 return SM_EVENT;
00632 }
00633 else
00634 {
00635 return SM_DELTA;
00636
00637 }
00638
00639 }
00640 }
00641
00642 STATUS controller_dg::post_deltaupdate(complex *useful_value, unsigned int mode_pass)
00643 {
00644 return SUCCESS;
00645 }
00646
00647
00648
00649
00650
00651
00652 STATUS controller_dg::apply_dynamics(CTRL_VARS *curr_time, CTRL_VARS *curr_delta, double deltaT, int index)
00653 {
00654
00655
00656 curr_delta->x = gain * (curr_time->wref_ctrl-*mapped_freq_variable*2*PI)/omega_ref*ki;
00657
00658
00659 double V_pos_temp = (GenPobj[index]->voltage[0].Mag() + GenPobj[index]->voltage[1].Mag() + GenPobj[index]->voltage[2].Mag())/3.0;
00660 curr_delta->x_QV = gain_QV * (curr_time->Vset_ref-V_pos_temp)/nominal_voltage*ki_QV;
00661
00662 return SUCCESS;
00663 }
00664
00665
00666
00667
00668 STATUS controller_dg::init_dynamics(CTRL_VARS *curr_time, int index)
00669 {
00670 OBJECT *obj = NULL;
00671 double omega = *mapped_freq_variable*2*PI;
00672
00673 curr_time->w_measured = pDG[index]->curr_state.omega/pDG[index]->omega_ref;
00674 curr_time->x = pDG[index]->gen_base_set_vals.Pref;
00675 curr_time->wref_ctrl = omega_ref;
00676 curr_time->Pref_ctrl = curr_time->x;
00677
00678
00679 if (curr_time->Vset_ref < 0) {
00680
00681 curr_time->Vset_ref = (GenPobj[index]->voltage[0].Mag() + GenPobj[index]->voltage[1].Mag() + GenPobj[index]->voltage[2].Mag())/3.0;
00682 nominal_voltage = GenPobj[index]->nominal_voltage;
00683 }
00684 curr_time->x_QV = pDG[index]->gen_base_set_vals.vset;
00685 curr_time->Vset_ctrl = curr_time->x_QV;
00686
00687 return SUCCESS;
00688 }
00689
00691
00693
00694 EXPORT int create_controller_dg(OBJECT **obj, OBJECT *parent)
00695 {
00696 try
00697 {
00698 *obj = gl_create_object(controller_dg::oclass);
00699 if (*obj!=NULL)
00700 {
00701 controller_dg *my = OBJECTDATA(*obj,controller_dg);
00702 gl_set_parent(*obj,parent);
00703 return my->create();
00704 }
00705 else
00706 return 0;
00707 }
00708 CREATE_CATCHALL(controller_dg);
00709 }
00710
00711 EXPORT int init_controller_dg(OBJECT *obj, OBJECT *parent)
00712 {
00713 try
00714 {
00715 if (obj!=NULL)
00716 return OBJECTDATA(obj,controller_dg)->init(parent);
00717 else
00718 return 0;
00719 }
00720 INIT_CATCHALL(controller_dg);
00721 }
00722
00723 EXPORT TIMESTAMP sync_controller_dg(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00724 {
00725 TIMESTAMP t1 = TS_INVALID;
00726 controller_dg *my = OBJECTDATA(obj,controller_dg);
00727 try
00728 {
00729 switch (pass) {
00730 case PC_PRETOPDOWN:
00731 t1 = my->presync(obj->clock,t0);
00732 break;
00733 case PC_BOTTOMUP:
00734 t1 = my->sync(obj->clock,t0);
00735 break;
00736 case PC_POSTTOPDOWN:
00737 t1 = my->postsync(obj->clock,t0);
00738 break;
00739 default:
00740 GL_THROW("invalid pass request (%d)", pass);
00741 break;
00742 }
00743 if (pass==clockpass)
00744 obj->clock = t1;
00745 }
00746 SYNC_CATCHALL(controller_dg);
00747 return t1;
00748 }
00749
00750 EXPORT SIMULATIONMODE interupdate_controller_dg(OBJECT *obj, unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val)
00751 {
00752 controller_dg *my = OBJECTDATA(obj,controller_dg);
00753 SIMULATIONMODE status = SM_ERROR;
00754 try
00755 {
00756 status = my->inter_deltaupdate(delta_time,dt,iteration_count_val);
00757 return status;
00758 }
00759 catch (char *msg)
00760 {
00761 gl_error("interupdate_controller_dg(obj=%d;%s): %s", obj->id, obj->name?obj->name:"unnamed", msg);
00762 return status;
00763 }
00764 }
00765
00766 EXPORT STATUS postupdate_controller_dg(OBJECT *obj, complex *useful_value, unsigned int mode_pass)
00767 {
00768 controller_dg *my = OBJECTDATA(obj,controller_dg);
00769 STATUS status = FAILED;
00770 try
00771 {
00772 status = my->post_deltaupdate(useful_value, mode_pass);
00773 return status;
00774 }
00775 catch (char *msg)
00776 {
00777 gl_error("postupdate_controller_dg(obj=%d;%s): %s", obj->id, obj->name?obj->name:"unnamed", msg);
00778 return status;
00779 }
00780 }
00781
00782