0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <unistd.h>
0011 #include <stdio.h>
0012 #include <stdlib.h>
0013 #include <string.h>
0014 #include <stdint.h>
0015 #include <sys/types.h>
0016 #include <dirent.h>
0017 #include <libintl.h>
0018 #include <ctype.h>
0019 #include <assert.h>
0020 #include <time.h>
0021 #include <limits.h>
0022 #include <math.h>
0023 #include <sys/stat.h>
0024 #include <syslog.h>
0025
0026 #include "tmon.h"
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 struct pid_params p_param;
0045
0046 static double xk_1, xk_2;
0047
0048
0049
0050
0051
0052
0053
0054
0055 int init_thermal_controller(void)
0056 {
0057
0058
0059 p_param.ts = ticktime;
0060
0061 p_param.kp = .36;
0062 p_param.ki = 5.0;
0063 p_param.kd = 0.19;
0064
0065 p_param.t_target = target_temp_user;
0066
0067 return 0;
0068 }
0069
0070 void controller_reset(void)
0071 {
0072
0073 syslog(LOG_DEBUG, "TC inactive, relax p-state\n");
0074 p_param.y_k = 0.0;
0075 xk_1 = 0.0;
0076 xk_2 = 0.0;
0077 set_ctrl_state(0);
0078 }
0079
0080
0081
0082
0083
0084
0085 #define GUARD_BAND (2)
0086 void controller_handler(const double xk, double *yk)
0087 {
0088 double ek;
0089 double p_term, i_term, d_term;
0090
0091 ek = p_param.t_target - xk;
0092 if (ek >= 3.0) {
0093 syslog(LOG_DEBUG, "PID: %3.1f Below set point %3.1f, stop\n",
0094 xk, p_param.t_target);
0095 controller_reset();
0096 *yk = 0.0;
0097 return;
0098 }
0099
0100 p_term = -p_param.kp * (xk - xk_1);
0101 i_term = p_param.kp * p_param.ki * p_param.ts * ek;
0102 d_term = -p_param.kp * p_param.kd * (xk - 2 * xk_1 + xk_2) / p_param.ts;
0103
0104 *yk += p_term + i_term + d_term;
0105
0106 xk_1 = xk;
0107 xk_2 = xk_1;
0108
0109
0110 if (*yk < -LIMIT_HIGH)
0111 *yk = -LIMIT_HIGH;
0112 else if (*yk > -LIMIT_LOW)
0113 *yk = -LIMIT_LOW;
0114
0115 p_param.y_k = *yk;
0116
0117 set_ctrl_state(lround(fabs(p_param.y_k)));
0118
0119 }