fuzzylite / help

A place to ask for help with the FuzzyLite Libraries
https://fuzzylite.com
0 stars 1 forks source link

Issues about Outputs #5

Closed OscarHuangWind closed 3 years ago

OscarHuangWind commented 3 years ago

Hi, Dr. Juan Rada-Vilela,

My name is Wenhui and I am a Ph.D student from Nanyang Technological University.

I am currently implementing C++ code of Fuzzylite-6.0 into my project and am suffering with a wrong output issue.

Several cases outputs nan at which it should not be default value(I know that nan can be displaced with any other value, but the issue is the output should not be a default value).

Unfortunately, I have no idea which line is incorrect after debugging. Could you please help me with this issue?

I also have attached my file in the email and sent to jcrada@fuzzylite.com

----------------------------------------------------- script ------------------------------------------------------------------------------- int main(int argc, char argv[]){ using namespace fl; //Code automatically generated with fuzzylite 6.0. using namespace fl; Engine engine = new Engine; engine->setName("ControlAuthority"); engine->setDescription("");

//Define Input Variable
InputVariable* arf = new InputVariable;
arf->setName("arf");
arf->setDescription("");
arf->setEnabled(true);
arf->setRange(1.000, 5.000);
arf->setLockValueInRange(false);
arf->addTerm(new Trapezoid("small", 1.000, 1.000, 1.500, 2.500));
arf->addTerm(new Triangle("medium", 1.500, 2.500, 3.500));
arf->addTerm(new Trapezoid("large", 2.500, 3.500, 5.000, 5.000));
engine->addInputVariable(arf);

InputVariable* steer_dev = new InputVariable;
steer_dev->setName("steer_dev");
steer_dev->setDescription("");
steer_dev->setEnabled(true);
steer_dev->setRange(0.000, 0.500);
steer_dev->setLockValueInRange(false);
steer_dev->addTerm(new Trapezoid("very small", 0.000, 0.000, 0.075, 0.150));
steer_dev->addTerm(new Triangle("small", 0.075, 0.150, 0.250));
steer_dev->addTerm(new Triangle("medium", 0.150, 0.250, 0.350));
steer_dev->addTerm(new Trapezoid("large", 0.250, 0.350, 0.500, 0.500));
engine->addInputVariable(steer_dev);

//Define Output Variable
OutputVariable* control_authority = new OutputVariable;
control_authority->setName("control_authority");
control_authority->setDescription("");
control_authority->setEnabled(true);
control_authority->setRange(0.000, 1.000);
control_authority->setLockValueInRange(false);
control_authority->setAggregation(new Maximum);
control_authority->setDefuzzifier(new Centroid(100));
// control_authority->setDefaultValue(fl::nan);
// control_authority->setDefaultValue(1.0);
control_authority->setLockPreviousValue(false);
control_authority->addTerm(new Triangle("low", 0.000, 0.000, 0.400));
control_authority->addTerm(new Triangle("medium", 0.200, 0.400, 0.600));
control_authority->addTerm(new Triangle("high", 0.400, 0.600, 0.800));
control_authority->addTerm(new Triangle("very high", 0.700, 1.000, 1.000));
engine->addOutputVariable(control_authority);

//Define RuleList
RuleBlock* mamdani = new RuleBlock;
mamdani->setName("mamdani");
mamdani->setDescription("");
mamdani->setEnabled(true);
mamdani->setConjunction(new Minimum);
mamdani->setDisjunction(new Maximum);
mamdani->setImplication(new Minimum);
mamdani->setActivation(new General);
// mamdani->setConjunction(new Minimum);
// mamdani->setDisjunction(fl::null);
// mamdani->setImplication(new AlgebraicProduct);
// mamdani->setActivation(new General);
mamdani->addRule(Rule::parse("if arf is small   and steer_dev is very small  then control_authority is very high", engine));
mamdani->addRule(Rule::parse("if arf is small   and steer_dev is small       then control_authority is high", engine));
mamdani->addRule(Rule::parse("if arf is small   and steer_dev is medium      then control_authority is medium", engine));
mamdani->addRule(Rule::parse("if arf is small   and steer_dev is large       then control_authority is medium", engine));
mamdani->addRule(Rule::parse("if arf is medium  and steer_dev is very small  then control_authority is high", engine));
mamdani->addRule(Rule::parse("if arf is medium  and steer_dev is small       then control_authority is medium", engine));
mamdani->addRule(Rule::parse("if arf is medium  and steer_dev is medium      then control_authority is medium", engine));
mamdani->addRule(Rule::parse("if arf is medium  and steer_dev is large       then control_authority is low", engine));
mamdani->addRule(Rule::parse("if arf is large   and steer_dev is very small  then control_authority is medium", engine));
mamdani->addRule(Rule::parse("if arf is large   and steer_dev is small       then control_authority is low", engine));
mamdani->addRule(Rule::parse("if arf is large   and steer_dev is medium      then control_authority is low", engine));
mamdani->addRule(Rule::parse("if arf is large   and steer_dev is large       then control_authority is low", engine));
engine->addRuleBlock(mamdani);

std::string status;
if (not engine->isReady(&status))
    throw Exception("[engine error] engine is not ready:\n" + status, FL_AT);

for (int i = 0; i <= 8; ++i)
{
    scalar arf_candidate = arf->getMinimum() + i * 0.5;
    arf->setValue(arf_candidate);
    for (int j = 0; j <= 10; ++j)
    {
        scalar steer_dev_candidate = steer_dev->getMinimum() + j * 0.05;
        steer_dev->setValue(steer_dev_candidate);
        engine->process();
        FL_LOG("arf.input = " << Op::str(arf_candidate) << "steer_dev.input = " << Op::str(steer_dev_candidate) <<
            " => " << "control_authority.output = " << Op::str(control_authority->getValue()));
    }
}

}

jcrada commented 3 years ago

Hi Oscar

Thanks for your post and for using the FuzzyLite libraries.

The default value of an output variable is returned when the rules did not affect the variable (for example, no rules were activated, or the activated rules did not modify the output variable).

Please take a look at the documentation: http://fuzzylite.com/documentation

You should investigate what rules are being activated. The best way to observe this and the operation of the controllers is using the QtFuzzyLite application.

I am closing this issue as I believe the problem is within the activation of your rules and maybe the understanding of the default value.

Please feel free to reopen this issue if you believe there is more to it.