source: src/main/java/agents/anac/y2015/agentBuyogV2/flanagan/control/SecondOrder.java

Last change on this file was 127, checked in by Wouter Pasman, 6 years ago

#41 ROLL BACK of rev.126 . So this version is equal to rev. 125

File size: 14.7 KB
Line 
1/* Class SecondOrder
2*
3* This class contains the constructor to create an instance of
4* a second order process,
5* a.d^2(output)/dt^2 + b.d(output)/dt + c.output = d.input
6* and the methods needed to use this process in simulation
7* of control loops.
8*
9* This class is a subclass of the superclass BlackBox.
10*
11* Author: Michael Thomas Flanagan.
12*
13* Created: March 2003
14* Updated: 23 April 2003, 3 May 2005, 3 April 2006, 2 July 2006, 6 April 2008, 2-7 November 2009, 23 May 2010
15* 24 May 2010, 18 January 2011
16*
17* DOCUMENTATION:
18* See Michael T Flanagan's JAVA library on-line web page:
19* http://www.ee.ucl.ac.uk/~mflanaga/java/SecondOrder.html
20* http://www.ee.ucl.ac.uk/~mflanaga/java/
21*
22* Copyright (c) 2003 - 2011 Michael Thomas Flanagan
23*
24* PERMISSION TO COPY:
25*
26* Permission to use, copy and modify this software and its documentation for NON-COMMERCIAL purposes is granted, without fee,
27* provided that an acknowledgement to the author, Dr Michael Thomas Flanagan at www.ee.ucl.ac.uk/~mflanaga, appears in all copies
28* and associated documentation or publications.
29*
30* Redistributions of the source code of this source code, or parts of the source codes, must retain the above copyright notice, this list of conditions
31* and the following disclaimer and requires written permission from the Michael Thomas Flanagan:
32*
33* Redistribution in binary form of all or parts of this class must reproduce the above copyright notice, this list of conditions and
34* the following disclaimer in the documentation and/or other materials provided with the distribution and requires written permission from the Michael Thomas Flanagan:
35*
36* Dr Michael Thomas Flanagan makes no representations about the suitability or fitness of the software for any or for a particular purpose.
37* Dr Michael Thomas Flanagan shall not be liable for any damages suffered as a result of using, modifying or distributing this software
38* or its derivatives.
39*
40***************************************************************************************/
41
42
43package agents.anac.y2015.agentBuyogV2.flanagan.control;
44import agents.anac.y2015.agentBuyogV2.flanagan.complex.Complex;
45import agents.anac.y2015.agentBuyogV2.flanagan.complex.ComplexPoly;
46
47public class SecondOrder extends BlackBox{
48
49 private double aConst = 1.0D; // a constant in differential equation above
50 private double bConst = 1.0D; // b constant in differential equation above
51 private double cConst = 1.0D; // c constant in differential equation above
52 private double dConst = 1.0D; // d constant in differential equation above
53 private double omegaN = 1.0D; // undamped natural frequency (resonant frequency)
54 private double zeta = 1.0D; // damping ratio
55 private double kConst = 1.0D; // the standard form gain constant
56 private double sigma = 1.0D; // attenuation (zeta*omegaN)
57
58 // Constructor
59 // Sets all constants to unity
60 public SecondOrder(){
61 super("SecondOrder");
62 super.setSnumer(new ComplexPoly(1.0D));
63 super.setSdenom(new ComplexPoly(1.0D, 1.0D, 1.0D));
64 super.sNumerDeg = 0;
65 super.setZtransformMethod(1);
66 super.addDeadTimeExtras();
67 }
68
69 // Constructor
70 // within constants set from argument list
71 public SecondOrder(double aa, double bb, double cc, double dd){
72 super("SecondOrder");
73 this.aConst = aa;
74 this.bConst = bb;
75 this.cConst = cc;
76 this.dConst = dd;
77 if(this.cConst>0.0D)this.standardForm();
78 super.setSnumer(new ComplexPoly(this.dConst));
79 super.setSdenom(new ComplexPoly(this.cConst, this.bConst, this.aConst));
80 super.setZtransformMethod(1);
81 super.addDeadTimeExtras();
82 }
83
84 // Set a, b, c and d
85 public void setCoeff(double aa, double bb, double cc, double dd){
86 this.aConst = aa;
87 this.bConst = bb;
88 this.cConst = cc;
89 this.dConst = dd;
90 if(this.cConst>0.0D)this.standardForm();
91 Complex[] num = Complex.oneDarray(1);
92 num[0].reset(this.dConst, 0.0);
93 super.sNumer.resetPoly(num);
94 Complex[] den = Complex.oneDarray(3);
95 den[0].reset(this.cConst, 0.0);
96 den[1].reset(this.bConst, 0.0);
97 den[2].reset(this.aConst, 0.0);
98 super.sDenom.resetPoly(den);
99 super.fixedName = "Second Order Process";
100 this.calcPolesZerosS();
101 super.addDeadTimeExtras();
102 }
103
104 // Private method for setting the contants of the natural frequency standard form
105 private void standardForm(){
106 this.omegaN = Math.sqrt(this.cConst/this.aConst);
107 this.zeta = this.bConst/(2.0D*this.aConst*this.omegaN);
108 this.kConst = this.dConst/this.cConst;
109 this.sigma = this.zeta*this.omegaN;
110 }
111
112 public void setA(double aa){
113 this.aConst = aa;
114 Complex co = new Complex(this.aConst, 0.0);
115 super.sDenom.resetCoeff(2, co);
116 if(this.cConst>0.0D)this.standardForm();
117 this.calcPolesZerosS();
118 super.addDeadTimeExtras();
119 }
120
121 public void setB(double bb){
122 this.bConst = bb;
123 Complex co = new Complex(this.bConst, 0.0);
124 super.sDenom.resetCoeff(1, co);
125 if(this.cConst>0.0D)this.standardForm();
126 this.calcPolesZerosS();
127 super.addDeadTimeExtras();
128 }
129
130 public void setC(double cc){
131 this.cConst = cc;
132 Complex co = new Complex(this.cConst, 0.0);
133 super.sDenom.resetCoeff(0, co);
134 if(this.cConst>0.0D)this.standardForm();
135 this.calcPolesZerosS();
136 super.addDeadTimeExtras();
137 }
138
139 public void setD(double dd){
140 this.dConst = dd;
141 Complex co = new Complex(this.dConst, 0.0);
142 super.sNumer.resetCoeff(0, co);
143 if(this.cConst>0.0D)this.standardForm();
144 this.calcPolesZerosS();
145 super.addDeadTimeExtras();
146 }
147
148 public void setStandardForm(double zet, double omega, double kk){
149 if(omega<=0)throw new IllegalArgumentException("zero or negative natural frequency");
150 if(zet<0)throw new IllegalArgumentException("negative damping ratio");
151 this.zeta = zet;
152 this.omegaN = omega;
153 this.kConst = kk;
154 this.sigma = this.omegaN*this.zeta;
155 this.reverseStandard();
156 this.calcPolesZerosS();
157 super.addDeadTimeExtras();
158 }
159
160 public void setZeta(double zet){
161 if(zet<0)throw new IllegalArgumentException("negative damping ratio");
162 this.zeta = zet;
163 this.sigma = this.omegaN*this.zeta;
164 this.reverseStandard();
165 this.calcPolesZerosS();
166 super.addDeadTimeExtras();
167 }
168
169 public void setOmegaN(double omega){
170 if(omega<=0)throw new IllegalArgumentException("zero or negative natural frequency");
171 this.omegaN = omega;
172 this.sigma = this.omegaN*this.zeta;
173 this.reverseStandard();
174 this.calcPolesZerosS();
175 super.addDeadTimeExtras();
176 }
177
178 public void setK(double kk){
179 this.kConst = kk;
180 this.reverseStandard();
181 this.calcPolesZerosS();
182 super.addDeadTimeExtras();
183 }
184
185 // Private method for obtaining a, b c and d from zeta, omegan and k
186 private void reverseStandard(){
187 this.aConst = this.omegaN*this.omegaN;
188 this.bConst = 2.0D*this.zeta*this.omegaN;
189 this.cConst = 1.0D;
190 this.dConst = this.kConst*this.aConst;
191 Complex[] num = Complex.oneDarray(1);
192 num[0].reset(this.dConst, 0.0);
193 super.sNumer.resetPoly(num);
194 Complex[] den = Complex.oneDarray(3);
195 den[0].reset(this.cConst, 0.0);
196 den[1].reset(this.bConst, 0.0);
197 den[2].reset(this.aConst, 0.0);
198 super.sDenom.resetPoly(den);
199 }
200
201 public double getA(){
202 return this.aConst;
203 }
204
205 public double getB(){
206 return this.bConst;
207 }
208
209 public double getC(){
210 return this.cConst;
211 }
212
213 public double getD(){
214 return this.dConst;
215 }
216
217 public double getOmegaN(){
218 return this.omegaN;
219 }
220
221 public double getZeta(){
222 return this.zeta;
223 }
224
225 public double getK(){
226 return this.kConst;
227 }
228
229 public double getAttenuation(){
230 return this.sigma;
231 }
232
233 // Get the s-domain output for a given s-value and a given input.
234 public Complex getOutputS(Complex sValue, Complex iinput){
235 super.sValue=sValue;
236 super.inputS=iinput;
237 return this.getOutputS();
238 }
239
240 // Get the s-domain output for the stored input and s-value.
241 public Complex getOutputS(){
242 Complex num = Complex.plusOne();
243 num = num.times(this.dConst);
244 Complex den = new Complex();
245 den = this.sValue.times(this.sValue.times(this.aConst));
246 den = den.plus(this.sValue.times(this.aConst));
247 den = den.plus(this.cConst);
248 Complex term = new Complex();
249 term = num.over(den);
250 super.outputS = term.times(super.inputS);
251 if(super.deadTime!=0.0D)super.outputS = super.outputS.times(Complex.exp(super.sValue.times(-super.deadTime)));
252 return super.outputS;
253 }
254
255 // Perform z transform using an already set delta T
256 public void zTransform(){
257 if(super.deltaT==0.0D)System.out.println("z-transform attempted in SecondOrder with a zero sampling period");
258 if(ztransMethod==0){
259 this.mapstozAdHoc();
260 }
261 else{
262 Complex[] ncoef = null;
263 Complex[] dcoef = null;
264 double bT = this.bConst*this.deltaT;
265 double t2 = this.deltaT*this.deltaT;
266 double cT2 = this.cConst*t2;
267 double dT2 = this.dConst*t2;
268 switch(this.integMethod){
269 // Trapezium Rule
270 case 0: ncoef = Complex.oneDarray(3);
271 ncoef[0].reset(dT2/4.0D, 0.0D);
272 ncoef[1].reset(dT2/2.0D, 0.0D);
273 ncoef[2].reset(dT2/4.0D, 0.0D);
274 super.zNumer=new ComplexPoly(2);
275 super.zNumer.resetPoly(ncoef);
276 super.zNumerDeg=2;
277 dcoef = Complex.oneDarray(3);
278 dcoef[0].reset(this.aConst - bT + cT2/4.0D, 0.0D);
279 dcoef[1].reset(-2.0D*this.aConst + bT + cT2/2.0D, 0.0D);
280 dcoef[2].reset(this.aConst + cT2/4.0D, 0.0D);
281 super.zDenom=new ComplexPoly(2);
282 super.zDenom.resetPoly(dcoef);
283 super.zDenomDeg=2;
284 super.zZeros = zNumer.roots();
285 super.zPoles = zDenom.roots();
286 break;
287 // Backward Rectangular Rule
288 case 1: ncoef = Complex.oneDarray(3);
289 ncoef[0].reset(0.0D, 0.0D);
290 ncoef[1].reset(0.0D, 0.0D);
291 ncoef[2].reset(dT2, 0.0D);
292 super.zNumer=new ComplexPoly(2);
293 super.zNumer.resetPoly(ncoef);
294 super.zNumerDeg=2;
295 dcoef = Complex.oneDarray(3);
296 dcoef[0].reset(this.aConst - bT, 0.0D);
297 dcoef[1].reset(-2.0D*this.aConst, 0.0D);
298 dcoef[2].reset(this.aConst + bT + cT2, 0.0D);
299 super.zDenom=new ComplexPoly(2);
300 super.zDenom.resetPoly(dcoef);
301 super.zDenomDeg=2;
302 super.zPoles = zDenom.roots();
303 super.zZeros = Complex.oneDarray(2);
304 super.zZeros[0].reset(0.0D, 0.0D);
305 super.zZeros[1].reset(0.0D, 0.0D);
306 break;
307 // Foreward Rectangular Rule
308 case 2: ncoef = Complex.oneDarray(3);
309 ncoef[0].reset(0.0D, 0.0D);
310 ncoef[1].reset(0.0D, 0.0D);
311 ncoef[2].reset(dT2, 0.0D);
312 super.zNumer=new ComplexPoly(2);
313 super.zNumer.resetPoly(ncoef);
314 super.zNumerDeg=2;
315 dcoef = Complex.oneDarray(3);
316 dcoef[0].reset(this.aConst - bT + cT2, 0.0D);
317 dcoef[1].reset(-2.0D*this.aConst + bT, 0.0D);
318 dcoef[2].reset(this.aConst, 0.0D);
319 super.zDenom=new ComplexPoly(2);
320 super.zDenom.resetPoly(dcoef);
321 super.zDenomDeg=2;
322 super.zPoles = zDenom.roots();
323 super.zZeros = Complex.oneDarray(2);
324 super.zZeros[0].reset(0.0D, 0.0D);
325 super.zZeros[1].reset(0.0D, 0.0D);
326 break;
327 default: System.out.println("Integration method option in SecondOrder must be 0,1 or 2");
328 System.out.println("It was set at "+integMethod);
329 System.out.println("z-transform not performed");
330 }
331 }
332 }
333
334 // Perform z transform setting delta T
335 public void zTransform(double deltaT){
336 super.setDeltaT(deltaT);
337 super.deadTimeWarning("zTransform");
338 this.zTransform();
339 }
340
341 // Calculate the current time domain output for a given input and given time
342 // resets deltaT
343 public double calcOutputT(double ttime, double inp){
344 return super.getCurrentOutputT(ttime, inp);
345 }
346
347 // Get the output for the stored sampled input, time and deltaT.
348 public double calcOutputT(){
349 return super.getCurrentOutputT();
350 }
351
352 // Get the s-domain zeros
353 public Complex[] getSzeros(){
354 System.out.println("This standard second order process (class SecondOrder) has no s-domain zeros");
355 return null;
356 }
357
358 // Deep copy
359 public SecondOrder copy(){
360 if(this==null){
361 return null;
362 }
363 else{
364 SecondOrder bb = new SecondOrder();
365 this.copyBBvariables(bb);
366
367 bb.aConst = this.aConst;
368 bb.bConst = this.bConst;
369 bb.cConst = this.cConst;
370 bb.dConst = this.dConst;
371 bb.omegaN = this.omegaN;
372 bb.zeta = this.zeta;
373 bb.kConst = this.kConst;
374 bb.sigma = this.sigma;
375 return bb;
376 }
377 }
378
379 // Clone - overrides Java.Object method clone
380 public Object clone(){
381 return (Object)this.copy();
382 }
383}
Note: See TracBrowser for help on using the repository browser.