1 #include "a/pid_fuzzy.h"
4 a_float (*a_pid_fuzzy_opr(unsigned int opr
))(a_float
, a_float
)
13 case A_PID_FUZZY_CAP_ALGEBRA
:
14 return a_fuzzy_cap_algebra
;
15 case A_PID_FUZZY_CAP_BOUNDED
:
16 return a_fuzzy_cap_bounded
;
19 case A_PID_FUZZY_CUP_ALGEBRA
:
20 return a_fuzzy_cup_algebra
;
21 case A_PID_FUZZY_CUP_BOUNDED
:
22 return a_fuzzy_cup_bounded
;
26 void a_pid_fuzzy_set_opr(a_pid_fuzzy
*ctx
, unsigned int opr
) { ctx
->opr
= a_pid_fuzzy_opr(opr
); }
28 A_HIDDEN
unsigned int a_pid_fuzzy_mf(a_float x
, unsigned int n
, a_float
const *a
, unsigned int *idx
, a_float
*val
);
29 unsigned int a_pid_fuzzy_mf(a_float x
, unsigned int n
, a_float
const *a
, unsigned int *idx
, a_float
*val
)
31 unsigned int counter
= 0;
32 for (unsigned int i
= 0; i
!= n
; ++i
)
38 case A_MF_NUL
: goto out
;
40 y
= a_mf_gauss(x
, a
[0], a
[1]);
44 y
= a_mf_gauss2(x
, a
[0], a
[1], a
[2], a
[3]);
48 y
= a_mf_gbell(x
, a
[0], a
[1], a
[2]);
52 y
= a_mf_sig(x
, a
[0], a
[1]);
56 y
= a_mf_dsig(x
, a
[0], a
[1], a
[2], a
[3]);
60 y
= a_mf_psig(x
, a
[0], a
[1], a
[2], a
[3]);
64 y
= a_mf_trap(x
, a
[0], a
[1], a
[2], a
[3]);
68 y
= a_mf_tri(x
, a
[0], a
[1], a
[2]);
72 y
= a_mf_lins(x
, a
[0], a
[1]);
76 y
= a_mf_linz(x
, a
[0], a
[1]);
80 y
= a_mf_s(x
, a
[0], a
[1]);
84 y
= a_mf_z(x
, a
[0], a
[1]);
88 y
= a_mf_pi(x
, a
[0], a
[1], a
[2], a
[3]);
92 if (y
> A_FLOAT_EPSILON
)
103 void a_pid_fuzzy_set_rule(a_pid_fuzzy
*ctx
, unsigned int nrule
, a_float
const *me
, a_float
const *mec
,
104 a_float
const *mkp
, a_float
const *mki
, a_float
const *mkd
)
114 void *a_pid_fuzzy_bfuzz(a_pid_fuzzy
const *ctx
) { return ctx
->idx
; }
115 void a_pid_fuzzy_set_bfuzz(a_pid_fuzzy
*ctx
, void *ptr
, a_size num
)
117 ctx
->nfuzz
= (unsigned int)num
;
118 ctx
->idx
= (unsigned int *)ptr
;
119 if (ptr
) { ptr
= (a_byte
*)ptr
+ 2 * sizeof(unsigned int) * num
; }
120 ctx
->val
= (a_float
*)ptr
;
123 void a_pid_fuzzy_set_kpid(a_pid_fuzzy
*ctx
, a_float kp
, a_float ki
, a_float kd
)
125 a_pid_set_kpid(&ctx
->pid
, kp
, ki
, kd
);
131 A_HIDDEN
void a_pid_fuzzy_out_(a_pid_fuzzy
*ctx
, a_float ec
, a_float e
);
132 void a_pid_fuzzy_out_(a_pid_fuzzy
*ctx
, a_float ec
, a_float e
)
137 /* calculate membership */
138 unsigned int const ne
= a_pid_fuzzy_mf(e
, ctx
->nrule
, ctx
->me
, ctx
->idx
, ctx
->val
);
139 if (!ne
) { goto pid
; }
140 unsigned int *const idx
= ctx
->idx
+ ne
;
141 a_float
*const val
= ctx
->val
+ ne
;
142 unsigned int const nec
= a_pid_fuzzy_mf(ec
, ctx
->nrule
, ctx
->mec
, idx
, val
);
143 if (!nec
) { goto pid
; }
144 a_float
*const mat
= val
+ nec
;
145 /* joint membership */
149 for (unsigned int i
= 0; i
!= ne
; ++i
)
151 for (unsigned int j
= 0; j
!= nec
; ++j
)
153 *it
= ctx
->opr(ctx
->val
[i
], val
[j
]); /* mat(i,j)=f(e[i],ec[j]) */
156 ctx
->idx
[i
] *= ctx
->nrule
;
160 /* mean of centers defuzzifier */
163 a_float
const *it
= mat
;
164 for (unsigned int i
= 0; i
!= ne
; ++i
)
166 a_float
const *const mkp
= ctx
->mkp
+ ctx
->idx
[i
];
167 for (unsigned int j
= 0; j
!= nec
; ++j
)
169 kp
+= *it
++ * mkp
[idx
[j
]]; /* += mat(i,j) * mkp(e[i],ec[j]) */
176 a_float
const *it
= mat
;
177 for (unsigned int i
= 0; i
!= ne
; ++i
)
179 a_float
const *const mki
= ctx
->mki
+ ctx
->idx
[i
];
180 for (unsigned int j
= 0; j
!= nec
; ++j
)
182 ki
+= *it
++ * mki
[idx
[j
]]; /* += mat(i,j) * mki(e[i],ec[j]) */
189 a_float
const *it
= mat
;
190 for (unsigned int i
= 0; i
!= ne
; ++i
)
192 a_float
const *const mkd
= ctx
->mkd
+ ctx
->idx
[i
];
193 for (unsigned int j
= 0; j
!= nec
; ++j
)
195 kd
+= *it
++ * mkd
[idx
[j
]]; /* += mat(i,j) * mkd(e[i],ec[j]) */
201 a_pid_set_kpid(&ctx
->pid
, ctx
->kp
+ kp
, ctx
->ki
+ ki
, ctx
->kd
+ kd
);
204 A_HIDDEN a_float
a_pid_run_(a_pid
*ctx
, a_float set
, a_float fdb
, a_float err
);
205 a_float
a_pid_fuzzy_run(a_pid_fuzzy
*ctx
, a_float set
, a_float fdb
)
207 a_float
const err
= set
- fdb
;
208 a_pid_fuzzy_out_(ctx
, err
- ctx
->pid
.err
, err
);
209 return a_pid_run_(&ctx
->pid
, set
, fdb
, err
);
212 A_HIDDEN a_float
a_pid_pos_(a_pid
*ctx
, a_float fdb
, a_float err
);
213 a_float
a_pid_fuzzy_pos(a_pid_fuzzy
*ctx
, a_float set
, a_float fdb
)
215 a_float
const err
= set
- fdb
;
216 a_pid_fuzzy_out_(ctx
, err
- ctx
->pid
.err
, err
);
217 return a_pid_pos_(&ctx
->pid
, fdb
, err
);
220 A_HIDDEN a_float
a_pid_inc_(a_pid
*ctx
, a_float fdb
, a_float err
);
221 a_float
a_pid_fuzzy_inc(a_pid_fuzzy
*ctx
, a_float set
, a_float fdb
)
223 a_float
const err
= set
- fdb
;
224 a_pid_fuzzy_out_(ctx
, err
- ctx
->pid
.err
, err
);
225 return a_pid_inc_(&ctx
->pid
, fdb
, err
);
228 void a_pid_fuzzy_zero(a_pid_fuzzy
*ctx
) { a_pid_zero(&ctx
->pid
); }