| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- #include "_fuzzypid.h"
- #include "_fuzzypid_FuzzyPIDController.h"
- #include "_fuzzypid_FuzzyPIDParams.h"
- #include "_fuzzypid_MembershipFunction.h"
- #include "_fuzzypid_PIDDirect.h"
- #include "_fuzzypid_RuleBase.h"
- #include "fuzzy_PID.h"
- void _fuzzypid___init__(PikaObj* self) {
- obj_setInt(self, "PB", PB);
- obj_setInt(self, "PM", PM);
- obj_setInt(self, "PS", PS);
- obj_setInt(self, "ZO", ZO);
- obj_setInt(self, "NS", NS);
- obj_setInt(self, "NM", NM);
- obj_setInt(self, "NB", NB);
- }
- static void _fillRuleBase(PikaObj* self,
- PikaObj* rules,
- int (*rules_base)[qf_default],
- size_t* offset) {
- size_t rules_len = pikaList_getSize(rules);
- for (size_t i = 0; i < rules_len; ++i) {
- PikaObj* rule = pikaList_getPtr(rules, i);
- size_t rule_len = pikaList_getSize(rule);
- for (size_t j = 0; j < rule_len; ++j) {
- rules_base[*offset][j] = pikaList_getInt(rule, j);
- }
- ++(*offset);
- }
- }
- void _fuzzypid_RuleBase___init__(PikaObj* self,
- PikaObj* kp_rules,
- PikaObj* ki_rules,
- PikaObj* kd_rules) {
- size_t kp_rules_len = pikaList_getSize(kp_rules);
- size_t ki_rules_len = pikaList_getSize(ki_rules);
- size_t kd_rules_len = pikaList_getSize(kd_rules);
- if (kp_rules_len != ki_rules_len || ki_rules_len != kd_rules_len) {
- obj_setSysOut(
- self,
- "Error: kp_rules, ki_rules, kd_rules must have the same length");
- obj_setErrorCode(self, -__LINE__);
- return;
- }
- size_t rules_len = kp_rules_len;
- if (rules_len == 0) {
- obj_setSysOut(self,
- "Error: kp_rules, ki_rules, kd_rules must not be "
- "empty");
- obj_setErrorCode(self, -__LINE__);
- return;
- }
- size_t rule_len = pikaList_getSize(pikaList_getPtr(kp_rules, 0));
- if (rule_len != qf_default) {
- obj_setSysOut(self,
- "Error: kp_rules, ki_rules, kd_rules must have "
- "qf_default columns");
- obj_setErrorCode(self, -__LINE__);
- return;
- }
- for (size_t i = 0; i < rules_len; ++i) {
- PikaObj* rule = pikaList_getPtr(kp_rules, i);
- if (pikaList_getSize(rule) != rule_len) {
- obj_setSysOut(self,
- "Error: kp_rules, ki_rules, kd_rules must have "
- "the same length");
- obj_setErrorCode(self, -__LINE__);
- return;
- }
- }
- size_t rules_size = sizeof(int) * rules_len * rule_len * 3;
- int(*rules)[qf_default] = pikaMalloc(rules_size);
- obj_setInt(self, "rules_size", rules_size);
- size_t offset = 0;
- _fillRuleBase(self, kp_rules, rules, &offset);
- _fillRuleBase(self, ki_rules, rules, &offset);
- _fillRuleBase(self, kd_rules, rules, &offset);
- obj_setPtr(self, "rules", rules);
- }
- void _fuzzypid_RuleBase___del__(PikaObj* self) {
- int* rules = obj_getPtr(self, "rules");
- pikaFree(rules, obj_getInt(self, "rules_size"));
- }
- void _fuzzypid_MembershipFunction___init__(PikaObj* self, PikaObj* params) {
- size_t params_len = pikaList_getSize(params);
- if (params_len != 4 * qf_default) {
- obj_setSysOut(self, "Error: params must have 4 * qf_default columns");
- obj_setErrorCode(self, -__LINE__);
- return;
- }
- int* mf_params = pikaMalloc(sizeof(int) * params_len);
- for (size_t i = 0; i < params_len; ++i) {
- mf_params[i] = pikaList_getInt(params, i);
- }
- obj_setPtr(self, "mf_params", mf_params);
- }
- void _fuzzypid_MembershipFunction___del__(PikaObj* self) {
- int* mf_params = obj_getPtr(self, "mf_params");
- pikaFree(mf_params, sizeof(int) * 4 * qf_default);
- }
- void _fuzzypid_FuzzyPIDParams___init__(PikaObj* self, PikaObj* pid_params) {
- size_t DOF = pikaList_getSize(pid_params);
- size_t pid_params_len = pikaList_getSize(pikaList_getPtr(pid_params, 0));
- if (pid_params_len != pid_params_count) {
- obj_setSysOut(self,
- "Error: pid_params must have pid_params_count columns");
- obj_setErrorCode(self, -__LINE__);
- return;
- }
- float(*fuzzy_pid_params)[pid_params_count] =
- pikaMalloc(sizeof(float) * DOF * pid_params_count);
- for (size_t i = 0; i < DOF; ++i) {
- PikaObj* pid_param = pikaList_getPtr(pid_params, i);
- if (pikaList_getSize(pid_param) != pid_params_len) {
- obj_setSysOut(self, "Error: pid_params must have the same length");
- obj_setErrorCode(self, -__LINE__);
- return;
- }
- for (size_t j = 0; j < pid_params_len; ++j) {
- fuzzy_pid_params[i][j] = pikaList_getFloat(pid_param, j);
- }
- }
- obj_setPtr(self, "fuzzy_pid_params", fuzzy_pid_params);
- obj_setInt(self, "DOF", DOF);
- }
- void _fuzzypid_FuzzyPIDParams___del__(PikaObj* self) {
- float* fuzzy_pid_params = obj_getPtr(self, "fuzzy_pid_params");
- size_t DOF = obj_getInt(self, "DOF");
- pikaFree(fuzzy_pid_params, sizeof(float) * DOF * pid_params_count);
- }
- void _fuzzypid_PIDDirect___init__(PikaObj* self, PikaObj* direct) {
- size_t DOF = pikaList_getSize(direct);
- pika_bool* direct_vector = pikaMalloc(sizeof(pika_bool) * DOF);
- for (size_t i = 0; i < DOF; ++i) {
- direct_vector[i] = pikaList_getBool(direct, i);
- }
- obj_setInt(self, "DOF", DOF);
- obj_setPtr(self, "direct_vector", direct_vector);
- }
- void _fuzzypid_PIDDirect___del__(PikaObj* self) {
- pika_bool* direct_vector = obj_getPtr(self, "direct_vector");
- pikaFree(direct_vector, sizeof(pika_bool) * obj_getInt(self, "DOF"));
- }
- void _fuzzypid_FuzzyPIDController___init__(PikaObj* self,
- PikaObj* rule_base,
- PikaObj* mf_params,
- PikaObj* pid_params,
- pika_float delta_k,
- int mf_type,
- int fo_type,
- int df_type,
- PikaObj* direct) {
- obj_setPtr(self, "rule_base", rule_base);
- obj_setPtr(self, "mf_params", mf_params);
- obj_setPtr(self, "pid_params", pid_params);
- obj_setPtr(self, "direct", direct);
- int* rules = obj_getPtr(rule_base, "rules");
- int* mf_params_mat = obj_getPtr(mf_params, "mf_params");
- float* fuzzy_pid_params = obj_getPtr(pid_params, "fuzzy_pid_params");
- int DOF_pid_parms = obj_getInt(pid_params, "DOF");
- int DOF_direct = obj_getInt(direct, "DOF");
- if (DOF_pid_parms != DOF_direct) {
- obj_setSysOut(self,
- "Error: pid_params and direct must have the same length");
- obj_setErrorCode(self, -__LINE__);
- return;
- }
- struct PID** pid_vector = fuzzy_pid_vector_init(
- (float(*)[pid_params_count])fuzzy_pid_params, delta_k, mf_type, fo_type,
- df_type, mf_params_mat, (int(*)[pid_params_count])rules, DOF_pid_parms);
- obj_setPtr(self, "pid_vector", pid_vector);
- obj_setInt(self, "DOF", DOF_pid_parms);
- obj_setPtr(self, "direct_vector", obj_getPtr(direct, "direct_vector"));
- }
- void _fuzzypid_FuzzyPIDController___del__(PikaObj* self) {
- struct PID** pid_vector = obj_getPtr(self, "pid_vector");
- if (NULL != pid_vector) {
- int DOF = obj_getInt(self, "DOF");
- delete_pid_vector(pid_vector, DOF);
- }
- }
- pika_float _fuzzypid_FuzzyPIDController_compute_output(PikaObj* self,
- int control_id,
- pika_float real,
- pika_float input) {
- struct PID** pid_vector = obj_getPtr(self, "pid_vector");
- pika_bool* direct_vector = obj_getPtr(self, "direct_vector");
- int DOF = obj_getInt(self, "DOF");
- if (control_id < 0 || control_id >= DOF) {
- obj_setSysOut(self, "Error: control_id out of range");
- obj_setErrorCode(self, -__LINE__);
- return 0;
- }
- return fuzzy_pid_motor_pwd_output(real, input, direct_vector[control_id],
- pid_vector[control_id]);
- }
|