1

Dependencies:   QEI2 chair_BNO055 PID Watchdog VL53L1X_Filter ros_lib_kinetic

Dependents:   wheelchairControlSumer2019

wheelchair.cpp

Committer:
jvfausto
Date:
2018-08-29
Revision:
18:663b6d693252
Parent:
17:7f3b69300bb6
Child:
19:71a6621ee5c3

File content as of revision 18:663b6d693252:

#include "wheelchair.h"
Serial qei(D1, D0);

bool manual_drive = false;
volatile float north;
//volatile double curr_yaw;
double curr_yaw;
double encoder_distance;
char myString[64];
double Setpoint, Output, Input, Input2;
double pid_yaw, Distance, Setpoint2, Output2, encoder_distance2;
PID myPID(&pid_yaw, &Output, &Setpoint, 5.5, .00, 0.0036, P_ON_E, DIRECT);
PID myPIDDistance(&Input, &Output, &Setpoint, 5.5, .00, 0.0036, P_ON_E, DIRECT);
PID myPIDDistance2(&Input2, &Output2, &Setpoint2, 5.5, .00, 0.0036, P_ON_E, DIRECT);
//QEI wheel_right(D0, D1, NC, 450);
void Wheelchair::compass_thread() {
     curr_yaw = imu->yaw();
     north = boxcar(imu->angle_north());

    }
void Wheelchair::distance_thread() {
/*        int i;
        qei.putc('h');
        //qei.gets(myString, 10);
        ti->reset();

        for (i=0; myString[i-1] != '\n'; i++) {
            while (true) {
                //pc.printf("%f\r\n", ti.read());
                if (ti->read() > .02) break;
                if (qei.readable()) {
                    myString[i]= qei.getc();
                    break;
                    }
                }
        }            
        myString[i-1] = 0;
        encoder_distance = atof(myString);
            //out->printf("displacement = %f\r\n", encoder_distance);
        for(i = 0; i < 64; i++)
        {
            myString[i] = 0;
        }   */ 
}
    
Wheelchair::Wheelchair(PinName xPin, PinName yPin, Serial* pc, Timer* time )
{
    x = new PwmOut(xPin);
    y = new PwmOut(yPin);
    imu = new chair_BNO055(pc, time);
    //imu = new chair_MPU9250(pc, time);
    Wheelchair::stop();
    imu->setup();
    out = pc;
    out->printf("wheelchair setup done \r\n");
    ti = time;
    wheel = new QEI(Encoder1, Encoder2, NC, EncoderReadRate);
    myPID.SetMode(AUTOMATIC);
}

/*
* joystick has analog out of 200-700, scale values between 1.3 and 3.3
*/
void Wheelchair::move(float x_coor, float y_coor)
{

    float scaled_x = ((x_coor * 1.6f) + 1.7f)/3.3f;
    float scaled_y = (3.3f - (y_coor * 1.6f))/3.3f;
    
   // lowPass(scaled_x);
    //lowPass(scaled_y);
    
    x->write(scaled_x);
    y->write(scaled_y);
    
    //out->printf("yaw %f\r\r\n", imu->yaw());

}

void Wheelchair::forward()
{
    x->write(high);
    y->write(def+offset);
  //  out->printf("distance %f\r\n", wheel_right.getDistance(37.5));
}

void Wheelchair::backward()
{
    x->write(low);
    y->write(def);
}

void Wheelchair::right()
{
    x->write(def);
    y->write(low);
}

void Wheelchair::left()
{
    x->write(def);
    y->write(high);
}

void Wheelchair::stop()
{
    x->write(def);
    y->write(def);
}
// counter clockwise is -
// clockwise is +
void Wheelchair::pid_right(int deg) 
{
    bool overturn = false;
    
    out->printf("pid right\r\r\n");
    x->write(def);
    Setpoint = curr_yaw + deg;
    pid_yaw = curr_yaw;
    if(Setpoint > 360) {
     //   Setpoint -= 360;
        overturn = true;
    }
    myPID.SetTunings(5.5,0, 0.00345);
    myPID.SetOutputLimits(0, def-low);
    myPID.SetControllerDirection(REVERSE);
    while(pid_yaw < Setpoint - 3){//curr_yaw <= Setpoint) {
        if(overturn && curr_yaw < Setpoint-deg-1)
        {
            pid_yaw = curr_yaw + 360;
        }   
        else
            pid_yaw = curr_yaw;
        myPID.Compute();
        double tempor = Output+low;
        y->write(tempor);
        out->printf("curr_yaw %f\r\r\n", curr_yaw);
        out->printf("Setpoint = %f \r\n", Setpoint);

        wait(.05);
        }
    Wheelchair::stop();
    out->printf("done \r\n");
    }

