|
| 1 | +#include <qlibs.h> |
| 2 | + |
| 3 | +enum : fis::tag { service, food}; |
| 4 | +enum : fis::tag { tip}; |
| 5 | +// I/O Membership functions tags |
| 6 | +enum : fis::tag { poor, good, excellent, rancid, delicious }; |
| 7 | +enum : fis::tag { cheap, average, generous}; |
| 8 | +fis::instance tipper; |
| 9 | +// I/O Fuzzy Objects |
| 10 | +fis::input tipper_inputs[ 2 ]; |
| 11 | +fis::output tipper_outputs[ 1 ]; |
| 12 | +// I/O Membership Objects |
| 13 | +fis::mf MFin[5], MFout[3]; |
| 14 | +const fis::rules rules[] = { |
| 15 | + FIS_RULES_BEGIN |
| 16 | + IF service IS poor OR food IS rancid THEN tip IS cheap END |
| 17 | + IF service IS good THEN tip IS average END |
| 18 | + IF service IS excellent OR food IS delicious THEN tip IS generous END |
| 19 | + FIS_RULES_END |
| 20 | +}; |
| 21 | +real_t rulesStrength[ 3 ]; |
| 22 | + |
| 23 | +int foodPin = A0; // select the input pin for the potentiometer that drives the food score |
| 24 | +int servicePin = A1; // select the input pin for the potentiometer that drives the service score |
| 25 | + |
| 26 | +void setup() { |
| 27 | + Serial.begin( 9600 ); |
| 28 | + tipper.setup( fis::Mamdani, tipper_inputs, tipper_outputs, MFin, MFout, rules, rulesStrength ); |
| 29 | + tipper.setupInput( service, 0.0f, 1.0f ); |
| 30 | + tipper.setupInput( food, 0.0f, 10.0f ); |
| 31 | + tipper.setupOutput( tip, 0.0f, 30.0f ); |
| 32 | + tipper.setupInputMF( service, poor, fis::gaussmf, (const real_t[]){ 1.5f, 0.0f } ); |
| 33 | + tipper.setupInputMF( service, good, fis::gaussmf, (const real_t[]){ 1.5f, 5.0f } ); |
| 34 | + tipper.setupInputMF( service, excellent, fis::gaussmf, (const real_t[]){ 1.5f, 10.0f } ); |
| 35 | + tipper.setupInputMF( food, rancid, fis::trapmf, (const real_t[]){ 0.0f, 0.0f, 1.0f, 3.0f } ); |
| 36 | + tipper.setupInputMF( food, delicious, fis::trapmf, (const real_t[]){ 7.0f, 9.0, 10.0f, 10.0f } ); |
| 37 | + tipper.setupOutputMF( tip, cheap, fis::trimf, (const real_t[]){ 0.0f, 5.0f, 10.0f } ); |
| 38 | + tipper.setupOutputMF( tip, average, fis::trimf, (const real_t[]){10.0f, 15.0f, 20.0f } ); |
| 39 | + tipper.setupOutputMF( tip, generous, fis::trimf, (const real_t[]){ 20.0f, 25.0f, 30.0f } ); |
| 40 | +} |
| 41 | + |
| 42 | +void loop() { |
| 43 | + real_t serviceScoreValue = mapMinMax( analogRead(servicePin), 0, 1023, 0.0f, 1.0f ); |
| 44 | + real_t foodScoreValue = mapMinMax( analogRead(foodPin), 0, 1023, 0.0f, 10.0f ); |
| 45 | + |
| 46 | + tipper.setInput( service, serviceScoreValue ); |
| 47 | + tipper.setInput( food, foodScoreValue ); |
| 48 | + |
| 49 | + tipper.fuzzify(); |
| 50 | + if ( tipper.inference() ) { |
| 51 | + tipper.deFuzzify(); |
| 52 | + } |
| 53 | + Serial.print("food[in] = "); |
| 54 | + Serial.println(foodScoreValue); |
| 55 | + Serial.print("service[in] = "); |
| 56 | + Serial.println(serviceScoreValue); |
| 57 | + Serial.print("tip[out] = "); |
| 58 | + Serial.println( tipper[ tip ] ); |
| 59 | + delay( 250 ); |
| 60 | +} |
0 commit comments