example 20 fuzzy control lecture l10.2. fuzzy control design of a fuzzy controller fuzzification of...
TRANSCRIPT
Example 20Fuzzy Control
Lecture L10.2
Fuzzy Control
• Design of a Fuzzy Controller
• Fuzzification of inputs– MEM and fill_weights()
• Processing the Rules– REV and fire_rules(…)
• Output Defuzzification– WAV and calc_output(…)
Fuzzy Control
Map to Fuzzy Sets
Fuzzy RulesIF A AND B THEN L
**
Defuzzification
Inputs
Output
get_inputs();
fire_rules();
find_output();
Ping-pong ballPlexiglas tube
Ultrasonic transducer
Muffin fan
Problem: Maintain ping-pong ball floating at a specified height
0 50 100 150 200 250
0 50 100 150 200 250
1
1
neg_far neg_close zero_pos pos_farpos_close
neg_fast neg_slow zero_speed pos_fastpos_slow
ball_position
ball_speed
Input membership functions for floating ping-pong ball
0 50 100 150 200 250
1neg_high neg_low zero_motor pos_highpos_low
motor_power
Output membership functions for floating ping-pong ball
ball_position neg_far neg_close zero_p pos_close pos_far
pos_fast zero_m
neg_low neg_high neg_high neg_high
pos_slow pos_low
zero_m neg_low neg_high neg_high
ball_speed zero_s pos_high
pos_low zero_m neg_low neg_high
neg_slow pos_high
pos_high pos_low zero_m neg_low
neg_fast pos_high
pos_high pos_high pos_low zero_m
Fuzzy K-map for floating ping-pong ball
Example 20: C function calls for a fuzzy controller
C Function Call Meaning void fill_weights(unsigned char* weight, unsigned char* membx, int num_mem_fncs, char x);
Given a crisp input x and membership functions, membx, fill the corresponding weight array.
void fire_rules(unsigned char* inout_array, unsigned char* rules, unsigned char* out, int numout);
Given inout_array containing weight arrays and a set of rules, fire all rules and fill the out array.
unsigned char calc_output(unsigned char* out, unsigned char* cent, int numout);
Calculate crisp output given the out array and the output membership singletons, cent.
Fuzzy Control
• Design of a Fuzzy Controller
• Fuzzification of inputs– MEM and fill_weights()
• Processing the Rules– REV and fire_rules(…)
• Output Defuzzification– WAV and calc_output(…)
u1 u2 u4
1
wt
u3
slope_1 slope_2
A membership function is defined in terms of u1, u2, u3, and u4
A xi
weight(j) X --> point_1 Y -->
point_2 Y + 1 --> slope_1 slope_2
X + 4 -->
Data structure used by the HCS12 MEM instruction
u1 u2 u4
1
wt
u3
slope_1 slope_2point_1 point_2
0 50 100 150 200 250
0 50 100 150 200 250
1
1
neg_far neg_close zero_pos pos_farpos_close
neg_fast neg_slow zero_speed pos_fastpos_slow
ball_position
ball_speed
void main(void) { // input membership functions const unsigned char ball_position[] = { 0, 0, 30, 60, // neg_far 40, 60, 80,110, // neg_close 90,120,135,165, // zero_pos 150,175,185,220, // pos_close 200,220,255,255 // pos_far };
static int maxsize = 20;
get_slopes(ball_position,memb_pos,maxsize);
unsigned char memb_pos[20];
0 50 100 150 200 250
0 50 100 150 200 250
1
1
neg_far neg_close zero_pos pos_farpos_close
neg_fast neg_slow zero_speed pos_fastpos_slow
ball_position
ball_speed
const unsigned char ball_speed[] = { 0, 0, 20, 60, // neg_fast 35, 60, 80,110, // neg_slow 80,130,130,180, // zero_speed 155,175,185,215, // pos_slow 195,220,255,255 // pos_fast };
unsigned char memb_speed[20];
get_slopes(ball_speed,memb_speed,maxsize);
A xi
weight(j) X --> point_1 Y -->
point_2 Y + 1 --> slope_1 slope_2
X + 4 -->
u1 u2 u4
1
wt
u3
slope_1 slope_2
void get_slopes(const unsigned char ball[],unsigned char memb[], int maxsize) { int j; unsigned char diff; for(j = 0; j < maxsize; j=j+4){ memb[j] = ball[j]; // point_1 memb[j+1] = ball[j+3]; // point_2 diff = (ball[j+1] - ball[j]); if(diff == 0) memb[j+2] = 0; else memb[j+2] = 255/diff; // slope_1 diff = (ball[j+3] - ball[j+2]); if(diff == 0) memb[j+3] = 0; else memb[j+3] = 255/diff; // slope_2 }}
Example 20: C function calls for a fuzzy controller
C Function Call Meaning void fill_weights(unsigned char* weight, unsigned char* membx, int num_mem_fncs, char x);
Given a crisp input x and membership functions, membx, fill the corresponding weight array.
void fire_rules(unsigned char* inout_array, unsigned char* rules, unsigned char* out, int numout);
Given inout_array containing weight arrays and a set of rules, fire all rules and fill the out array.
unsigned char calc_output(unsigned char* out, unsigned char* cent, int numout);
Calculate crisp output given the out array and the output membership singletons, cent.
// The fuzzy controller while(1) { // x1 = get_position(); // (user defined) x1 = 100; // test case -- remove fill_weights(ptr_weight_pos,ptr_memb_pos,num_memb_pos,x1); // x2 = get_speed(); // (user defined) x2 = 150; // test case -- remove fill_weights(ptr_weight_speed,ptr_memb_speed,num_memb_speed,x2);
A xi
weight(j) X --> point_1 Y -->
point_2 Y + 1 --> slope_1 slope_2
X + 4 -->
Fuzzy Control
• Design of a Fuzzy Controller
• Fuzzification of inputs– MEM and fill_weights()
• Processing the Rules– REV and fire_rules(…)
• Output Defuzzification– WAV and calc_output(…)
fire_rules() clear out array; for j = 1, num_rules { min_wt = 1; for i = 1, num_inputs {
wt = weighti[Aij] if wt < min_wt min_wt = wt; } out[Lj] = MAX(Out[Lj], min_wt); }
Pseudocode for fire_rules()
inout_array rules
Y neg_far 0 - - weight_pos[] X 0 x1 is neg_far neg_close 1 - - 5 x2 is neg_fast zero_pos 2 - - FE
pos_close 3 - - 15 y is pos_high pos_far 4 - - FE
neg_fast 5 - - weight_speed[] 0 x1 is neg_far neg_slow 6 - - 6 x2 is neg_slow
zero_speed 7 - - FE pos_slow 8 - - 15 y is pos_high pos_fast 9 - - FE
neg_high 10 0 Out[] neg_low 11 0 zero_m 12 0
pos_low 13 0 11 pos_high 14 0 A = $FF FF end of rules
The HCS12 REV Instruction
if x1 is neg_far and x2 is neg_fast then y is pos_high
ball_position neg_far neg_close zero_p pos_close pos_far 0 1 2 3 4
pos_fast 9
zero_motor 12
neg_low 11
neg_high 10
neg_high 10
neg_high 10
pos_slow 8
pos_low 13
zero_motor 12
neg_low 11
neg_high 10
neg_high 10
ball_speed zero_speed 7
pos_high 14
pos_low 13
zero_motor 12
neg_low 11
neg_high 10
neg_slow 6
pos_high 14
pos_high 14
pos_low 13
zero_motor 12
neg_low 11
neg_fast 5
pos_high 14
pos_high 14
pos_high 14
pos_low 13
zero_motor 12
Fuzzy K-map inout_array[] indicies
unsigned char inout_array[] = { 0, // weight_pos[] 0 neg_far 0, // 1 neg_close 0, // 2 zero_pos 0, // 3 pos_close 0, // 4 pos_far 0, // weight_speed[] 5 neg_fast 0, // 6 neg_slow 0, // 7 zero_speed 0, // 8 pos_slow 0, // 9 pos_fast 0, // out[] 10 neg_high 0, // 11 neg_low 0, // 12 zero_motor 0, // 13 pos_low 0, // 14 pos_high };
inout_array
Y neg_far 0 - - weight_pos[] X neg_close 1 - - zero_pos 2 - -
pos_close 3 - - pos_far 4 - -
neg_fast 5 - - weight_speed[] neg_slow 6 - -
zero_speed 7 - - pos_slow 8 - - pos_fast 9 - -
neg_high 10 0 Out[] neg_low 11 0 zero_m 12 0
pos_low 13 0 pos_high 14 0 A = $FF
unsigned char rules[] = { 0,5,0xFE,14,0xFE, // if x1 is neg_far && x2 is neg_fast then y is pos_high 0,6,0xFE,14,0xFE, 0,7,0xFE,14,0xFE, 0,8,0xFE,13,0xFE, 0,9,0xFE,12,0xFE, 1,5,0xFE,14,0xFE, // if x1 is neg_close && x2 is neg_fast then y is pos_high 1,6,0xFE,14,0xFE, 1,7,0xFE,13,0xFE, 1,8,0xFE,12,0xFE, 1,9,0xFE,11,0xFE, 2,5,0xFE,14,0xFE, // if x1 is zero_pos && x2 is neg_fast then y is pos_high 2,6,0xFE,13,0xFE, 2,7,0xFE,12,0xFE, 2,8,0xFE,11,0xFE, 2,9,0xFE,10,0xFE, 3,5,0xFE,13,0xFE, // if x1 is pos_close && x2 is neg_fast then y is pos_low 3,6,0xFE,12,0xFE, 3,7,0xFE,11,0xFE, 3,8,0xFE,10,0xFE, 3,9,0xFE,10,0xFE, 4,5,0xFE,12,0xFE, // if x1 is pos_far && x2 is neg_fast then y is zero_motor 4,6,0xFE,11,0xFE, 4,7,0xFE,10,0xFE, 4,8,0xFE,10,0xFE, 4,9,0xFE,10,0xFF };
unsigned char* ptr_memb_pos; unsigned char* ptr_memb_speed; unsigned char* ptr_weight_pos; unsigned char* ptr_weight_speed; unsigned char* ptr_inout_array; unsigned char* ptr_out; unsigned char* ptr_rules; unsigned char x1; // input x1 unsigned char x2; // input x2 unsigned char y; // output y ptr_memb_pos = memb_pos; ptr_memb_speed = memb_speed; ptr_weight_pos = inout_array; ptr_weight_speed = inout_array+num_memb_pos; ptr_inout_array = inout_array; ptr_out = inout_array+num_memb_pos+num_memb_speed; ptr_rules = rules;
inout_array rules
Y neg_far 0 - - weight_pos[] X 0 x1 is neg_far neg_close 1 - - 5 x2 is neg_fast zero_pos 2 - - FE
pos_close 3 - - 15 y is pos_high pos_far 4 - - FE
neg_fast 5 - - weight_speed[] 0 x1 is neg_far neg_slow 6 - - 6 x2 is neg_slow
zero_speed 7 - - FE pos_slow 8 - - 15 y is pos_high pos_fast 9 - - FE
neg_high 10 0 Out[] neg_low 11 0 zero_m 12 0
pos_low 13 0 11 pos_high 14 0 A = $FF FF end of rules
Example 20: C function calls for a fuzzy controller
C Function Call Meaning void fill_weights(unsigned char* weight, unsigned char* membx, int num_mem_fncs, char x);
Given a crisp input x and membership functions, membx, fill the corresponding weight array.
void fire_rules(unsigned char* inout_array, unsigned char* rules, unsigned char* out, int numout);
Given inout_array containing weight arrays and a set of rules, fire all rules and fill the out array.
unsigned char calc_output(unsigned char* out, unsigned char* cent, int numout);
Calculate crisp output given the out array and the output membership singletons, cent.
// The fuzzy controllerwhile(1) { // x1 = get_position(); // (user defined) x1 = 100; // test case -- remove fill_weights(ptr_weight_pos,ptr_memb_pos,num_memb_pos,x1); // x2 = get_speed(); // (user defined) x2 = 150; // test case -- remove fill_weights(ptr_weight_speed,ptr_memb_speed,num_memb_speed,x2); fire_rules(ptr_inout_array,ptr_rules,ptr_out,num_memb_motor);
Fuzzy Control
• Design of a Fuzzy Controller
• Fuzzification of inputs– MEM and fill_weights()
• Processing the Rules– REV and fire_rules(…)
• Output Defuzzification– WAV and calc_output(…)
find_output() numer = 0; denom = 0; for k = 1, Q if out[k] != 0 { numer = numer + out[k]*cent[k]; denom = denom + out[k]; } y0 = numer/denom;
Pseudocode for find_output(…)
HCS12 WAV instruction computes numer and denom
unsigned char* ptr_cent;unsigned char y; // output yptr_cent = cent;
// output membership functions unsigned char cent[] = {
5,65,128,175,22 };
0 50 100 150 200 250
1neg_high neg_low zero_motor pos_highpos_low
motor_power
Example 20: C function calls for a fuzzy controller
C Function Call Meaning void fill_weights(unsigned char* weight, unsigned char* membx, int num_mem_fncs, char x);
Given a crisp input x and membership functions, membx, fill the corresponding weight array.
void fire_rules(unsigned char* inout_array, unsigned char* rules, unsigned char* out, int numout);
Given inout_array containing weight arrays and a set of rules, fire all rules and fill the out array.
unsigned char calc_output(unsigned char* out, unsigned char* cent, int numout);
Calculate crisp output given the out array and the output membership singletons, cent.
// The fuzzy controller while(1) { // x1 = get_position(); // (user defined) x1 = 100; // test case -- remove fill_weights(ptr_weight_pos,ptr_memb_pos,num_memb_pos,x1); // x2 = get_speed(); // (user defined) x2 = 150; // test case -- remove fill_weights(ptr_weight_speed,ptr_memb_speed,num_memb_speed,x2); fire_rules(ptr_inout_array,ptr_rules,ptr_out,num_memb_motor); y = calc_output(ptr_out,ptr_cent,num_memb_motor); // adjust_motor(y): // (user defined) } }