Library with P, PI and PID controller

Dependents:   buttoncontrol includeair includeair Oudverslag

controlandadjust.cpp

Committer:
Gerth
Date:
2015-10-26
Revision:
18:ef413d2fd0b1
Parent:
17:666505754e3f
Child:
19:e3585d3c5a85

File content as of revision 18:ef413d2fd0b1:

#include "controlandadjust.h"
#include "mbed.h"
#include "QEI.h"

float CW=1;
float CCW=0;
float direction1,direction2;
float speed1,speed2;
float signaal1,signaal2;
float error1_int,error2_int;
float error1_prev,error2_prev;

float maxvaluepwm=0;
float minimal_error;
float Ts;
const float pi=3.14159265359;
const float degtorad=(pi/180);


DigitalOut motor1_dir(D7);// draairichting motor 1 (1 is CW encoder als je daar op kijkt en CW shaft als je daar op kijkt)
PwmOut motor1_speed(D6);//aanstuursnelheid motor 1
PwmOut motor2_speed(D5);
DigitalOut motor2_dir(D4);



controlandadjust::controlandadjust(float errorband, float controlfrequency)
{
    minimal_error=errorband*degtorad/2;
    Ts=1.0/controlfrequency;
}

void controlandadjust::verwerksignaal(float signaal1,float signaal2)
{
    //motor1
    if (signaal1>=0) {//determine CW or CCW rotation
        direction1=CCW;
    } else {
        direction1=CW;
    }

    if (fabs(signaal1)>=maxvaluepwm) { //check if signal is <1
        speed1=maxvaluepwm;//if signal >1 make it 1 to not damage motor
    } else {
        speed1=fabs(signaal1);// if signal<1 use signal
    }

    //motor2
    if (signaal2>=0) {//determine CW or CCW rotation
        direction2=CW;
    } else {
        direction2=CCW;
    }

    if (fabs(signaal2)>=maxvaluepwm) { //check if signal is <1
        speed2=maxvaluepwm;//if signal >1 make it 1 to not damage motor
    } else {
        speed2=fabs(signaal2);// if signal<1 use signal
    }
    //write to motor
    motor1_dir.write(direction1);
    motor1_speed.write(speed1);
    motor2_dir.write(direction2);
    motor2_speed.write(speed2);

}
float controlandadjust::motor1pwm()
{
    return speed1;
}

float controlandadjust::motor2pwm()
{
    return speed2;
}


void controlandadjust::P(float error1,float error2,float Kp)
{
    signaal1=error1*Kp;
    signaal2=error2*Kp;

    //check if error is big enough to produce signal, else signal is 0 to save motors
    if (fabs(error1) > minimal_error && fabs(error2) > minimal_error) {
        verwerksignaal(signaal1,signaal2);
    } else if (fabs(error1) <= minimal_error && fabs(error2) <= minimal_error) {
        verwerksignaal(0,0);
    } else if (fabs(error1) > minimal_error && fabs(error2) <= minimal_error) {
        verwerksignaal(signaal1,0);
    } else if (fabs(error1) <= minimal_error && fabs(error2) > minimal_error) {
        verwerksignaal(0,signaal2);
    }
}

void controlandadjust::PI(float error1, float error2, float Kp, float Ki)
{
    error1_int = error1_int + Ts * error1;
    signaal1=Kp*error1+Ki*error1_int;

    error2_int = error2_int + Ts * error2;
    signaal2=Kp*error2+Ki*error2_int;

    //check if error is big enough to produce signal, else signal is 0 to save motors
    //and make error_int 0 if the error is small enough to protect from "spooling up"
    if (fabs(error1) > minimal_error && fabs(error2) > minimal_error) {
        verwerksignaal(signaal1,signaal2);
    } else if (fabs(error1) <= minimal_error && fabs(error2) <= minimal_error) {
        verwerksignaal(0,0);
        error1_int=0,error2_int=0;
    } else if (fabs(error1) > minimal_error && fabs(error2) <= minimal_error) {
        verwerksignaal(signaal1,0);
        error2_int=0;
    } else if (fabs(error1) <= minimal_error && fabs(error2) > minimal_error) {
        verwerksignaal(0,signaal2);
        error1_int=0;
    }
}

void controlandadjust::PID(float error1, float error2, float Kp, float Ki,float Kd)
{
    // Derivative
    double error1_der = (error1 - error1_prev)/Ts;
    error1_prev = error1;

    double error2_der = (error2 - error2_prev)/Ts;
    error2_prev = error2;

// Integral
    error1_int = error1_int + Ts * error1;
    error2_int = error2_int + Ts * error2;
// PID
    signaal1= Kp * error1 + Ki * error1_int + Kd * error1_der;
    signaal2= Kp * error2 + Ki * error2_int + Kd * error2_der;

    //check if error is big enough to produce signal, else signal is 0 to save motors
    //and make error_int 0 if the error is small enough to protect from "spooling up"
    if (fabs(error1) > minimal_error && fabs(error2) > minimal_error) {
        verwerksignaal(signaal1,signaal2);
    } else if (fabs(error1) <= minimal_error && fabs(error2) <= minimal_error) {
        verwerksignaal(0,0);
        error1_int=0,error2_int=0;
    } else if (fabs(error1) > minimal_error && fabs(error2) <= minimal_error) {
        verwerksignaal(signaal1,0);
        error2_int=0;
    } else if (fabs(error1) <= minimal_error && fabs(error2) > minimal_error) {
        verwerksignaal(0,signaal2);
        error1_int=0;
    }
}
//////////////////////////////////////PID WITH LOW PASS FILTER
void controlandadjust::PIDLowPass(float error1, float error2, float Kp, float Ki,float Kd, float tau_p)
{
    // Derivative
    double error1_der = (error1 - error1_prev)/Ts; //(e(k)-e(k-1))/Ts
    error1_prev = error1;

    double error2_der = (error2 - error2_prev)/Ts;
    error2_prev = error2;

// Integral
    error1_int = error1_int + Ts * error1;
    error2_int = error2_int + Ts * error2;
// PID
     signaal1= (signaal1*(tau_p/Ts) + Kp * error1 + Ki * error1_int + Kd * error1_der)*( 1/( 1+ (tau_p/Ts) ) );
     signaal2= (signaal2*(tau_p/Ts) + Kp * error2 + Ki * error2_int + Kd * error2_der)*( 1/( 1+ (tau_p/Ts) ) );

    //check if error is big enough to produce signal, else signal is 0 to save motors
    //and make error_int 0 if the error is small enough to protect from "spooling up"
    if (fabs(error1) > minimal_error && fabs(error2) > minimal_error) {
        verwerksignaal(signaal1,signaal2);
    } else if (fabs(error1) <= minimal_error && fabs(error2) <= minimal_error) {
        verwerksignaal(0,0);
        error1_int=0,error2_int=0;
    } else if (fabs(error1) > minimal_error && fabs(error2) <= minimal_error) {
        verwerksignaal(signaal1,0);
        error2_int=0;
    } else if (fabs(error1) <= minimal_error && fabs(error2) > minimal_error) {
        verwerksignaal(0,signaal2);
        error1_int=0;
    }
}

void controlandadjust::STOP()
{
    motor1_speed.write(0);
    motor2_speed.write(0);
}
void controlandadjust::cutoff(float maxvalue)
{
    maxvaluepwm=maxvalue;
}