PI Controller working!

Dependencies:   HIDScope MODSERIAL QEI biquadFilter mbed

Fork of prog_pract3_3_feedback by Gerhard Berman

main.cpp

Committer:
GerhardBerman
Date:
2016-10-17
Revision:
4:19e376d31380
Parent:
3:8caef4872b0c
Child:
5:37e230689418

File content as of revision 4:19e376d31380:

#include "mbed.h"
#include <math.h>
#include "MODSERIAL.h"
#include "QEI.h"
#include "HIDScope.h"
#include "BiQuad.h"

//set pins
DigitalIn encoder1A (D13); //Channel A van Encoder 1
DigitalIn encoder1B (D12); //Channel B van Encoder 1
DigitalOut led1 (D11); 
DigitalOut led2 (D10);
AnalogIn potMeter1(A2);
AnalogIn potMeter2(A1);
DigitalOut motor1DirectionPin(D7);
PwmOut motor1MagnitudePin(D6);
DigitalIn button1(D5);

//set settings
Serial pc(USBTX,USBRX);
Ticker MeasureTicker, BiQuadTicker; //, TimeTracker; // sampleT;
//HIDScope    scope(2);

//set datatypes
int counts = 0;
double DerivativeCounts;

float error_prev = 0;
float IntError = 0;
float t_sample = 0.01; //seconds

int countsPrev = 0;
float referenceVelocity = 0;
float bqcDerivativeCounts = 0;
const float PI = 3.141592653589793;
//float Potmeter1 = potMeter1.read();
//float Potmeter2 = potMeter2.read();
const int cw = 0;       //values for cw and ccw are inverted!! cw=0 and ccw=1
const int ccw = 1;

//set BiQuad
BiQuadChain bqc;
BiQuad bq1(0.0186,    0.0743,    0.1114,    0.0743,    0.0186); //get numbers from butter filter MATLAB
BiQuad bq2(1.0000,   -1.5704,    1.2756,   -0.4844,    0.0762);

//set go-Ticker settings
volatile bool MeasureTicker_go=false, BiQuadTicker_go=false, FeedbackTicker_go=false, TimeTracker_go=false; // sampleT_go=false;
void MeasureTicker_act(){MeasureTicker_go=true;}; // Activates go-flags
void BiQuadTicker_act(){BiQuadTicker_go=true;};
void FeedbackTicker_act(){FeedbackTicker_go=true;};
void TimeTracker_act(){TimeTracker_go=true;};
//void sampleT_act(){sampleT_go=true;};

//define encoder counts and degrees
QEI Encoder(D12, D13, NC, 32); // turns on encoder
const int counts_per_revolution = 4200; //counts per motor axis revolution
const int inverse_gear_ratio = 131;
//const float motor_axial_resolution = counts_per_revolution/(2*PI);
const float resolution = counts_per_revolution/(2*PI/inverse_gear_ratio);  //87567.0496892 counts per radian, encoder axis

float GetReferencePosition()
{
    // Returns reference position in rad. 
    // Positive value means clockwise rotation.
    const float maxPosition = 2*PI; //6.283185307179586; // in radians
    float Potmeter1 = potMeter1.read();
    float referencePosition = Potmeter1 * maxPosition; //Potmeter1 * maxPosition; //refpos in radians 
    pc.printf("Max Position: %f rad \r\n", maxPosition);
    pc.printf("Potmeter1, refpos: %f \r\n", Potmeter1);
    pc.printf("Motor Axis Ref Position: %f rad \r\n", referencePosition);
    return referencePosition;
}

float FeedForwardControl(float referencePosition)
{
    float EncoderPosition = counts/resolution;         //position in radians, encoder axis
    float Position = EncoderPosition*inverse_gear_ratio;        //position in radians, motor axis
    // linear feedback control
    float error = referencePosition - Position; // 'error' in radians
    float Kp = 1; //potMeter2.read();
    
    float IntError = IntError + error*t_sample;
    float Ki = potMeter2.read();
    
    //float DerivativeError = (error_prev + error)/t_sample;
    //float Kd = 1;
    
    float motorValue = error * Kp + IntError * Ki; //+ DerivativeError * Kd;
    pc.printf("Motor Axis Position: %f rad \r\n", Position);
    pc.printf("Counts encoder: %i rad \r\n", counts);
    pc.printf("Kp: %f \r\n", Kp);
    pc.printf("MotorValue: %f \r\n", motorValue);
    
    error_prev = error;
    return motorValue;
}

