Académique Documents
Professionnel Documents
Culture Documents
The fuzzy sets package contains five exports which are described below.
>
with( FuzzySets );
Warning, the protected name RealDomain has been redefined and unprotected
, the derivatives of
by the
NL
NM
NS
AZ
PS
PM
PL
negative large
negative medium
negative small
approximately zero
positive small
positive medium
positive large
>
restart;
>
with( FuzzySets[RealDomain] ):
Warning, these protected names have been redefined and unprotected: implies,
intersect, minus, plot, subset, union
angleNL,
angleNM, angleNS, angleAZ, anglePS, anglePM,
anglePL
) := (
L( -30, -20 ),
Partition( -30, -20, -10, 0, 10, 20, 30 ),
Gamma( 20, 30 )
):
> plot( [
angleNL, angleNM, angleNS, angleAZ, anglePS, anglePM, anglePL
], -40..40 );
Next, we define the following sets which describe the rate of change of the angle in degrees per
second:
>
derivNL,
derivNM, derivNS, derivAZ, derivPS, derivPM,
derivPL
) := (
L( -30, -20 ),
Partition( -30, -20, -10, 0, 10, 20, 30 ),
Gamma( 20, 30 )
):
> plot( [
derivNL, derivNM, derivNS, derivAZ, derivPS, derivPM, derivPL
], -45..45 );
Finally, we define the acceleration of the carriage carrying the pendulum in metres per second
squared:
>
accelerationNL,
accelerationNM, accelerationNS, accelerationAZ, accelerationPS, accelerationPM,
accelerationPL
) := Partition( -16, -12, -8, -4, 0, 4, 8, 12, 16 ):
> plot( [
accelerationNL, accelerationNM, accelerationNS, accelerationAZ,
accelerationPS, accelerationPM, accelerationPL
], -17..17 );
Now that we have partition the observable and control variables into fuzzy sets, we must
generate a list of rules which map the observables onto the control variables.
For example, the first rule says:
If the angle is negative and medium and the rate of change of angle is approximately zero,
m/s
Rules := Controller( {
[angleNM, derivAZ] = accelerationNM,
[angleNS, derivAZ] = accelerationNS,
[angleAZ, derivAZ] = accelerationAZ,
[anglePS, derivAZ] = accelerationPS,
[anglePM, derivAZ] = accelerationPM,
[angleNM, derivPS] = accelerationNS,
[angleNS, derivPS] = accelerationAZ,
[angleAZ, derivPS] = accelerationPS,
[anglePS, derivPS] = accelerationPM,
[angleNS, derivNS] = accelerationNM,
[angleAZ, derivNS] = accelerationNS,
[anglePS, derivNS] = accelerationAZ,
[anglePM, derivNS] = accelerationPS
}, inference = minimum ):
>
>
We cannot use a fuzzy set to control the acceleration of the carriage, so we must interpret this
fuzzy set as a single real value which we may use as the acceleration. We can convert this fuzzy
set into a real value using the routine Defuzzify :
>
Defuzzify( soln );
The following routine simulates an inverted pendulum and returns an animation of the pendulum
over time.
>
end do;
plots[display]( seq( plotlist[i], i = 1..(i - 1) ), insequence = true, scaling = constrained );
end proc:
The following function call generates a simulation where the pendulum begins at -10 degrees
and its initial angular speed is 40 degrees per second.
>
ProductRules := Controller( {
[angleNM, derivAZ] = accelerationNL,
[angleNS, derivAZ] = accelerationNS,
[angleAZ, derivAZ] = accelerationAZ,
[anglePS, derivAZ] = accelerationPS,
[anglePM, derivAZ] = accelerationPL,
[angleNM, derivPS] = accelerationNS,
[angleNS, derivPS] = accelerationAZ,
[angleAZ, derivPS] = accelerationPS,
[anglePS, derivPS] = accelerationPL,
[angleNS, derivNS] = accelerationNL,
[angleAZ, derivNS] = accelerationNS,
[anglePS, derivNS] = accelerationAZ,
[anglePM, derivNS] = accelerationPS
}, inference = product ):
>
>
>
This next example uses the Sugeno form of fuzzy rules. The first rule may be interpreted as if
the angle is negative and medium and the derivative is approximately zero, accelerate the cart at
-12 m/s
>
SugenoRules := Controller( {
[angleNM, derivAZ] = -12,
[angleNS, derivAZ] = -4,
[angleAZ, derivAZ] = 0,
[anglePS, derivAZ] = 4,
[anglePM, derivAZ] = 12,
[angleNM, derivPS] = -4,
[angleNS, derivPS] = 0,
[angleAZ, derivPS] = 4,
[anglePS, derivPS] = 12,
>
restart;
>
>
with( FzS ):
Warning, these protected names have been redefined and unprotected: implies,
intersect, minus, plot, subset, union
>
angleNL,
angleNM, angleNS, angleAZ, anglePS, anglePM,
anglePL
) := (
L( -30, -20 ),
Partition( -30, -20, -10, 0, 10, 20, 30 ),
Gamma( 20, 30 )
):
> (
derivNL,
derivNM, derivNS, derivAZ, derivPS, derivPM,
derivPL
) := (
L( -30, -20 ),
Partition( -30, -20, -10, 0, 10, 20, 30 ),
Gamma( 20, 30 )
):
> (
accelerationNL,
accelerationNM, accelerationNS, accelerationAZ, accelerationPS, accelerationPM,
accelerationPL
) := Partition( -16, -12, -8, -4, 0, 4, 8, 12, 16 ):
> Rules := Controller( {
[angleNM, derivAZ] = accelerationNM,
[angleNS, derivAZ] = accelerationNS,
[angleAZ, derivAZ] = accelerationAZ,
[anglePS, derivAZ] = accelerationPS,
[anglePM, derivAZ] = accelerationPM,
[angleNM, derivPS] = accelerationNS,
[angleNS, derivPS] = accelerationAZ,
[angleAZ, derivPS] = accelerationPS,
[anglePS, derivPS] = accelerationPM,
[angleNS, derivNS] = accelerationNM,
[angleAZ, derivNS] = accelerationNS,
[anglePS, derivNS] = accelerationAZ,
[anglePM, derivNS] = accelerationPS
}, inference = minimum ):
> soln := Rules( -13, -2.1 ):
>
>
Defuzzify( soln );
The defuzzified value is very close to the value found using fuzzy sets on the real domain:
.
>
evalf(%);
>
x := sin(a);
y := cos(a);
plots[display](
plots[pointplot]( [[posn, 0], [posn + x, y]], symbol = circle, symbolsize = 20 ),
plots[pointplot]( [[-1, 0], [1, 0]] ),
plottools[line]( [posn, 0], [posn + x, y] ),
plots[textplot]( [0.5, 1.2, sprintf( "% 3d deg, % 3d deg/s", round( evalf( a*180/Pi ) ),
round( evalf( angular_velocity*180/Pi ) ) )] ),
scaling = constrained
);
end proc;
plotlist := Vector( 1..iterations + 1 );
plotlist[1] := plotvehicle( position, angle, angular_velocity );
for i from 2 to iterations + 1 do
try
acceleration := 1.5*Defuzzify( controller( angle*180/3.14, angular_velocity*180/3.14 )
);
catch:
acceleration := 0;
end try;
angular_acceleration := 9.8 * sin( angle ) - acceleration * cos( angle );
angular_velocity := angular_velocity + angular_acceleration * dt - 0.02 *
angular_velocity;
angle := angle + angular_velocity * dt;
if i mod 100 = 0 then print( i ); end if;
velocity := velocity + acceleration * dt;
position := position + velocity * dt;
plotlist[i] := plotvehicle( position, angle, angular_velocity );
end do;
plots[display]( seq( plotlist[i], i = 1..(i - 1) ), insequence = true, scaling = constrained );
end proc:
This command takes 25% the time of the RealDomain version to run.
>
On my computer, this takes approximately one minute to calculate and the animation runs for
approximately one minute. This should not be taken to imply that this package should be used
for real-time systems.
>