Follower Robot

Dependencies:   Motor2 PID mbed-rtos mbed

main.cpp

Committer:
mpereira30
Date:
2016-12-11
Revision:
0:4d45673148c2

File content as of revision 0:4d45673148c2:

#include "mbed.h" 
#include "Motor.h"
#include "PID.h"
#include <stdlib.h>
#include "rtos.h"

#define PI 3.1415926
#define threshold 27
//objects:
Motor rightMotor(p24, p28, p27); // pwm, fwd(in1), rev(in2) Motor B (right wheel)
Motor leftMotor(p22, p29, p30); // pwm, fwd(in1), rev(in2) Motor A (left wheel)
Timer timer;
Serial xbee(p13, p14);
Serial pc(USBTX,USBRX);
Mutex wheelMutex;
Mutex timermutex; 

//functions
void go_fwd(float);
void turn_R(float);
void turn_L(float);
void stop(float);
void tunePID(void);
void go_fwd_thread(void const *argument);

//globals:
int leftPrevPulses  = 0;
int leftActPulses=0; //pulses from left motor
float leftVelocity  = 0.0; //The velocity of the left wheel in pulses per second
int rightPrevPulses = 0;
int rightActPulses=0; //pulses from right motor
float rightVelocity = 0.0; //The velocity of the right wheel in pulses per second
int turnDistance     = 0; //Number of pulses to travel.
int distanceR = 0; // in mm
int distanceL = 0; // in mm
int distanceRold = 0; // in mm
int distanceLold = 0; // in mm
bool go;
float go_time = 0.0;

class Counter {     //interrupt driven rotation counter to be used with the feedback control
    public:
    Counter(PinName pin) : _interrupt(pin) {        // create the InterruptIn on the pin specified to Counter
        _interrupt.rise(this, &Counter::increment); // attach increment function of this counter instance
    }
 
    void increment() {
        _count++;
    }
 
    int read() {
        return _count;
    }
 
private:
    InterruptIn _interrupt;
    volatile int _count;
};


Counter leftPulses(p9), rightPulses (p10);
PID leftPid(0.4620, 0.1, 0.1, 0.01);  //Kc, Ti, Td
PID rightPid(0.4620, 0.1, 0.1, 0.01); //Kc, Ti, Td
//PID rightPid(0.515, 0.1, 0.0, 0.01); //Kc, Ti, Td

int main()
{
    tunePID();
    xbee.baud(19200);
    leftPid.setSetPoint(975);  //set velocity goals for PID
    rightPid.setSetPoint(990);
    wait(1);
    Thread fwdThread(go_fwd_thread);
    go = false;
    char tag;
    char turnDirectionBuf[5];
    float turnDirection; 
    char distToTravelBuf[5];
    float distToTravel;
    while(1)
    {
        tag = xbee.getc();
        
        if(tag == '*')
        {
            //pc.printf("tag=%c\r\n",tag);
            distToTravelBuf[0] = xbee.getc();
            distToTravelBuf[1] = xbee.getc();
            distToTravelBuf[2] = xbee.getc();
            distToTravelBuf[3] = xbee.getc();
            distToTravelBuf[4] = xbee.getc();
            //pc.printf("dist = %s\r\n",distToTravelBuf);
            distToTravel = atof(distToTravelBuf);
            //pc.printf("traveldist=%f\r\n",distToTravel);
            //go_fwd(distToTravel);
            timermutex.lock();
            go_time = distToTravel;
            timermutex.unlock();
            go = true;
                                    
        }
        else if(tag == 'R')
        {
            //pc.printf("tag=%c\r\n",tag);
            turnDirectionBuf[0] = xbee.getc();
            turnDirectionBuf[1] = xbee.getc();
            turnDirectionBuf[2] = xbee.getc();
            turnDirectionBuf[3] = xbee.getc();
            turnDirectionBuf[4] = xbee.getc();
            //pc.printf("turn right %s\n\r",turnDirectionBuf);
            turnDirection = atof(turnDirectionBuf);
            //pc.printf("turn right %f\n\r",turnDirection);
            stop(1);
            turn_R(turnDirection);
        }
        else if(tag == 'L')
        {
            //pc.printf("tag=%c\r\n",tag);
            turnDirectionBuf[0] = xbee.getc();
            turnDirectionBuf[1] = xbee.getc();
            turnDirectionBuf[2] = xbee.getc();
            turnDirectionBuf[3] = xbee.getc();
            turnDirectionBuf[4] = xbee.getc();
            //pc.printf("turn left %s\n\r",turnDirectionBuf);
            turnDirection = atof(turnDirectionBuf);
            //pc.printf("turn left %f\n\r",turnDirection);
            stop(1);
            turn_L(turnDirection);
        }   
    }
} 

void tunePID(void){
    leftPid.setInputLimits(0, 3000);    
    leftPid.setOutputLimits(0.0, 0.4);
    leftPid.setMode(AUTO_MODE);
    rightPid.setInputLimits(0, 3000);
    rightPid.setOutputLimits(0.0, 0.4);
    rightPid.setMode(AUTO_MODE);
}

//void go_fwd(float time)
//{
void go_fwd_thread(void const *argument) {
    while(1){
        if(!go) {Thread::yield();}
        while (go) {
            wheelMutex.lock();

    timer.start();
    while(timer.read_ms() < go_time){
    leftActPulses=leftPulses.read();
    leftVelocity = (leftActPulses - leftPrevPulses) / 0.01;
    leftPrevPulses = leftActPulses;
    rightActPulses=rightPulses.read();
    rightVelocity = (rightActPulses - rightPrevPulses) / 0.01;
    rightPrevPulses = rightActPulses;    
    leftPid.setProcessValue(fabs(leftVelocity));
    leftMotor.speed(leftPid.compute());
    rightPid.setProcessValue(fabs(rightVelocity));
    rightMotor.speed(rightPid.compute());
    }
    timer.stop();
    timer.reset();
    go = false;
    timermutex.lock();
    go_time = 0.0;
    timermutex.unlock();
    wheelMutex.unlock();
    }
 
  }
}


void stop(float t)
{
    wheelMutex.lock();
    
    leftMotor.speed(0.0);    
    rightMotor.speed(0.0);
    //wait(t);
    wheelMutex.unlock();
}




void turn_R(float deg)
{
    wheelMutex.lock();
    leftActPulses=leftPulses.read();
    rightActPulses=rightPulses.read();
    turnDistance=rightActPulses+(int)deg;     
    while (rightActPulses<turnDistance) { //turn approximately half a revolution
    leftMotor.speed(0.35);  //rotate to the right
    rightMotor.speed(-0.35);  //open loop, because the PID class can't handle negative values
    leftActPulses=leftPulses.read();
    rightActPulses=rightPulses.read();
    wait(0.005);
    }
    wheelMutex.unlock();
    stop(1);
}
    
void turn_L(float deg)
{
    wheelMutex.lock();
    leftActPulses=leftPulses.read();
    rightActPulses=rightPulses.read();
    turnDistance=leftActPulses+(int)deg;     
    while (leftActPulses<turnDistance) { //turn approximately half a revolution
    leftMotor.speed(-0.35);  //rotate to the right
    rightMotor.speed(0.35);  //open loop, because the PID class can't handle negative values
    leftActPulses=leftPulses.read();
    rightActPulses=rightPulses.read();
    wait(0.005);
    }
    wheelMutex.unlock();
    stop(1);
}