void SetMotor1(float motorValue)
{
    // Given -1<=motorValue<=1, this sets the PWM and direction
    // bits for motor 1. Positive value makes motor rotating
    // clockwise. motorValues outside range are truncated to
    // within range
    if (motorValue >=0) 
        {motor1DirectionPin=cw;
        led1=1;
        led2=0;
        }
    else {motor1DirectionPin=ccw;
        led1=0;
        led2=1;
        }
    if (fabs(motorValue)>1) motor1MagnitudePin = 1;
        else motor1MagnitudePin = fabs(motorValue);
}

void MeasureAndControl()
{
    // This function measures the potmeter position, extracts a
    // reference position from it, and controls the motor with 
    // a Feedback controller. Call this from a Ticker.
    float referencePosition = GetReferencePosition();
    float motorValue = FeedForwardControl(referencePosition);
    SetMotor1(motorValue);
}

void TimeTrackerF(){
     //wait(1);   
     //float Potmeter1 = potMeter1.read();
     float referencePosition = GetReferencePosition();
     pc.printf("TTReference Position: %d rad \r\n", referencePosition);
     //pc.printf("TTPotmeter1, for refpos: %f \r\n", Potmeter1);
     //pc.printf("TTPotmeter2, Kp: %f \r\n", Potmeter2);
     pc.printf("TTCounts: %i \r\n", counts);
}
/*
void sample()
{
    int countsPrev = 0;
    QEI Encoder(D12, D13, NC, 32);
    counts = Encoder.getPulses();  // gives position
    //scope.set(0,counts);
    DerivativeCounts = (counts-countsPrev)/0.001;
    //scope.set(1,DerivativeCounts);
    countsPrev = counts; 
    //scope.send();
    pc.printf("Counts: %i rad/s \r\n", counts);
    pc.printf("Derivative Counts: %d rad/s \r\n", DerivativeCounts);
}

void BiQuadFilter(){            //this function creates a BiQuad filter for the DerivativeCounts
    //double in=DerivativeCounts();
    bqcDerivativeCounts=bqc.step(DerivativeCounts);
    //return(bqcDerivativeCounts);
    }
    
void MeasureP(){
    double ref_position = Potmeter1;                //reference position from potmeter
    int counts = Encoder.getPulses();           // gives position    
    double position = counts/resolution;         //position in radians
    double rotation = ref_position-position;     //rotation is 'position error' in radians
    double movement = rotation/(2*PI);  //movement in rotations
    double Kp = Potmeter2;
    }
    
double P(double rotation, double Kp){
    double P_output = Kp*movement;
    return P_output;
    }
    
void MotorController(){
    double output = P(rotation, Kp);
    
    if(rotation>0){
        motor1DirectionPin.write(cw);
        motor1MagnitudePin.write(output);
        }
    if(rotation<0){
        motor1DirectionPin.write(ccw);
        motor1MagnitudePin.write(-output);
        }
    }
*/
int main()
{
 //Initialize
 led1=1;
 led2=1;
 pc.baud(115200);
 pc.printf("Test putty");
 //float Potmeter = potMeterIn.read();
 MeasureTicker.attach(&MeasureTicker_act, 0.01f); 
 bqc.add(&bq1).add(&bq2);
 //BiQuadTicker.attach(&BiQuadTicker_act, 0.01f); //frequentie van 100 Hz
 //TimeTracker.attach(&TimeTracker_act, 1.0f);
 QEI Encoder(D12, D13, NC, 32); // turns on encoder
 //sampleT.attach(&sampleT_act, 0.1f);
 //pc.printf("Reference velocity: %f rad/s \r\n", referenceVelocity);
 //pc.printf("Potmeter: %f rad/s \r\n", Potmeter);
 
 while(1)
    {
        if (MeasureTicker_go){
            MeasureTicker_go=false;
            MeasureAndControl();
            counts = Encoder.getPulses();           // gives position of encoder 
            pc.printf("Resolution: %f pulses/rad \r\n",resolution);
            }
      /*
            // Encoder part
            counts = Encoder.getPulses();  // gives position
            DerivativeCounts = ((double) counts-countsPrev)/0.01;  
            
            scope.set(0,counts);
            scope.set(1,DerivativeCounts);
            //scope.set(1,bqcDerivativeCounts);
            scope.send();
            countsPrev = counts;
            //pc.printf("Counts: %i rad/s \r\n", counts);
            //pc.printf("Derivative Counts: %f rad/s \r\n", DerivativeCounts);
        }
        
        if (BiQuadTicker_go){
            BiQuadTicker_go=false;
            BiQuadFilter();
        }
    
        if (FeedbackTicker_go){
            FeedbackTicker_go=false;
            Feedback();
        
        if (TimeTracker_go){
            TimeTracker_go=false;
            TimeTrackerF();
        }
        
        if (sampleT_go){
            sampleT_go=false;
            sample();
        }*/
    }
}