br3ttb / Arduino-PID-AutoTune-Library

420 stars 225 forks source link

Autotune should be a method for class PID #6

Open t0mpr1c3 opened 11 years ago

t0mpr1c3 commented 11 years ago

It seems desirable to me to have the entire PID object passed to the auto tune function rather than the individual variables. Probably not possible since I don't see a way to do this that would not break existing programs.

br3ttb commented 11 years ago

I can definitely see benefit to something like a hard-link between the PID and Autotune. at the same time, there's a little dance that happens between pid and autotune when the "autotune" button is pressed, and I don't think that dance will be the same in every application. having a them separate allows for some flexibility on that front.

maybe the solution is a LinkedAutotune class that inherits from the autotuner. it could get passed all the same constructors, along with a pointer to a pid object.

t0mpr1c3 commented 11 years ago

I'll probably code something up in a fork. It may not be for everybody, like you say.

Wei1234c commented 8 years ago

Here is the class I'm using, which combine PID and PID_ATune. Set autoTune = true, and it will adapt the tuned parameters automatically when the tuning process is completed.

`

ifndef PID_enhanced_H

define PID_enhanced_H

include

include

class PID_enhanced: public PID, public PID_ATune {

private:

byte currentMode = 2;

public:

double Input, Output, Setpoint = 0;   
bool autoTune = false;   

PID_enhanced(double Kp = 2, double Ki = 5, double Kd = 1, 
             int ControllerDirection = DIRECT, 
             int SampleTime = 100, 
             double OutputLimit_min = 0, double OutputLimit_max = 255,
             int controlType = 0) 
             : PID(&this->Input, &this->Output, &this->Setpoint, Kp, Ki, Kd, ControllerDirection),
               PID_ATune(&this->Input, &this->Output){ 

  SetOutputLimits(OutputLimit_min, OutputLimit_max);
  SetSampleTime(SampleTime);
  SetControlType(controlType);
}

void setup() {
  SetMode(AUTOMATIC);
  backupMode();
  Cancel();
}

int tune() {
  int result = 0; 

  if (autoTune) {
    result = PID_ATune::Runtime();
    if (result !=0) { 
      adaptTunedParameters();
      Cancel();
      autoTune = false;
    }
  }

  return result;
}

int tuneAndCompute() {
  if (autoTune) {
    return tune();
  } else {
    Compute();
    return 0;
  }
}

void backupMode() { 
    currentMode = GetMode();
}    

void restoreMode() {  
    SetMode(currentMode);
}    

double GetOperatingKp()
{
  return PID::GetKp();
}

double GetOperatingKi()
{
  return PID::GetKi();
}

double GetOperatingKd()
{
  return PID::GetKd();
}

double GetTunedKp()
{
  return PID_ATune::GetKp();
}

double GetTunedKi()
{
  return PID_ATune::GetKi();
}

double GetTunedKd()
{
  return PID_ATune::GetKd();
}

void adaptTunedParameters() {
  SetTunings(GetTunedKp(), GetTunedKi(), GetTunedKd());

  Serial.println("Parameters set to: ");
  Serial.print("Kp: ");Serial.print(GetOperatingKp());Serial.print("; ");
  Serial.print("Ki: ");Serial.print(GetOperatingKi());Serial.print("; ");
  Serial.print("Kd: ");Serial.print(GetOperatingKd());Serial.print("; ");
  Serial.println();        
}

};

endif

`

edgsc commented 7 years ago

I tried using your code, Wei1234c, but it returns me this error:

Archiving built core (caching) in: C:\Users\EDUARD~1\AppData\Local\Temp\arduino_cache_379640\core\core_arduino_avr_uno_0c812875ac70eb4a9b385d8fb077f54c.a
C:\Users\EDUARD~1\AppData\Local\Temp\ccGD3Nq5.ltrans0.ltrans.o: In function `main':

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/main.cpp:43: undefined reference to `setup'

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/main.cpp:46: undefined reference to `loop'

collect2.exe: error: ld returned 1 exit status

exit status 1

Has anyone got it to work?

Thanks!