2 #include "a/pid_neuro.h"
4 static JSClassID liba_pid_neuro_class_id
;
6 static void liba_pid_neuro_finalizer(JSRuntime
*rt
, JSValue val
)
8 js_free_rt(rt
, JS_GetOpaque(val
, liba_pid_neuro_class_id
));
11 static JSClassDef liba_pid_neuro_class
= {"pid_neuro", .finalizer
= liba_pid_neuro_finalizer
};
13 static JSValue
liba_pid_neuro_ctor(JSContext
*ctx
, JSValueConst new_target
, int argc
, JSValueConst
*argv
)
17 JSValue proto
, clazz
= JS_UNDEFINED
;
18 a_pid_neuro
*const self
= (a_pid_neuro
*)js_mallocz(ctx
, sizeof(a_pid_neuro
));
19 if (!self
) { return JS_EXCEPTION
; }
20 self
->pid
.summax
= +A_FLOAT_INF
;
21 self
->pid
.summin
= -A_FLOAT_INF
;
22 self
->pid
.outmax
= +A_FLOAT_INF
;
23 self
->pid
.outmin
= -A_FLOAT_INF
;
24 self
->k
= self
->pid
.kp
= 1;
25 self
->wp
= A_FLOAT_C(0.1);
26 self
->wi
= A_FLOAT_C(0.1);
27 self
->wd
= A_FLOAT_C(0.1);
28 a_pid_neuro_init(self
);
29 proto
= JS_GetPropertyStr(ctx
, new_target
, "prototype");
30 if (JS_IsException(proto
)) { goto fail
; }
31 clazz
= JS_NewObjectProtoClass(ctx
, proto
, liba_pid_neuro_class_id
);
32 JS_FreeValue(ctx
, proto
);
33 if (JS_IsException(clazz
)) { goto fail
; }
34 JS_SetOpaque(clazz
, self
);
38 JS_FreeValue(ctx
, clazz
);
42 static JSValue
liba_pid_neuro_get(JSContext
*ctx
, JSValueConst this_val
, int magic
)
44 a_pid_neuro
*const self
= (a_pid_neuro
*)JS_GetOpaque2(ctx
, this_val
, liba_pid_neuro_class_id
);
45 if (!self
) { return JS_EXCEPTION
; }
49 case 0: x
= (double)self
->k
; break;
50 case 1: x
= (double)self
->pid
.kp
; break;
51 case 2: x
= (double)self
->pid
.ki
; break;
52 case 3: x
= (double)self
->pid
.kd
; break;
53 case 4: x
= (double)self
->wp
; break;
54 case 5: x
= (double)self
->wi
; break;
55 case 6: x
= (double)self
->wd
; break;
56 case 7: x
= (double)self
->pid
.outmax
; break;
57 case 8: x
= (double)self
->pid
.outmin
; break;
58 case 9: x
= (double)self
->pid
.out
; break;
59 case 10: x
= (double)self
->pid
.fdb
; break;
60 case 11: x
= (double)self
->pid
.err
; break;
61 case 12: x
= (double)self
->ec
; break;
62 default: return JS_UNDEFINED
;
64 return JS_NewFloat64(ctx
, x
);
67 static JSValue
liba_pid_neuro_set(JSContext
*ctx
, JSValueConst this_val
, JSValueConst val
, int magic
)
69 a_pid_neuro
*const self
= (a_pid_neuro
*)JS_GetOpaque2(ctx
, this_val
, liba_pid_neuro_class_id
);
70 if (!self
) { return JS_EXCEPTION
; }
72 if (JS_ToFloat64(ctx
, &x
, val
)) { return JS_EXCEPTION
; }
75 case 0: self
->k
= (a_float
)x
; break;
76 case 1: self
->pid
.kp
= (a_float
)x
; break;
77 case 2: self
->pid
.ki
= (a_float
)x
; break;
78 case 3: self
->pid
.kd
= (a_float
)x
; break;
79 case 4: self
->wp
= (a_float
)x
; break;
80 case 5: self
->wi
= (a_float
)x
; break;
81 case 6: self
->wd
= (a_float
)x
; break;
82 case 7: self
->pid
.outmax
= (a_float
)x
; break;
83 case 8: self
->pid
.outmin
= (a_float
)x
; break;
89 static JSValue
liba_pid_neuro_kpid(JSContext
*ctx
, JSValueConst this_val
, int argc
, JSValueConst
*argv
)
92 a_pid_neuro
*const self
= (a_pid_neuro
*)JS_GetOpaque2(ctx
, this_val
, liba_pid_neuro_class_id
);
93 if (!self
) { return JS_EXCEPTION
; }
94 double args
[] = {0, 0, 0, 0};
95 for (unsigned int i
= 0; i
< A_LEN(args
); ++i
)
97 if (JS_ToFloat64(ctx
, &args
[i
], argv
[i
])) { return JS_EXCEPTION
; }
99 a_pid_neuro_kpid(self
, (a_float
)args
[0], (a_float
)args
[1], (a_float
)args
[2], (a_float
)args
[3]);
103 static JSValue
liba_pid_neuro_wpid(JSContext
*ctx
, JSValueConst this_val
, int argc
, JSValueConst
*argv
)
106 a_pid_neuro
*const self
= (a_pid_neuro
*)JS_GetOpaque2(ctx
, this_val
, liba_pid_neuro_class_id
);
107 if (!self
) { return JS_EXCEPTION
; }
108 double args
[] = {0, 0, 0};
109 for (unsigned int i
= 0; i
< A_LEN(args
); ++i
)
111 if (JS_ToFloat64(ctx
, &args
[i
], argv
[i
])) { return JS_EXCEPTION
; }
113 a_pid_neuro_wpid(self
, (a_float
)args
[0], (a_float
)args
[1], (a_float
)args
[2]);
117 static JSValue
liba_pid_neuro_zero(JSContext
*ctx
, JSValueConst this_val
, int argc
, JSValueConst
*argv
)
121 a_pid_neuro
*const self
= (a_pid_neuro
*)JS_GetOpaque2(ctx
, this_val
, liba_pid_neuro_class_id
);
122 if (!self
) { return JS_EXCEPTION
; }
123 a_pid_neuro_zero(self
);
127 static JSValue
liba_pid_neuro_run(JSContext
*ctx
, JSValueConst this_val
, int argc
, JSValueConst
*argv
)
130 a_pid_neuro
*const self
= (a_pid_neuro
*)JS_GetOpaque2(ctx
, this_val
, liba_pid_neuro_class_id
);
131 if (!self
) { return JS_EXCEPTION
; }
132 double args
[] = {0, 0};
133 for (unsigned int i
= 0; i
< A_LEN(args
); ++i
)
135 if (JS_ToFloat64(ctx
, &args
[i
], argv
[i
])) { return JS_EXCEPTION
; }
137 return JS_NewFloat64(ctx
, (double)a_pid_neuro_run(self
, (a_float
)args
[0], (a_float
)args
[1]));
140 static JSValue
liba_pid_neuro_inc(JSContext
*ctx
, JSValueConst this_val
, int argc
, JSValueConst
*argv
)
143 a_pid_neuro
*const self
= (a_pid_neuro
*)JS_GetOpaque2(ctx
, this_val
, liba_pid_neuro_class_id
);
144 if (!self
) { return JS_EXCEPTION
; }
145 double args
[] = {0, 0};
146 for (unsigned int i
= 0; i
< A_LEN(args
); ++i
)
148 if (JS_ToFloat64(ctx
, &args
[i
], argv
[i
])) { return JS_EXCEPTION
; }
150 return JS_NewFloat64(ctx
, (double)a_pid_neuro_inc(self
, (a_float
)args
[0], (a_float
)args
[1]));
153 static JSCFunctionListEntry
const liba_pid_neuro_proto
[] = {
154 JS_PROP_STRING_DEF("[Symbol.toStringTag]", "a.pid.neuron", 0),
155 JS_CGETSET_MAGIC_DEF("k", liba_pid_neuro_get
, liba_pid_neuro_set
, 0),
156 JS_CGETSET_MAGIC_DEF("kp", liba_pid_neuro_get
, liba_pid_neuro_set
, 1),
157 JS_CGETSET_MAGIC_DEF("ki", liba_pid_neuro_get
, liba_pid_neuro_set
, 2),
158 JS_CGETSET_MAGIC_DEF("kd", liba_pid_neuro_get
, liba_pid_neuro_set
, 3),
159 JS_CGETSET_MAGIC_DEF("wp", liba_pid_neuro_get
, liba_pid_neuro_set
, 4),
160 JS_CGETSET_MAGIC_DEF("wi", liba_pid_neuro_get
, liba_pid_neuro_set
, 5),
161 JS_CGETSET_MAGIC_DEF("wd", liba_pid_neuro_get
, liba_pid_neuro_set
, 6),
162 JS_CGETSET_MAGIC_DEF("outmax", liba_pid_neuro_get
, liba_pid_neuro_set
, 7),
163 JS_CGETSET_MAGIC_DEF("outmin", liba_pid_neuro_get
, liba_pid_neuro_set
, 8),
164 JS_CGETSET_MAGIC_DEF("out", liba_pid_neuro_get
, NULL
, 9),
165 JS_CGETSET_MAGIC_DEF("fdb", liba_pid_neuro_get
, NULL
, 10),
166 JS_CGETSET_MAGIC_DEF("err", liba_pid_neuro_get
, NULL
, 11),
167 JS_CGETSET_MAGIC_DEF("ec", liba_pid_neuro_get
, NULL
, 12),
168 JS_CFUNC_DEF("kpid", 4, liba_pid_neuro_kpid
),
169 JS_CFUNC_DEF("wpid", 3, liba_pid_neuro_wpid
),
170 JS_CFUNC_DEF("zero", 0, liba_pid_neuro_zero
),
171 JS_CFUNC_DEF("run", 2, liba_pid_neuro_run
),
172 JS_CFUNC_DEF("inc", 2, liba_pid_neuro_inc
),
175 int js_liba_pid_neuro_init(JSContext
*ctx
, JSModuleDef
*m
)
177 JS_NewClassID(&liba_pid_neuro_class_id
);
178 JS_NewClass(JS_GetRuntime(ctx
), liba_pid_neuro_class_id
, &liba_pid_neuro_class
);
180 JSValue
const proto
= JS_NewObject(ctx
);
181 JS_SetPropertyFunctionList(ctx
, proto
, liba_pid_neuro_proto
, A_LEN(liba_pid_neuro_proto
));
183 JSValue
const clazz
= JS_NewCFunction2(ctx
, liba_pid_neuro_ctor
, "pid_neuro", 3, JS_CFUNC_constructor
, 0);
184 JS_SetConstructor(ctx
, clazz
, proto
);
185 JS_SetClassProto(ctx
, liba_pid_neuro_class_id
, proto
);
187 return JS_SetModuleExport(ctx
, m
, "pid_neuro", clazz
);