_fuzzypid.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include "_fuzzypid.h"
  2. #include "_fuzzypid_FuzzyPIDController.h"
  3. #include "_fuzzypid_FuzzyPIDParams.h"
  4. #include "_fuzzypid_MembershipFunction.h"
  5. #include "_fuzzypid_PIDDirect.h"
  6. #include "_fuzzypid_RuleBase.h"
  7. #include "fuzzy_PID.h"
  8. void _fuzzypid___init__(PikaObj* self) {
  9. obj_setInt(self, "PB", PB);
  10. obj_setInt(self, "PM", PM);
  11. obj_setInt(self, "PS", PS);
  12. obj_setInt(self, "ZO", ZO);
  13. obj_setInt(self, "NS", NS);
  14. obj_setInt(self, "NM", NM);
  15. obj_setInt(self, "NB", NB);
  16. }
  17. static void _fillRuleBase(PikaObj* self,
  18. PikaObj* rules,
  19. int (*rules_base)[qf_default],
  20. size_t* offset) {
  21. size_t rules_len = pikaList_getSize(rules);
  22. for (size_t i = 0; i < rules_len; ++i) {
  23. PikaObj* rule = pikaList_getPtr(rules, i);
  24. size_t rule_len = pikaList_getSize(rule);
  25. for (size_t j = 0; j < rule_len; ++j) {
  26. rules_base[*offset][j] = pikaList_getInt(rule, j);
  27. }
  28. ++(*offset);
  29. }
  30. }
  31. void _fuzzypid_RuleBase___init__(PikaObj* self,
  32. PikaObj* kp_rules,
  33. PikaObj* ki_rules,
  34. PikaObj* kd_rules) {
  35. size_t kp_rules_len = pikaList_getSize(kp_rules);
  36. size_t ki_rules_len = pikaList_getSize(ki_rules);
  37. size_t kd_rules_len = pikaList_getSize(kd_rules);
  38. if (kp_rules_len != ki_rules_len || ki_rules_len != kd_rules_len) {
  39. obj_setSysOut(
  40. self,
  41. "Error: kp_rules, ki_rules, kd_rules must have the same length");
  42. obj_setErrorCode(self, -__LINE__);
  43. return;
  44. }
  45. size_t rules_len = kp_rules_len;
  46. if (rules_len == 0) {
  47. obj_setSysOut(self,
  48. "Error: kp_rules, ki_rules, kd_rules must not be "
  49. "empty");
  50. obj_setErrorCode(self, -__LINE__);
  51. return;
  52. }
  53. size_t rule_len = pikaList_getSize(pikaList_getPtr(kp_rules, 0));
  54. if (rule_len != qf_default) {
  55. obj_setSysOut(self,
  56. "Error: kp_rules, ki_rules, kd_rules must have "
  57. "qf_default columns");
  58. obj_setErrorCode(self, -__LINE__);
  59. return;
  60. }
  61. for (size_t i = 0; i < rules_len; ++i) {
  62. PikaObj* rule = pikaList_getPtr(kp_rules, i);
  63. if (pikaList_getSize(rule) != rule_len) {
  64. obj_setSysOut(self,
  65. "Error: kp_rules, ki_rules, kd_rules must have "
  66. "the same length");
  67. obj_setErrorCode(self, -__LINE__);
  68. return;
  69. }
  70. }
  71. size_t rules_size = sizeof(int) * rules_len * rule_len * 3;
  72. int(*rules)[qf_default] = pikaMalloc(rules_size);
  73. obj_setInt(self, "rules_size", rules_size);
  74. size_t offset = 0;
  75. _fillRuleBase(self, kp_rules, rules, &offset);
  76. _fillRuleBase(self, ki_rules, rules, &offset);
  77. _fillRuleBase(self, kd_rules, rules, &offset);
  78. obj_setPtr(self, "rules", rules);
  79. }
  80. void _fuzzypid_RuleBase___del__(PikaObj* self) {
  81. int* rules = obj_getPtr(self, "rules");
  82. pikaFree(rules, obj_getInt(self, "rules_size"));
  83. }
  84. void _fuzzypid_MembershipFunction___init__(PikaObj* self, PikaObj* params) {
  85. size_t params_len = pikaList_getSize(params);
  86. if (params_len != 4 * qf_default) {
  87. obj_setSysOut(self, "Error: params must have 4 * qf_default columns");
  88. obj_setErrorCode(self, -__LINE__);
  89. return;
  90. }
  91. int* mf_params = pikaMalloc(sizeof(int) * params_len);
  92. for (size_t i = 0; i < params_len; ++i) {
  93. mf_params[i] = pikaList_getInt(params, i);
  94. }
  95. obj_setPtr(self, "mf_params", mf_params);
  96. }
  97. void _fuzzypid_MembershipFunction___del__(PikaObj* self) {
  98. int* mf_params = obj_getPtr(self, "mf_params");
  99. pikaFree(mf_params, sizeof(int) * 4 * qf_default);
  100. }
  101. void _fuzzypid_FuzzyPIDParams___init__(PikaObj* self, PikaObj* pid_params) {
  102. size_t DOF = pikaList_getSize(pid_params);
  103. size_t pid_params_len = pikaList_getSize(pikaList_getPtr(pid_params, 0));
  104. if (pid_params_len != pid_params_count) {
  105. obj_setSysOut(self,
  106. "Error: pid_params must have pid_params_count columns");
  107. obj_setErrorCode(self, -__LINE__);
  108. return;
  109. }
  110. float(*fuzzy_pid_params)[pid_params_count] =
  111. pikaMalloc(sizeof(float) * DOF * pid_params_count);
  112. for (size_t i = 0; i < DOF; ++i) {
  113. PikaObj* pid_param = pikaList_getPtr(pid_params, i);
  114. if (pikaList_getSize(pid_param) != pid_params_len) {
  115. obj_setSysOut(self, "Error: pid_params must have the same length");
  116. obj_setErrorCode(self, -__LINE__);
  117. return;
  118. }
  119. for (size_t j = 0; j < pid_params_len; ++j) {
  120. fuzzy_pid_params[i][j] = pikaList_getFloat(pid_param, j);
  121. }
  122. }
  123. obj_setPtr(self, "fuzzy_pid_params", fuzzy_pid_params);
  124. obj_setInt(self, "DOF", DOF);
  125. }
  126. void _fuzzypid_FuzzyPIDParams___del__(PikaObj* self) {
  127. float* fuzzy_pid_params = obj_getPtr(self, "fuzzy_pid_params");
  128. size_t DOF = obj_getInt(self, "DOF");
  129. pikaFree(fuzzy_pid_params, sizeof(float) * DOF * pid_params_count);
  130. }
  131. void _fuzzypid_PIDDirect___init__(PikaObj* self, PikaObj* direct) {
  132. size_t DOF = pikaList_getSize(direct);
  133. pika_bool* direct_vector = pikaMalloc(sizeof(pika_bool) * DOF);
  134. for (size_t i = 0; i < DOF; ++i) {
  135. direct_vector[i] = pikaList_getBool(direct, i);
  136. }
  137. obj_setInt(self, "DOF", DOF);
  138. obj_setPtr(self, "direct_vector", direct_vector);
  139. }
  140. void _fuzzypid_PIDDirect___del__(PikaObj* self) {
  141. pika_bool* direct_vector = obj_getPtr(self, "direct_vector");
  142. pikaFree(direct_vector, sizeof(pika_bool) * obj_getInt(self, "DOF"));
  143. }
  144. void _fuzzypid_FuzzyPIDController___init__(PikaObj* self,
  145. PikaObj* rule_base,
  146. PikaObj* mf_params,
  147. PikaObj* pid_params,
  148. pika_float delta_k,
  149. int mf_type,
  150. int fo_type,
  151. int df_type,
  152. PikaObj* direct) {
  153. obj_setPtr(self, "rule_base", rule_base);
  154. obj_setPtr(self, "mf_params", mf_params);
  155. obj_setPtr(self, "pid_params", pid_params);
  156. obj_setPtr(self, "direct", direct);
  157. int* rules = obj_getPtr(rule_base, "rules");
  158. int* mf_params_mat = obj_getPtr(mf_params, "mf_params");
  159. float* fuzzy_pid_params = obj_getPtr(pid_params, "fuzzy_pid_params");
  160. int DOF_pid_parms = obj_getInt(pid_params, "DOF");
  161. int DOF_direct = obj_getInt(direct, "DOF");
  162. if (DOF_pid_parms != DOF_direct) {
  163. obj_setSysOut(self,
  164. "Error: pid_params and direct must have the same length");
  165. obj_setErrorCode(self, -__LINE__);
  166. return;
  167. }
  168. struct PID** pid_vector = fuzzy_pid_vector_init(
  169. (float(*)[pid_params_count])fuzzy_pid_params, delta_k, mf_type, fo_type,
  170. df_type, mf_params_mat, (int(*)[pid_params_count])rules, DOF_pid_parms);
  171. obj_setPtr(self, "pid_vector", pid_vector);
  172. obj_setInt(self, "DOF", DOF_pid_parms);
  173. obj_setPtr(self, "direct_vector", obj_getPtr(direct, "direct_vector"));
  174. }
  175. void _fuzzypid_FuzzyPIDController___del__(PikaObj* self) {
  176. struct PID** pid_vector = obj_getPtr(self, "pid_vector");
  177. if (NULL != pid_vector) {
  178. int DOF = obj_getInt(self, "DOF");
  179. delete_pid_vector(pid_vector, DOF);
  180. }
  181. }
  182. pika_float _fuzzypid_FuzzyPIDController_compute_output(PikaObj* self,
  183. int control_id,
  184. pika_float real,
  185. pika_float input) {
  186. struct PID** pid_vector = obj_getPtr(self, "pid_vector");
  187. pika_bool* direct_vector = obj_getPtr(self, "direct_vector");
  188. int DOF = obj_getInt(self, "DOF");
  189. if (control_id < 0 || control_id >= DOF) {
  190. obj_setSysOut(self, "Error: control_id out of range");
  191. obj_setErrorCode(self, -__LINE__);
  192. return 0;
  193. }
  194. return fuzzy_pid_motor_pwd_output(real, input, direct_vector[control_id],
  195. pid_vector[control_id]);
  196. }