Exercise #2 -- show the angular velocity in HIDScope

Dependencies:   HIDScope QEI mbed

main.cpp

Committer:
Jankoekenpan
Date:
2016-10-07
Revision:
0:35f03aa18046

File content as of revision 0:35f03aa18046:

#include "mbed.h"
#include "math.h"
#include "HIDScope.h"
#include "QEI.h"

// ------ Hardware Interfaces -------

const PinName motor1dir = D7;
const PinName motor1PWM = D6;
DigitalOut motor1direction(motor1dir);
PwmOut motor1control(motor1PWM);

const PinName button1name = D10; //for some reason D8 does not seem to work. wtf!
const PinName pot1name = A0;
InterruptIn button1(button1name);
AnalogIn potMeterIn(pot1name);

const PinName encoderpin1 = D13;
const PinName encoderpin2 = D12;
QEI qei(encoderpin1, encoderpin2, NC, 32);

// ------- Objects used -------

// Ticker which controls the mother every 1/100 of a second.
Ticker controlTicker;

Ticker debugTicker;
Serial pc(USBTX, USBRX);

Ticker encoderTicker;

HIDScope scope(1);

// ------- Constants

const float motorGain = 8.4f;

const float MAX_VELOCITY = 8.4f; //radians per second

const bool CLOCKWISE = true;

//1 output rod revolution == 131.25 encoder revolution
const float RATIO = 1.0f/131.25f;

const float tSample = 1.0f/1000.0f;

const double pi = 3.14159265358979323846;

const int VELOCITY_CHANNEL = 0;


// ------ variables

volatile bool direction = CLOCKWISE;

volatile double lastEncoderRead = 0; //angle in radians.

// ------ functions

float getReferenceVelocity() {
    // Returns reference velocity in rad/s. 
    return MAX_VELOCITY * potMeterIn.read();
}

void setMotor1(float motorValue) {
    // Given motorValue<=1, writes the velocity to the pwm control.
    // MotorValues outside range are truncated to within range.
    motor1control.write(fabs(motorValue) > 1 ? 1 : fabs(motorValue));
}

float feedForwardControl(float referenceVelocity) {
    // very simple linear feed-forward control
    // returns motorValue
    return referenceVelocity / motorGain;
}

void measureAndControl(void) {
    // This function measures the potmeter position, extracts a
    // reference velocity from it, and controls the motor with 
    // a simple FeedForward controller. Call this from a Ticker.
    float referenceVelocity = getReferenceVelocity();
    float motorValue = feedForwardControl(referenceVelocity);
    setMotor1(motorValue);
}

void onButtonPress() {
    // reverses the direction
    motor1direction.write(direction = !direction);
    pc.printf("direction: %s\r\n\n", direction == CLOCKWISE ? "clockwise" : "counter clockwise");
}

void onDebugTick() {
    
    pc.printf("pot input: %f\r\n", potMeterIn.read());
    pc.printf("motorValue: %f\r\n", feedForwardControl(getReferenceVelocity()));
    pc.printf("\n\n\n");

}

void encoderTick() {
    int pulses = qei.getPulses();
    
    //calculate the total angle that is travelel so far.
    double radians = (pulses / tSample) * ((2*pi)/32);
    
    //approximate the derivative for the angular velocity.
    double xdif = radians - lastEncoderRead;
    double xderiv = xdif / tSample;
    
    //TODO apply a BiQuard filter in between here.
    
    //send velocity to HIDScope
    scope.set(VELOCITY_CHANNEL, xderiv);
    scope.send();
    
    //update lastEncoderRead such that it can be used for next time
    lastEncoderRead = radians;
}

int main()
{
    pc.baud(115200);
    qei.reset();
    
    encoderTicker.attach(&encoderTick, tSample);
    controlTicker.attach(&measureAndControl, 1.0f/100.0f);
    button1.fall(&onButtonPress);
    
    debugTicker.attach(&onDebugTick, 1);
    
    while (true);
}