From 8662239978cdd778d01b575e05a1dd64db32f1c0 Mon Sep 17 00:00:00 2001 From: David Wehr <dawehr@iastate.edu> Date: Thu, 6 Apr 2017 09:08:04 -0500 Subject: [PATCH] PID block now uses the derivative of input value rather than the error. --- quad/src/graph_blocks/node_pid.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/quad/src/graph_blocks/node_pid.c b/quad/src/graph_blocks/node_pid.c index df6b61110..eb166b3c9 100644 --- a/quad/src/graph_blocks/node_pid.c +++ b/quad/src/graph_blocks/node_pid.c @@ -6,9 +6,10 @@ static double FLT_EPSILON = 0.0001; struct pid_node_state { - double prev_error; // Previous error + double prev_val; // Previous input value double acc_error; // Accumulated error double last_filtered; // Last output from the filtered derivative + int just_reset; // Set to 1 after a call to reset }; // The generic PID diagram. This function takes in pid inputs (CUR_POINT and SETOINT) and calculates the output "pid_correction" @@ -50,21 +51,27 @@ static void pid_computation(void *state, const double* params, const double *inp pid_state->acc_error += error; } + if (pid_state->just_reset) { + // On first call after a reset, set the previous value to + // the current value to prevent a spike in derivative + pid_state->prev_val = inputs[PID_CUR_POINT]; + pid_state->just_reset = 0; + } // Compute each term's contribution P = params[PID_KP] * error; I = params[PID_KI] * pid_state->acc_error * inputs[PID_DT]; // Low-pass filter on derivative - double change_in_error = error - pid_state->prev_error; + double change_in_value = inputs[PID_CUR_POINT] - pid_state->prev_val; double term1 = params[PID_ALPHA] * pid_state->last_filtered; - double derivative = change_in_error / inputs[PID_DT]; + double derivative = change_in_value / inputs[PID_DT]; if (inputs[PID_DT] == 0) { // Divide by zero check derivative = 0; } double term2 = params[PID_KD] * (1.0f - params[PID_ALPHA]) * derivative; D = term1 + term2; pid_state->last_filtered = D; // Store filtered value for next filter iteration - pid_state->prev_error = error; // Store the current error into the state + pid_state->prev_val = inputs[PID_CUR_POINT]; // Store the current error into the state outputs[PID_CORRECTION] = P + I + D; // Store the computed correction } @@ -74,8 +81,8 @@ static void pid_computation(void *state, const double* params, const double *inp static void reset_pid(void *state) { struct pid_node_state* pid_state = (struct pid_node_state*)state; pid_state->acc_error = 0; - pid_state->prev_error = 0; pid_state->last_filtered = 0; + pid_state->just_reset = 1; } -- GitLab