fuzzy_PID.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. #include "fuzzy_PID.h"
  2. struct fuzzy* fuzzy_init(unsigned int input_num, unsigned int output_num) {
  3. struct fuzzy* fuzzy_struct =
  4. (struct fuzzy*)pika_platform_malloc(sizeof(struct fuzzy));
  5. fuzzy_struct->input_num = input_num;
  6. fuzzy_struct->output_num = output_num;
  7. fuzzy_struct->mf_type = (unsigned int*)pika_platform_malloc(
  8. (input_num + output_num) * sizeof(unsigned int));
  9. #ifdef fuzzy_pid_rule_base_deep_copy
  10. fuzzy_struct->mf_params =
  11. (int*)pika_platform_malloc(4 * qf_default * sizeof(int));
  12. fuzzy_struct->rule_base = (int*)pika_platform_malloc(
  13. output_num * qf_default * qf_default * sizeof(int));
  14. #endif
  15. fuzzy_struct->output =
  16. (float*)pika_platform_malloc(output_num * sizeof(float));
  17. return fuzzy_struct;
  18. }
  19. void delete_fuzzy(struct fuzzy* fuzzy_struct) {
  20. pika_platform_free(fuzzy_struct->mf_type);
  21. pika_platform_free(fuzzy_struct->output);
  22. pika_platform_free(fuzzy_struct);
  23. }
  24. void fuzzy_params_init(struct fuzzy* fuzzy_struct,
  25. unsigned int mf_type,
  26. unsigned int fo_type,
  27. unsigned int df_type,
  28. int mf_params[],
  29. int rule_base[][qf_default]) {
  30. for (unsigned int i = 0;
  31. i < fuzzy_struct->input_num + fuzzy_struct->output_num; ++i) {
  32. fuzzy_struct->mf_type[i] = mf_type;
  33. }
  34. for (unsigned int i = 0; i < fuzzy_struct->output_num; ++i) {
  35. fuzzy_struct->output[i] = 0;
  36. }
  37. #ifdef fuzzy_pid_rule_base_deep_copy
  38. for (unsigned int j = 0; j < 4 * qf_default; ++j) {
  39. fuzzy_struct->mf_params[j] = mf_params[j];
  40. }
  41. for (unsigned int k = 0; k < fuzzy_struct->output_num * qf_default; ++k) {
  42. for (unsigned int i = 0; i < qf_default; ++i) {
  43. fuzzy_struct->rule_base[k * 7 + i] = rule_base[k][i];
  44. }
  45. }
  46. #else
  47. fuzzy_struct->mf_params = mf_params;
  48. fuzzy_struct->rule_base = (int*)rule_base;
  49. #endif
  50. fuzzy_struct->fo_type = fo_type;
  51. fuzzy_struct->df_type = df_type;
  52. }
  53. #define inverse(parameter) 1.0f / (float)parameter
  54. // Gaussian membership function
  55. float gaussmf(float x, float sigma, float c) {
  56. return expf(-powf(((x - c) / sigma), 2.0f));
  57. }
  58. // Generalized bell-shaped membership function
  59. float gbellmf(float x, float a, float b, float c) {
  60. return inverse(1.0f + powf(fabsf((x - c) / a), 2.0f * b));
  61. }
  62. // Sigmoidal membership function
  63. float sigmf(float x, float a, float c) {
  64. return inverse(1.0f + expf(a * (c - x)));
  65. }
  66. // Trapezoidal membership function
  67. float trapmf(float x, float a, float b, float c, float d) {
  68. if (x >= a && x < b)
  69. return (x - a) / (b - a);
  70. else if (x >= b && x < c)
  71. return 1.0f;
  72. else if (x >= c && x <= d)
  73. return (d - x) / (d - c);
  74. else
  75. return 0.0f;
  76. }
  77. // Triangular membership function
  78. float trimf(float x, float a, float b, float c) {
  79. return trapmf(x, a, b, b, c);
  80. }
  81. // Z-shaped membership function
  82. float zmf(float x, float a, float b) {
  83. if (x <= a)
  84. return 1.0f;
  85. else if (x >= a && x <= (a + b) / 2.0f)
  86. return 1.0f - 2.0f * powf((x - a) / (b - a), 2.0f);
  87. else if (x >= (a + b) / 2.0f && x < b)
  88. return 2.0f * powf((x - b) / (b - a), 2.0f);
  89. else
  90. return 0;
  91. }
  92. // Membership function
  93. float mf(float x, unsigned int mf_type, int* params) {
  94. switch (mf_type) {
  95. case 0:
  96. return gaussmf(x, params[0], params[1]);
  97. case 1:
  98. return gbellmf(x, params[0], params[1], params[2]);
  99. case 2:
  100. return sigmf(x, params[0], params[2]);
  101. case 3:
  102. return trapmf(x, params[0], params[1], params[2], params[3]);
  103. case 5:
  104. return zmf(x, params[0], params[1]);
  105. default: // set triangular as default membership function
  106. return trimf(x, params[0], params[1], params[2]);
  107. }
  108. }
  109. // Union operator
  110. float or (float a, float b, unsigned int type) {
  111. if (type == 1) { // algebraic sum
  112. return a + b - a * b;
  113. } else if (type == 2) { // bounded sum
  114. return fminf(1, a + b);
  115. } else { // fuzzy union
  116. return fmaxf(a, b);
  117. }
  118. }
  119. // Intersection operator
  120. float and (float a, float b, unsigned int type) {
  121. if (type == 1) { // algebraic product
  122. return a * b;
  123. } else if (type == 2) { // bounded product
  124. return fmaxf(0, a + b - 1);
  125. } else { // fuzzy intersection
  126. return fminf(a, b);
  127. }
  128. }
  129. // Equilibrium operator
  130. float equilibrium(float a, float b, float params) {
  131. return powf(a * b, 1 - params) * powf(1 - (1 - a) * (1 - b), params);
  132. }
  133. // Fuzzy operator
  134. float fo(float a, float b, unsigned int type) {
  135. if (type < 3) {
  136. return and(a, b, type);
  137. } else if (type < 6) {
  138. return or (a, b, type - 3);
  139. } else {
  140. return equilibrium(a, b, 0.5f);
  141. }
  142. }
  143. // Mean of centers defuzzifier, only for two input multiple index
  144. void moc(const float* joint_membership,
  145. const unsigned int* index,
  146. const unsigned int* count,
  147. struct fuzzy* fuzzy_struct) {
  148. float denominator_count = 0;
  149. float numerator_count[fuzzy_struct->output_num];
  150. for (unsigned int l = 0; l < fuzzy_struct->output_num; ++l) {
  151. numerator_count[l] = 0;
  152. }
  153. for (int i = 0; i < count[0]; ++i) {
  154. for (int j = 0; j < count[1]; ++j) {
  155. denominator_count += joint_membership[i * count[1] + j];
  156. }
  157. }
  158. for (unsigned int k = 0; k < fuzzy_struct->output_num; ++k) {
  159. for (unsigned int i = 0; i < count[0]; ++i) {
  160. for (unsigned int j = 0; j < count[1]; ++j) {
  161. numerator_count[k] +=
  162. joint_membership[i * count[1] + j] *
  163. fuzzy_struct->rule_base[k * qf_default * qf_default +
  164. index[i] * qf_default +
  165. index[count[0] + j]];
  166. }
  167. }
  168. }
  169. #ifdef fuzzy_pid_debug_print
  170. pika_platform_printf("output:\n");
  171. #endif
  172. for (unsigned int l = 0; l < fuzzy_struct->output_num; ++l) {
  173. fuzzy_struct->output[l] = numerator_count[l] / denominator_count;
  174. #ifdef fuzzy_pid_debug_print
  175. pika_platform_printf("%f,%f,%f\n", numerator_count[l],
  176. denominator_count, fuzzy_struct->index[l]);
  177. #endif
  178. }
  179. }
  180. // Defuzzifier
  181. void df(const float* joint_membership,
  182. const unsigned int* output,
  183. const unsigned int* count,
  184. struct fuzzy* fuzzy_struct,
  185. int df_type) {
  186. if (df_type == 0)
  187. moc(joint_membership, output, count, fuzzy_struct);
  188. else {
  189. pika_platform_printf("Waring: No such of defuzzifier!\n");
  190. moc(joint_membership, output, count, fuzzy_struct);
  191. }
  192. }
  193. void fuzzy_control(float e, float de, struct fuzzy* fuzzy_struct) {
  194. float membership[qf_default * 2]; // Store membership
  195. unsigned int index[qf_default * 2]; // Store the index of each membership
  196. unsigned int count[2] = {0, 0};
  197. {
  198. int j = 0;
  199. for (int i = 0; i < qf_default; ++i) {
  200. float temp = mf(e, fuzzy_struct->mf_type[0],
  201. fuzzy_struct->mf_params + 4 * i);
  202. if (temp > 1e-4) {
  203. membership[j] = temp;
  204. index[j++] = i;
  205. }
  206. }
  207. count[0] = j;
  208. for (int i = 0; i < qf_default; ++i) {
  209. float temp = mf(de, fuzzy_struct->mf_type[1],
  210. fuzzy_struct->mf_params + 4 * i);
  211. if (temp > 1e-4) {
  212. membership[j] = temp;
  213. index[j++] = i;
  214. }
  215. }
  216. count[1] = j - count[0];
  217. }
  218. #ifdef fuzzy_pid_debug_print
  219. pika_platform_printf("membership:\n");
  220. for (unsigned int k = 0; k < j; ++k) {
  221. pika_platform_printf("%f\n", membership[k]);
  222. }
  223. pika_platform_printf("index:\n");
  224. for (unsigned int k = 0; k < j; ++k) {
  225. pika_platform_printf("%d\n", index[k]);
  226. }
  227. pika_platform_printf("count:\n");
  228. for (unsigned int k = 0; k < 2; ++k) {
  229. pika_platform_printf("%d\n", count[k]);
  230. }
  231. #endif
  232. if (count[0] == 0 || count[1] == 0) {
  233. for (unsigned int l = 0; l < fuzzy_struct->output_num; ++l) {
  234. fuzzy_struct->output[l] = 0;
  235. }
  236. return;
  237. }
  238. // Joint membership
  239. float joint_membership[count[0] * count[1]];
  240. for (int i = 0; i < count[0]; ++i) {
  241. for (int j = 0; j < count[1]; ++j) {
  242. joint_membership[i * count[1] + j] = fo(
  243. membership[i], membership[count[0] + j], fuzzy_struct->fo_type);
  244. }
  245. }
  246. df(joint_membership, index, count, fuzzy_struct, 0);
  247. }
  248. struct PID* raw_fuzzy_pid_init(float kp,
  249. float ki,
  250. float kd,
  251. float integral_limit,
  252. float dead_zone,
  253. float feed_forward,
  254. float error_max,
  255. float delta_error_max,
  256. float delta_kp_max,
  257. float delta_ki_max,
  258. float delta_kd_max,
  259. unsigned int mf_type,
  260. unsigned int fo_type,
  261. unsigned int df_type,
  262. int mf_params[],
  263. int rule_base[][qf_default],
  264. int output_min_value,
  265. int output_middle_value,
  266. int output_max_value) {
  267. struct PID* pid = (struct PID*)pika_platform_malloc(sizeof(struct PID));
  268. pid->kp = kp;
  269. pid->ki = ki;
  270. pid->kd = kd;
  271. pid->delta_kp_max = delta_kp_max;
  272. pid->delta_ki_max = delta_ki_max;
  273. pid->delta_kd_max = delta_kd_max;
  274. pid->delta_kp = 0;
  275. pid->delta_ki = 0;
  276. pid->delta_kd = 0;
  277. pid->error_max = error_max;
  278. pid->delta_error_max = delta_error_max;
  279. int output_count = 1;
  280. if (ki > 1e-4) {
  281. output_count += 1;
  282. if (kd > 1e-4)
  283. output_count += 1;
  284. }
  285. pid->fuzzy_struct = fuzzy_init(2, output_count);
  286. fuzzy_params_init(pid->fuzzy_struct, mf_type, fo_type, df_type, mf_params,
  287. rule_base);
  288. pid->last_error = 0;
  289. pid->current_error = 0;
  290. pid->intergral = 0;
  291. pid->intergral_limit = integral_limit;
  292. pid->dead_zone = dead_zone;
  293. pid->feed_forward = feed_forward;
  294. pid->output_max_value = output_max_value;
  295. pid->output_middle_value = output_middle_value;
  296. pid->output_min_value = output_min_value;
  297. return pid;
  298. }
  299. struct PID* fuzzy_pid_init(float* params,
  300. float delta_k,
  301. unsigned int mf_type,
  302. unsigned int fo_type,
  303. unsigned int df_type,
  304. int mf_params[],
  305. int rule_base[][qf_default]) {
  306. return raw_fuzzy_pid_init(
  307. params[0], params[1], params[2], params[3], params[4], params[5],
  308. max_error, max_delta_error, params[0] / delta_k, params[1] / delta_k,
  309. params[2] / delta_k, mf_type, fo_type, df_type, mf_params, rule_base,
  310. min_pwm_output, middle_pwm_output, max_pwm_output);
  311. }
  312. struct PID* raw_pid_init(float kp,
  313. float ki,
  314. float kd,
  315. float integral_limit,
  316. float dead_zone,
  317. float feed_forward,
  318. float linear_adaptive_kp,
  319. float error_max,
  320. float delta_error_max,
  321. int output_min_value,
  322. int output_middle_value,
  323. int output_max_value) {
  324. struct PID* pid = (struct PID*)pika_platform_malloc(sizeof(struct PID));
  325. pid->kp = kp;
  326. pid->ki = ki;
  327. pid->kd = kd;
  328. pid->delta_kp_max = 0;
  329. pid->delta_ki_max = 0;
  330. pid->delta_kd_max = 0;
  331. pid->delta_kp = 0;
  332. pid->delta_ki = 0;
  333. pid->delta_kd = 0;
  334. pid->error_max = error_max;
  335. pid->delta_error_max = delta_error_max;
  336. pid->fuzzy_struct = NULL;
  337. pid->last_error = 0;
  338. pid->current_error = 0;
  339. pid->intergral = 0;
  340. pid->intergral_limit = integral_limit;
  341. pid->dead_zone = dead_zone;
  342. pid->feed_forward = feed_forward;
  343. pid->output_max_value = output_max_value;
  344. pid->output_middle_value = output_middle_value;
  345. pid->output_min_value = output_min_value;
  346. pid->linear_adaptive_kp = linear_adaptive_kp;
  347. return pid;
  348. }
  349. struct PID* pid_init(float* params) {
  350. return raw_pid_init(params[0], params[1], params[2], params[3], params[4],
  351. params[5], params[6], max_error, max_delta_error,
  352. min_pwm_output, middle_pwm_output, max_pwm_output);
  353. }
  354. int round_user(float parameter) {
  355. if ((int)(parameter * 10.0) % 10 >= 5)
  356. return parameter + 1;
  357. else
  358. return parameter;
  359. }
  360. int limit(int value, int max_limit, int min_limit) {
  361. if (value > max_limit)
  362. return max_limit;
  363. if (value < min_limit)
  364. return min_limit;
  365. return value;
  366. }
  367. float fuzzy_pid_control(float real, float idea, struct PID* pid) {
  368. pid->last_error = pid->current_error;
  369. pid->current_error = idea - real;
  370. float delta_error = pid->current_error - pid->last_error;
  371. #ifdef fuzzy_pid_dead_zone
  372. if (pid->current_error < pid->dead_zone &&
  373. pid->current_error > -pid->dead_zone) {
  374. pid->current_error = 0;
  375. } else {
  376. if (pid->current_error > pid->dead_zone)
  377. pid->current_error = pid->current_error - pid->dead_zone;
  378. else {
  379. if (pid->current_error < -pid->dead_zone)
  380. pid->current_error = pid->current_error + pid->dead_zone;
  381. }
  382. }
  383. #endif
  384. fuzzy_control(pid->current_error / pid->error_max * 3.0f,
  385. delta_error / pid->delta_error_max * 3.0f, pid->fuzzy_struct);
  386. pid->delta_kp =
  387. pid->fuzzy_struct->output[0] / 3.0f * pid->delta_kp_max + pid->kp;
  388. if (pid->fuzzy_struct->output_num >= 2)
  389. pid->delta_ki = pid->fuzzy_struct->output[1] / 3.0f * pid->delta_ki_max;
  390. else
  391. pid->delta_ki = 0;
  392. if (pid->fuzzy_struct->output_num >= 3)
  393. pid->delta_kd = pid->fuzzy_struct->output[2] / 3.0f * pid->delta_kd_max;
  394. else
  395. pid->delta_ki = 0;
  396. #ifdef fuzzy_pid_debug_print
  397. pika_platform_printf("kp : %f, ki : %f, kd : %f\n", kp, ki, kd);
  398. #endif
  399. pid->intergral += (pid->ki + pid->delta_ki) * pid->current_error;
  400. #ifdef fuzzy_pid_integral_limit
  401. if (pid->intergral > pid->intergral_limit)
  402. pid->intergral = pid->intergral_limit;
  403. else {
  404. if (pid->intergral < -pid->intergral_limit)
  405. pid->intergral = -pid->intergral_limit;
  406. }
  407. #endif
  408. pid->output =
  409. (pid->kp + pid->delta_kp) * pid->current_error + pid->intergral +
  410. (pid->kd + pid->delta_kd) * (pid->current_error - pid->last_error);
  411. pid->output += pid->feed_forward * (float)idea;
  412. return pid->output;
  413. }
  414. float pid_control(float real, float idea, struct PID* pid) {
  415. pid->last_error = pid->current_error;
  416. pid->current_error = idea - real;
  417. #ifdef pid_dead_zone
  418. if (pid->current_error < pid->dead_zone &&
  419. pid->current_error > -pid->dead_zone) {
  420. pid->current_error = 0;
  421. } else {
  422. if (pid->current_error > pid->dead_zone)
  423. pid->current_error = pid->current_error - pid->dead_zone;
  424. else {
  425. if (pid->current_error < -pid->dead_zone)
  426. pid->current_error = pid->current_error + pid->dead_zone;
  427. }
  428. }
  429. #endif
  430. #ifdef pid_debug_print
  431. pika_platform_printf("kp : %f, ki : %f, kd : %f\n", kp, ki, kd);
  432. #endif
  433. pid->intergral += (pid->ki) * pid->current_error;
  434. #ifdef pid_integral_limit
  435. if (pid->intergral > pid->intergral_limit)
  436. pid->intergral = pid->intergral_limit;
  437. else {
  438. if (pid->intergral < -pid->intergral_limit)
  439. pid->intergral = -pid->intergral_limit;
  440. }
  441. #endif
  442. float linear_adaptive_kp = 1;
  443. if (pid->linear_adaptive_kp > 1e-4)
  444. linear_adaptive_kp = (1 - pid->linear_adaptive_kp) *
  445. pid->current_error / pid->error_max +
  446. pid->linear_adaptive_kp;
  447. pid->output = pid->kp * linear_adaptive_kp * pid->current_error +
  448. pid->intergral +
  449. (pid->kd) * (pid->current_error - pid->last_error);
  450. pid->output += pid->feed_forward * (float)idea;
  451. return pid->output;
  452. }
  453. void delete_pid(struct PID* pid) {
  454. if (pid->fuzzy_struct != NULL) {
  455. delete_fuzzy(pid->fuzzy_struct);
  456. }
  457. pika_platform_free(pid);
  458. }
  459. void delete_pid_vector(struct PID** pid_vector, unsigned int count) {
  460. for (unsigned int i = 0; i < count; ++i) {
  461. delete_pid(pid_vector[i]);
  462. }
  463. pika_platform_free(pid_vector);
  464. }
  465. struct PID** pid_vector_init(float params[][pid_params_count],
  466. unsigned int count) {
  467. struct PID** pid =
  468. (struct PID**)pika_platform_malloc(sizeof(struct PID*) * count);
  469. for (unsigned int i = 0; i < count; ++i) {
  470. pid[i] = pid_init(params[i]);
  471. }
  472. return pid;
  473. }
  474. struct PID** fuzzy_pid_vector_init(float params[][pid_params_count],
  475. float delta_k,
  476. unsigned int mf_type,
  477. unsigned int fo_type,
  478. unsigned int df_type,
  479. int* mf_params,
  480. int rule_base[][qf_default],
  481. unsigned int count) {
  482. struct PID** pid =
  483. (struct PID**)pika_platform_malloc(sizeof(struct PID*) * count);
  484. for (unsigned int i = 0; i < count; ++i) {
  485. pid[i] = fuzzy_pid_init(params[i], delta_k, mf_type, fo_type, df_type,
  486. mf_params, rule_base);
  487. }
  488. return pid;
  489. }
  490. int direct_control(int zero_value, int offset_value, pika_bool direct) {
  491. if (direct == pika_true) {
  492. return zero_value + offset_value;
  493. } else {
  494. return zero_value - offset_value;
  495. }
  496. }
  497. int fuzzy_pid_motor_pwd_output(float real,
  498. float idea,
  499. pika_bool direct,
  500. struct PID* pid) {
  501. return limit(direct_control(pid->output_middle_value,
  502. fuzzy_pid_control(real, idea, pid), direct),
  503. pid->output_max_value, pid->output_min_value);
  504. }
  505. int pid_motor_pwd_output(float real,
  506. float idea,
  507. pika_bool direct,
  508. struct PID* pid) {
  509. return limit(direct_control(pid->output_middle_value,
  510. pid_control(real, idea, pid), direct),
  511. pid->output_max_value, pid->output_min_value);
  512. }