00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "stdafx.h"
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include "pid.h"
00051 #include <math.h>
00052 #include <stdlib.h>
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 control_state *init_state(double p, double i, double d, double f,
00067 double out_filter, double gain,
00068 double dead_zone, double sat_low, double sat_high)
00069 {
00070 control_state *state;
00071 state = (control_state *)calloc(sizeof(*state), 1);
00072 state->last_action = 0;
00073 state->p = state->i = state->d = state->filter = 0;
00074 state->soft_saturate = 0;
00075 state->soft_saturate_scale = 1.0;
00076 state->x = state->target_x = 0;
00077 state->sat_low = sat_low;
00078 state->sat_high = sat_high;
00079 state->gain = gain;
00080 state->cn_p = p;
00081 state->cn_i = i;
00082 state->cn_d = d;
00083 state->cn_f = f;
00084 state->offset = 0;
00085 state->dead_zone = dead_zone;
00086 state->out_filter = out_filter;
00087 state->input = NULL;
00088 state->output = NULL;
00089 state->float_in = 0;
00090 state->float_out = 0;
00091 state->saturate = 0;
00092 state->max_integrator = 0.0;
00093 state->integrator_decay = 1.0;
00094 state->integrator_max_decay = 1.0;
00095 state->max_change = 0;
00096 state->integrator_kill = 5;
00097 state->input_filter = 1.0;
00098 state->i_cap = 1e18;
00099 return state;
00100 }
00101
00102
00103 void set_integrator_cap(control_state *state, double cap)
00104 {
00105 state->i_cap = cap;
00106 }
00107
00108 void set_integrator_kill(control_state *state, double kill)
00109 {
00110
00111 state->integrator_kill = kill;
00112 }
00113
00114
00115 void set_input_filter(control_state *state, double f)
00116 {
00117
00118 state->input_filter = f;
00119 }
00120
00121
00122 void set_rate_limiter(control_state *state, double max_change)
00123 {
00124 state->max_change = max_change;
00125
00126 }
00127
00128
00129 void set_dc(control_state *state, double dc)
00130 {
00131 state->offset = dc;
00132 }
00133
00134
00135 double clip(double x, double a, double b)
00136 {
00137 if(x<a)
00138 x=a;
00139 if(x>b)
00140 x=b;
00141 return x;
00142 }
00143
00144
00145
00146
00147
00148
00149 void set_integrator_decay(control_state *state, double max, double decay, double max_decay)
00150 {
00151 state->max_integrator = max;
00152 state->integrator_decay = decay;
00153 state->integrator_max_decay = max_decay;
00154 }
00155
00156
00157 double control(control_state *state, double x, double target)
00158 {
00159 double filter, action;
00160
00161
00162
00163 state->x = x;
00164 state->target_x = state->input_filter * target + (1-state->input_filter) * state->target_x;
00165
00166
00167 if(fabs(x-target) > state->dead_zone)
00168 {
00169 state->p = state->target_x - state->x;
00170
00171 if(state->max_change>0.0)
00172 {
00173 if(state->p > state->max_change)
00174 state->p = state->max_change;
00175 if(state->p < -state->max_change)
00176 state->p = -state->max_change;
00177 }
00178
00179 filter = state->cn_f * state->p + (1-state->cn_f) * state->filter;
00180
00181 if(fabs(state->p) < state->integrator_kill)
00182 state->i = 0;
00183
00184 state->i += state->p;
00185
00186 state->i *= (state->i>state->max_integrator) ? state->integrator_max_decay : state->integrator_decay;
00187
00188 if(state->i>fabs(state->i_cap))
00189 {
00190 state->i = state->i_cap;
00191 }
00192
00193 state->d = filter - state->filter;
00194 state->filter = filter;
00195 action = state->p * state->cn_p + state->cn_i * state->i + state->d * state->cn_d;
00196 action *= state->gain;
00197
00198
00199
00200 action = (state->out_filter * action) + (1-state->out_filter) * state->last_action;
00201 action += state->offset;
00202
00203
00204 if(state->soft_saturate)
00205 action = ((1.0/(1.0+exp(-action * state->soft_saturate_scale))) ) *
00206 (state->sat_high - state->sat_low) + state->sat_low;
00207
00208
00209
00210 action = clip(action, state->sat_low, state->sat_high);
00211
00212
00213 if(action==state->sat_low || action==state->sat_high)
00214 state->saturate = 1;
00215 else
00216 state->saturate = 0;
00217
00218 state->last_action = action;
00219 }
00220 else
00221 {
00222 action = state->last_action;
00223 }
00224 return action;
00225 }
00226
00227
00228
00229
00230 void set_soft_saturation(control_state *state, double scale)
00231 {
00232 if(scale==0)
00233 state->soft_saturate = 0;
00234 else
00235 {
00236 state->soft_saturate = 1;
00237 state->soft_saturate_scale = scale;
00238 }
00239 }
00240
00241
00242 void reset_state(control_state *state)
00243 {
00244 state->i = 0;
00245 state->d = 0;
00246 state->p = 0;
00247 state->last_action = 0;
00248 state->filter = 0;
00249
00250 }