2 fuzzy proportional integral derivative controller
7 #include "a/pid_fuzzy.h"
10 destructor for fuzzy PID controller
11 @tparam a.pid_fuzzy ctx fuzzy PID controller userdata
14 int liba_pid_fuzzy_die(lua_State
*L
)
16 a_pid_fuzzy
*const ctx
= (a_pid_fuzzy
*)lua_touserdata(L
, 1);
19 lua_alloc(L
, ctx
->me
, 0);
20 lua_alloc(L
, ctx
->mec
, 0);
21 lua_alloc(L
, ctx
->mkp
, 0);
22 lua_alloc(L
, ctx
->mki
, 0);
23 lua_alloc(L
, ctx
->mkd
, 0);
24 lua_alloc(L
, a_pid_fuzzy_bfuzz(ctx
), 0);
37 constructor for fuzzy PID controller
38 @treturn a.pid_fuzzy fuzzy PID controller userdata
41 int liba_pid_fuzzy_new(lua_State
*L
)
43 a_pid_fuzzy
*const ctx
= lua_newclass(L
, a_pid_fuzzy
);
44 lua_registry_get(L
, liba_pid_fuzzy_new
);
45 lua_setmetatable(L
, -2);
46 ctx
->pid
.kp
= ctx
->kp
= 1;
47 ctx
->pid
.ki
= ctx
->ki
= 0;
48 ctx
->pid
.kd
= ctx
->kd
= 0;
49 ctx
->pid
.summax
= +A_FLOAT_INF
;
50 ctx
->pid
.summin
= -A_FLOAT_INF
;
51 ctx
->pid
.outmax
= +A_FLOAT_INF
;
52 ctx
->pid
.outmin
= -A_FLOAT_INF
;
62 ctx
->opr
= a_fuzzy_equ
;
63 a_pid_fuzzy_init(ctx
);
68 initialize for fuzzy PID controller
69 @tparam a.pid_fuzzy ctx fuzzy PID controller userdata
70 @treturn a.pid_fuzzy fuzzy PID controller userdata
73 int liba_pid_fuzzy_init(lua_State
*L
)
75 luaL_checktype(L
, 1, LUA_TUSERDATA
);
76 a_pid_fuzzy
*const ctx
= (a_pid_fuzzy
*)lua_touserdata(L
, 1);
77 ctx
->pid
.kp
= ctx
->kp
= 1;
78 ctx
->pid
.ki
= ctx
->ki
= 0;
79 ctx
->pid
.kd
= ctx
->kd
= 0;
80 ctx
->pid
.summax
= +A_FLOAT_INF
;
81 ctx
->pid
.summin
= -A_FLOAT_INF
;
82 ctx
->pid
.outmax
= +A_FLOAT_INF
;
83 ctx
->pid
.outmin
= -A_FLOAT_INF
;
84 ctx
->opr
= a_fuzzy_equ
;
85 a_pid_fuzzy_init(ctx
);
90 set fuzzy relational operator for fuzzy PID controller
91 @tparam a.pid_fuzzy ctx fuzzy PID controller userdata
92 @tparam int opr enumeration for fuzzy PID controller operator
93 @treturn a.pid_fuzzy fuzzy PID controller userdata
96 int liba_pid_fuzzy_set_opr(lua_State
*L
)
98 a_pid_fuzzy
*const ctx
= (a_pid_fuzzy
*)lua_touserdata(L
, 1);
101 a_pid_fuzzy_set_opr(ctx
, (unsigned int)luaL_checkinteger(L
, 2));
109 set memory block for fuzzy PID controller
110 @tparam a.pid_fuzzy ctx fuzzy PID controller userdata
111 @tparam int num maximum number triggered by the rule
112 @treturn a.pid_fuzzy fuzzy PID controller userdata
115 int liba_pid_fuzzy_set_nfuzz(lua_State
*L
)
117 a_pid_fuzzy
*const ctx
= (a_pid_fuzzy
*)lua_touserdata(L
, 1);
120 unsigned int const num
= (unsigned int)luaL_checkinteger(L
, 2);
121 void *ptr
= lua_alloc(L
, a_pid_fuzzy_bfuzz(ctx
), A_PID_FUZZY_BFUZZ(num
));
122 a_pid_fuzzy_set_bfuzz(ctx
, ptr
, num
);
130 set rule base for fuzzy PID controller
131 @tparam a.pid_fuzzy ctx fuzzy PID controller userdata
132 @tparam table me points to membership function parameter table, terminated by 0
133 @tparam table mec points to membership function parameter table, terminated by 0
134 @tparam table mkp points to Kp's rule base table which must be a square matrix
135 @tparam table mki points to Ki's rule base table which must be a square matrix
136 @tparam table mkd points to Kd's rule base table which must be a square matrix
137 @treturn a.pid_fuzzy fuzzy PID controller userdata
140 int liba_pid_fuzzy_set_rule(lua_State
*L
)
142 a_pid_fuzzy
*const ctx
= (a_pid_fuzzy
*)lua_touserdata(L
, 1);
145 unsigned int const num
= (unsigned int)lua_rawlen(L
, 2);
146 a_float
const *const me
= lua_table_num_get(L
, 2, ctx
->me
, 0);
147 a_float
const *const mec
= lua_table_num_get(L
, 3, ctx
->mec
, 0);
148 a_float
const *const mkp
= lua_table_num_get(L
, 4, ctx
->mkp
, 0);
149 a_float
const *const mki
= lua_table_num_get(L
, 5, ctx
->mki
, 0);
150 a_float
const *const mkd
= lua_table_num_get(L
, 6, ctx
->mkd
, 0);
151 a_pid_fuzzy_set_rule(ctx
, num
, me
, mec
, mkp
, mki
, mkd
);
159 set proportional integral derivative constant for fuzzy PID controller
160 @tparam a.pid_fuzzy ctx fuzzy PID controller userdata
161 @tparam number kp proportional constant
162 @tparam number ki integral constant
163 @tparam number kd derivative constant
164 @treturn a.pid_fuzzy fuzzy PID controller userdata
167 int liba_pid_fuzzy_set_kpid(lua_State
*L
)
169 a_pid_fuzzy
*const ctx
= (a_pid_fuzzy
*)lua_touserdata(L
, 1);
172 a_float
const kp
= (a_float
)luaL_checknumber(L
, 2);
173 a_float
const ki
= (a_float
)luaL_checknumber(L
, 3);
174 a_float
const kd
= (a_float
)luaL_checknumber(L
, 4);
175 a_pid_fuzzy_set_kpid(ctx
, kp
, ki
, kd
);
183 calculate for fuzzy PID controller
184 @tparam a.pid_fuzzy ctx fuzzy PID controller userdata
185 @tparam number set setpoint value
186 @tparam number fdb feedback value
187 @treturn number setpoint value
190 int liba_pid_fuzzy_run(lua_State
*L
)
192 a_pid_fuzzy
*const ctx
= (a_pid_fuzzy
*)lua_touserdata(L
, 1);
195 a_float
const set
= (a_float
)luaL_checknumber(L
, 2);
196 a_float
const fdb
= (a_float
)luaL_checknumber(L
, 3);
197 lua_pushnumber(L
, (lua_Number
)a_pid_fuzzy_run(ctx
, set
, fdb
));
204 calculate for positional fuzzy PID controller
205 @tparam a.pid_fuzzy ctx fuzzy PID controller userdata
206 @tparam number set setpoint value
207 @tparam number fdb feedback value
208 @treturn number output value
211 int liba_pid_fuzzy_pos(lua_State
*L
)
213 a_pid_fuzzy
*const ctx
= (a_pid_fuzzy
*)lua_touserdata(L
, 1);
216 a_float
const set
= (a_float
)luaL_checknumber(L
, 2);
217 a_float
const fdb
= (a_float
)luaL_checknumber(L
, 3);
218 lua_pushnumber(L
, (lua_Number
)a_pid_fuzzy_pos(ctx
, set
, fdb
));
225 calculate for incremental fuzzy PID controller
226 @tparam a.pid_fuzzy ctx fuzzy PID controller userdata
227 @tparam number set setpoint value
228 @tparam number fdb feedback value
229 @treturn number output value
232 int liba_pid_fuzzy_inc(lua_State
*L
)
234 a_pid_fuzzy
*const ctx
= (a_pid_fuzzy
*)lua_touserdata(L
, 1);
237 a_float
const set
= (a_float
)luaL_checknumber(L
, 2);
238 a_float
const fdb
= (a_float
)luaL_checknumber(L
, 3);
239 lua_pushnumber(L
, (lua_Number
)a_pid_fuzzy_inc(ctx
, set
, fdb
));
246 zeroing for fuzzy PID controller
247 @tparam a.pid_fuzzy ctx fuzzy PID controller userdata
248 @treturn a.pid_fuzzy fuzzy PID controller userdata
251 int liba_pid_fuzzy_zero(lua_State
*L
)
253 a_pid_fuzzy
*const ctx
= (a_pid_fuzzy
*)lua_touserdata(L
, 1);
256 a_pid_fuzzy_zero(ctx
);
262 static int liba_pid_fuzzy_set(lua_State
*L
)
264 a_pid_fuzzy
*const ctx
= (a_pid_fuzzy
*)lua_touserdata(L
, 1);
265 switch (a_hash_bkdr(lua_tostring(L
, 2), 0))
267 case 0x00003731: // kp
268 ctx
->pid
.kp
= ctx
->kp
= (a_float
)luaL_checknumber(L
, 3);
270 case 0x0000372A: // ki
271 ctx
->pid
.ki
= ctx
->ki
= (a_float
)luaL_checknumber(L
, 3);
273 case 0x00003725: // kd
274 ctx
->pid
.kd
= ctx
->kd
= (a_float
)luaL_checknumber(L
, 3);
276 case 0x10E9FF9D: // summax
277 ctx
->pid
.summax
= (a_float
)luaL_checknumber(L
, 3);
279 case 0x10EA03AB: // summin
280 ctx
->pid
.summin
= (a_float
)luaL_checknumber(L
, 3);
282 case 0x23C8F10E: // outmax
283 ctx
->pid
.outmax
= (a_float
)luaL_checknumber(L
, 3);
285 case 0x23C8F51C: // outmin
286 ctx
->pid
.outmin
= (a_float
)luaL_checknumber(L
, 3);
288 case 0x98AE2495: // nfuzz
290 unsigned int const num
= (unsigned int)luaL_checkinteger(L
, 3);
291 void *ptr
= lua_alloc(L
, a_pid_fuzzy_bfuzz(ctx
), A_PID_FUZZY_BFUZZ(num
));
292 a_pid_fuzzy_set_bfuzz(ctx
, ptr
, num
);
295 case 0xE8859EEB: // __name
296 case 0xE70C48C6: // __call
297 case 0xA65758B2: // __index
298 case 0xAEB551C6: // __newindex
301 lua_getmetatable(L
, 1);
308 static int liba_pid_fuzzy_get(lua_State
*L
)
310 a_pid_fuzzy
const *const ctx
= (a_pid_fuzzy
const *)lua_touserdata(L
, 1);
311 switch (a_hash_bkdr(lua_tostring(L
, 2), 0))
313 case 0x00003731: // kp
314 lua_pushnumber(L
, (lua_Number
)ctx
->kp
);
316 case 0x0000372A: // ki
317 lua_pushnumber(L
, (lua_Number
)ctx
->ki
);
319 case 0x00003725: // kd
320 lua_pushnumber(L
, (lua_Number
)ctx
->kd
);
322 case 0x10E9FF9D: // summax
323 lua_pushnumber(L
, (lua_Number
)ctx
->pid
.summax
);
325 case 0x10EA03AB: // summin
326 lua_pushnumber(L
, (lua_Number
)ctx
->pid
.summin
);
328 case 0x001E5957: // sum
329 lua_pushnumber(L
, (lua_Number
)ctx
->pid
.sum
);
331 case 0x23C8F10E: // outmax
332 lua_pushnumber(L
, (lua_Number
)ctx
->pid
.outmax
);
334 case 0x23C8F51C: // outmin
335 lua_pushnumber(L
, (lua_Number
)ctx
->pid
.outmin
);
337 case 0x001D4D3A: // out
338 lua_pushnumber(L
, (lua_Number
)ctx
->pid
.out
);
340 case 0x001AE924: // fdb
341 lua_pushnumber(L
, (lua_Number
)ctx
->pid
.fdb
);
343 case 0x001AAD55: // err
344 lua_pushnumber(L
, (lua_Number
)ctx
->pid
.err
);
346 case 0x9A49C09A: // nrule
347 lua_pushinteger(L
, (lua_Integer
)ctx
->nrule
);
349 case 0x98AE2495: // nfuzz
350 lua_pushinteger(L
, (lua_Integer
)ctx
->nfuzz
);
352 case 0xA65758B2: // __index
353 lua_registry_get(L
, liba_pid_fuzzy_new
);
354 lua_num_set(L
, -1, "kp", ctx
->kp
);
355 lua_num_set(L
, -1, "ki", ctx
->ki
);
356 lua_num_set(L
, -1, "kd", ctx
->kd
);
357 lua_num_set(L
, -1, "summax", ctx
->pid
.summax
);
358 lua_num_set(L
, -1, "summin", ctx
->pid
.summin
);
359 lua_num_set(L
, -1, "sum", ctx
->pid
.sum
);
360 lua_num_set(L
, -1, "outmax", ctx
->pid
.outmax
);
361 lua_num_set(L
, -1, "outmin", ctx
->pid
.outmin
);
362 lua_num_set(L
, -1, "out", ctx
->pid
.out
);
363 lua_num_set(L
, -1, "fdb", ctx
->pid
.fdb
);
364 lua_num_set(L
, -1, "err", ctx
->pid
.err
);
365 lua_int_set(L
, -1, "nrule", (lua_Integer
)ctx
->nrule
);
366 lua_int_set(L
, -1, "nfuzz", (lua_Integer
)ctx
->nfuzz
);
369 lua_getmetatable(L
, 1);
376 static int liba_pid_fuzzy_(lua_State
*L
)
378 lua_pushcfunction(L
, liba_pid_fuzzy_new
);
380 lua_call(L
, lua_gettop(L
) - 1, 1);
384 int luaopen_liba_pid_fuzzy(lua_State
*L
)
387 enumeration for fuzzy relational operator
389 @field CAP_ALGEBRA a*b
390 @field CAP_BOUNDED max(a+b-1,0)
392 @field CUP_ALGEBRA a+b-a*b
393 @field CUP_BOUNDED min(a+b,1)
394 @field EQU sqrt(a,b)*sqrt(1-(1-a)*(1-b))
397 static lua_int
const enums
[] = {
398 {"CAP", A_PID_FUZZY_CAP
},
399 {"CAP_ALGEBRA", A_PID_FUZZY_CAP_ALGEBRA
},
400 {"CAP_BOUNDED", A_PID_FUZZY_CAP_BOUNDED
},
401 {"CUP", A_PID_FUZZY_CUP
},
402 {"CUP_ALGEBRA", A_PID_FUZZY_CUP_ALGEBRA
},
403 {"CUP_BOUNDED", A_PID_FUZZY_CUP_BOUNDED
},
404 {"EQU", A_PID_FUZZY_EQU
},
406 static lua_fun
const funcs
[] = {
407 {"new", liba_pid_fuzzy_new
},
408 {"init", liba_pid_fuzzy_init
},
409 {"set_opr", liba_pid_fuzzy_set_opr
},
410 {"set_nfuzz", liba_pid_fuzzy_set_nfuzz
},
411 {"set_rule", liba_pid_fuzzy_set_rule
},
412 {"set_kpid", liba_pid_fuzzy_set_kpid
},
413 {"run", liba_pid_fuzzy_run
},
414 {"pos", liba_pid_fuzzy_pos
},
415 {"inc", liba_pid_fuzzy_inc
},
416 {"zero", liba_pid_fuzzy_zero
},
418 lua_createtable(L
, 0, A_LEN(enums
) + A_LEN(funcs
));
419 lua_int_reg(L
, -1, enums
, A_LEN(enums
));
420 lua_fun_reg(L
, -1, funcs
, A_LEN(funcs
));
421 lua_createtable(L
, 0, 1);
422 lua_fun_set(L
, -1, "__call", liba_pid_fuzzy_
);
423 lua_setmetatable(L
, -2);
425 static lua_fun
const metas
[] = {
426 {"__newindex", liba_pid_fuzzy_set
},
427 {"__index", liba_pid_fuzzy_get
},
428 #if defined(LUA_VERSION_NUM) && (LUA_VERSION_NUM > 503)
429 {"__close", liba_pid_fuzzy_die
},
430 #endif /* LUA_VERSION_NUM */
431 {"__gc", liba_pid_fuzzy_die
},
433 lua_createtable(L
, 0, A_LEN(metas
) + A_LEN(funcs
) + 1);
434 lua_fun_reg(L
, -1, metas
, A_LEN(metas
));
435 lua_fun_reg(L
, -1, funcs
, A_LEN(funcs
));
436 lua_str_set(L
, -1, "__name", "a.pid_fuzzy");
437 lua_registry_set(L
, liba_pid_fuzzy_new
);