Hello: I am a senior undergraduate Computer Science/Mathematics major at Hiram College and I recently completed my senior seminar: _Precision in Control Systems Using Fuzzy Set Theory_ I thought that a few people out in cyberspace might be interested in how fuzzy sets are used in an embedded realtime application besides that inverted pendulum control system which plagues every fuzzy application demonstration :) I have finished this project, but I am still working on developing adaptive control systems using fuzzy set theory (and now genetic algorithms too!), so any feedback, questions, and etc. are welcome. Now I would like to present an overview of what this program does and the underlying concept behind this adaptive controller. An Adaptive Filter for use in Data Acquisition. The process we wish to monitor is changing light levels and we wist to quantify these light levels in the presence of noise. The control technique we will be using to filter the environment's readings is an Infinite Impulse Response Filter (IIR Filter). The characteristic equation for an IIR filter is the following: new_filter_output_value = ((((100 - alpha) * old_filter_output_value) + (alpha * system_input))/100); The IIR filter keeps a history of all previous input readings that have been filtered. Theoretically, no matter how long ago a specific filtered input occurred it has some influence on the IIR filter's output. Notice as alpha approaches zero, the current reading, System Input, has less effect on the output, than the previous readings, Old Filter Output. Obviously, if alpha = 0 then the filter uses only previous readings, Old Filter Output, and if alpha = 100 then the filter uses only the current reading, System Input. Therefore by varying alpha, we can specify the amount of filtering. There is however two issues of conflicting interest to be noted: (1) the need for stable readings, and (2) the response time of the control system. For example, if we lower alpha to provide stable readings, the control system's response time would become slow. Thus we must find a value for alpha that reduces the noise to an acceptable level without ruining the system's response time. Instead of fixing alpha at predetermined value(s), we want alpha to adapt over time, in order to maximize both filtering and stability. The adaptation routine I developed uses fuzzy set theory to quantify two uncertain events: the measurement's (1) noise and (2) slope. First let us work through the methods I used to measure the noise and slope. Measurement of noise: A brief history of filtered inputs reside in an array, of four elements, _history_. The method of quantifying the amount of noise present in the measurement over a brief period of time (~50 milliseconds) is to calculate the standard deviation, s, of the elements in history. The measurement's slope: Once again we will be using a brief history of the filtered system input to perform our calculations of the measurement's slope (or trend). In order to measure slope we must find a line that best fits the four past measurements. Therefore I used a discrete least-squares algorithm on the previous set of measurements. This method measures the past 'trend' by finding the slope to the best-fit line through four previous system inputs. Now that we have analyzed the methods of measuring noise and the slope, we may now define the fuzzy sets to quantify the following events with respect to the measurement: (1) The measurement's slope is rising. (2) The measurement's slope is zero. (3) The measurement's slope is falling. (4) The measurement contains noise-too noisy. (5) The measurement is not too noisy and not overfiltered. (6) The measurement is overfiltered-too quiet. The events (1) and (3) both refer to the same property of the measurement: that the measurement is changing. Therefore we shall use only two fuzzy sets to represent the state of the measurement: it is changing, _changing_, and it is not changing, _zero_. We shall also implement only two fuzzy sets that will bound the region where it is not too noisy and not too overfiltered. The fuzzy sets that were implemented are: _too_quiet_, _too_noisy_, _changing_ and _zero_. Step 2: Acquisition of Rules. The method that I used to determine the control rules is a simple straightforward method. I viewed the rule acquisition as the responses of a hypothetical human operator to system actions. The only possible human actions were to modify a dial that controlled alpha that ultimately increased filtering, decreased filtering or did nothing. An example might be: if the signal was too quiet, then I would turn the dial to decrease filtering. Another example: if the signal was not changing and the signal was getting noisier, then I would turn the dial to increase filtering. The control rules that I created are as follows: Rule 1: If the signal is too_quiet AND the slope_of_measurement is changing then apply less filtering by increasing alpha. Rule 2: If the signal is too_quiet AND the slope_of_measurement is zero then apply less filtering by increasing alpha a little. Rule 3: If the signal is too_noisy AND the slope_of_measurement is changing then apply more filtering by decreasing alpha. Rule 4: If the signal is too_noisy AND the slope_of_measurement is zero then apply more filtering by decreasing alpha a little. Sources: The idea for this came mainly from two articles: [1] Rosenthal, S. _The Future of High Precision is Fuzzy_. Personal Engineering & Instrumentation News, July, 1993. pp 64-65. [2] Rosenthal, S. _Building a Fuzzy-Logic Controller Doesn't Require an AI Degree-Just Common Sense_. Personal Engineering & Instrumentation News, Sept, 1993. pp 69-71. The fuzzy set theory material originated from Zadeh's original paper, and _many_ other sources. The _Miniboard 2.0_ is a single-board computer optimized for controlling small DC motors and receiving data from various electronic sensors. The Miniboard 2.0 design owes itself to Randy Sargent and Fred G. Martin both of MIT. More information on the Miniboard is available via anonymous FTP to cherupakha.media.mit.edu (Internet 18.85.0.47) in the directory pub/miniboard and/or monitor comp.robotics. My project is an example of a non-robotic application of the Miniboard 2.0, yet for an introduction to embedded systems the Miniboard design is excellent. The following is the source code that I wrote that runs on the Miniboard 2.0 (M68HC11) system: ---Cut-Here---Cut-Here---Cut-Here---Cut-Here---Cut-Here---Cut-Here---Cut-Here--- /*---------------------------------------------------------------------------- Program: Fuzzius Controlus, an Infinite Impulse Response Filter with Fuzzy Adaptation Routine. Project: Precision in Control Systems Using Fuzzy Set Theory Senior Seminar Winter Quarter 1994 Programmed by Brian O. Bush Due Date: January 7, 1994 File: IIR.c Data File: none Language: Micro C (Dunfield Development Systems/Miniboard 2.0 libraries) System Input: A CdS cell light sensor. System Output: an LED connected to Port C, pin 0, to indicate active filtering (i.e. sensor input != filter output). System: The Motorola MC68HC811E2FN microcontroller (Miniboard 2.0). Purpose: This program demostrates the use of fuzzy set theory in a dynamic filter. The filter is an Inifnite Impulse Response Filter (IIR Filter) with a fuzzy set theory based adaptation routine to modify the alpha variable used in the filtering to minimize the system response time while filtering noise. This program uses as input, a light sensor, but this application is not limited to this specific usage. The adaptation routine is based on two measurements: (1) the amount of noise in a brief history of measurements and (2) the measurement's slope (trend) over a brief history. The noise is measured by the standard deviation of the finite history, while the measurement's slope is calculated using a least-squares algorithm. ----------------------------------------------------------------------------*/ #include cyber.h /* define TRUE,FALSE,FOREVER */ #define no_membership 0 /* for use with fuzzy sets, defines abolute false */ #define Unity 100 /* for use with fuzzy sets, defines absolute truth */ #define port 5 /* analog port, pin 5 is used for system input */ #define h_length 4 /* length of the finite history for system input */ #define weight1 20 /* weights 1 and 2 are to increase alpha */ #define weight2 10 #define weight3 20 /* weights 3 and 4 are to decrease alpha */ #define weight4 10 #define sum_of_x 10 /* used in the slope of measurement */ #define m_denominator 20 /* slope denominator is n*sum(x^2) - sum(x)*sum(x) */ #define iterate 5 /* this sets the iteration limit for newton's method */ /*--------------------------------------------------------------------------*/ int MIN(x,y) /* AND operator - return the minimum of x and y */ int x,y; { if (x <= y) return(x); else return(y); } /*--------------------------------------------------------------------------*/ /* Downhill fuzzy set membership function defined by 2 values: low, high */ /* ..... . . . . | |......... low high */ int neg_m(low,high,input) /* negative slope */ int low,high,input; /* if input <= high and -m then degree of membership is: */ return(((high*Unity) - (input*Unity))/(high - low)); /*--------------------------------------------------------------------------*/ /* Uphill fuzzy set membership function defined by 2 values: low, high */ /* ........... . . . . ....| | low high */ int pos_m(low,high,input) /* postive slope */ int low,high,input; /* if input <= high and +m then degree of membership is: */ return(((input*Unity) - (low*Unity))/(high - low)); /*--------------------------------------------------------------------------*/ main() { /*------------------------program declarations------------------------------*/ /* unsigned char declares 8 bit integers */ unsigned char history[h_length], /* finite history of 4 system inputs */ old_filter_output_value, new_filter_output_value, /* IIR filter variables */ alpha, /* used in filter, adapted by fuzzy routine */ i, /* used at different times as a counter */ too_quiet, too_noisy, /* fuzzy sets for noise */ changing,zero, /* fuzzy sets for measurement's slope */ plus,minus, /* used in changing alpha */ rule_1,rule_2,rule_3,rule_4, /* storage space for truth values of the rules */ error; /* difference in actual and filtered measurement */ /* int declares a 16 bit signed integer for large number calculations */ int slope_of_measurement, /* used in adaptation of alpha */ noise_of_measurement, /* used in adaptation of alpha */ s_squared, /* sample variance of finite system history */ sum, /* used in calculating sum of history */ mean, /* used in finding mean of system inputs */ xn, /* previous value of xn_plus_1 */ numerator, denominator; /* used in weighted average defuzzification */ /*------------------------system initializations----------------------------*/ alpha = 100; /* filter will use only new reading on system startup */ sum=0; /* assembly routine to change direction of port c and initialize to zero */ asm { ldaa #$01 staa $1007 ldaa #$00 staa $1003 } /*------------------------------main program--------------------------------*/ FOREVER /* continuously execute */ { history[0]=analog(port); /* hack: use history[0] to temporarily hold system input */ /*--Infinite Impulse Response Filtering--*/ new_filter_output_value = ((((100 - alpha) * old_filter_output_value) + (alpha * history[0]))/100); error = (new_filter_output_value - history[0]); if (history[0] > new_filter_output_value) error = (history[0] - new_filter_output_value); if(error > 0) /* output a one */ asm { ldaa #$01 staa $1003 } else /* output a zero */ asm { ldaa #$00 staa $1003 } /* a "stack", actually FIFO implementation for finite system history */ for(i=0;i<3;i++) history[i] = history[i+1]; history[3] = new_filter_output_value; /* push filtered system input onto FIFO, history[0] lost */ old_filter_output_value = new_filter_output_value; /* The remaining code is a fuzzy set theory based adaptation of alpha */ /*------------------------noise of measurement------------------------------*/ /* Calculate noise by standard deviation of 4 previous system inputs. Newton's method of root finding is used to find s (standard deviation) */ sum=0; /* kill past usage of sum */ for(i=0;i numerator) numerator = (sum - numerator); else numerator = (numerator - sum); /* above is (sum(y*x)*n - sum(x)*sum(y)) with negative slope check */ slope_of_measurement = (numerator/m_denominator); /*----------------------------fuzzification---------------------------------*/ /* fuzzy set definitions and fuzzification of measurement's noise */ if(noise_of_measurement > 18) { too_noisy = Unity; too_quiet = no_membership; } else { if(noise_of_measurement > 6) too_noisy = pos_m(6,18,noise_of_measurement); else if(noise_of_measurement <= 6) { too_noisy = no_membership; too_quiet = neg_m(0,6,noise_of_measurement); } } /* fuzzy set definitions and fuzzification of measurement's slope */ if(slope_of_measurement <= 10) { changing = pos_m(0,10,slope_of_measurement); zero = (Unity - changing); /* property of symmetric fuzzy sets */ } else { changing = Unity; zero = no_membership; } /*---------------------------fuzzy inference---------------------------------- The value of alpha varies between zero and one hundred. As alpha approaches zero, the less effect a new reading has and the more the previous readings determine the output value. Obviously from the IIR filter update equation, if alpha equals zero, then the filter uses only the previous readings to determine the output value; also if alpha equals one hundred, then the filter uses only the new reading to completely determine the filter output. There are two conflicting issues here: we want stable readings (alpha low) and a fast system response (alpha high), so we must minimize alpha to satisfy the two needed system properties. The adaptation routine determines the value for alpha from the following four control rules, a sort of fuzzy algorithm: 1) If the signal is too_quiet _AND_ the slope_of_measurement is changing then apply less filtering by increasing alpha. 2) If the signal is too_quiet _AND_ the slope_of_measurement is zero then apply less filtering by increasing alpha a little. 3) If the signal is too_noisy _AND_ the slope_of_measurement is changing then apply more filtering by decreasing alpha. 4) If the signal is too_noisy _AND_ the slope_of_measurement is zero then apply more filtering by decreasing alpha a little. ----------------------------------------------------------------------------*/ /* The _AND_ operator finds the minimum membership and assigns that value to the truth value of the entire statement. */ rule_1 = MIN(too_quiet,changing); rule_2 = MIN(too_quiet,zero); rule_3 = MIN(too_noisy,changing); rule_4 = MIN(too_noisy,zero); /*---------------------------defuzzification--------------------------------*/ /* The method of defuzzification is the weight average method, which performs better than the maximum membership method, and yet computationally inexpensive */ denominator = (rule_1 + rule_2 + rule_3); if(denominator == 0) denominator = 1; rule_1 = (rule_1 * weight1); rule_2 = (rule_2 * weight2); rule_3 = (rule_3 * weight3); rule_4 = (rule_4 * weight4); plus = (rule_1 + rule_2); /* increase alpha */ minus = (rule_3 + rule_4); /* decrease alpha */ if(minus > plus) { /* negative adjustment */ numerator = (minus - plus); if((numerator/denominator) >= alpha) alpha = 1; /* lower bound for alpha */ else alpha = (alpha - (numerator/denominator)); } else { numerator = (plus - minus); /* positive adjustment */ alpha = (alpha + (numerator/denominator)); } if(alpha > 100) alpha = 100; /* upper bound is one hundred */ }}