Skip to main content

robotic_behaviours__abstacle_avoidance/
robotic_behaviours__abstacle_avoidance.rs

1use fuzzy_logic_engine_rs::{
2    fis::{FisType, FuzzyInferenceSystem},
3    membership::MembershipKind as M,
4    rule::{Connective, Rule},
5    term::Term,
6    variable::{LinguisticVariable, Range},
7};
8
9fn main() -> Result<(), Box<dyn std::error::Error>> {
10    let mut system = FuzzyInferenceSystem::new("Robot behaviour");
11
12    // Output: speed
13    let mut speed = LinguisticVariable::new(
14        "speed",
15        Range {
16            min: 0.0,
17            max: 100.0,
18        },
19    );
20    speed.add_term(Term::new(
21        "stop",
22        M::Triangle {
23            a: 0.0,
24            b: 0.0,
25            c: 20.0,
26        },
27    ));
28    speed.add_term(Term::new(
29        "slow",
30        M::Triangle {
31            a: 10.0,
32            b: 30.0,
33            c: 50.0,
34        },
35    ));
36    speed.add_term(Term::new(
37        "fast",
38        M::Triangle {
39            a: 50.0,
40            b: 75.0,
41            c: 100.0,
42        },
43    ));
44    system.add_output(speed);
45
46    // Input: distance to obstacle
47    let mut distance = LinguisticVariable::new(
48        "distance",
49        Range {
50            min: 0.0,
51            max: 200.0,
52        },
53    );
54    distance.add_term(Term::new(
55        "near",
56        M::Triangle {
57            a: 0.0,
58            b: 0.0,
59            c: 50.0,
60        },
61    ));
62    distance.add_term(Term::new(
63        "medium",
64        M::Triangle {
65            a: 40.0,
66            b: 100.0,
67            c: 160.0,
68        },
69    ));
70    distance.add_term(Term::new(
71        "far",
72        M::Triangle {
73            a: 120.0,
74            b: 200.0,
75            c: 200.0,
76        },
77    ));
78    system.add_input(distance);
79
80    // Input: battery level
81    let mut battery = LinguisticVariable::new(
82        "battery",
83        Range {
84            min: 0.0,
85            max: 100.0,
86        },
87    );
88    battery.add_term(Term::new(
89        "low",
90        M::Triangle {
91            a: 0.0,
92            b: 0.0,
93            c: 40.0,
94        },
95    ));
96    battery.add_term(Term::new(
97        "medium",
98        M::Triangle {
99            a: 30.0,
100            b: 50.0,
101            c: 70.0,
102        },
103    ));
104    battery.add_term(Term::new(
105        "high",
106        M::Triangle {
107            a: 60.0,
108            b: 100.0,
109            c: 100.0,
110        },
111    ));
112    system.add_input(battery);
113
114    // Rules
115    system.set_rules(vec![
116        Rule::new(
117            vec![Some("near".into()), None],
118            vec!["stop".into()],
119            Connective::And,
120        ),
121        Rule::new(
122            vec![Some("medium".into()), Some("low".into())],
123            vec!["slow".into()],
124            Connective::And,
125        ),
126        Rule::new(
127            vec![Some("far".into()), Some("high".into())],
128            vec!["fast".into()],
129            Connective::And,
130        ),
131    ]);
132
133    // Evaluate
134    let distance_inp = 150.0;
135    let battery_inp = 80.0;
136    let inputs = vec![distance_inp, battery_inp];
137
138    let result = system.compute(FisType::Mamdani, &inputs);
139    let out = result.unwrap();
140
141    println!("Robot speed decision: {:?}", out[0]);
142
143    println!(
144        "Inputs: distance_inp={:?}, battery_inp={:?} => Robot behaviour ≈ {:?}",
145        distance_inp, battery_inp, out
146    );
147    assert!(out[0] > 74.0);
148    assert!(out[0] < 75.0);
149
150    match system.compute_verbose(FisType::Mamdani, &inputs) {
151        Ok(outputs) => {
152            for out in outputs {
153                println!("{}", out.describe());
154            }
155        }
156        Err(e) => eprintln!("compute_verbose() - Error: {}", e),
157    }
158
159    Ok(())
160}