Commit dcb1b00d authored by Claes Sjofors's avatar Claes Sjofors

bcomp IMC, division by 0 protection added, and fix for Accel in object graph

parent 1927c727
...@@ -134,6 +134,7 @@ void RunTimeCounterFo_exec( plc_sThread *tp, ...@@ -134,6 +134,7 @@ void RunTimeCounterFo_exec( plc_sThread *tp,
o->OldReset = *o->ResetP; o->OldReset = *o->ResetP;
} }
/*_* /*_*
CompModePID_Fo CompModePID_Fo
...@@ -567,6 +568,7 @@ void CompOnOffZoneFo_exec( plc_sThread *tp, ...@@ -567,6 +568,7 @@ void CompOnOffZoneFo_exec( plc_sThread *tp,
co->CycleCount = 0; co->CycleCount = 0;
} }
//---- modified v0.3-----------------------------------------------START--------
/*_* /*_*
PLC interface & calculus to discrete time Internal Model Controler component PLC interface & calculus to discrete time Internal Model Controler component
...@@ -574,13 +576,17 @@ void CompOnOffZoneFo_exec( plc_sThread *tp, ...@@ -574,13 +576,17 @@ void CompOnOffZoneFo_exec( plc_sThread *tp,
@aref compimc @aref compimc
@aref compimc_fo CompImc_Fo @aref compimc_fo CompImc_Fo
2015 - 12 - 19 Bruno: initial object. 2015 - 12 - 19 Bruno: initial object. v0.1
2016 - 04 - 11 Bruno: cleaning. 2016 - 04 - 11 Bruno: cleaning. v0.2
2017 - 04 - 14 Bruno: remove "division by zero" potential bugs v0.3
*/ */
#define Clamp(x, min, max) x = ((x)<(min)) ? (min) : (((x)>(max)) ? (max) : (x))
#define Normalize(x, y, xmin, xmax, ymin, ymax) y = (((((ymax)-(ymin))/((xmax)-(xmin)))*((x)-(xmin)))+(ymin))
#define Te tp->ActualScanTime #define Te tp->ActualScanTime
#define MAXCELLS 100 #define MAXCELLS 100
#define Clamp(x, min, max) x = ((x)<(min)) ? (min) : (((x)>(max)) ? (max) : (x))
//#define Normalize(x, y, xmin, xmax, ymin, ymax) y = (((((ymax)-(ymin))/((xmax)-(xmin)))*((x)-(xmin)))+(ymin)) // replaced by a function in v0.3
void CompIMC_Fo_init( pwr_sClass_CompIMC_Fo *plc_obj) void CompIMC_Fo_init( pwr_sClass_CompIMC_Fo *plc_obj)
{ {
...@@ -599,6 +605,11 @@ void CompIMC_Fo_exec( plc_sThread *tp, ...@@ -599,6 +605,11 @@ void CompIMC_Fo_exec( plc_sThread *tp,
if ( !plant_obj) return; if ( !plant_obj) return;
pwr_tFloat32 man_OP, sig, yr, LSP, PV, nLSP, nPV, Tl1, Tl2; pwr_tFloat32 man_OP, sig, yr, LSP, PV, nLSP, nPV, Tl1, Tl2;
void Normalize (pwr_tFloat32 x, pwr_tFloat32 *y, pwr_tFloat32 xmin, pwr_tFloat32 xmax, pwr_tFloat32 ymin, pwr_tFloat32 ymax) // v0.3
{
if((xmax-xmin)!=0.0) *y =(ymax-ymin)/(xmax-xmin)*(x-xmin)+ymin; else return;
}
void LagFilter(pwr_tInt16 n, pwr_tFloat32 Tlag) void LagFilter(pwr_tInt16 n, pwr_tFloat32 Tlag)
{ {
if (Tlag < Te) { plant_obj->S[n+1] = plant_obj->S[n]; return; } if (Tlag < Te) { plant_obj->S[n+1] = plant_obj->S[n]; return; }
...@@ -615,6 +626,7 @@ void CompIMC_Fo_exec( plc_sThread *tp, ...@@ -615,6 +626,7 @@ void CompIMC_Fo_exec( plc_sThread *tp,
pwr_tFloat32 ka = 1.0+kd; pwr_tFloat32 ka = 1.0+kd;
pwr_tFloat32 kb = 1.0-kc; pwr_tFloat32 kb = 1.0-kc;
if (ka<=0) return; // v0.3
Clamp (plant_obj->S[n+1], 0.0, 100.0); Clamp (plant_obj->S[n+1], 0.0, 100.0);
plant_obj->S[n+1] = plant_obj->S[n+1] =
kd/ka* plant_obj->S[n+1] kd/ka* plant_obj->S[n+1]
...@@ -631,6 +643,7 @@ void CompIMC_Fo_exec( plc_sThread *tp, ...@@ -631,6 +643,7 @@ void CompIMC_Fo_exec( plc_sThread *tp,
pwr_tFloat32 a2 = -1.0; pwr_tFloat32 a2 = -1.0;
pwr_tFloat32 b0 = Te*Te*w0P*w0P; pwr_tFloat32 b0 = Te*Te*w0P*w0P;
if (a0<=0) return; // v0.3
Clamp (plant_obj->S[n+1], 0.0, 100.0); Clamp (plant_obj->S[n+1], 0.0, 100.0);
plant_obj->uOutm2 = plant_obj->uOutm1; plant_obj->uOutm2 = plant_obj->uOutm1;
plant_obj->uOutm1 = plant_obj->S[n+1]; plant_obj->uOutm1 = plant_obj->S[n+1];
...@@ -651,6 +664,7 @@ void CompIMC_Fo_exec( plc_sThread *tp, ...@@ -651,6 +664,7 @@ void CompIMC_Fo_exec( plc_sThread *tp,
pwr_tFloat32 a1 = w0*w0*(2.0*Tl1*Tl2+Te*(Tl1+Tl2)); pwr_tFloat32 a1 = w0*w0*(2.0*Tl1*Tl2+Te*(Tl1+Tl2));
pwr_tFloat32 a2 = -w0*w0*Tl1*Tl2; pwr_tFloat32 a2 = -w0*w0*Tl1*Tl2;
if (a0<=0) return; // v0.3
Clamp (plant_obj->S[n+1], 0.0, 100.0); Clamp (plant_obj->S[n+1], 0.0, 100.0);
plant_obj->Outm2 = plant_obj->Outm1; plant_obj->Outm2 = plant_obj->Outm1;
plant_obj->Outm1 = plant_obj->S[n+1]; plant_obj->Outm1 = plant_obj->S[n+1];
...@@ -706,16 +720,16 @@ void CompIMC_Fo_exec( plc_sThread *tp, ...@@ -706,16 +720,16 @@ void CompIMC_Fo_exec( plc_sThread *tp,
LSP=plant_obj->SP+plant_obj->Trim_SP; // Calculate working setpoint LSP=plant_obj->SP+plant_obj->Trim_SP; // Calculate working setpoint
Clamp (LSP, plant_obj->LL_SP, plant_obj->HL_SP); // Apply limits Clamp (LSP, plant_obj->LL_SP, plant_obj->HL_SP); // Apply limits
Normalize(LSP,nLSP, plant_obj->LR_PV, plant_obj->HR_PV,0.0,100.0); // Normalize setpoint value Normalize(LSP,&nLSP, plant_obj->LR_PV, plant_obj->HR_PV,0.0,100.0); // Normalize setpoint value // v0.3
PV = plant_obj->PV; // Copy from GUI PV = plant_obj->PV; // Copy from GUI
Normalize(PV,nPV, plant_obj->LR_PV, plant_obj->HR_PV,0.0,100.0); // Normalize process value Normalize(PV,&nPV, plant_obj->LR_PV, plant_obj->HR_PV,0.0,100.0); // Normalize process value // v0.3
sig = (plant_obj->Inverse) ? nLSP - nPV : nPV - nLSP; // Error signal after direct/inverse Comparator sig = (plant_obj->Inverse) ? nLSP - nPV : nPV - nLSP; // Error signal after direct/inverse Comparator
plant_obj->EP=-sig; // Calculate error value to display plant_obj->EP=-sig; // Calculate error value to display
if(!plant_obj->aut){ // Manage manual mode & reset all buffers if(!plant_obj->aut){ // Manage manual mode & reset all buffers
sig=0; sig=0;
Normalize(*plc_obj->Man_OPP, man_OP, plant_obj->LR_OP, plant_obj->HR_OP, 0.0, 100.0); Normalize(*plc_obj->Man_OPP, &man_OP, plant_obj->LR_OP, plant_obj->HR_OP, 0.0, 100.0); // v0.3
for (i=0; i<12; i++) plant_obj->S[i]=man_OP; for (i=0; i<12; i++) plant_obj->S[i]=man_OP;
for (i=0; i<100; i++) plant_obj->D[i]=man_OP; for (i=0; i<100; i++) plant_obj->D[i]=man_OP;
...@@ -729,7 +743,9 @@ void CompIMC_Fo_exec( plc_sThread *tp, ...@@ -729,7 +743,9 @@ void CompIMC_Fo_exec( plc_sThread *tp,
} }
else{ // Calculate IMC controller else{ // Calculate IMC controller
sig /= plant_obj->Gain; // Apply static gain if (Te<=0) return; // v0.3
if (plant_obj->Accel<1.0) return; // v0.3
if (plant_obj->Gain>0.0) sig /= plant_obj->Gain; else return; // Apply static gain // v0.3
plant_obj->S[0] = sig+plant_obj->S[11]; // Add previous model's feedback plant_obj->S[0] = sig+plant_obj->S[11]; // Add previous model's feedback
...@@ -757,7 +773,7 @@ void CompIMC_Fo_exec( plc_sThread *tp, ...@@ -757,7 +773,7 @@ void CompIMC_Fo_exec( plc_sThread *tp,
OP=plant_obj->S[6]; OP=plant_obj->S[6];
Clamp (OP, 0.0, 100.0); // Apply limits on model output Clamp (OP, 0.0, 100.0); // Apply limits on model output
Normalize(OP,yr,0.0,100.0,plant_obj->LR_OP, plant_obj->HR_OP); // Denormalize output Normalize(OP,&yr,0.0,100.0,plant_obj->LR_OP, plant_obj->HR_OP); // Denormalize output // v0.3
yr+=plant_obj->FF; // Add feedforward input value yr+=plant_obj->FF; // Add feedforward input value
Clamp (yr, plant_obj->LL_OP, plant_obj->HL_OP); // Apply limits to control signal Clamp (yr, plant_obj->LL_OP, plant_obj->HL_OP); // Apply limits to control signal
plc_obj->OP=plant_obj->OP = yr; // copy to GUI objects plc_obj->OP=plant_obj->OP = yr; // copy to GUI objects
...@@ -778,11 +794,13 @@ void CompIMC_Fo_exec( plc_sThread *tp, ...@@ -778,11 +794,13 @@ void CompIMC_Fo_exec( plc_sThread *tp,
Delay(10, plant_obj->DelayT); Delay(10, plant_obj->DelayT);
// ----
} }
} }
//---- modified v0.3-----------------------------------------------END----
/*_* /*_*
PLC Mode interface to a discrete time Internal Model Controler component PLC Mode interface to a discrete time Internal Model Controler component
......
...@@ -29,22 +29,22 @@ ...@@ -29,22 +29,22 @@
100 20 100 20
135 20 135 20
101 20 101 20
102 1 102 58
103 -21 103 78
104 2.73277 104 2.75
136 2.73277 136 2.75
105 100 105 100
106 0 106 2
107 -2 107 1
108 57 108 57
109 1 109 1
110 36.5428 110 36.5428
111 0.499952 111 0.499952
116 0 116 5
117 0 117 9
118 169 118 105
119 112 119 93
120 1 120 0
121 Claes context 121 Claes context
122 0 122 0
126 0.5 126 0.5
...@@ -4465,7 +4465,7 @@ pwr_exe: ...@@ -4465,7 +4465,7 @@ pwr_exe:
3000 0.63148 3000 0.63148
3001 0.23148 3001 0.23148
3002 0.696505 3002 0.696505
3003 0.146505 3003 0.246505
3008 0 3008 0
3010 4 3010 4
3011 2 3011 2
...@@ -7622,6 +7622,10 @@ pwr_exe: ...@@ -7622,6 +7622,10 @@ pwr_exe:
2305 $object.PV_MaxShow##Float32 2305 $object.PV_MaxShow##Float32
2306 $local.TrendHold##Boolean 2306 $local.TrendHold##Boolean
2307 $object.TrendTimeRange##Float32 2307 $object.TrendTimeRange##Float32
2308
2309
2310 9999
2311 9999
99 99
99 99
99 99
...@@ -8152,6 +8156,10 @@ pwr_exe: ...@@ -8152,6 +8156,10 @@ pwr_exe:
2305 2305
2306 $local.TrendHold##Boolean 2306 $local.TrendHold##Boolean
2307 $object.TrendTimeRange##Float32 2307 $object.TrendTimeRange##Float32
2308
2309
2310 9999
2311 9999
99 99
99 99
99 99
...@@ -9025,6 +9033,7 @@ pwr_exe: ...@@ -9025,6 +9033,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 2 1310 2
1311 0
99 99
99 99
99 99
...@@ -9175,6 +9184,7 @@ pwr_exe: ...@@ -9175,6 +9184,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 0 1310 0
1311 0
99 99
99 99
99 99
...@@ -9325,6 +9335,7 @@ pwr_exe: ...@@ -9325,6 +9335,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 2 1310 2
1311 0
99 99
99 99
99 99
...@@ -10248,6 +10259,7 @@ pwr_exe: ...@@ -10248,6 +10259,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 2 1310 2
1311 0
99 99
99 99
99 99
...@@ -10312,11 +10324,11 @@ pwr_exe: ...@@ -10312,11 +10324,11 @@ pwr_exe:
0 0
1006 12.6859 1006 12.6859
1007 7.35936 1007 7.35936
1008 13.1805 1008 13.1806
1009 12.0966 1009 12.0966
1013 12.6859 1013 12.6859
1014 7.35936 1014 7.35936
1015 13.1805 1015 13.1806
1016 12.0966 1016 12.0966
1003 1003
0 0
...@@ -10380,7 +10392,7 @@ pwr_exe: ...@@ -10380,7 +10392,7 @@ pwr_exe:
102 22 102 22
103 0 103 0
12 12
1200 $object.Gain##Float32 1200 $object.Accel##Float32
1201 %10.3f 1201 %10.3f
1202 1 1202 1
1203 1 1203 1
...@@ -10398,6 +10410,7 @@ pwr_exe: ...@@ -10398,6 +10410,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 2 1310 2
1311 0
99 99
99 99
99 99
...@@ -10721,6 +10734,7 @@ pwr_exe: ...@@ -10721,6 +10734,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 0 1310 0
1311 0
99 99
99 99
99 99
...@@ -11084,6 +11098,7 @@ pwr_exe: ...@@ -11084,6 +11098,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 2 1310 2
1311 0
99 99
99 99
99 99
...@@ -11481,6 +11496,7 @@ pwr_exe: ...@@ -11481,6 +11496,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 2 1310 2
1311 0
99 99
99 99
99 99
...@@ -11844,6 +11860,7 @@ pwr_exe: ...@@ -11844,6 +11860,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 0 1310 0
1311 0
99 99
99 99
99 99
...@@ -12241,6 +12258,7 @@ pwr_exe: ...@@ -12241,6 +12258,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 0 1310 0
1311 0
99 99
99 99
99 99
...@@ -12638,6 +12656,7 @@ pwr_exe: ...@@ -12638,6 +12656,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 2 1310 2
1311 0
99 99
99 99
99 99
...@@ -13029,6 +13048,7 @@ pwr_exe: ...@@ -13029,6 +13048,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 0 1310 0
1311 0
99 99
99 99
99 99
...@@ -13426,6 +13446,7 @@ pwr_exe: ...@@ -13426,6 +13446,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 2 1310 2
1311 0
99 99
99 99
99 99
...@@ -14461,6 +14482,7 @@ pwr_exe: ...@@ -14461,6 +14482,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 2 1310 2
1311 0
99 99
99 99
99 99
...@@ -14611,6 +14633,7 @@ pwr_exe: ...@@ -14611,6 +14633,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 2 1310 2
1311 0
99 99
99 99
99 99
...@@ -14761,6 +14784,7 @@ pwr_exe: ...@@ -14761,6 +14784,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 2 1310 2
1311 0
99 99
99 99
99 99
...@@ -14911,6 +14935,7 @@ pwr_exe: ...@@ -14911,6 +14935,7 @@ pwr_exe:
1308 1308
1309 0 1309 0
1310 2 1310 2
1311 0
99 99
99 99
99 99
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment