source: src/main/java/agents/anac/y2015/agentBuyogV2/flanagan/control/AtoD.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: 17.3 KB
Line 
1/* Class AtoD
2*
3* This class contains constructor and methods that will
4* 1. Simulate an Analogue to Digital Converter (ADC)
5* Range may be set to 0 to Vref or -Vref to +Vref
6* The former is the default value.
7* The quantization error for this ADC is a truncation error
8* or
9* 2. Simply act as a marker to be used in OpenPath and
10* ClosedLoop to indicate the presence of an ADC.
11*
12* In the latter case the output is equal to the input plus any delay set.
13*
14* This class is a subclass of the superclass BlackBox.
15*
16* Author: Michael Thomas Flanagan.
17*
18* Created: 27 June 2003
19* Revised: 18 August 2003, 5 May 2005, 2 July 2006, 6 April 2008
20*
21* DOCUMENTATION:
22* See Michael T Flanagan's JAVA library on-line web page:
23* http://www.ee.ucl.ac.uk/~mflanaga/java/AtoD.html
24* http://www.ee.ucl.ac.uk/~mflanaga/java/
25*
26* Copyright (c) 2003 - 2008 Michael Thomas Flanagan
27*
28* PERMISSION TO COPY:
29* Permission to use, copy and modify this software and its documentation for
30* NON-COMMERCIAL purposes is granted, without fee, provided that an acknowledgement
31* to the author, Michael Thomas Flanagan at www.ee.ucl.ac.uk/~mflanaga, appears in all copies.
32*
33* Dr Michael Thomas Flanagan makes no representations about the suitability
34* or fitness of the software for any or for a particular purpose.
35* Michael Thomas Flanagan shall not be liable for any damages suffered
36* as a result of using, modifying or distributing this software or its derivatives.
37*
38***************************************************************************************/
39
40package agents.anac.y2015.agentBuyogV2.flanagan.control;
41
42import agents.anac.y2015.agentBuyogV2.flanagan.complex.*;
43import agents.anac.y2015.agentBuyogV2.flanagan.control.*;
44import agents.anac.y2015.agentBuyogV2.flanagan.math.*;
45
46public class AtoD extends BlackBox{
47
48 private int nBits = 0; // Number of bits, n
49 private long maximumDecimal = 0; // 2^n-1
50 private double vRef = 0.0D; // Reference voltage
51 private int[] vBinary = null; // array holding binary output
52 private boolean trueAtoD = true; // if true, a real ADC is simulated
53 // if false, the instance is simply an AtoD marker
54 private boolean range = true; // if true, range = 0 to vRef
55 // if false, range = -vRef/2 to +vRef/2
56 private double voltageOutput = 0.0D;// if range = true: output voltage corresponding to input voltage truncated by quantiztion error
57 // if range = false: output voltage equals input voltage
58 private String binaryOutput = ""; // if range = true: Sting holding the binary representation of the output voltage
59 private long decimalOutput = 0L; // if range = true: decimal representation of the binary representation of the output
60 private double sqnr = 0.0D; // signal to quantisation noise ratio
61 private double input = 0.0D; // input
62 private double inputC = 0.0D; // input after any clipping
63 private double shift = 0.0D; // voltage shift (vRef/2) if range is -vRef/2 to +vRef/2
64 private long decimalShift = 0L; // voltage shift as decimal represention of its binary representation
65 private boolean decCalcDone = false; // = true when the decimal output has been calculated
66 private boolean binCalcDone = false; // = true when the binary output has been calculated
67 private boolean inputSet = false; // = true when the input has been entered
68
69 private boolean firstCopy = true; // check used by copy method
70
71 // Constructor
72 // Simulates an ADC
73 public AtoD(int nBits, double vRef ){
74 super("AtoD");
75 if(nBits>63)throw new IllegalArgumentException("This program cannot accomadate an ADC simulation with a number of bits greater than 63");
76 this.nBits = nBits;
77 this.maximumDecimal = (long)Math.pow(2, this.nBits)-1L;
78 this.vRef = vRef;
79 this.vBinary = new int[nBits+1];
80 this.trueAtoD = true;
81 super.setSnumer(new ComplexPoly(1.0D));
82 super.setSdenom(new ComplexPoly(1.0D));
83 super.setZtransformMethod(1);
84 }
85
86 // Constructor
87 // Simply marks an AtoD event
88 public AtoD(){
89 super("AtoD");
90 super.fixedName = "AtoD";
91 super.sNumerDeg = 0;
92 super.sDenomDeg = 0;
93 super.setSnumer(new ComplexPoly(1.0D));
94 super.setSdenom(new ComplexPoly(1.0D));
95 super.ztransMethod=1;
96 super.setZtransformMethod(1);
97 }
98
99 // Reset range option
100 // opt = 0 for range 0 to Vref (default option)
101 // opt = 1 for range -Vref to + vref
102 public void setRangeOption(int opt){
103 if(opt<0 || opt>2)throw new IllegalArgumentException("argument must be either 0 or 1");
104 if(opt==0)this.range = true;
105 if(opt==1){
106 this.range = false;
107 this.shift = this.vRef/2.0D;
108 this.decimalShift = this.maximumDecimal/2L;
109 }
110 if(this.inputSet)this.checkInput();
111 this.decCalcDone = false;
112 }
113
114 // Return the range option
115 public String getRange(){
116 String ran = null;
117 if(this.trueAtoD){
118 if(this.range){
119 ran = "0 to "+this.vRef;
120 }
121 else{
122 ran = "-"+this.vRef/2 + " to "+this.vRef/2;
123 }
124 }
125 else{
126 System.out.println("Class AtoD; method getRange()");
127 System.out.println("No range option set - this instance of AtoD is an 'ADC marker' only");
128 System.out.println("getRangeOption has returned 'ADC marker only'");
129 ran = "ADC marker only";
130 }
131 return ran;
132 }
133
134 // Return the true AtoD option
135 public boolean getTrueAtoDoption(){
136 if(this.trueAtoD){
137 System.out.println("This instance of AtoD is a true simulation of an ADC");
138 System.out.println("getTrueAtoDoption has returned 'true'");
139 }
140 else{
141 System.out.println("This instance of AtoD is not a true simulation of an ADC");
142 System.out.println("It is simple an 'A to D marker'");
143 System.out.println("getTrueAtoDoption has returned 'false'");
144 }
145 return this.trueAtoD;
146 }
147
148 // Returns the reference voltage
149 public double getVref(){
150 if(!this.trueAtoD){
151 System.out.println("No reference voltage set - this instance of AtoD is an 'ADC marker' only");
152 System.out.println("getVref has returned 0.0 V");
153 }
154 return this.vRef;
155 }
156
157 // Set input
158 public void setInput(double input){
159 this.input = input;
160 this.checkInput();
161 this.inputSet=true;
162 }
163
164 // Check whether input in range
165 public void checkInput(){
166 this.inputC = input;
167 if(this.trueAtoD){
168 if(this.range){
169 if(this.input<0.0D){
170 System.out.println("lower limit of the ADC range exceeded");
171 System.out.println("input voltage set to zero");
172 this.inputC=0.0D;
173 }
174 if(this.input>this.vRef){
175 System.out.println("upper limit of the ADC range exceeded");
176 System.out.println("input voltage set to "+this.vRef);
177 this.inputC=this.vRef;
178 }
179 }
180 else{
181 if(this.input<-this.vRef){
182 System.out.println("lower limit of the ADC range exceeded");
183 System.out.println("input voltage set to "+(-this.vRef/2));
184 this.inputC=-this.vRef/2.0D;
185 }
186 if(this.input>this.vRef){
187 System.out.println("upper limit of the ADC range exceeded");
188 System.out.println("input voltage set to "+this.vRef/2);
189 this.inputC=this.vRef/2.0D;
190 }
191 }
192 }
193 this.inputC += this.shift;
194 this.decCalcDone = false;
195 this.binCalcDone = false;
196 }
197
198
199 // Return decimal representation of the maximum binary number
200 public long getMaximumDecimal(){
201 if(!this.trueAtoD){
202 System.out.println("This instance of AtoD is not a true simulation of an ADC");
203 System.out.println("It is simple an 'A to D marker'");
204 System.out.println("getTrueAtoDoption has returned 0");
205 }
206 return this.maximumDecimal;
207 }
208
209 // Return maximum quantization error
210 public double maximumQuantizationError(){
211 double error = 0.0D;
212 if(this.trueAtoD){
213 error = this.vRef/this.maximumDecimal;
214 }
215 else{
216 System.out.println("This instance of AtoD is not a true simulation of an ADC");
217 System.out.println("It is simple an 'A to D marker'");
218 System.out.println("getMaxQuantizationError returns zero");
219 }
220 return error;
221 }
222
223
224
225
226 // Calculate output
227 public void calcOutput(){
228
229 if(this.trueAtoD){
230 this.decimalOutput = (long)(Math.floor(((this.inputC)/this.vRef)*this.maximumDecimal))-this.decimalShift;
231 this.voltageOutput = (this.vRef*this.decimalOutput)/this.maximumDecimal;
232 this.sqnr = 20.0D*Fmath.log10(Math.abs((this.inputC-this.shift)/(this.inputC - this.shift - this.voltageOutput)));
233 }
234 else{
235 this.voltageOutput = this.input;
236 this.sqnr = 1.0D/0.0D;
237 }
238
239 super.sNumer.resetCoeff(0, new Complex(this.voltageOutput/this.input, 0.0D));
240
241 this.decCalcDone = true;
242 }
243
244 // Return SQNR (signal to quantization noise ratio)
245 public double getSQNR(){
246 if(!this.decCalcDone)this.calcOutput();
247 if(!this.trueAtoD){
248 System.out.println("This instance of AtoD is not a true simulation of an ADC");
249 System.out.println("It is simple an 'A to D marker'");
250 System.out.println("getSQNR returned INFINITY");
251 }
252 return this.sqnr;
253 }
254
255 // Return output voltage for the given input
256 // output rescaled to input voltage but with quantization error
257 public double voltageOutput(){
258 if(!this.decCalcDone)this.calcOutput();
259 return this.voltageOutput;
260 }
261
262 // Return decimal representation of the binary output voltage
263 public long decimalOutput(){
264 if(!this.decCalcDone)this.calcOutput();
265 if(!this.trueAtoD){
266 System.out.println("No formal A to D conversion performed - this instance of AtoD is an 'ADC marker' only");
267 System.out.println("decimalOutput has returned 0");
268 }
269
270 return this.decimalOutput;
271 }
272
273 // Convert decimal to binary number of nBits length
274 // Two's complement
275 public static int[] decimalToBinary(long decimal, int nBits){
276 // check sign and reverse if negative
277 long decSign = 1L;
278 if(decimal<0){
279 decSign = -1L;
280 decimal *= decSign;
281 }
282
283 // check nBits is long enough to accomodate decimal
284 // if not extend nBits by powers of two
285 long len = (long)Math.ceil(Math.log(decimal)/Math.log(2));
286 if(nBits<len){
287 boolean test=true;
288 int ii=2;
289 while(test){
290 if(Math.pow(2, ii)>len){
291 nBits=ii;
292 test=false;
293 }
294 }
295 }
296
297 // convert positive decimal to binary
298 int[] binary = new int[nBits];
299 for(int i=0; i<nBits; i++)binary[i] = 0;
300 boolean test = true;
301 int ii = 0;
302 while(test){
303 binary[ii] = (int) (decimal % 2);
304 decimal = decimal/2;
305 ii++;
306 if(decimal==0)test = false;
307 }
308
309 // if decimal was entered as negative negate binary
310 if(decSign==-1L)binary = AtoD.negateBinary(binary);
311
312 return binary;
313 }
314
315 // Negate a positive binary number
316 // Two's complement
317 public static int[] negateBinary(int[] binary){
318 int nBinary = binary.length;
319 int nBin = nBinary;
320
321 // add bit if MSB = 1 and assign it zero to give a two's complement positive number
322 if(binary[nBinary-1]==1)nBin += nBin;
323 int[] negate = new int[nBin];
324 int[] one = new int[nBin];
325 for(int i=0; i<nBin; i++){
326 one[i]=0;
327 negate[i]=1;
328 }
329 one[0]=1;
330 // invert all bits
331 for(int i=0; i<nBinary; i++){
332 if(binary[i] == 1)negate[i] = 0;
333 }
334 // add one
335 negate = AtoD.addBinary(negate, one);
336
337 return negate;
338 }
339
340 // Add two binary numbers
341 public static int[] addBinary(int[] aa, int[] bb){
342 int n = aa.length;
343 int m = bb.length;
344 int lenMax = n;
345 int lenMin = m;
346 if(m>n){
347 lenMax = m;
348 lenMin = n;
349 }
350 int[] addition = new int[lenMax];
351 int carry = 0;
352 int sum = 0;
353 for(int i=0; i<lenMin; i++){
354 sum = aa[i] + bb[i] + carry;
355 switch(sum){
356 case 0: addition[i] = 0;
357 carry = 0;
358 break;
359 case 1: addition[i] = 1;
360 carry = 0;
361 break;
362 case 2: addition[i] = 0;
363 carry = 1;
364 break;
365 case 3: addition[i] = 1;
366 carry = 1;
367 break;
368 }
369 }
370
371 return addition;
372 }
373
374 // Return binary representation of the output
375 public String binaryOutput(){
376 if(!this.decCalcDone)this.calcOutput();
377 if(this.trueAtoD){
378 int nBit = this.nBits+1;
379 // shited output to binary
380 long absDecOut = this.decimalOutput+this.decimalShift;
381 this.vBinary = AtoD.decimalToBinary(absDecOut, nBit);
382
383 if(this.shift>0.0D){
384 // shift, if any, to binary
385 int[] binaryShift = AtoD.decimalToBinary(this.decimalShift, nBit);
386
387 // negate binary shift
388 binaryShift = AtoD.negateBinary(binaryShift);
389
390 // add binary to negated shift
391 this.vBinary = AtoD.addBinary(this.vBinary, binaryShift);
392 }
393
394 // convert to String
395 this.binaryOutput="";
396 for(int i=nBit-1; i>=0; i--){
397 this.binaryOutput = this.binaryOutput + this.vBinary[i];
398 }
399
400 }
401 else{
402 System.out.println("No formal A to D conversion performed - this instance of AtoD is an 'ADC marker' only");
403 System.out.println("binaryOutput has returned 'null'");
404 }
405
406 this.binCalcDone = true;
407 return this.binaryOutput;
408 }
409
410 // Return binary representation of the output as an int array
411 // LSB is the zeroth element
412 public int[] binaryArray(){
413
414 if(this.trueAtoD){
415 if(!this.binCalcDone)this.binaryOutput();
416 }
417 else{
418 System.out.println("No formal A to D conversion performed - this instance of AtoD is an 'ADC marker' only");
419 System.out.println("binaryOutput has returned 'null'");
420 }
421
422 return this.vBinary;
423 }
424
425
426 // Return quantization error
427 public double quantizationError(){
428 if(!this.decCalcDone)this.calcOutput();
429 double error = 0.0D;
430 if(this.trueAtoD){
431 error = this.inputC - this.voltageOutput;
432 }
433 else{
434 System.out.println("This instance of AtoD is not a true simulation of an ADC");
435 System.out.println("It is simple an 'A to D marker'");
436 System.out.println("getQuantizationError returns zero");
437 }
438 return error;
439 }
440
441 // Return any clipping error
442 public double clippingError(){
443
444 return this.inputC - this.input;
445 }
446
447 // Deep copy
448 public AtoD copy(){
449 if(this==null){
450 return null;
451 }
452 else{
453 AtoD bb = new AtoD();
454 this.copyBBvariables(bb);
455
456 bb.nBits = this.nBits;
457 bb.maximumDecimal = this.maximumDecimal;
458 bb.vRef = this.vRef;
459 bb.vBinary = Conv.copy(this.vBinary);
460 bb.trueAtoD = this.trueAtoD;
461 bb.range = this.range;
462 bb.voltageOutput = this.voltageOutput;
463 bb.binaryOutput = this.binaryOutput;
464 bb.decimalOutput = this.decimalOutput;
465 bb.sqnr = this.sqnr;
466 bb.input = this.input;
467 bb.inputC = this.inputC;
468 bb.shift = this.shift;
469 bb.decimalShift = this.decimalShift;
470 bb.decCalcDone = this.decCalcDone;
471 bb.binCalcDone = this.binCalcDone;
472 bb.inputSet = this.inputSet;
473
474 return bb;
475 }
476 }
477
478 // Clone - overrides Java.Object method clone
479 public Object clone(){
480 return (Object)this.copy();
481 }
482}
Note: See TracBrowser for help on using the repository browser.