void Wheelchair::pid_left(int deg) 
{
    bool overturn = false;
    
    out->printf("pid Left\r\r\n");
    x->write(def);
    Setpoint = curr_yaw - deg;
    pid_yaw = curr_yaw;
    if(Setpoint < 0) {
   //     Setpoint += 360;
        overturn = true;
    }
    myPID.SetTunings(5,0, 0.004);
    myPID.SetOutputLimits(0,high-def);
    myPID.SetControllerDirection(REVERSE);
    while(pid_yaw > Setpoint + 3){//pid_yaw < Setpoint + 2) {
       myPID.Compute();
       if(overturn && curr_yaw > Setpoint+deg+1)
       {
          pid_yaw = curr_yaw - 360;
        }   
        else
            pid_yaw = curr_yaw;
       double tempor = Output+def;

        y->write(tempor);
        out->printf("curr_yaw %f\r\n", curr_yaw);
        wait(.05);
        }
        Wheelchair::stop();
    }

void Wheelchair::pid_turn(int deg) {
    if(deg > 180) {
        deg -= 360;
    }

    else if(deg < -180) {
        deg+=360;
    }  
    
    int turnAmt = abs(deg);
    ti->reset();

    if(deg >= 0){
        Wheelchair::pid_right(turnAmt);
        }
    else {
        Wheelchair::pid_left(turnAmt);
        }
    }
void Wheelchair::pid_foward(double mm)
{
    qei.putc('r');
    out->printf("pid foward\r\n");

    double tempor;
    Setpoint2 = mm;

  //  Setpoint = wheel_right.getDistance(37.5)+mm;
    myPIDDistance.SetTunings(5,0, 0.004);
    myPIDDistance.SetOutputLimits(0,high-def);
    myPIDDistance.SetControllerDirection(DIRECT);
    y->write(def);
    while(encoder_distance < Setpoint2-5){//pid_yaw < Setpoint + 2) {
        int i;
        qei.putc('h');
        //qei.gets(myString, 10);
        ti->reset();

        for (i=0; myString[i-1] != '\n'; i++) {
            while (true) {
                //pc.printf("%f\r\n", ti.read());
                if (ti->read() > .02) break;
                if (qei.readable()) {
                    myString[i]= qei.getc();
                    break;
                    }
                }
        }            
        myString[i-1] = 0;
        double tempor2 = atof(myString);
        out->printf("displacement = %f\r\n", tempor);
        if(abs(tempor - encoder_distance) < 500)
        {
            encoder_distance = tempor;
            out->printf("this is fine\r\n");
        }        
        for(i = 0; i < 64; i++)
        {
            myString[i] = 0;
        } 
        Input = encoder_distance;
        out->printf("input foward %f\r\n", Input);
        wait(.1);
        myPIDDistance.Compute();

        tempor = Output + def;
        x->write(tempor);
        out->printf("distance %f\r\n", encoder_distance);
        }
        
    
}   
void Wheelchair::pid_reverse(double mm)
{
    qei.putc('r');
    out->printf("pid reverse\r\n");

    double tempor;
    Setpoint2 = mm;

  //  Setpoint = wheel_right.getDistance(37.5)+mm;
    myPIDDistance.SetTunings(5,0, 0.004);
    myPIDDistance.SetOutputLimits(0,def);
    myPIDDistance.SetControllerDirection(REVERSE);
    y->write(def);
    while(encoder_distance > Setpoint2+5){//pid_yaw < Setpoint + 2) {
        int i;
        qei.putc('h');
        //qei.gets(myString, 10);
        ti->reset();

        for (i=0; myString[i-1] != '\n'; i++) {
            while (true) {
                //pc.printf("%f\r\n", ti.read());
                if (ti->read() > .02) break;
                if (qei.readable()) {
                    myString[i]= qei.getc();
                    break;
                    }
                }
        }            
        myString[i-1] = 0;
        double tempor = atof(myString);
        out->printf("displacement = %f\r\n", tempor);
        if(abs(tempor - encoder_distance) < 500)
        {
            encoder_distance = tempor;
            out->printf("this is fine\r\n");
        }
        for(i = 0; i < 64; i++)
        {
            myString[i] = 0;
        } 
        Input = encoder_distance;
        out->printf("input foward %f\r\n", Input);
        wait(.1);
        myPIDDistance.Compute();
        
        qei.putc('k');
        //qei.gets(myString, 10);
        ti->reset();

        for (i=0; myString[i-1] != '\n'; i++) {
            while (true) {
                //pc.printf("%f\r\n", ti.read());
                if (ti->read() > .02) break;
                if (qei.readable()) {
                    myString[i]= qei.getc();
                    break;
                    }
                }
        }            
        myString[i-1] = 0;
        double tempor2 = atof(myString);
        out->printf("displacement = %f\r\n", tempor2);
        
        if(abs(tempor - encoder_distance) < 500)
        {
            encoder_distance = tempor;
            out->printf("this is fine\r\n");
        }        
        if(abs(tempor - encoder_distance2) < 500)
        {
            encoder_distance = tempor;
            out->printf("this is fine\r\n");
        }
        for(i = 0; i < 64; i++)
        {
            myString[i] = 0;
        } 
        tempor = Output;
        x->write(tempor);
        out->printf("distance %f\r\n", encoder_distance);
        }
}   
double Wheelchair::turn_right(int deg)
{
    bool overturn = false;
    out->printf("turning right\r\n");

    double start = curr_yaw;
    double final = start + deg;

    if(final > 360) {
        final -= 360;
        overturn = true;
    }

    out->printf("start %f, final %f\r\n", start, final);

    double curr = -1;
    while(curr <= final - 30) {
        Wheelchair::right();
        if( out->readable()) {
            out->printf("stopped\r\n");
            Wheelchair::stop();
            return;
        }
        curr = curr_yaw;
        if(overturn && curr > (360 - deg) ) {
            curr = 0;
        }
    }
    
    out->printf("done turning start %f final %f\r\n", start, final);
    Wheelchair::stop();
    
     //delete me
    wait(5);
    
    float correction = final - curr_yaw;
    out->printf("final pos %f actual pos %f\r\n", final, curr_yaw);
    Wheelchair::turn_left(abs(correction));
    Wheelchair::stop();
    
    wait(5);
    out->printf("curr_yaw %f\r\n", curr_yaw);
    return final;
}

