#include "pid.h"
#include "a/pid.h"
int liba_pid_new(lua_State *L)
{
a_pid *const ctx = lua_newclass(L, a_pid);
lua_registry_get(L, liba_pid_new);
lua_setmetatable(L, -2);
ctx->kp = 1;
ctx->ki = 0;
ctx->kd = 0;
ctx->summax = +A_FLOAT_INF;
ctx->summin = -A_FLOAT_INF;
ctx->outmax = +A_FLOAT_INF;
ctx->outmin = -A_FLOAT_INF;
a_pid_init(ctx);
return 1;
}
int liba_pid_init(lua_State *L)
{
luaL_checktype(L, 1, LUA_TUSERDATA);
a_pid *const ctx = (a_pid *)lua_touserdata(L, 1);
ctx->kp = 1;
ctx->ki = 0;
ctx->kd = 0;
ctx->summax = +A_FLOAT_INF;
ctx->summin = -A_FLOAT_INF;
ctx->outmax = +A_FLOAT_INF;
ctx->outmin = -A_FLOAT_INF;
a_pid_init(ctx);
return 1;
}
int liba_pid_set_kpid(lua_State *L)
{
a_pid *const ctx = (a_pid *)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_set_kpid(ctx, kp, ki, kd);
lua_pushvalue(L, 1);
return 1;
}
return 0;
}
int liba_pid_run(lua_State *L)
{
a_pid *const ctx = (a_pid *)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_run(ctx, set, fdb));
return 1;
}
return 0;
}
int liba_pid_pos(lua_State *L)
{
a_pid *const ctx = (a_pid *)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_pos(ctx, set, fdb));
return 1;
}
return 0;
}
int liba_pid_inc(lua_State *L)
{
a_pid *const ctx = (a_pid *)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_inc(ctx, set, fdb));
return 1;
}
return 0;
}
int liba_pid_zero(lua_State *L)
{
a_pid *const ctx = (a_pid *)lua_touserdata(L, 1);
if (ctx)
{
a_pid_zero(ctx);
return 1;
}
return 0;
}
static int liba_pid_set(lua_State *L)
{
a_pid *const ctx = (a_pid *)lua_touserdata(L, 1);
switch (a_hash_bkdr(lua_tostring(L, 2), 0))
{
case 0x00003731: ctx->kp = (a_float)luaL_checknumber(L, 3);
break;
case 0x0000372A: ctx->ki = (a_float)luaL_checknumber(L, 3);
break;
case 0x00003725: ctx->kd = (a_float)luaL_checknumber(L, 3);
break;
case 0x10E9FF9D: ctx->summax = (a_float)luaL_checknumber(L, 3);
break;
case 0x10EA03AB: ctx->summin = (a_float)luaL_checknumber(L, 3);
break;
case 0x23C8F10E: ctx->outmax = (a_float)luaL_checknumber(L, 3);
break;
case 0x23C8F51C: ctx->outmin = (a_float)luaL_checknumber(L, 3);
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_get(lua_State *L)
{
a_pid const *const ctx = (a_pid 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->summax);
break;
case 0x10EA03AB: lua_pushnumber(L, (lua_Number)ctx->summin);
break;
case 0x001E5957: lua_pushnumber(L, (lua_Number)ctx->sum);
break;
case 0x23C8F10E: lua_pushnumber(L, (lua_Number)ctx->outmax);
break;
case 0x23C8F51C: lua_pushnumber(L, (lua_Number)ctx->outmin);
break;
case 0x001D4D3A: lua_pushnumber(L, (lua_Number)ctx->out);
break;
case 0x001AE924: lua_pushnumber(L, (lua_Number)ctx->fdb);
break;
case 0x001AAD55: lua_pushnumber(L, (lua_Number)ctx->err);
break;
case 0xA65758B2: lua_registry_get(L, liba_pid_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->summax);
lua_num_set(L, -1, "summin", ctx->summin);
lua_num_set(L, -1, "sum", ctx->sum);
lua_num_set(L, -1, "outmax", ctx->outmax);
lua_num_set(L, -1, "outmin", ctx->outmin);
lua_num_set(L, -1, "out", ctx->out);
lua_num_set(L, -1, "fdb", ctx->fdb);
lua_num_set(L, -1, "err", ctx->err);
break;
default:
lua_getmetatable(L, 1);
lua_replace(L, 1);
lua_rawget(L, 1);
}
return 1;
}
static int liba_pid_(lua_State *L)
{
lua_pushcfunction(L, liba_pid_new);
lua_replace(L, 1);
lua_call(L, lua_gettop(L) - 1, 1);
return 1;
}
int luaopen_liba_pid(lua_State *L)
{
static lua_fun const funcs[] = {
{"new", liba_pid_new},
{"init", liba_pid_init},
{"set_kpid", liba_pid_set_kpid},
{"run", liba_pid_run},
{"pos", liba_pid_pos},
{"inc", liba_pid_inc},
{"zero", liba_pid_zero},
};
lua_createtable(L, 0, A_LEN(funcs));
lua_fun_reg(L, -1, funcs, A_LEN(funcs));
lua_createtable(L, 0, 1);
lua_fun_set(L, -1, "__call", liba_pid_);
lua_setmetatable(L, -2);
static lua_fun const metas[] = {
{"__newindex", liba_pid_set},
{"__index", liba_pid_get},
};
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");
lua_registry_set(L, liba_pid_new);
return 1;
}