#include "pid_fuzzy.h"
#include "a/pid_fuzzy.h"
int liba_pid_fuzzy_die(lua_State *L)
{
a_pid_fuzzy *const ctx = (a_pid_fuzzy *)lua_touserdata(L, 1);
if (ctx)
{
lua_alloc(L, ctx->me, 0);
lua_alloc(L, ctx->mec, 0);
lua_alloc(L, ctx->mkp, 0);
lua_alloc(L, ctx->mki, 0);
lua_alloc(L, ctx->mkd, 0);
lua_alloc(L, a_pid_fuzzy_bfuzz(ctx), 0);
ctx->me = 0;
ctx->mec = 0;
ctx->mkp = 0;
ctx->mki = 0;
ctx->mkd = 0;
ctx->idx = 0;
ctx->val = 0;
}
return 0;
}
int liba_pid_fuzzy_new(lua_State *L)
{
a_pid_fuzzy *const ctx = lua_newclass(L, a_pid_fuzzy);
lua_registry_get(L, liba_pid_fuzzy_new);
lua_setmetatable(L, -2);
ctx->pid.kp = ctx->kp = 1;
ctx->pid.ki = ctx->ki = 0;
ctx->pid.kd = ctx->kd = 0;
ctx->pid.summax = +A_FLOAT_INF;
ctx->pid.summin = -A_FLOAT_INF;
ctx->pid.outmax = +A_FLOAT_INF;
ctx->pid.outmin = -A_FLOAT_INF;
ctx->me = 0;
ctx->mec = 0;
ctx->mkp = 0;
ctx->mki = 0;
ctx->mkd = 0;
ctx->idx = 0;
ctx->val = 0;
ctx->nrule = 0;
ctx->nfuzz = 0;
ctx->opr = a_fuzzy_equ;
a_pid_fuzzy_init(ctx);
return 1;
}
int liba_pid_fuzzy_init(lua_State *L)
{
luaL_checktype(L, 1, LUA_TUSERDATA);
a_pid_fuzzy *const ctx = (a_pid_fuzzy *)lua_touserdata(L, 1);
ctx->pid.kp = ctx->kp = 1;
ctx->pid.ki = ctx->ki = 0;
ctx->pid.kd = ctx->kd = 0;
ctx->pid.summax = +A_FLOAT_INF;
ctx->pid.summin = -A_FLOAT_INF;
ctx->pid.outmax = +A_FLOAT_INF;
ctx->pid.outmin = -A_FLOAT_INF;
ctx->opr = a_fuzzy_equ;
a_pid_fuzzy_init(ctx);
return 1;
}
int liba_pid_fuzzy_set_opr(lua_State *L)
{
a_pid_fuzzy *const ctx = (a_pid_fuzzy *)lua_touserdata(L, 1);
if (ctx)
{
a_pid_fuzzy_set_opr(ctx, (unsigned int)luaL_checkinteger(L, 2));
lua_pushvalue(L, 1);
return 1;
}
return 0;
}
int liba_pid_fuzzy_set_nfuzz(lua_State *L)
{
a_pid_fuzzy *const ctx = (a_pid_fuzzy *)lua_touserdata(L, 1);
if (ctx)
{
unsigned int const num = (unsigned int)luaL_checkinteger(L, 2);
void *ptr = lua_alloc(L, a_pid_fuzzy_bfuzz(ctx), A_PID_FUZZY_BFUZZ(num));
a_pid_fuzzy_set_bfuzz(ctx, ptr, num);
lua_pushvalue(L, 1);
return 1;
}
return 0;
}
int liba_pid_fuzzy_set_rule(lua_State *L)
{
a_pid_fuzzy *const ctx = (a_pid_fuzzy *)lua_touserdata(L, 1);
if (ctx)
{
unsigned int const num = (unsigned int)lua_rawlen(L, 2);
a_float const *const me = lua_table_num_get(L, 2, ctx->me, 0);
a_float const *const mec = lua_table_num_get(L, 3, ctx->mec, 0);
a_float const *const mkp = lua_table_num_get(L, 4, ctx->mkp, 0);
a_float const *const mki = lua_table_num_get(L, 5, ctx->mki, 0);
a_float const *const mkd = lua_table_num_get(L, 6, ctx->mkd, 0);
a_pid_fuzzy_set_rule(ctx, num, me, mec, mkp, mki, mkd);
lua_pushvalue(L, 1);
return 1;
}
return 0;
}
int liba_pid_fuzzy_set_kpid(lua_State *L)
{
a_pid_fuzzy *const ctx = (a_pid_fuzzy *)lua_touserdata(L, 1);
if (ctx)
{
a_float const kp = (a_float)luaL_checknumber(L, 2);
a_float const ki = (a_float)luaL_checknumber(L, 3);
a_float const kd = (a_float)luaL_checknumber(L, 4);
a_pid_fuzzy_set_kpid(ctx, kp, ki, kd);
lua_pushvalue(L, 1);
return 1;
}
return 0;
}
int liba_pid_fuzzy_run(lua_State *L)
{
a_pid_fuzzy *const ctx = (a_pid_fuzzy *)lua_touserdata(L, 1);
if (ctx)
{
a_float const set = (a_float)luaL_checknumber(L, 2);
a_float const fdb = (a_float)luaL_checknumber(L, 3);
lua_pushnumber(L, (lua_Number)a_pid_fuzzy_run(ctx, set, fdb));
return 1;
}
return 0;
}
int liba_pid_fuzzy_pos(lua_State *L)
{
a_pid_fuzzy *const ctx = (a_pid_fuzzy *)lua_touserdata(L, 1);
if (ctx)
{
a_float const set = (a_float)luaL_checknumber(L, 2);
a_float const fdb = (a_float)luaL_checknumber(L, 3);
lua_pushnumber(L, (lua_Number)a_pid_fuzzy_pos(ctx, set, fdb));
return 1;
}
return 0;
}
int liba_pid_fuzzy_inc(lua_State *L)
{
a_pid_fuzzy *const ctx = (a_pid_fuzzy *)lua_touserdata(L, 1);
if (ctx)
{
a_float const set = (a_float)luaL_checknumber(L, 2);
a_float const fdb = (a_float)luaL_checknumber(L, 3);
lua_pushnumber(L, (lua_Number)a_pid_fuzzy_inc(ctx, set, fdb));
return 1;
}
return 0;
}
int liba_pid_fuzzy_zero(lua_State *L)
{
a_pid_fuzzy *const ctx = (a_pid_fuzzy *)lua_touserdata(L, 1);
if (ctx)
{
a_pid_fuzzy_zero(ctx);
return 1;
}
return 0;
}
static int liba_pid_fuzzy_set(lua_State *L)
{
a_pid_fuzzy *const ctx = (a_pid_fuzzy *)lua_touserdata(L, 1);
switch (a_hash_bkdr(lua_tostring(L, 2), 0))
{
case 0x00003731: ctx->pid.kp = ctx->kp = (a_float)luaL_checknumber(L, 3);
break;
case 0x0000372A: ctx->pid.ki = ctx->ki = (a_float)luaL_checknumber(L, 3);
break;
case 0x00003725: ctx->pid.kd = ctx->kd = (a_float)luaL_checknumber(L, 3);
break;
case 0x10E9FF9D: ctx->pid.summax = (a_float)luaL_checknumber(L, 3);
break;
case 0x10EA03AB: ctx->pid.summin = (a_float)luaL_checknumber(L, 3);
break;
case 0x23C8F10E: ctx->pid.outmax = (a_float)luaL_checknumber(L, 3);
break;
case 0x23C8F51C: ctx->pid.outmin = (a_float)luaL_checknumber(L, 3);
break;
case 0x98AE2495: {
unsigned int const num = (unsigned int)luaL_checkinteger(L, 3);
void *ptr = lua_alloc(L, a_pid_fuzzy_bfuzz(ctx), A_PID_FUZZY_BFUZZ(num));
a_pid_fuzzy_set_bfuzz(ctx, ptr, num);
break;
}
case 0xE8859EEB: case 0xE70C48C6: case 0xA65758B2: case 0xAEB551C6: break;
default:
lua_getmetatable(L, 1);
lua_replace(L, 1);
lua_rawset(L, 1);
}
return 0;
}
static int liba_pid_fuzzy_get(lua_State *L)
{
a_pid_fuzzy const *const ctx = (a_pid_fuzzy const *)lua_touserdata(L, 1);
switch (a_hash_bkdr(lua_tostring(L, 2), 0))
{
case 0x00003731: lua_pushnumber(L, (lua_Number)ctx->kp);
break;
case 0x0000372A: lua_pushnumber(L, (lua_Number)ctx->ki);
break;
case 0x00003725: lua_pushnumber(L, (lua_Number)ctx->kd);
break;
case 0x10E9FF9D: lua_pushnumber(L, (lua_Number)ctx->pid.summax);
break;
case 0x10EA03AB: lua_pushnumber(L, (lua_Number)ctx->pid.summin);
break;
case 0x001E5957: lua_pushnumber(L, (lua_Number)ctx->pid.sum);
break;
case 0x23C8F10E: lua_pushnumber(L, (lua_Number)ctx->pid.outmax);
break;
case 0x23C8F51C: lua_pushnumber(L, (lua_Number)ctx->pid.outmin);
break;
case 0x001D4D3A: lua_pushnumber(L, (lua_Number)ctx->pid.out);
break;
case 0x001AE924: lua_pushnumber(L, (lua_Number)ctx->pid.fdb);
break;
case 0x001AAD55: lua_pushnumber(L, (lua_Number)ctx->pid.err);
break;
case 0x9A49C09A: lua_pushinteger(L, (lua_Integer)ctx->nrule);
break;
case 0x98AE2495: lua_pushinteger(L, (lua_Integer)ctx->nfuzz);
break;
case 0xA65758B2: lua_registry_get(L, liba_pid_fuzzy_new);
lua_num_set(L, -1, "kp", ctx->kp);
lua_num_set(L, -1, "ki", ctx->ki);
lua_num_set(L, -1, "kd", ctx->kd);
lua_num_set(L, -1, "summax", ctx->pid.summax);
lua_num_set(L, -1, "summin", ctx->pid.summin);
lua_num_set(L, -1, "sum", ctx->pid.sum);
lua_num_set(L, -1, "outmax", ctx->pid.outmax);
lua_num_set(L, -1, "outmin", ctx->pid.outmin);
lua_num_set(L, -1, "out", ctx->pid.out);
lua_num_set(L, -1, "fdb", ctx->pid.fdb);
lua_num_set(L, -1, "err", ctx->pid.err);
lua_int_set(L, -1, "nrule", (lua_Integer)ctx->nrule);
lua_int_set(L, -1, "nfuzz", (lua_Integer)ctx->nfuzz);
break;
default:
lua_getmetatable(L, 1);
lua_replace(L, 1);
lua_rawget(L, 1);
}
return 1;
}
static int liba_pid_fuzzy_(lua_State *L)
{
lua_pushcfunction(L, liba_pid_fuzzy_new);
lua_replace(L, 1);
lua_call(L, lua_gettop(L) - 1, 1);
return 1;
}
int luaopen_liba_pid_fuzzy(lua_State *L)
{
static lua_int const enums[] = {
{"CAP", A_PID_FUZZY_CAP},
{"CAP_ALGEBRA", A_PID_FUZZY_CAP_ALGEBRA},
{"CAP_BOUNDED", A_PID_FUZZY_CAP_BOUNDED},
{"CUP", A_PID_FUZZY_CUP},
{"CUP_ALGEBRA", A_PID_FUZZY_CUP_ALGEBRA},
{"CUP_BOUNDED", A_PID_FUZZY_CUP_BOUNDED},
{"EQU", A_PID_FUZZY_EQU},
};
static lua_fun const funcs[] = {
{"new", liba_pid_fuzzy_new},
{"init", liba_pid_fuzzy_init},
{"set_opr", liba_pid_fuzzy_set_opr},
{"set_nfuzz", liba_pid_fuzzy_set_nfuzz},
{"set_rule", liba_pid_fuzzy_set_rule},
{"set_kpid", liba_pid_fuzzy_set_kpid},
{"run", liba_pid_fuzzy_run},
{"pos", liba_pid_fuzzy_pos},
{"inc", liba_pid_fuzzy_inc},
{"zero", liba_pid_fuzzy_zero},
};
lua_createtable(L, 0, A_LEN(enums) + A_LEN(funcs));
lua_int_reg(L, -1, enums, A_LEN(enums));
lua_fun_reg(L, -1, funcs, A_LEN(funcs));
lua_createtable(L, 0, 1);
lua_fun_set(L, -1, "__call", liba_pid_fuzzy_);
lua_setmetatable(L, -2);
static lua_fun const metas[] = {
{"__newindex", liba_pid_fuzzy_set},
{"__index", liba_pid_fuzzy_get},
#if defined(LUA_VERSION_NUM) && (LUA_VERSION_NUM > 503)
{"__close", liba_pid_fuzzy_die},
#endif
{"__gc", liba_pid_fuzzy_die},
};
lua_createtable(L, 0, A_LEN(metas) + A_LEN(funcs) + 1);
lua_fun_reg(L, -1, metas, A_LEN(metas));
lua_fun_reg(L, -1, funcs, A_LEN(funcs));
lua_str_set(L, -1, "__name", "a.pid_fuzzy");
lua_registry_set(L, liba_pid_fuzzy_new);
return 1;
}