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 */
}}