PID auto-tune
This commit is contained in:
parent
e5bb803869
commit
ee273e07db
|
@ -4,4 +4,5 @@ CONTROLLERS_MATH_SRC =
|
||||||
CONTROLLERS_MATH_SRC_CPP = $(PROJECT_DIR)/controllers/math/engine_math.cpp \
|
CONTROLLERS_MATH_SRC_CPP = $(PROJECT_DIR)/controllers/math/engine_math.cpp \
|
||||||
$(PROJECT_DIR)/controllers/math/pid.cpp \
|
$(PROJECT_DIR)/controllers/math/pid.cpp \
|
||||||
$(PROJECT_DIR)/controllers/math/biquad.cpp \
|
$(PROJECT_DIR)/controllers/math/biquad.cpp \
|
||||||
|
$(PROJECT_DIR)/controllers/math/pid_auto_tune.cpp \
|
||||||
$(PROJECT_DIR)/controllers/math/speed_density.cpp
|
$(PROJECT_DIR)/controllers/math/speed_density.cpp
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pid_auto_tune.h"
|
#include "pid_auto_tune.h"
|
||||||
|
#include "efilib.h"
|
||||||
|
|
||||||
PID_AutoTune::PID_AutoTune() {
|
PID_AutoTune::PID_AutoTune() {
|
||||||
running = false;
|
running = false;
|
||||||
|
@ -14,7 +15,13 @@ PID_AutoTune::PID_AutoTune() {
|
||||||
noiseBand = 0.5;
|
noiseBand = 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PID_AutoTune::Runtime() {
|
void PID_AutoTune::FinishUp() {
|
||||||
|
Ku = 4 * (2 * oStep) / ((absMax - absMin) * 3.14159);
|
||||||
|
Pu = (float) (currentPeakTime - prevPeakTime) / 1000.0; // converting ms to seconds
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int PID_AutoTune::Runtime(Logging *logging) {
|
||||||
justevaled = false;
|
justevaled = false;
|
||||||
if (peakCount > 9 && running) {
|
if (peakCount > 9 && running) {
|
||||||
running = false;
|
running = false;
|
||||||
|
@ -27,11 +34,12 @@ int PID_AutoTune::Runtime() {
|
||||||
//initialize working variables the first time around
|
//initialize working variables the first time around
|
||||||
peakType = 0;
|
peakType = 0;
|
||||||
peakCount = 0;
|
peakCount = 0;
|
||||||
justchanged = false;
|
|
||||||
absMax = input;
|
absMax = input;
|
||||||
absMin = input;
|
absMin = input;
|
||||||
setpoint = input;
|
setpoint = input;
|
||||||
running = true;
|
running = true;
|
||||||
|
dataPointsCount = 0;
|
||||||
outputStart = output;
|
outputStart = output;
|
||||||
output = outputStart + oStep;
|
output = outputStart + oStep;
|
||||||
|
|
||||||
|
@ -45,15 +53,86 @@ int PID_AutoTune::Runtime() {
|
||||||
absMax = input;
|
absMax = input;
|
||||||
if (input < absMin)
|
if (input < absMin)
|
||||||
absMin = input;
|
absMin = input;
|
||||||
|
dataPointsCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//oscillate the output base on the input's relation to the setpoint
|
//oscillate the output base on the input's relation to the setpoint
|
||||||
|
|
||||||
|
float prevOutput = output;
|
||||||
if (input > setpoint + noiseBand)
|
if (input > setpoint + noiseBand)
|
||||||
output = outputStart - oStep;
|
output = outputStart - oStep;
|
||||||
else if (input < setpoint - noiseBand)
|
else if (input < setpoint - noiseBand)
|
||||||
output = outputStart + oStep;
|
output = outputStart + oStep;
|
||||||
|
|
||||||
|
if (output != prevOutput) {
|
||||||
|
scheduleMsg(logging, "direction change");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool isMax = true; // is current input max value for the known input history?
|
||||||
|
bool isMin = true; // is current input min value for the known input history?
|
||||||
|
//identify peaks
|
||||||
|
for (int i = nLookBack - 1; i >= 0; i--) {
|
||||||
|
float val = lastInputs[i];
|
||||||
|
if (isMax)
|
||||||
|
isMax = input > val;
|
||||||
|
if (isMin)
|
||||||
|
isMin = input < val;
|
||||||
|
lastInputs[i + 1] = lastInputs[i];
|
||||||
|
}
|
||||||
|
lastInputs[0] = input;
|
||||||
|
if (dataPointsCount < 9) { //we don't want to trust the maxes or mins until the inputs array has been filled
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isMax || isMin) {
|
||||||
|
scheduleMsg(logging, "min %d max %d %f peakType=%d", isMin, isMax, input, peakType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool directionJustChanged = false;
|
||||||
|
|
||||||
|
if (isMax) {
|
||||||
|
if (peakType == 0)
|
||||||
|
peakType = 1;
|
||||||
|
if (peakType == -1) {
|
||||||
|
peakType = 1;
|
||||||
|
directionJustChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// peaks[peakCount] = input; we are not using max peak values
|
||||||
|
|
||||||
|
} else if (isMin) {
|
||||||
|
if (peakType == 0)
|
||||||
|
peakType = -1;
|
||||||
|
if (peakType == 1) {
|
||||||
|
peakType = -1;
|
||||||
|
prevPeakTime = currentPeakTime;
|
||||||
|
currentPeakTime = currentTimeMillis();
|
||||||
|
directionJustChanged = true;
|
||||||
|
|
||||||
|
if (peakCount < 10) {
|
||||||
|
peakCount++;
|
||||||
|
peaks[peakCount] = input;
|
||||||
|
} else {
|
||||||
|
// todo: reset peak counter maybe?
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (directionJustChanged && peakCount > 2) { //we've transitioned. check if we can autotune based on the last peaks
|
||||||
|
float avgSeparation = (absF(peaks[peakCount - 1] - peaks[peakCount - 2])
|
||||||
|
+ absF(peaks[peakCount - 2] - peaks[peakCount - 3])) / 2;
|
||||||
|
if (avgSeparation < 0.05 * (absMax - absMin)) {
|
||||||
|
FinishUp();
|
||||||
|
running = false;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,16 @@
|
||||||
#ifndef CONTROLLERS_MATH_PID_AUTO_TUNE_H_
|
#ifndef CONTROLLERS_MATH_PID_AUTO_TUNE_H_
|
||||||
#define CONTROLLERS_MATH_PID_AUTO_TUNE_H_
|
#define CONTROLLERS_MATH_PID_AUTO_TUNE_H_
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "rusefi_types.h"
|
||||||
|
|
||||||
class PID_AutoTune {
|
class PID_AutoTune {
|
||||||
public:
|
public:
|
||||||
PID_AutoTune();
|
PID_AutoTune();
|
||||||
void reset();
|
void reset();
|
||||||
void FinishUp();
|
void FinishUp();
|
||||||
int Runtime();
|
int Runtime(Logging *logging);
|
||||||
bool isMax, isMin;
|
// bool isMax, isMin;
|
||||||
/**
|
/**
|
||||||
* sensor position
|
* sensor position
|
||||||
*/
|
*/
|
||||||
|
@ -33,14 +36,16 @@ public:
|
||||||
float noiseBand;
|
float noiseBand;
|
||||||
//int controlType = 1;
|
//int controlType = 1;
|
||||||
bool running;
|
bool running;
|
||||||
unsigned int peak1, peak2, lastTime;
|
efitimems_t currentPeakTime, prevPeakTime;
|
||||||
|
// unsigned int peak1, peak2, lastTime;
|
||||||
//int sampleTime;
|
//int sampleTime;
|
||||||
int nLookBack;
|
int nLookBack;
|
||||||
int peakType; // todo: convert to enum
|
int peakType; // todo: convert to enum
|
||||||
float lastInputs[101];
|
float lastInputs[101];
|
||||||
float peaks[10];
|
float peaks[10];
|
||||||
int peakCount;
|
int peakCount;
|
||||||
bool justchanged;
|
int dataPointsCount;
|
||||||
|
//bool justchanged; //
|
||||||
bool justevaled;
|
bool justevaled;
|
||||||
float absMax, absMin;
|
float absMax, absMin;
|
||||||
float oStep;
|
float oStep;
|
||||||
|
|
Loading…
Reference in New Issue