update pid, work version
This commit is contained in:
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
||||||
BIN
PID Controller Implementation in Software.pdf
Normal file
BIN
PID Controller Implementation in Software.pdf
Normal file
Binary file not shown.
37
PID.c
37
PID.c
@@ -1,22 +1,6 @@
|
|||||||
#include "PID.h"
|
#include "PID.h"
|
||||||
|
|
||||||
/*test push*/
|
void PIDController_Init(PIDController *pid) {
|
||||||
|
|
||||||
void pidControllerInit(PidController *pid, float Kp, float Ki, float Kd, float tau, float limMin, float limMax,
|
|
||||||
float limMinInt, float limMaxInt, float T) {
|
|
||||||
pid->Kp = Kp;
|
|
||||||
pid->Ki = Ki;
|
|
||||||
pid->Kd = Kd;
|
|
||||||
pid->KpDefault = Kp;
|
|
||||||
pid->KiDefault = Ki;
|
|
||||||
pid->KdDefault = Kd;
|
|
||||||
|
|
||||||
pid->tau = tau;
|
|
||||||
pid->limMin = limMin;
|
|
||||||
pid->limMax = limMax;
|
|
||||||
pid->limMinInt = limMinInt;
|
|
||||||
pid->limMaxInt = limMaxInt;
|
|
||||||
pid->T = T;
|
|
||||||
|
|
||||||
/* Clear controller variables */
|
/* Clear controller variables */
|
||||||
pid->integrator = 0.0f;
|
pid->integrator = 0.0f;
|
||||||
@@ -27,10 +11,9 @@ void pidControllerInit(PidController *pid, float Kp, float Ki, float Kd, float t
|
|||||||
|
|
||||||
pid->out = 0.0f;
|
pid->out = 0.0f;
|
||||||
|
|
||||||
pid->enable = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float pidControllerUpdate(PidController *pid, float setpoint, float measurement) {
|
float PIDController_Update(PIDController *pid, float setpoint, float measurement) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Error signal
|
* Error signal
|
||||||
@@ -65,8 +48,7 @@ float pidControllerUpdate(PidController *pid, float setpoint, float measurement)
|
|||||||
* Derivative (band-limited differentiator)
|
* Derivative (band-limited differentiator)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pid->differentiator = -(2.0f * pid->Kd * (measurement -
|
pid->differentiator = -(2.0f * pid->Kd * (measurement - pid->prevMeasurement) /* Note: derivative on measurement, therefore minus sign in front of equation! */
|
||||||
pid->prevMeasurement) /* Note: derivative on measurement, therefore minus sign in front of equation! */
|
|
||||||
+ (2.0f * pid->tau - pid->T) * pid->differentiator)
|
+ (2.0f * pid->tau - pid->T) * pid->differentiator)
|
||||||
/ (2.0f * pid->tau + pid->T);
|
/ (2.0f * pid->tau + pid->T);
|
||||||
|
|
||||||
@@ -74,17 +56,7 @@ float pidControllerUpdate(PidController *pid, float setpoint, float measurement)
|
|||||||
/*
|
/*
|
||||||
* Compute output and apply limits
|
* Compute output and apply limits
|
||||||
*/
|
*/
|
||||||
pid->out = pid->proportional + pid->integrator + pid->differentiator;
|
pid->out = pid->offset + pid->proportional + pid->integrator + pid->differentiator;
|
||||||
|
|
||||||
if (pid->proportional > pid->limMax) {
|
|
||||||
|
|
||||||
pid->proportional = pid->limMax;
|
|
||||||
|
|
||||||
} else if (pid->proportional < pid->limMin) {
|
|
||||||
|
|
||||||
pid->proportional = pid->limMin;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid->out > pid->limMax) {
|
if (pid->out > pid->limMax) {
|
||||||
|
|
||||||
@@ -102,4 +74,5 @@ float pidControllerUpdate(PidController *pid, float setpoint, float measurement)
|
|||||||
|
|
||||||
/* Return controller output */
|
/* Return controller output */
|
||||||
return pid->out;
|
return pid->out;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
22
PID.h
22
PID.h
@@ -1,8 +1,6 @@
|
|||||||
#ifndef PID_CONTROLLER_H
|
#ifndef PID_CONTROLLER_H
|
||||||
#define PID_CONTROLLER_H
|
#define PID_CONTROLLER_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
/* Controller gains */
|
/* Controller gains */
|
||||||
@@ -10,11 +8,6 @@ typedef struct {
|
|||||||
float Ki;
|
float Ki;
|
||||||
float Kd;
|
float Kd;
|
||||||
|
|
||||||
/* Default controller gains */
|
|
||||||
float KpDefault;
|
|
||||||
float KiDefault;
|
|
||||||
float KdDefault;
|
|
||||||
|
|
||||||
/* Derivative low-pass filter time constant */
|
/* Derivative low-pass filter time constant */
|
||||||
float tau;
|
float tau;
|
||||||
|
|
||||||
@@ -29,23 +22,22 @@ typedef struct {
|
|||||||
/* Sample time (in seconds) */
|
/* Sample time (in seconds) */
|
||||||
float T;
|
float T;
|
||||||
|
|
||||||
bool enable;
|
/* pid coefficient offset for start pid */
|
||||||
|
float offset;
|
||||||
|
|
||||||
/* Controller "memory" */
|
/* Controller "memory" */
|
||||||
float proportional;
|
|
||||||
float integrator;
|
float integrator;
|
||||||
float prevError; /* Required for integrator */
|
float prevError; /* Required for integrator */
|
||||||
|
float proportional;
|
||||||
float differentiator;
|
float differentiator;
|
||||||
float prevMeasurement; /* Required for differentiator */
|
float prevMeasurement; /* Required for differentiator */
|
||||||
|
|
||||||
/* Controller output */
|
/* Controller output */
|
||||||
float out;
|
float out;
|
||||||
|
|
||||||
} PidController;
|
} PIDController;
|
||||||
|
|
||||||
void pidControllerInit(PidController *pid, float Kp, float Ki, float Kd, float tau, float limMin, float limMax,
|
void PIDController_Init(PIDController *pid);
|
||||||
float limMinInt, float limMaxInt, float T);
|
float PIDController_Update(PIDController *pid, float setpoint, float measurement);
|
||||||
|
|
||||||
float pidControllerUpdate(PidController *pid, float setpoint, float measurement);
|
#endif
|
||||||
|
|
||||||
#endif //PID_CONTROLLER_H
|
|
||||||
|
|||||||
65
PID_Test.txt
Normal file
65
PID_Test.txt
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "PID.h"
|
||||||
|
|
||||||
|
/* Controller parameters */
|
||||||
|
#define PID_KP 2.0f
|
||||||
|
#define PID_KI 0.5f
|
||||||
|
#define PID_KD 0.25f
|
||||||
|
|
||||||
|
#define PID_TAU 0.02f
|
||||||
|
|
||||||
|
#define PID_LIM_MIN -10.0f
|
||||||
|
#define PID_LIM_MAX 10.0f
|
||||||
|
|
||||||
|
#define PID_LIM_MIN_INT -5.0f
|
||||||
|
#define PID_LIM_MAX_INT 5.0f
|
||||||
|
|
||||||
|
#define SAMPLE_TIME_S 0.01f
|
||||||
|
|
||||||
|
/* Maximum run-time of simulation */
|
||||||
|
#define SIMULATION_TIME_MAX 4.0f
|
||||||
|
|
||||||
|
/* Simulated dynamical system (first order) */
|
||||||
|
float TestSystem_Update(float inp);
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
/* Initialise PID controller */
|
||||||
|
PIDController pid = { PID_KP, PID_KI, PID_KD,
|
||||||
|
PID_TAU,
|
||||||
|
PID_LIM_MIN, PID_LIM_MAX,
|
||||||
|
PID_LIM_MIN_INT, PID_LIM_MAX_INT,
|
||||||
|
SAMPLE_TIME_S };
|
||||||
|
|
||||||
|
PIDController_Init(&pid);
|
||||||
|
|
||||||
|
/* Simulate response using test system */
|
||||||
|
float setpoint = 1.0f;
|
||||||
|
|
||||||
|
printf("Time (s)\tSystem Output\tControllerOutput\r\n");
|
||||||
|
for (float t = 0.0f; t <= SIMULATION_TIME_MAX; t += SAMPLE_TIME_S) {
|
||||||
|
|
||||||
|
/* Get measurement from system */
|
||||||
|
float measurement = TestSystem_Update(pid.out);
|
||||||
|
|
||||||
|
/* Compute new control signal */
|
||||||
|
PIDController_Update(&pid, setpoint, measurement);
|
||||||
|
|
||||||
|
printf("%f\t%f\t%f\r\n", t, measurement, pid.out);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TestSystem_Update(float inp) {
|
||||||
|
|
||||||
|
static float output = 0.0f;
|
||||||
|
static const float alpha = 0.02f;
|
||||||
|
|
||||||
|
output = (SAMPLE_TIME_S * inp + output) / (1.0f + alpha * SAMPLE_TIME_S);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
5
README.md
Normal file
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# PID
|
||||||
|
PID controller implementation written in C.
|
||||||
|
|
||||||
|
Note on 'derivative-on-measurement': Since the 'error signal' effectively going into the differentiator does not depend on the setpoint: e[n] = 0 - measurement, and therefore (e[n] - e[n - 1]) = (0 - measurement) - (0 - prevMeasurement) = -Kd * (measurement - prevMeasurement). (Note the minus sign compared to derivative-on-error!)
|
||||||
|
I've included the minus sign in the code, so gains will have the effect as normal.
|
||||||
Reference in New Issue
Block a user