double Wheelchair::turn_left(int deg)
{
    bool overturn = false;
    out->printf("turning left\r\n");

    double start = curr_yaw;
    double final = start - deg;

    if(final < 0) {
        final += 360;
        overturn = true;
    }

    out->printf("start %f, final %f\r\n", start, final);

    double curr = 361;
    while(curr >= final) {
        Wheelchair::left();
        if( out->readable()) {
            out->printf("stopped\r\n");
            Wheelchair::stop();
            return;
        }
        curr = curr_yaw;

        if(overturn && curr >= 0 && curr <= start ) {
            curr = 361;
        }
    }

    out->printf("done turning start %f final %f\r\n", start, final);
    Wheelchair::stop();
    
    //delete me
    wait(2);
    /*
    float correction = final - curr_yaw;
    out->printf("final pos %f actual pos %f\r\n", final, curr_yaw);
    Wheelchair::turn_right(abs(correction));
    Wheelchair::stop();
*/
    return final;
}

void Wheelchair::turn(int deg)
{
    if(deg > 180) {
        deg -= 360;
    }

    else if(deg < -180) {
        deg+=360;
    }  
    
    double finalpos;
    int turnAmt = abs(deg);
    //ti->reset();
    /*
    if(deg >= 0){
        finalpos = Wheelchair::turn_right(turnAmt);
        }
    else {
        finalpos = Wheelchair::turn_left(turnAmt);
        }
    */
    wait(2);
    
    float correction = finalpos - curr_yaw;
    out->printf("final pos %f actual pos %f\r\n", finalpos, curr_yaw);
    
    
    //if(abs(correction) > turn_precision) {
        out->printf("correcting %f\r\n", correction);
        //ti->reset();
        Wheelchair::turn_left(curr_yaw - finalpos);
        return;
        //} 
    
}

float Wheelchair::getDistance() {
    return wheel->getDistance(Diameter);
    }
    
void Wheelchair::resetDistance(){
    wheel->reset();
    }