/** ファジィ制御による自動車自動制御プログラム * ゴール手前100m地点で静止状態から始め、ゴールにぴったりと止める。 * (c)2009 マッキン ケネス */ public class FuzzyCar { double x=-100; //ゴール手前100mからスタート double speed=0;//初期速度 0m/s double accel=0;//初期加速 0m/s^2 int LOOP=200;//200秒繰り返す public static void main(String[] args){ FuzzyCar f=new FuzzyCar(); //f.test(); //ファジィメンバシップ関数表示 f.start(); //ファジィ制御 } //ファジィ制御開始 void start(){ System.out.println("x, speed, accel"); //出力用ラベル System.out.println(x+","+speed+","+accel); //初期状態表示 for(int i=0; i 加速(out1) //Rule2 IF 車が手前 AND 前進が速い -> そのまま(out2) //Rule3 IF 車が手前 AND 後退が速い -> 多く加速(out3) //Rule4 IF 車が近い AND 遅い -> そのまま(out4) //Rule5 IF 車が近い AND 前進が速い -> 少し減速(out5) //Rule6 IF 車が近い AND 後退が速い -> 少し加速(out6) //Rule7 IF 車が行き過ぎ AND 遅い -> 減速(out7) //Rule8 IF 車が行き過ぎ AND 前進が速い -> 多く減速(out8) //Rule9 IF 車が行き過ぎ AND 後退が速い -> そのまま(out9) double rule1 = AND(fuzzySetL(x),fuzzySetC(speed)); double rule2 = AND(fuzzySetL(x),fuzzySetR(speed)); double rule3 = AND(fuzzySetL(x),fuzzySetL(speed)); double rule4 = AND(fuzzySetC(x),fuzzySetC(speed)); double rule5 = AND(fuzzySetC(x),fuzzySetR(speed)); double rule6 = AND(fuzzySetC(x),fuzzySetL(speed)); double rule7 = AND(fuzzySetR(x),fuzzySetC(speed)); double rule8 = AND(fuzzySetR(x),fuzzySetR(speed)); double rule9 = AND(fuzzySetR(x),fuzzySetL(speed)); //ファジィルールのシングルトン後件部 double out1 = 2.0; //Rule1後件部 加速 double out2 = 0.0; //Rule2後件部 そのまま double out3 = 10.0; //Rule3後件部 多く加速 double out4 = 0.0; //Rule4後件部 そのまま double out5 = -1.0; //Rule5後件部 少し減速 double out6 = 1.0; //Rule6後件部 少し加速 double out7 = -2.0; //Rule7後件部 減速 double out8 = -10.0;//Rule8後件部 多く減速 double out9 = 0.0; //Rule9後件部 そのまま //簡略化推論法による重心計算(平均を取る) accel = ((rule1*out1) + (rule2*out2) + (rule3*out3) + (rule4*out4) + (rule5*out5) + (rule6*out6) + (rule7*out7) + (rule8*out8) + (rule9*out9)) / (rule1 + rule2 + rule3 + rule4 + rule5 + rule6 + rule7 + rule8 + rule9); speed=speed+accel; //現在の速度に加速を加算 x=x+speed; //現在の位置に速度を加算 System.out.println(x+","+speed+","+accel); //現在位置を表示 } } //ファジィメンバシップ関数(CENTER) double fuzzySetC(double value){ //近い, 遅い: 0を中心とした山 double grade=1.0; if(value<=-100 || value>=100){ grade=0.0; }else if(value>0){ grade=((value-100.0)/-100.0); }else if(value<=0){ grade=((value+100.0)/100.0); } return grade; } //ファジィメンバシップ関数(LEFT) double fuzzySetL(double value){ // 手前,速いバック:-100を頂点の坂 double grade=0.0; if(value<=-100){ grade=1.0; }else if(value<0){ grade=(value/-100.0); }else if(value>=0){ grade=0.0; } return grade; } //ファジィメンバシップ関数(RIGHT) double fuzzySetR(double value){ // 行き過ぎ,速い前進:+100を頂点の坂 double grade=0.0; if(value>=100){ grade=1.0; }else if(value>0){ grade=(value/100.0); }else if(value<=0){ grade=0.0; } return grade; } //ファジィ論理積(AND) double AND(double a, double b){ double and; if(a < b){ and = a; }else{ and = b; } return and; } //ファジィメンバシップ関数を表示するためのメソッド void test(){ System.out.println("fuzzySetL"); for(int i=-100;i<=100;i++){ System.out.print(fuzzySetL(i)+","); } System.out.println(); System.out.println("fuzzySetC"); for(int i=-100;i<=100;i++){ System.out.print(fuzzySetC(i)+","); } System.out.println(); System.out.println("fuzzySetR"); for(int i=-100;i<=100;i++){ System.out.print(fuzzySetR(i)+","); } System.out.println(); } }