def test_constructor(self) -> None: OutputVariableAssert(self, fl.OutputVariable("name", "description")) \ .exports_fll("\n".join(["OutputVariable: name", " description: description", " enabled: true", " range: -inf inf", " lock-range: false", " aggregation: none", " defuzzifier: none", " default: nan", " lock-previous: false" ])) OutputVariableAssert(self, fl.OutputVariable(name="name", description="description", minimum=-1.0, maximum=1.0, terms=[ fl.Triangle('A', -1.0, 1.0), fl.Triangle('B', -10.0, 10.0) ])) \ .exports_fll("\n".join(["OutputVariable: name", " description: description", " enabled: true", " range: -1.000 1.000", " lock-range: false", " aggregation: none", " defuzzifier: none", " default: nan", " lock-previous: false", " term: A Triangle -1.000 0.000 1.000", " term: B Triangle -10.000 0.000 10.000", ]))
def test_header(self) -> None: engine = fl.Engine( input_variables=[ fl.InputVariable("A"), fl.InputVariable("B") ], output_variables=[ fl.OutputVariable("X"), fl.OutputVariable("Y"), fl.OutputVariable("Z") ] ) self.assertEqual("A B X Y Z", fl.FldExporter().header(engine)) self.assertEqual("A\tB\tX\tY\tZ", fl.FldExporter(separator="\t").header(engine))
def test_single_line_indent(self) -> None: engine = fl.Engine("engine", "single line export to FLL", [fl.InputVariable("A", "variable A")], [fl.OutputVariable("Z", "variable Z")], [fl.RuleBlock("R", "rule block R")]) self.assertEqual( fl.FllExporter(separator="; ", indent='\t').engine(engine), "Engine: engine; " "\tdescription: single line export to FLL; " "InputVariable: A; " "\tdescription: variable A; " "\tenabled: true; " "\trange: -inf inf; " "\tlock-range: false; " "OutputVariable: Z; " "\tdescription: variable Z; " "\tenabled: true; " "\trange: -inf inf; " "\tlock-range: false; " "\taggregation: none; " "\tdefuzzifier: none; " "\tdefault: nan; " "\tlock-previous: false; " "RuleBlock: R; " "\tdescription: rule block R; " "\tenabled: true; " "\tconjunction: none; " "\tdisjunction: none; " "\timplication: none; " "\tactivation: none; ")
def test_outputs(self) -> None: flc = fl.Engine("name", "description", [], [fl.OutputVariable("A"), fl.OutputVariable("B")]) EngineAssert(self, flc) \ .has_name("name").has_description("description") \ .has_n_outputs(2).has_outputs(["A", "B"]) flc.output_variables = [] EngineAssert(self, flc).has_n_outputs(0).has_outputs([]) flc.output_variables = [fl.OutputVariable("X"), fl.OutputVariable("Y"), fl.OutputVariable("Z")] EngineAssert(self, flc).has_n_outputs(3).has_outputs(["X", "Y", "Z"]) names = ["X", "Y", "Z"] for i, iv in enumerate(flc.output_variables): self.assertEqual(iv.name, names[i])
def test_engine(self) -> None: engine = fl.Engine( name="engine", description="an engine", input_variables=[ fl.InputVariable(name="input_variable", description="an input variable", minimum=0, maximum=1, terms=[fl.Triangle("A")]) ], output_variables=[ fl.OutputVariable(name="output_variable", description="an output variable", minimum=0, maximum=1, terms=[fl.Triangle("A")]) ], rule_blocks=[ fl.RuleBlock(name="rb", description="a rule block", rules=[fl.Rule.create("if a then z")]) ]) self.assertEqual(fl.FllExporter().to_string(engine), fl.FllExporter().engine(engine)) self.assertEqual( fl.FllExporter().engine(engine), """\ Engine: engine description: an engine InputVariable: input_variable description: an input variable enabled: true range: 0 1 lock-range: false term: A Triangle nan nan nan OutputVariable: output_variable description: an output variable enabled: true range: 0 1 lock-range: false aggregation: none defuzzifier: none default: nan lock-previous: false term: A Triangle nan nan nan RuleBlock: rb description: a rule block enabled: true conjunction: none disjunction: none implication: none activation: none rule: if a then z """)
def test_output_variable(self) -> None: ov = fl.OutputVariable(name="output_variable", description="an output variable", minimum=0.0, maximum=1.0, terms=[fl.Triangle("A")]) self.assertEqual(fl.PythonExporter().to_string(ov), fl.PythonExporter().output_variable(ov)) self.assertEqual( fl.PythonExporter().output_variable(ov), """\ fl.OutputVariable( name="output_variable", description="an output variable", enabled=True, minimum=0.000, maximum=1.000, lock_range=False, aggregation=None, defuzzifier=None, lock_previous=False, terms=[fl.Triangle("A", nan, nan, nan)] )""") ov.terms.append(fl.Triangle("Z")) self.assertEqual( fl.PythonExporter().output_variable(ov), """\ fl.OutputVariable( name="output_variable", description="an output variable", enabled=True, minimum=0.000, maximum=1.000, lock_range=False, aggregation=None, defuzzifier=None, lock_previous=False, terms=[ fl.Triangle("A", nan, nan, nan), fl.Triangle("Z", nan, nan, nan) ] )""")
def test_describe(self) -> None: self.assertEqual( "OutputVariable[{" "'default_value': 'nan', 'defuzzifier': 'None', " "'fuzzy': 'term: x Aggregated []', " "'lock_previous': 'False', 'previous_value': 'nan'" "}]", fl.Op.describe( fl.OutputVariable("x", "an x", terms=[fl.Triangle("t")]))) self.assertEqual( "InputVariable[{}]", fl.Op.describe( fl.InputVariable("x", "an x", terms=[fl.Triangle("t")])))
def test_write_from_reader_empty_engine_not_empty(self) -> None: engine = fl.Engine( input_variables=[fl.InputVariable("Input")], output_variables=[fl.OutputVariable("Output")] ) writer = io.StringIO() fl.FldExporter().write_from_reader(engine, writer, io.StringIO()) self.assertEqual("Input Output\n", writer.getvalue()) writer = io.StringIO() fl.FldExporter(headers=False).write_from_reader(engine, writer, io.StringIO()) self.assertEqual("", writer.getvalue())
def test_output_variable(self) -> None: variable = fl.OutputVariable(name="output_variable", description="an output variable", minimum=0, maximum=1, terms=[fl.Triangle("A")]) self.assertEqual(fl.FllExporter().to_string(variable), fl.FllExporter().output_variable(variable)) self.assertEqual(fl.FllExporter().output_variable(variable), """\ OutputVariable: output_variable description: an output variable enabled: true range: 0 1 lock-range: false aggregation: none defuzzifier: none default: nan lock-previous: false term: A Triangle nan nan nan""")
def test_fuzzy_value(self) -> None: low, medium, high = [ fl.Triangle('Low', -1.0, -1.0, 0.0), fl.Triangle('Medium', -0.5, 0.0, 0.5), fl.Triangle('High', 0.0, 1.0, 1.0) ] OutputVariableAssert(self, fl.OutputVariable(name="name", description="description", minimum=-1.0, maximum=1.0, terms=[low, medium, high])) \ .activated_values({tuple(): "0.000/Low + 0.000/Medium + 0.000/High", tuple([fl.Activated(low, 0.5)]): "0.500/Low + 0.000/Medium + 0.000/High", tuple([fl.Activated(low, -1.0), fl.Activated(medium, -0.5), fl.Activated(high, -0.1)]): "-1.000/Low - 0.500/Medium - 0.100/High"})
def test_clear(self) -> None: low, medium, high = [ fl.Triangle('Low', -1.0, -1.0, 0.0), fl.Triangle('Medium', -0.5, 0.0, 0.5), fl.Triangle('High', 0.0, 1.0, 1.0) ] variable = fl.OutputVariable(name="name", description="description", minimum=-1.0, maximum=1.0, terms=[low, medium, high]) variable.value = 0.0 variable.previous_value = -1.0 variable.fuzzy.terms.extend( [fl.Activated(term, 0.5) for term in variable.terms]) OutputVariableAssert(self, variable) \ .exports_fll("\n".join(["OutputVariable: name", " description: description", " enabled: true", " range: -1.000 1.000", " lock-range: false", " aggregation: none", " defuzzifier: none", " default: nan", " lock-previous: false", " term: Low Triangle -1.000 -1.000 0.000", " term: Medium Triangle -0.500 0.000 0.500", " term: High Triangle 0.000 1.000 1.000", ])) self.assertEqual(variable.value, 0.0) self.assertEqual(variable.previous_value, -1.0) self.assertSequenceEqual( [term.parameters() for term in variable.fuzzy.terms], ["(0.500*Low)", "(0.500*Medium)", "(0.500*High)"]) variable.clear() self.assertEqual(math.isnan(variable.value), True) self.assertEqual(math.isnan(variable.previous_value), True) self.assertSequenceEqual(variable.fuzzy.terms, [])
fl.InputVariable(name="control2", description="", enabled=True, minimum=-0.785, maximum=0.785, lock_range=False) ] engine.output_variables = [ fl.OutputVariable(name="control", description="", enabled=True, minimum=-0.785, maximum=0.785, lock_range=False, aggregation=None, defuzzifier=fl.WeightedAverage("TakagiSugeno"), lock_previous=False, terms=[ fl.Linear("out1mf1", [0.000, 0.000, 1.000, 0.000], engine), fl.Linear("out1mf2", [0.000, 1.000, 0.000, 0.000], engine) ]) ] engine.rule_blocks = [ fl.RuleBlock( name="", description="", enabled=True, conjunction=None, disjunction=None,
lock_range=False, terms=[ fl.Trapezoid("Bad", 0.000, 1.000, 3.000, 7.000), fl.Trapezoid("Good", 3.000, 7.000, 10.000, 11.000) ] ) ] engine.output_variables = [ fl.OutputVariable( name="CheapTip", description="", enabled=True, minimum=5.000, maximum=25.000, lock_range=False, aggregation=None, defuzzifier=fl.WeightedAverage("TakagiSugeno"), lock_previous=False, terms=[ fl.Constant("Low", 10.000), fl.Constant("Medium", 15.000), fl.Constant("High", 20.000) ] ), fl.OutputVariable( name="AverageTip", description="", enabled=True, minimum=5.000, maximum=25.000, lock_range=False, aggregation=None,
fl.Trapezoid("LowHDL", -1.000, 0.000, 35.000, 45.000), fl.Trapezoid("ModerateHDL", 35.000, 45.000, 55.000, 65.000), fl.Trapezoid("HighHDL", 55.000, 65.000, 100.000, 101.000) ] ) ] engine.output_variables = [ fl.OutputVariable( name="HeartDiseaseRisk", description="", enabled=True, minimum=0.000, maximum=10.000, lock_range=False, aggregation=None, defuzzifier=fl.WeightedAverage("TakagiSugeno"), lock_previous=False, terms=[ fl.Constant("NoRisk", 0.000), fl.Constant("LowRisk", 2.500), fl.Constant("MediumRisk", 5.000), fl.Constant("HighRisk", 7.500), fl.Constant("ExtremeRisk", 10.000) ] ) ] engine.rule_blocks = [ fl.RuleBlock( name="", description="", enabled=True, conjunction=fl.Minimum(),
fl.OutputVariable( name="output", description="", enabled=True, minimum=0.000, maximum=3.100, lock_range=False, aggregation=None, defuzzifier=fl.WeightedAverage("TakagiSugeno"), lock_previous=False, terms=[ fl.Linear("out1mf1", [-0.048, 1.456, 2.222], engine), fl.Linear("out1mf2", [-0.218, -0.305, 2.042], engine), fl.Linear("out1mf3", [0.026, -0.141, 3.067], engine), fl.Linear("out1mf4", [0.052, -0.150, 3.419], engine), fl.Linear("out1mf5", [0.113, -0.189, 4.339], engine), fl.Linear("out1mf6", [2.543, 0.361, -2.738], engine), fl.Linear("out1mf7", [2.517, -6.809, 23.353], engine), fl.Linear("out1mf8", [-0.208, -0.394, 4.472], engine), fl.Linear("out1mf9", [-0.046, -0.300, 4.452], engine), fl.Linear("out1mf10", [-0.006, -0.217, 4.195], engine), fl.Linear("out1mf11", [0.089, -0.254, 4.992], engine), fl.Linear("out1mf12", [-0.033, 0.103, -2.012], engine), fl.Linear("out1mf13", [1.355, 1.228, -5.678], engine), fl.Linear("out1mf14", [-0.245, -0.124, 3.753], engine), fl.Linear("out1mf15", [-0.099, -0.111, 3.304], engine), fl.Linear("out1mf16", [-0.052, -0.163, 3.560], engine), fl.Linear("out1mf17", [0.099, -0.260, 4.662], engine), fl.Linear("out1mf18", [0.082, -1.849, 31.104], engine), fl.Linear("out1mf19", [2.180, -2.963, -0.061], engine), fl.Linear("out1mf20", [-0.982, 0.510, 5.657], engine), fl.Linear("out1mf21", [-0.087, -0.179, 3.744], engine), fl.Linear("out1mf22", [-0.124, -0.161, 4.094], engine), fl.Linear("out1mf23", [0.383, 0.007, -1.559], engine), fl.Linear("out1mf24", [-8.415, 2.083, 5.177], engine), fl.Linear("out1mf25", [1.721, -15.079, -0.687], engine), fl.Linear("out1mf26", [-1.043, -0.786, 20.510], engine), fl.Linear("out1mf27", [-0.249, -0.396, 6.995], engine), fl.Linear("out1mf28", [-0.076, -0.245, 4.416], engine), fl.Linear("out1mf29", [0.765, -1.488, 17.384], engine), fl.Linear("out1mf30", [-21.210, -43.022, -2.522], engine), fl.Linear("out1mf31", [-0.661, 3.523, 6.215], engine), fl.Linear("out1mf32", [-1.998, 1.582, 33.256], engine), fl.Linear("out1mf33", [-2.068, 5.673, 6.520], engine), fl.Linear("out1mf34", [-5.044, 7.093, 3.516], engine), fl.Linear("out1mf35", [-46.049, -35.021, -2.926], engine), fl.Linear("out1mf36", [-0.448, -0.770, -0.041], engine) ])
lock_range=True, terms=[ fl.Trapezoid("rancid", 0.000, 0.000, 2.500, 7.500), fl.Trapezoid("delicious", 2.500, 7.500, 10.000, 10.000) ] ) ] engine.output_variables = [ fl.OutputVariable( name="mTip", description="tip based on Mamdani inference", enabled=True, minimum=0.000, maximum=30.000, lock_range=False, aggregation=fl.Maximum(), defuzzifier=fl.Centroid(100), lock_previous=False, terms=[ fl.Triangle("cheap", 0.000, 5.000, 10.000), fl.Triangle("average", 10.000, 15.000, 20.000), fl.Triangle("generous", 20.000, 25.000, 30.000) ] ), fl.OutputVariable( name="tsTip", description="tip based on Takagi-Sugeno inference", enabled=True, minimum=0.000, maximum=30.000, lock_range=False, aggregation=None,
minimum=1.000, maximum=10.000, lock_range=False, terms=[ fl.Trapezoid("Bad", 0.000, 1.000, 3.000, 7.000), fl.Trapezoid("Good", 3.000, 7.000, 10.000, 11.000) ]) ] engine.output_variables = [ fl.OutputVariable(name="Tip", description="", enabled=True, minimum=0.000, maximum=30.000, lock_range=False, aggregation=fl.AlgebraicSum(), defuzzifier=fl.Centroid(200), lock_previous=False, terms=[ fl.Gaussian("AboutTenPercent", 10.000, 2.000), fl.Gaussian("AboutFifteenPercent", 15.000, 2.000), fl.Gaussian("AboutTwentyPercent", 20.000, 2.000) ]), fl.OutputVariable(name="CheckPlusTip", description="", enabled=True, minimum=1.000, maximum=1.300, lock_range=False, aggregation=fl.AlgebraicSum(), defuzzifier=fl.Centroid(200), lock_previous=False,
terms=[ fl.Bell("small", -10.000, 5.000, 3.000), fl.Bell("medium", 0.000, 5.000, 3.000), fl.Bell("large", 10.000, 5.000, 3.000) ] ) ] engine.output_variables = [ fl.OutputVariable( name="Ramps", description="", enabled=True, minimum=0.000, maximum=1.000, lock_range=False, aggregation=None, defuzzifier=fl.WeightedAverage("Automatic"), lock_previous=False, terms=[ fl.Ramp("b", 0.600, 0.400), fl.Ramp("a", 0.000, 0.250), fl.Ramp("c", 0.700, 1.000) ] ), fl.OutputVariable( name="Sigmoids", description="", enabled=True, minimum=0.020, maximum=1.000, lock_range=False, aggregation=None,
name="obstacle", description="", enabled=True, minimum=0.000, maximum=1.000, lock_range=False, terms=[fl.Ramp("left", 1.000, 0.000), fl.Ramp("right", 0.000, 1.000)]) ] engine.output_variables = [ fl.OutputVariable( name="mSteer", description="", enabled=True, minimum=0.000, maximum=1.000, lock_range=False, aggregation=fl.Maximum(), defuzzifier=fl.Centroid(100), lock_previous=False, terms=[fl.Ramp("left", 1.000, 0.000), fl.Ramp("right", 0.000, 1.000)]), fl.OutputVariable( name="tsSteer", description="", enabled=True, minimum=0.000, maximum=1.000, lock_range=False, aggregation=fl.Maximum(), defuzzifier=fl.WeightedAverage("Automatic"), lock_previous=False,
maximum=5.000, lock_range=False, terms=[ fl.Bell("small", -5.000, 5.000, 2.000), fl.Bell("big", 5.000, 5.000, 2.000) ]) ] engine.output_variables = [ fl.OutputVariable(name="force", description="", enabled=True, minimum=-5.000, maximum=5.000, lock_range=False, aggregation=fl.Maximum(), defuzzifier=fl.Centroid(200), lock_previous=False, terms=[ fl.Bell("negBig", -5.000, 1.670, 8.000), fl.Bell("negSmall", -1.670, 1.670, 8.000), fl.Bell("posSmall", 1.670, 1.670, 8.000), fl.Bell("posBig", 5.000, 1.670, 8.000) ]) ] engine.rule_blocks = [ fl.RuleBlock( name="", description="", enabled=True, conjunction=fl.Minimum(), disjunction=fl.Maximum(),
minimum=-5.000, maximum=5.000, lock_range=False, terms=[ fl.Gaussian("low", -5.000, 4.000), fl.Gaussian("high", 5.000, 4.000) ]) ] engine.output_variables = [ fl.OutputVariable(name="output", description="", enabled=True, minimum=0.000, maximum=1.000, lock_range=False, aggregation=None, defuzzifier=fl.WeightedAverage("TakagiSugeno"), lock_previous=False, terms=[ fl.Linear("line1", [-1.000, -1.000], engine), fl.Linear("line2", [1.000, -1.000], engine) ]) ] engine.rule_blocks = [ fl.RuleBlock(name="", description="", enabled=True, conjunction=None, disjunction=None, implication=None, activation=fl.General(),
lock_range=False, terms=[ fl.Trapezoid("Bad", 0.000, 1.000, 3.000, 7.000), fl.Trapezoid("Good", 3.000, 7.000, 10.000, 11.000) ]) ] engine.output_variables = [ fl.OutputVariable(name="Tip", description="", enabled=True, minimum=10.000, maximum=20.000, lock_range=False, aggregation=None, defuzzifier=fl.WeightedAverage("TakagiSugeno"), lock_previous=False, terms=[ fl.Linear("TenPercent", [0.000, 0.000, 10.000], engine), fl.Linear("FifteenPercent", [0.000, 0.000, 15.000], engine), fl.Linear("TwentyPercent", [0.000, 0.000, 20.000], engine) ]) ] engine.rule_blocks = [ fl.RuleBlock( name="", description="", enabled=True, conjunction=fl.Minimum(),
lock_range=False, terms=[ fl.Triangle("left", 0.000000000, 0.333000000, 0.666000000), fl.Triangle("right", 0.333000000, 0.666000000, 1.000000000) ]) ] engine.output_variables = [ fl.OutputVariable(name="steer", description="direction to steer the vehicle to", enabled=True, minimum=0.000000000, maximum=1.000000000, lock_range=False, aggregation=fl.Maximum(), defuzzifier=fl.Centroid(100), lock_previous=False, terms=[ fl.Gaussian("left", 0.333000000, 0.143534483), fl.Gaussian("right", 0.666500000, 0.143750000) ]) ] engine.rule_blocks = [ fl.RuleBlock(name="steer_away", description="steer away from obstacles", enabled=True, conjunction=None, disjunction=None, implication=fl.Minimum(), activation=fl.General(),
fl.OutputVariable(name="AllOutputTerms", description="", enabled=True, minimum=0.000, maximum=6.500, lock_range=False, aggregation=fl.Maximum(), defuzzifier=fl.Centroid(200), lock_previous=False, terms=[ fl.Sigmoid("A", 0.500, -20.000), fl.ZShape("B", 0.000, 1.000), fl.Ramp("C", 1.000, 0.000), fl.Triangle("D", 0.500, 1.000, 1.500), fl.Trapezoid("E", 1.000, 1.250, 1.750, 2.000), fl.Concave("F", 0.850, 0.250), fl.Rectangle("G", 1.750, 2.250), fl.Discrete("H", [ 2.000, 0.000, 2.250, 1.000, 2.500, 0.500, 2.750, 1.000, 3.000, 0.000 ]), fl.Gaussian("I", 3.000, 0.200), fl.Cosine("J", 3.250, 0.650), fl.GaussianProduct("K", 3.500, 0.100, 3.300, 0.300), fl.Spike("L", 3.640, 1.040), fl.Bell("M", 4.000, 0.250, 3.000), fl.PiShape("N", 4.000, 4.500, 4.500, 5.000), fl.Concave("O", 5.650, 6.250), fl.SigmoidDifference("P", 4.750, 10.000, 30.000, 5.250), fl.SigmoidProduct("Q", 5.250, 20.000, -10.000, 5.750), fl.Ramp("R", 5.500, 6.500), fl.SShape("S", 5.500, 6.500), fl.Sigmoid("T", 6.000, 20.000) ])
fl.Triangle('medium', .5, 2.5, 3.75), fl.Ramp('far', 2.5, 5) ] ), ] avoidance_engine.output_variables = [ fl.OutputVariable( name='Rotation', description='Rotational/angular velocity', enabled=True, minimum=-1.5, maximum=1.5, lock_range=True, aggregation=fl.Maximum(), defuzzifier=fl.Centroid(), terms=[ # Angular velocity (used be to degree of rotation mapped from -90 to 90 but /cmd_vel expects angular velocity) fl.Ramp('very_right', -.75, -1.5), fl.Triangle('right', -1.5, -.75, 0), fl.Triangle('straight_ahead', -.1, 0, .1), fl.Triangle('left', 0, .75, 1.5), fl.Ramp('very_left', .75, 1.5), ] ), fl.OutputVariable( name='Velocity', description='Translational velocity', enabled=True, minimum=-.5, maximum=.6, lock_range=True,
fl.OutputVariable( name="out", description="", enabled=True, minimum=-10.000, maximum=10.000, lock_range=False, aggregation=None, defuzzifier=fl.WeightedAverage("TakagiSugeno"), lock_previous=False, terms=[ fl.Linear("outmf1", [ 168.400, 31.000, -188.050, -49.250, -1.000, -2.700, 0.000, 0.000 ], engine), fl.Linear("outmf2", [ 233.950, 47.190, -254.520, -66.580, -1.000, -2.740, 0.000, 0.000 ], engine), fl.Linear("outmf3", [ 342.940, 74.730, -364.370, -95.230, -1.000, -2.780, 0.000, 0.000 ], engine), fl.Linear("outmf4", [ 560.710, 130.670, -582.960, -152.240, -1.000, -2.810, 0.000, 0.000 ], engine), fl.Linear("outmf5", [ 1213.880, 300.190, -1236.900, -322.800, -1.000, -2.840, 0.000, 0.000 ], engine), fl.Linear("outmf6", [0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000], engine), fl.Linear("outmf7", [ -1399.120, -382.950, 1374.630, 358.340, -1.000, -2.900, 0.000, 0.000 ], engine), fl.Linear("outmf8", [ -746.070, -213.420, 720.900, 187.840, -1.000, -2.930, 0.000, 0.000 ], engine), fl.Linear("outmf9", [ -528.520, -157.460, 502.680, 130.920, -1.000, -2.960, 0.000, 0.000 ], engine), fl.Linear("outmf10", [ -419.870, -129.890, 393.380, 102.410, -1.000, -2.980, 0.000, 0.000 ], engine), fl.Linear("outmf11", [ -354.770, -113.680, 327.650, 85.270, -1.000, -3.010, 0.000, 0.000 ], engine) ])
terms=[ fl.Trapezoid("falling", -0.140, -0.100, -0.060, 0.000), fl.Trapezoid("rising", -0.001, 0.060, 0.100, 0.140) ] ) ] engine.output_variables = [ fl.OutputVariable( name="valve", description="", enabled=True, minimum=-1.000, maximum=1.000, lock_range=False, aggregation=fl.Maximum(), defuzzifier=fl.Centroid(200), lock_previous=False, terms=[ fl.Triangle("close_fast", -1.000, -0.900, -0.800), fl.Triangle("close_slow", -0.600, -0.500, -0.400), fl.Triangle("no_change", -0.100, 0.000, 0.100), fl.Triangle("open_slow", 0.400, 0.500, 0.600), fl.Triangle("open_fast", 0.800, 0.900, 1.000) ] ) ] engine.rule_blocks = [ fl.RuleBlock( name="", description="", enabled=True, conjunction=fl.AlgebraicProduct(),
terms=[ fl.Triangle("left", 0.000000000, 0.333000000, 0.666000000), fl.Triangle("right", 0.333000000, 0.666000000, 1.000000000) ]) ] engine.output_variables = [ fl.OutputVariable(name="steer", description="direction to steer the vehicle to", enabled=True, minimum=0.000000000, maximum=1.000000000, lock_range=False, aggregation=fl.Maximum(), defuzzifier=fl.Centroid(100), lock_previous=False, terms=[ fl.SigmoidProduct("left", 0.166500000, 30.030030030, -30.030030030, 0.499500000), fl.SigmoidProduct("right", 0.499750000, 29.985007496, -29.985007496, 0.833250000) ]) ] engine.rule_blocks = [ fl.RuleBlock(name="steer_away", description="steer away from obstacles", enabled=True, conjunction=None, disjunction=None, implication=fl.Minimum(),
lock_range=False, terms=[ fl.Triangle("left", 0.000000000, 0.333000000, 0.666000000), fl.Triangle("right", 0.333000000, 0.666000000, 1.000000000) ]) ] engine.output_variables = [ fl.OutputVariable(name="steer", description="direction to steer the vehicle to", enabled=True, minimum=0.000000000, maximum=1.000000000, lock_range=False, aggregation=None, defuzzifier=fl.WeightedAverage("TakagiSugeno"), lock_previous=False, terms=[ fl.Constant("left", 0.333000000), fl.Constant("right", 0.666500000) ]) ] engine.rule_blocks = [ fl.RuleBlock(name="steer_away", description="steer away from obstacles", enabled=True, conjunction=None, disjunction=None, implication=None, activation=fl.General(),
maximum=1.000, lock_range=False, terms=[ fl.Triangle("DARK", 0.000, 0.250, 0.500), fl.Triangle("MEDIUM", 0.250, 0.500, 0.750), fl.Triangle("BRIGHT", 0.500, 0.750, 1.000) ]) ] engine.output_variables = [ fl.OutputVariable(name="Power", description="", enabled=True, minimum=0.000, maximum=1.000, lock_range=False, aggregation=fl.Maximum(), defuzzifier=fl.Centroid(200), lock_previous=False, terms=[ fl.Triangle("LOW", 0.000, 0.250, 0.500), fl.Triangle("MEDIUM", 0.250, 0.500, 0.750), fl.Triangle("HIGH", 0.500, 0.750, 1.000) ]) ] engine.rule_blocks = [ fl.RuleBlock(name="", description="", enabled=True, conjunction=None, disjunction=None, implication=fl.Minimum(), activation=fl.General(),